[NET]: Make NAPI polling independent of struct net_device objects.
[safe/jmp/linux-2.6] / drivers / net / forcedeth.c
index 6d1d50a..24c1294 100644 (file)
 #define dprintk(x...)          do { } while (0)
 #endif
 
+#define TX_WORK_PER_LOOP  64
+#define RX_WORK_PER_LOOP  64
 
 /*
  * Hardware access:
 #define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics version 2 */
 #define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic test */
 #define DEV_HAS_MGMT_UNIT       0x2000  /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address order */
 
 enum {
        NvRegIrqStatus = 0x000,
@@ -551,7 +554,7 @@ union ring_type {
 #define PHY_OUI_MARVELL        0x5043
 #define PHY_OUI_CICADA 0x03f1
 #define PHY_OUI_VITESSE        0x01c1
-#define PHY_OUI_REALTEK        0x01c1
+#define PHY_OUI_REALTEK        0x0732
 #define PHYID1_OUI_MASK        0x03ff
 #define PHYID1_OUI_SHFT        6
 #define PHYID2_OUI_MASK        0xfc00
@@ -744,6 +747,9 @@ struct nv_skb_map {
 struct fe_priv {
        spinlock_t lock;
 
+       struct net_device *dev;
+       struct napi_struct napi;
+
        /* General data:
         * Locking: spin_lock(&np->lock); */
        struct net_device_stats stats;
@@ -1585,9 +1591,10 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
 static void nv_do_rx_refill(unsigned long data)
 {
        struct net_device *dev = (struct net_device *) data;
+       struct fe_priv *np = netdev_priv(dev);
 
        /* Just reschedule NAPI rx processing */
-       netif_rx_schedule(dev);
+       netif_rx_schedule(dev, &np->napi);
 }
 #else
 static void nv_do_rx_refill(unsigned long data)
@@ -2996,7 +3003,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
 
 #ifdef CONFIG_FORCEDETH_NAPI
                if (events & NVREG_IRQ_RX_ALL) {
-                       netif_rx_schedule(dev);
+                       netif_rx_schedule(dev, &np->napi);
 
                        /* Disable furthur receive irq's */
                        spin_lock(&np->lock);
@@ -3009,7 +3016,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
                        spin_unlock(&np->lock);
                }
 #else
-               if (nv_rx_process(dev, dev->weight)) {
+               if (nv_rx_process(dev, RX_WORK_PER_LOOP)) {
                        if (unlikely(nv_alloc_rx(dev))) {
                                spin_lock(&np->lock);
                                if (!np->in_shutdown)
@@ -3067,8 +3074,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
                                np->nic_poll_irq = np->irqmask;
                                mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
                        }
-                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
                        spin_unlock(&np->lock);
+                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
                        break;
                }
 
@@ -3078,8 +3085,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
        return IRQ_RETVAL(i);
 }
 
-#define TX_WORK_PER_LOOP  64
-#define RX_WORK_PER_LOOP  64
 /**
  * All _optimized functions are used to help increase performance
  * (reduce CPU and increase throughput). They use descripter version 3,
@@ -3113,7 +3118,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
 
 #ifdef CONFIG_FORCEDETH_NAPI
                if (events & NVREG_IRQ_RX_ALL) {
-                       netif_rx_schedule(dev);
+                       netif_rx_schedule(dev, &np->napi);
 
                        /* Disable furthur receive irq's */
                        spin_lock(&np->lock);
@@ -3126,7 +3131,7 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
                        spin_unlock(&np->lock);
                }
 #else
-               if (nv_rx_process_optimized(dev, dev->weight)) {
+               if (nv_rx_process_optimized(dev, RX_WORK_PER_LOOP)) {
                        if (unlikely(nv_alloc_rx_optimized(dev))) {
                                spin_lock(&np->lock);
                                if (!np->in_shutdown)
@@ -3185,8 +3190,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
                                np->nic_poll_irq = np->irqmask;
                                mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
                        }
-                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
                        spin_unlock(&np->lock);
+                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
                        break;
                }
 
@@ -3232,8 +3237,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
                                np->nic_poll_irq |= NVREG_IRQ_TX_ALL;
                                mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
                        }
-                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
                        spin_unlock_irqrestore(&np->lock, flags);
+                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
                        break;
                }
 
@@ -3244,19 +3249,19 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
 }
 
 #ifdef CONFIG_FORCEDETH_NAPI
-static int nv_napi_poll(struct net_device *dev, int *budget)
+static int nv_napi_poll(struct napi_struct *napi, int budget)
 {
-       int pkts, limit = min(*budget, dev->quota);
-       struct fe_priv *np = netdev_priv(dev);
+       struct fe_priv *np = container_of(napi, struct fe_priv, napi);
+       struct net_device *dev = np->dev;
        u8 __iomem *base = get_hwbase(dev);
        unsigned long flags;
-       int retcode;
+       int pkts, retcode;
 
        if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
-               pkts = nv_rx_process(dev, limit);
+               pkts = nv_rx_process(dev, budget);
                retcode = nv_alloc_rx(dev);
        } else {
-               pkts = nv_rx_process_optimized(dev, limit);
+               pkts = nv_rx_process_optimized(dev, budget);
                retcode = nv_alloc_rx_optimized(dev);
        }
 
@@ -3267,13 +3272,12 @@ static int nv_napi_poll(struct net_device *dev, int *budget)
                spin_unlock_irqrestore(&np->lock, flags);
        }
 
-       if (pkts < limit) {
-               /* all done, no more packets present */
-               netif_rx_complete(dev);
-
+       if (pkts < budget) {
                /* re-enable receive interrupts */
                spin_lock_irqsave(&np->lock, flags);
 
+               __netif_rx_complete(dev, napi);
+
                np->irqmask |= NVREG_IRQ_RX_ALL;
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
@@ -3281,13 +3285,8 @@ static int nv_napi_poll(struct net_device *dev, int *budget)
                        writel(np->irqmask, base + NvRegIrqMask);
 
                spin_unlock_irqrestore(&np->lock, flags);
-               return 0;
-       } else {
-               /* used up our quantum, so reschedule */
-               dev->quota -= pkts;
-               *budget -= pkts;
-               return 1;
        }
+       return pkts;
 }
 #endif
 
@@ -3295,6 +3294,7 @@ static int nv_napi_poll(struct net_device *dev, int *budget)
 static irqreturn_t nv_nic_irq_rx(int foo, void *data)
 {
        struct net_device *dev = (struct net_device *) data;
+       struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
        u32 events;
 
@@ -3302,7 +3302,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
        writel(NVREG_IRQ_RX_ALL, base + NvRegMSIXIrqStatus);
 
        if (events) {
-               netif_rx_schedule(dev);
+               netif_rx_schedule(dev, &np->napi);
                /* disable receive interrupts on the nic */
                writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
                pci_push(base);
@@ -3328,7 +3328,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
                if (!(events & np->irqmask))
                        break;
 
-               if (nv_rx_process_optimized(dev, dev->weight)) {
+               if (nv_rx_process_optimized(dev, RX_WORK_PER_LOOP)) {
                        if (unlikely(nv_alloc_rx_optimized(dev))) {
                                spin_lock_irqsave(&np->lock, flags);
                                if (!np->in_shutdown)
@@ -3347,8 +3347,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data)
                                np->nic_poll_irq |= NVREG_IRQ_RX_ALL;
                                mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
                        }
-                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
                        spin_unlock_irqrestore(&np->lock, flags);
+                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
                        break;
                }
        }
@@ -3420,8 +3420,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data)
                                np->nic_poll_irq |= NVREG_IRQ_OTHER;
                                mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
                        }
-                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
                        spin_unlock_irqrestore(&np->lock, flags);
+                       printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
                        break;
                }
 
@@ -4619,7 +4619,9 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
        if (test->flags & ETH_TEST_FL_OFFLINE) {
                if (netif_running(dev)) {
                        netif_stop_queue(dev);
-                       netif_poll_disable(dev);
+#ifdef CONFIG_FORCEDETH_NAPI
+                       napi_disable(&np->napi);
+#endif
                        netif_tx_lock_bh(dev);
                        spin_lock_irq(&np->lock);
                        nv_disable_hw_interrupts(dev, np->irqmask);
@@ -4678,7 +4680,9 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
                        nv_start_rx(dev);
                        nv_start_tx(dev);
                        netif_start_queue(dev);
-                       netif_poll_enable(dev);
+#ifdef CONFIG_FORCEDETH_NAPI
+                       napi_enable(&np->napi);
+#endif
                        nv_enable_hw_interrupts(dev, np->irqmask);
                }
        }
@@ -4706,7 +4710,6 @@ static const struct ethtool_ops ops = {
        .get_regs_len = nv_get_regs_len,
        .get_regs = nv_get_regs,
        .nway_reset = nv_nway_reset,
-       .get_perm_addr = ethtool_op_get_perm_addr,
        .get_tso = ethtool_op_get_tso,
        .set_tso = nv_set_tso,
        .get_ringparam = nv_get_ringparam,
@@ -4911,7 +4914,9 @@ static int nv_open(struct net_device *dev)
        nv_start_rx(dev);
        nv_start_tx(dev);
        netif_start_queue(dev);
-       netif_poll_enable(dev);
+#ifdef CONFIG_FORCEDETH_NAPI
+       napi_enable(&np->napi);
+#endif
 
        if (ret) {
                netif_carrier_on(dev);
@@ -4942,7 +4947,9 @@ static int nv_close(struct net_device *dev)
        spin_lock_irq(&np->lock);
        np->in_shutdown = 1;
        spin_unlock_irq(&np->lock);
-       netif_poll_disable(dev);
+#ifdef CONFIG_FORCEDETH_NAPI
+       napi_disable(&np->napi);
+#endif
        synchronize_irq(dev->irq);
 
        del_timer_sync(&np->oom_kick);
@@ -4994,6 +5001,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                goto out;
 
        np = netdev_priv(dev);
+       np->dev = dev;
        np->pci_dev = pci_dev;
        spin_lock_init(&np->lock);
        SET_MODULE_OWNER(dev);
@@ -5155,9 +5163,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = nv_poll_controller;
 #endif
-       dev->weight = RX_WORK_PER_LOOP;
 #ifdef CONFIG_FORCEDETH_NAPI
-       dev->poll = nv_napi_poll;
+       netif_napi_add(dev, &np->napi, nv_napi_poll, RX_WORK_PER_LOOP);
 #endif
        SET_ETHTOOL_OPS(dev, &ops);
        dev->tx_timeout = nv_tx_timeout;
@@ -5172,7 +5179,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 
        /* check the workaround bit for correct mac address order */
        txreg = readl(base + NvRegTransmitPoll);
-       if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) {
+       if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) ||
+           (id->driver_data & DEV_HAS_CORRECT_MACADDR)) {
                /* mac address is already in correct order */
                dev->dev_addr[0] = (np->orig_mac[0] >>  0) & 0xff;
                dev->dev_addr[1] = (np->orig_mac[0] >>  8) & 0xff;
@@ -5500,51 +5508,67 @@ static struct pci_device_id pci_tbl[] = {
        },
        {       /* MCP61 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP61 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP61 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP61 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP65 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP65 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP65 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP65 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP67 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP67 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP67 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {       /* MCP67 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
-               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+       },
+       {       /* MCP73 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+       },
+       {       /* MCP73 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+       },
+       {       /* MCP73 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+       },
+       {       /* MCP73 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
        {0,},
 };