This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / net / acenic.c
index 51cf164..9e049c0 100644 (file)
@@ -85,6 +85,8 @@
 #include <asm/uaccess.h>
 
 
+#define DRV_NAME "acenic"
+
 #undef INDEX_DEBUG
 
 #ifdef CONFIG_ACENIC_OMIT_TIGON_I
@@ -439,10 +441,20 @@ MODULE_PARM_DESC(max_rx_desc, "AceNIC/3C985/GA620 max number of receive descript
 MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)");
 
 
-static char version[] __initdata = 
+static char version[]  = 
   "acenic.c: v0.92 08/05/2002  Jes Sorensen, linux-acenic@SunSITE.dk\n"
   "                            http://home.cern.ch/~jes/gige/acenic.html\n";
 
+static int ace_get_settings(struct net_device *, struct ethtool_cmd *);
+static int ace_set_settings(struct net_device *, struct ethtool_cmd *);
+static void ace_get_drvinfo(struct net_device *, struct ethtool_drvinfo *);
+
+static struct ethtool_ops ace_ethtool_ops = {
+       .get_settings = ace_get_settings,
+       .set_settings = ace_set_settings,
+       .get_drvinfo = ace_get_drvinfo,
+};
+
 static int __devinit acenic_probe_one(struct pci_dev *pdev,
                const struct pci_device_id *id)
 {
@@ -480,7 +492,7 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev,
        dev->hard_start_xmit = &ace_start_xmit;
        dev->get_stats = &ace_get_stats;
        dev->set_multicast_list = &ace_set_multicast_list;
-       dev->do_ioctl = &ace_ioctl;
+       SET_ETHTOOL_OPS(dev, &ace_ethtool_ops);
        dev->set_mac_address = &ace_set_mac_addr;
        dev->change_mtu = &ace_change_mtu;
 
@@ -1195,10 +1207,10 @@ static int __init ace_init(struct net_device *dev)
        }
 
        ecode = request_irq(pdev->irq, ace_interrupt, SA_SHIRQ,
-                           dev->name, dev);
+                           DRV_NAME, dev);
        if (ecode) {
                printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
-                      dev->name, pdev->irq);
+                      DRV_NAME, pdev->irq);
                goto init_error;
        } else
                dev->irq = pdev->irq;
@@ -1622,7 +1634,7 @@ static void ace_tasklet(unsigned long dev)
        cur_size = atomic_read(&ap->cur_rx_bufs);
        if ((cur_size < RX_LOW_STD_THRES) &&
            !test_and_set_bit(0, &ap->std_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
                printk("refilling buffers (current %i)\n", cur_size);
 #endif
                ace_load_std_rx_ring(ap, RX_RING_SIZE - cur_size);
@@ -1632,7 +1644,7 @@ static void ace_tasklet(unsigned long dev)
                cur_size = atomic_read(&ap->cur_mini_bufs);
                if ((cur_size < RX_LOW_MINI_THRES) &&
                    !test_and_set_bit(0, &ap->mini_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
                        printk("refilling mini buffers (current %i)\n",
                               cur_size);
 #endif
@@ -1643,7 +1655,7 @@ static void ace_tasklet(unsigned long dev)
        cur_size = atomic_read(&ap->cur_jumbo_bufs);
        if (ap->jumbo && (cur_size < RX_LOW_JUMBO_THRES) &&
            !test_and_set_bit(0, &ap->jumbo_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
                printk("refilling jumbo buffers (current %i)\n", cur_size);
 #endif
                ace_load_jumbo_rx_ring(ap, RX_JUMBO_SIZE - cur_size);
@@ -1995,6 +2007,11 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm)
                int bd_flags, desc_type, mapsize;
                u16 csum;
 
+
+               /* make sure the rx descriptor isn't read before rxretprd */
+               if (idx == rxretcsm) 
+                       rmb();
+
                retdesc = &ap->rx_return_ring[idx];
                skbidx = retdesc->idx;
                bd_flags = retdesc->flags;
@@ -2243,7 +2260,7 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
                if (cur_size < RX_LOW_STD_THRES) {
                        if ((cur_size < RX_PANIC_STD_THRES) &&
                            !test_and_set_bit(0, &ap->std_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
                                printk("low on std buffers %i\n", cur_size);
 #endif
                                ace_load_std_rx_ring(ap,
@@ -2258,7 +2275,7 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
                                if ((cur_size < RX_PANIC_MINI_THRES) &&
                                    !test_and_set_bit(0,
                                                      &ap->mini_refill_busy)) {
-#if DEBUG
+#ifdef DEBUG
                                        printk("low on mini buffers %i\n",
                                               cur_size);
 #endif
@@ -2274,7 +2291,7 @@ static irqreturn_t ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
                                if ((cur_size < RX_PANIC_JUMBO_THRES) &&
                                    !test_and_set_bit(0,
                                                      &ap->jumbo_refill_busy)){
-#if DEBUG
+#ifdef DEBUG
                                        printk("low on jumbo buffers %i\n",
                                               cur_size);
 #endif
@@ -2688,146 +2705,136 @@ static int ace_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-
-static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
        struct ace_private *ap = dev->priv;
        struct ace_regs *regs = ap->regs;
-#ifdef SIOCETHTOOL
-       struct ethtool_cmd ecmd;
-       u32 link, speed;
+       u32 link;
 
-       if (cmd != SIOCETHTOOL)
-               return -EOPNOTSUPP;
-       if (copy_from_user(&ecmd, ifr->ifr_data, sizeof(ecmd)))
-               return -EFAULT;
-       switch (ecmd.cmd) {
-       case ETHTOOL_GSET:
-               ecmd.supported =
-                       (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
-                        SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
-                        SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full |
-                        SUPPORTED_Autoneg | SUPPORTED_FIBRE);
-
-               ecmd.port = PORT_FIBRE;
-               ecmd.transceiver = XCVR_INTERNAL;
-               ecmd.phy_address = 0;
-
-               link = readl(&regs->GigLnkState);
-               if (link & LNK_1000MB)
-                       ecmd.speed = SPEED_1000;
-               else {
-                       link = readl(&regs->FastLnkState);
-                       if (link & LNK_100MB)
-                               ecmd.speed = SPEED_100;
-                       else if (link & LNK_100MB)
-                               ecmd.speed = SPEED_10;
-                       else
-                               ecmd.speed = 0;
-               }
-               if (link & LNK_FULL_DUPLEX)
-                       ecmd.duplex = DUPLEX_FULL;
-               else
-                       ecmd.duplex = DUPLEX_HALF;
+       memset(ecmd, 0, sizeof(struct ethtool_cmd));
+       ecmd->supported =
+               (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+                SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+                SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full |
+                SUPPORTED_Autoneg | SUPPORTED_FIBRE);
 
-               if (link & LNK_NEGOTIATE)
-                       ecmd.autoneg = AUTONEG_ENABLE;
+       ecmd->port = PORT_FIBRE;
+       ecmd->transceiver = XCVR_INTERNAL;
+
+       link = readl(&regs->GigLnkState);
+       if (link & LNK_1000MB)
+               ecmd->speed = SPEED_1000;
+       else {
+               link = readl(&regs->FastLnkState);
+               if (link & LNK_100MB)
+                       ecmd->speed = SPEED_100;
+               else if (link & LNK_10MB)
+                       ecmd->speed = SPEED_10;
                else
-                       ecmd.autoneg = AUTONEG_DISABLE;
+                       ecmd->speed = 0;
+       }
+       if (link & LNK_FULL_DUPLEX)
+               ecmd->duplex = DUPLEX_FULL;
+       else
+               ecmd->duplex = DUPLEX_HALF;
+
+       if (link & LNK_NEGOTIATE)
+               ecmd->autoneg = AUTONEG_ENABLE;
+       else
+               ecmd->autoneg = AUTONEG_DISABLE;
 
 #if 0
-               /*
-                * Current struct ethtool_cmd is insufficient
-                */
-               ecmd.trace = readl(&regs->TuneTrace);
+       /*
+        * Current struct ethtool_cmd is insufficient
+        */
+       ecmd->trace = readl(&regs->TuneTrace);
 
-               ecmd.txcoal = readl(&regs->TuneTxCoalTicks);
-               ecmd.rxcoal = readl(&regs->TuneRxCoalTicks);
+       ecmd->txcoal = readl(&regs->TuneTxCoalTicks);
+       ecmd->rxcoal = readl(&regs->TuneRxCoalTicks);
 #endif
-               ecmd.maxtxpkt = readl(&regs->TuneMaxTxDesc);
-               ecmd.maxrxpkt = readl(&regs->TuneMaxRxDesc);
+       ecmd->maxtxpkt = readl(&regs->TuneMaxTxDesc);
+       ecmd->maxrxpkt = readl(&regs->TuneMaxRxDesc);
 
-               if(copy_to_user(ifr->ifr_data, &ecmd, sizeof(ecmd)))
-                       return -EFAULT;
-               return 0;
+       return 0;
+}
 
-       case ETHTOOL_SSET:
-               link = readl(&regs->GigLnkState);
-               if (link & LNK_1000MB)
-                       speed = SPEED_1000;
-               else {
-                       link = readl(&regs->FastLnkState);
-                       if (link & LNK_100MB)
-                               speed = SPEED_100;
-                       else if (link & LNK_100MB)
-                               speed = SPEED_10;
-                       else
-                               speed = SPEED_100;
-               }
+static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct ace_private *ap = dev->priv;
+       struct ace_regs *regs = ap->regs;
+       u32 link, speed;
 
-               link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB |
-                       LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL;
-               if (!ACE_IS_TIGON_I(ap))
-                       link |= LNK_TX_FLOW_CTL_Y;
-               if (ecmd.autoneg == AUTONEG_ENABLE)
-                       link |= LNK_NEGOTIATE;
-               if (ecmd.speed != speed) {
-                       link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
-                       switch (speed) {
-                       case SPEED_1000:
-                               link |= LNK_1000MB;
-                               break;
-                       case SPEED_100:
-                               link |= LNK_100MB;
-                               break;
-                       case SPEED_10:
-                               link |= LNK_10MB;
-                               break;
-                       }
+       link = readl(&regs->GigLnkState);
+       if (link & LNK_1000MB)
+               speed = SPEED_1000;
+       else {
+               link = readl(&regs->FastLnkState);
+               if (link & LNK_100MB)
+                       speed = SPEED_100;
+               else if (link & LNK_10MB)
+                       speed = SPEED_10;
+               else
+                       speed = SPEED_100;
+       }
+
+       link = LNK_ENABLE | LNK_1000MB | LNK_100MB | LNK_10MB |
+               LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL;
+       if (!ACE_IS_TIGON_I(ap))
+               link |= LNK_TX_FLOW_CTL_Y;
+       if (ecmd->autoneg == AUTONEG_ENABLE)
+               link |= LNK_NEGOTIATE;
+       if (ecmd->speed != speed) {
+               link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
+               switch (speed) {
+               case SPEED_1000:
+                       link |= LNK_1000MB;
+                       break;
+               case SPEED_100:
+                       link |= LNK_100MB;
+                       break;
+               case SPEED_10:
+                       link |= LNK_10MB;
+                       break;
                }
-               if (ecmd.duplex == DUPLEX_FULL)
-                       link |= LNK_FULL_DUPLEX;
+       }
 
-               if (link != ap->link) {
-                       struct cmd cmd;
-                       printk(KERN_INFO "%s: Renegotiating link state\n",
-                              dev->name);
+       if (ecmd->duplex == DUPLEX_FULL)
+               link |= LNK_FULL_DUPLEX;
 
-                       ap->link = link;
-                       writel(link, &regs->TuneLink);
-                       if (!ACE_IS_TIGON_I(ap))
-                               writel(link, &regs->TuneFastLink);
-                       wmb();
+       if (link != ap->link) {
+               struct cmd cmd;
+               printk(KERN_INFO "%s: Renegotiating link state\n",
+                      dev->name);
 
-                       cmd.evt = C_LNK_NEGOTIATION;
-                       cmd.code = 0;
-                       cmd.idx = 0;
-                       ace_issue_cmd(regs, &cmd);
-               }
-               return 0;
-
-       case ETHTOOL_GDRVINFO: {
-               struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-               strncpy(info.driver, "acenic", sizeof(info.driver) - 1);
-               sprintf(info.fw_version, "%i.%i.%i", 
-                        tigonFwReleaseMajor, tigonFwReleaseMinor,
-                        tigonFwReleaseFix);
-               strncpy(info.version, version, sizeof(info.version) - 1);
-               if (ap && ap->pdev)
-                       strcpy(info.bus_info, pci_name(ap->pdev));
-               if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       default:
-               break;
-       }
-       
-#endif
+               ap->link = link;
+               writel(link, &regs->TuneLink);
+               if (!ACE_IS_TIGON_I(ap))
+                       writel(link, &regs->TuneFastLink);
+               wmb();
 
-       return -EOPNOTSUPP;
+               cmd.evt = C_LNK_NEGOTIATION;
+               cmd.code = 0;
+               cmd.idx = 0;
+               ace_issue_cmd(regs, &cmd);
+       }
+       return 0;
 }
 
+static void ace_get_drvinfo(struct net_device *dev, 
+                           struct ethtool_drvinfo *info)
+{
+       struct ace_private *ap = dev->priv;
+
+       strlcpy(info->driver, "acenic", sizeof(info->driver));
+       snprintf(info->version, sizeof(info->version), "%i.%i.%i", 
+               tigonFwReleaseMajor, tigonFwReleaseMinor,
+               tigonFwReleaseFix);
+
+       if (ap->pdev)
+               strlcpy(info->bus_info, pci_name(ap->pdev), 
+                       sizeof(info->bus_info));
+
+}
 
 /*
  * Set the hardware MAC address.