upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / drivers / net / eepro100.c
index 1132101..0199073 100644 (file)
@@ -102,8 +102,8 @@ static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #include <linux/init.h>
 #include <linux/mii.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
@@ -490,9 +490,6 @@ struct speedo_private {
        unsigned short partner;                 /* Link partner caps. */
        struct mii_if_info mii_if;              /* MII API hooks, info */
        u32 msg_enable;                         /* debug message level */
-#ifdef CONFIG_PM
-       u32 pm_state[16];
-#endif
 };
 
 /* The parameters for a CmdConfigure operation.
@@ -541,6 +538,7 @@ static struct net_device_stats *speedo_get_stats(struct net_device *dev);
 static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void set_rx_mode(struct net_device *dev);
 static void speedo_show_state(struct net_device *dev);
+static struct ethtool_ops ethtool_ops;
 
 \f
 
@@ -895,6 +893,7 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
        dev->get_stats = &speedo_get_stats;
        dev->set_multicast_list = &set_rx_mode;
        dev->do_ioctl = &speedo_ioctl;
+       SET_ETHTOOL_OPS(dev, &ethtool_ops);
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = &poll_speedo;
 #endif
@@ -2010,82 +2009,68 @@ speedo_get_stats(struct net_device *dev)
        return &sp->stats;
 }
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
+static void speedo_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       u32 ethcmd;
        struct speedo_private *sp = netdev_priv(dev);
-               
-       if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
-               return -EFAULT;
-       
-        switch (ethcmd) {
-       /* get driver-specific version/etc. info */
-       case ETHTOOL_GDRVINFO: {
-               struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-               strncpy(info.driver, "eepro100", sizeof(info.driver)-1);
-               strncpy(info.version, version, sizeof(info.version)-1);
-               if (sp && sp->pdev)
-                       strcpy(info.bus_info, pci_name(sp->pdev));
-               if (copy_to_user(useraddr, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       
-       /* get settings */
-       case ETHTOOL_GSET: {
-               struct ethtool_cmd ecmd = { ETHTOOL_GSET };
-               spin_lock_irq(&sp->lock);
-               mii_ethtool_gset(&sp->mii_if, &ecmd);
-               spin_unlock_irq(&sp->lock);
-               if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
-                       return -EFAULT;
-               return 0;
-       }
-       /* set settings */
-       case ETHTOOL_SSET: {
-               int r;
-               struct ethtool_cmd ecmd;
-               if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
-                       return -EFAULT;
-               spin_lock_irq(&sp->lock);
-               r = mii_ethtool_sset(&sp->mii_if, &ecmd);
-               spin_unlock_irq(&sp->lock);
-               return r;
-       }
-       /* restart autonegotiation */
-       case ETHTOOL_NWAY_RST: {
-               return mii_nway_restart(&sp->mii_if);
-       }
-       /* get link status */
-       case ETHTOOL_GLINK: {
-               struct ethtool_value edata = {ETHTOOL_GLINK};
-               edata.data = mii_link_ok(&sp->mii_if);
-               if (copy_to_user(useraddr, &edata, sizeof(edata)))
-                       return -EFAULT;
-               return 0;
-       }
-       /* get message-level */
-       case ETHTOOL_GMSGLVL: {
-               struct ethtool_value edata = {ETHTOOL_GMSGLVL};
-               edata.data = sp->msg_enable;
-               if (copy_to_user(useraddr, &edata, sizeof(edata)))
-                       return -EFAULT;
-               return 0;
-       }
-       /* set message-level */
-       case ETHTOOL_SMSGLVL: {
-               struct ethtool_value edata;
-               if (copy_from_user(&edata, useraddr, sizeof(edata)))
-                       return -EFAULT;
-               sp->msg_enable = edata.data;
-               return 0;
-       }
+       strncpy(info->driver, "eepro100", sizeof(info->driver)-1);
+       strncpy(info->version, version, sizeof(info->version)-1);
+       if (sp->pdev)
+               strcpy(info->bus_info, pci_name(sp->pdev));
+}
 
-        }
-       
-       return -EOPNOTSUPP;
+static int speedo_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       spin_lock_irq(&sp->lock);
+       mii_ethtool_gset(&sp->mii_if, ecmd);
+       spin_unlock_irq(&sp->lock);
+       return 0;
+}
+
+static int speedo_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       int res;
+       spin_lock_irq(&sp->lock);
+       res = mii_ethtool_sset(&sp->mii_if, ecmd);
+       spin_unlock_irq(&sp->lock);
+       return res;
+}
+
+static int speedo_nway_reset(struct net_device *dev)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       return mii_nway_restart(&sp->mii_if);
+}
+
+static u32 speedo_get_link(struct net_device *dev)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       return mii_link_ok(&sp->mii_if);
 }
 
+static u32 speedo_get_msglevel(struct net_device *dev)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       return sp->msg_enable;
+}
+
+static void speedo_set_msglevel(struct net_device *dev, u32 v)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       sp->msg_enable = v;
+}
+
+static struct ethtool_ops ethtool_ops = {
+       .get_drvinfo = speedo_get_drvinfo,
+       .get_settings = speedo_get_settings,
+       .set_settings = speedo_set_settings,
+       .nway_reset = speedo_nway_reset,
+       .get_link = speedo_get_link,
+       .get_msglevel = speedo_get_msglevel,
+       .set_msglevel = speedo_set_msglevel,
+};
+
 static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct speedo_private *sp = netdev_priv(dev);
@@ -2121,8 +2106,6 @@ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                        add_timer(&sp->timer); /* may be set to the past  --SAW */
                pci_set_power_state(sp->pdev, saved_acpi);
                return 0;
-       case SIOCETHTOOL:
-               return netdev_ethtool_ioctl(dev, rq->ifr_data);
        default:
                return -EOPNOTSUPP;
        }
@@ -2334,7 +2317,7 @@ static int eepro100_suspend(struct pci_dev *pdev, u32 state)
        struct speedo_private *sp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
 
-       pci_save_state(pdev, sp->pm_state);
+       pci_save_state(pdev);
 
        if (!netif_running(dev))
                return 0;
@@ -2345,6 +2328,8 @@ static int eepro100_suspend(struct pci_dev *pdev, u32 state)
        outl(PortPartialReset, ioaddr + SCBPort);
        
        /* XXX call pci_set_power_state ()? */
+       pci_disable_device(pdev);
+       pci_set_power_state (pdev, 3);
        return 0;
 }
 
@@ -2354,7 +2339,10 @@ static int eepro100_resume(struct pci_dev *pdev)
        struct speedo_private *sp = netdev_priv(dev);
        long ioaddr = dev->base_addr;
 
-       pci_restore_state(pdev, sp->pm_state);
+       pci_set_power_state(pdev, 0);
+       pci_restore_state(pdev);
+       pci_enable_device(pdev);
+       pci_set_master(pdev);
 
        if (!netif_running(dev))
                return 0;