Initial revision
[linux-2.6.git] / drivers / net / eepro100.c
index 56fc878..0199073 100644 (file)
@@ -87,14 +87,7 @@ static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 /* Size of an pre-allocated Rx buffer: <Ethernet MTU> + slack.*/
 #define PKT_BUF_SZ             1536
 
-#if !defined(__OPTIMIZE__)  ||  !defined(__KERNEL__)
-#warning  You must compile this file with the correct options!
-#warning  See the last lines of the source file.
-#error You must compile this driver with "-O".
-#endif
-
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -109,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>
@@ -497,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.
@@ -548,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
 
@@ -902,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
@@ -1027,7 +1019,7 @@ speedo_open(struct net_device *dev)
        /* Set up the Tx queue early.. */
        sp->cur_tx = 0;
        sp->dirty_tx = 0;
-       sp->last_cmd = 0;
+       sp->last_cmd = NULL;
        sp->tx_full = 0;
        sp->in_interrupt = 0;
 
@@ -1361,7 +1353,7 @@ static void speedo_purge_tx(struct net_device *dev)
                                        le32_to_cpu(sp->tx_ring[entry].tx_buf_addr0),
                                        sp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);
                        dev_kfree_skb_irq(sp->tx_skbuff[entry]);
-                       sp->tx_skbuff[entry] = 0;
+                       sp->tx_skbuff[entry] = NULL;
                }
                sp->dirty_tx++;
        }
@@ -1565,7 +1557,7 @@ static void speedo_tx_buffer_gc(struct net_device *dev)
                                        le32_to_cpu(sp->tx_ring[entry].tx_buf_addr0),
                                        sp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);
                        dev_kfree_skb_irq(sp->tx_skbuff[entry]);
-                       sp->tx_skbuff[entry] = 0;
+                       sp->tx_skbuff[entry] = NULL;
                }
                dirty_tx++;
        }
@@ -1938,7 +1930,7 @@ speedo_close(struct net_device *dev)
     /* Free all the skbuffs in the Rx and Tx queues. */
        for (i = 0; i < RX_RING_SIZE; i++) {
                struct sk_buff *skb = sp->rx_skbuff[i];
-               sp->rx_skbuff[i] = 0;
+               sp->rx_skbuff[i] = NULL;
                /* Clear the Rx descriptors. */
                if (skb) {
                        pci_unmap_single(sp->pdev,
@@ -1950,7 +1942,7 @@ speedo_close(struct net_device *dev)
 
        for (i = 0; i < TX_RING_SIZE; i++) {
                struct sk_buff *skb = sp->tx_skbuff[i];
-               sp->tx_skbuff[i] = 0;
+               sp->tx_skbuff[i] = NULL;
                /* Clear the Tx descriptors. */
                if (skb) {
                        pci_unmap_single(sp->pdev,
@@ -2017,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);
@@ -2128,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;
        }
@@ -2180,7 +2156,7 @@ static void set_rx_mode(struct net_device *dev)
                last_cmd = sp->last_cmd;
                sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
 
-               sp->tx_skbuff[entry] = 0;                       /* Redundant. */
+               sp->tx_skbuff[entry] = NULL;                    /* Redundant. */
                sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdConfigure);
                sp->tx_ring[entry].link =
                        cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
@@ -2223,7 +2199,7 @@ static void set_rx_mode(struct net_device *dev)
                last_cmd = sp->last_cmd;
                sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
 
-               sp->tx_skbuff[entry] = 0;
+               sp->tx_skbuff[entry] = NULL;
                sp->tx_ring[entry].status = cpu_to_le32(CmdSuspend | CmdMulticastList);
                sp->tx_ring[entry].link =
                        cpu_to_le32(TX_RING_ELEM_DMA(sp, (entry + 1) % TX_RING_SIZE));
@@ -2304,7 +2280,7 @@ static void set_rx_mode(struct net_device *dev)
                sp->last_cmd = mc_setup_frm;
 
                /* Change the command to a NoOp, pointing to the CmdMulti command. */
-               sp->tx_skbuff[entry] = 0;
+               sp->tx_skbuff[entry] = NULL;
                sp->tx_ring[entry].status = cpu_to_le32(CmdNOp);
                sp->tx_ring[entry].link = cpu_to_le32(mc_blk->frame_dma);
 
@@ -2341,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;
@@ -2352,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;
 }
 
@@ -2361,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;
@@ -2453,22 +2434,6 @@ static struct pci_driver eepro100_driver = {
 #endif /* CONFIG_PM */
 };
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)
-static int pci_module_init(struct pci_driver *pdev)
-{
-       int rc;
-
-       rc = pci_register_driver(pdev);
-       if (rc <= 0) {
-               printk(KERN_INFO "%s: No cards found, driver not installed.\n",
-                          pdev->name);
-               pci_unregister_driver(pdev);
-               return -ENODEV;
-       }
-       return 0;
-}
-#endif
-
 static int __init eepro100_init_module(void)
 {
 #ifdef MODULE