[VETH]: move veth.h to include/linux
[safe/jmp/linux-2.6] / drivers / net / forcedeth.c
index 136827f..a96583c 100644 (file)
 #else
 #define DRIVERNAPI
 #endif
-#define FORCEDETH_VERSION              "0.60"
+#define FORCEDETH_VERSION              "0.61"
 #define DRV_NAME                       "forcedeth"
 
 #include <linux/module.h>
 #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,9 +747,11 @@ 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;
        struct nv_ethtool_stats estats;
        int in_shutdown;
        u32 linkspeed;
@@ -987,7 +992,7 @@ static void nv_enable_irq(struct net_device *dev)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       enable_irq(dev->irq);
+                       enable_irq(np->pci_dev->irq);
        } else {
                enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
                enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1003,7 +1008,7 @@ static void nv_disable_irq(struct net_device *dev)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       disable_irq(dev->irq);
+                       disable_irq(np->pci_dev->irq);
        } else {
                disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
                disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1499,15 +1504,16 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
                nv_get_hw_stats(dev);
 
                /* copy to net_device stats */
-               np->stats.tx_bytes = np->estats.tx_bytes;
-               np->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
-               np->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
-               np->stats.rx_crc_errors = np->estats.rx_crc_errors;
-               np->stats.rx_over_errors = np->estats.rx_over_errors;
-               np->stats.rx_errors = np->estats.rx_errors_total;
-               np->stats.tx_errors = np->estats.tx_errors_total;
-       }
-       return &np->stats;
+               dev->stats.tx_bytes = np->estats.tx_bytes;
+               dev->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
+               dev->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
+               dev->stats.rx_crc_errors = np->estats.rx_crc_errors;
+               dev->stats.rx_over_errors = np->estats.rx_over_errors;
+               dev->stats.rx_errors = np->estats.rx_errors_total;
+               dev->stats.tx_errors = np->estats.tx_errors_total;
+       }
+
+       return &dev->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)
@@ -1600,7 +1607,7 @@ static void nv_do_rx_refill(unsigned long data)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       disable_irq(dev->irq);
+                       disable_irq(np->pci_dev->irq);
        } else {
                disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
        }
@@ -1618,7 +1625,7 @@ static void nv_do_rx_refill(unsigned long data)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       enable_irq(dev->irq);
+                       enable_irq(np->pci_dev->irq);
        } else {
                enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
        }
@@ -1726,7 +1733,7 @@ static void nv_drain_tx(struct net_device *dev)
                        np->tx_ring.ex[i].buflow = 0;
                }
                if (nv_release_txskb(dev, &np->tx_skb[i]))
-                       np->stats.tx_dropped++;
+                       dev->stats.tx_dropped++;
        }
 }
 
@@ -2042,13 +2049,13 @@ static void nv_tx_done(struct net_device *dev)
                        if (flags & NV_TX_LASTPACKET) {
                                if (flags & NV_TX_ERROR) {
                                        if (flags & NV_TX_UNDERFLOW)
-                                               np->stats.tx_fifo_errors++;
+                                               dev->stats.tx_fifo_errors++;
                                        if (flags & NV_TX_CARRIERLOST)
-                                               np->stats.tx_carrier_errors++;
-                                       np->stats.tx_errors++;
+                                               dev->stats.tx_carrier_errors++;
+                                       dev->stats.tx_errors++;
                                } else {
-                                       np->stats.tx_packets++;
-                                       np->stats.tx_bytes += np->get_tx_ctx->skb->len;
+                                       dev->stats.tx_packets++;
+                                       dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
                                }
                                dev_kfree_skb_any(np->get_tx_ctx->skb);
                                np->get_tx_ctx->skb = NULL;
@@ -2057,13 +2064,13 @@ static void nv_tx_done(struct net_device *dev)
                        if (flags & NV_TX2_LASTPACKET) {
                                if (flags & NV_TX2_ERROR) {
                                        if (flags & NV_TX2_UNDERFLOW)
-                                               np->stats.tx_fifo_errors++;
+                                               dev->stats.tx_fifo_errors++;
                                        if (flags & NV_TX2_CARRIERLOST)
-                                               np->stats.tx_carrier_errors++;
-                                       np->stats.tx_errors++;
+                                               dev->stats.tx_carrier_errors++;
+                                       dev->stats.tx_errors++;
                                } else {
-                                       np->stats.tx_packets++;
-                                       np->stats.tx_bytes += np->get_tx_ctx->skb->len;
+                                       dev->stats.tx_packets++;
+                                       dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
                                }
                                dev_kfree_skb_any(np->get_tx_ctx->skb);
                                np->get_tx_ctx->skb = NULL;
@@ -2100,7 +2107,7 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
 
                if (flags & NV_TX2_LASTPACKET) {
                        if (!(flags & NV_TX2_ERROR))
-                               np->stats.tx_packets++;
+                               dev->stats.tx_packets++;
                        dev_kfree_skb_any(np->get_tx_ctx->skb);
                        np->get_tx_ctx->skb = NULL;
                }
@@ -2261,13 +2268,13 @@ static int nv_rx_process(struct net_device *dev, int limit)
 {
        struct fe_priv *np = netdev_priv(dev);
        u32 flags;
-       u32 rx_processed_cnt = 0;
+       int rx_work = 0;
        struct sk_buff *skb;
        int len;
 
        while((np->get_rx.orig != np->put_rx.orig) &&
              !((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) &&
-               (rx_processed_cnt++ < limit)) {
+               (rx_work < limit)) {
 
                dprintk(KERN_DEBUG "%s: nv_rx_process: flags 0x%x.\n",
                                        dev->name, flags);
@@ -2301,7 +2308,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        if (flags & NV_RX_ERROR4) {
                                                len = nv_getlen(dev, skb->data, len);
                                                if (len < 0) {
-                                                       np->stats.rx_errors++;
+                                                       dev->stats.rx_errors++;
                                                        dev_kfree_skb(skb);
                                                        goto next_pkt;
                                                }
@@ -2315,12 +2322,12 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        /* the rest are hard errors */
                                        else {
                                                if (flags & NV_RX_MISSEDFRAME)
-                                                       np->stats.rx_missed_errors++;
+                                                       dev->stats.rx_missed_errors++;
                                                if (flags & NV_RX_CRCERR)
-                                                       np->stats.rx_crc_errors++;
+                                                       dev->stats.rx_crc_errors++;
                                                if (flags & NV_RX_OVERFLOW)
-                                                       np->stats.rx_over_errors++;
-                                               np->stats.rx_errors++;
+                                                       dev->stats.rx_over_errors++;
+                                               dev->stats.rx_errors++;
                                                dev_kfree_skb(skb);
                                                goto next_pkt;
                                        }
@@ -2336,7 +2343,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        if (flags & NV_RX2_ERROR4) {
                                                len = nv_getlen(dev, skb->data, len);
                                                if (len < 0) {
-                                                       np->stats.rx_errors++;
+                                                       dev->stats.rx_errors++;
                                                        dev_kfree_skb(skb);
                                                        goto next_pkt;
                                                }
@@ -2350,10 +2357,10 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        /* the rest are hard errors */
                                        else {
                                                if (flags & NV_RX2_CRCERR)
-                                                       np->stats.rx_crc_errors++;
+                                                       dev->stats.rx_crc_errors++;
                                                if (flags & NV_RX2_OVERFLOW)
-                                                       np->stats.rx_over_errors++;
-                                               np->stats.rx_errors++;
+                                                       dev->stats.rx_over_errors++;
+                                               dev->stats.rx_errors++;
                                                dev_kfree_skb(skb);
                                                goto next_pkt;
                                        }
@@ -2382,16 +2389,18 @@ static int nv_rx_process(struct net_device *dev, int limit)
                netif_rx(skb);
 #endif
                dev->last_rx = jiffies;
-               np->stats.rx_packets++;
-               np->stats.rx_bytes += len;
+               dev->stats.rx_packets++;
+               dev->stats.rx_bytes += len;
 next_pkt:
                if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
                        np->get_rx.orig = np->first_rx.orig;
                if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx))
                        np->get_rx_ctx = np->first_rx_ctx;
+
+               rx_work++;
        }
 
-       return rx_processed_cnt;
+       return rx_work;
 }
 
 static int nv_rx_process_optimized(struct net_device *dev, int limit)
@@ -2399,13 +2408,13 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
        struct fe_priv *np = netdev_priv(dev);
        u32 flags;
        u32 vlanflags = 0;
-       u32 rx_processed_cnt = 0;
+       int rx_work = 0;
        struct sk_buff *skb;
        int len;
 
        while((np->get_rx.ex != np->put_rx.ex) &&
              !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) &&
-             (rx_processed_cnt++ < limit)) {
+             (rx_work < limit)) {
 
                dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n",
                                        dev->name, flags);
@@ -2498,8 +2507,8 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
                        }
 
                        dev->last_rx = jiffies;
-                       np->stats.rx_packets++;
-                       np->stats.rx_bytes += len;
+                       dev->stats.rx_packets++;
+                       dev->stats.rx_bytes += len;
                } else {
                        dev_kfree_skb(skb);
                }
@@ -2508,9 +2517,11 @@ next_pkt:
                        np->get_rx.ex = np->first_rx.ex;
                if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx))
                        np->get_rx_ctx = np->first_rx_ctx;
+
+               rx_work++;
        }
 
-       return rx_processed_cnt;
+       return rx_work;
 }
 
 static void set_bufsize(struct net_device *dev)
@@ -2996,7 +3007,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 +3020,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 +3078,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 +3089,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 +3122,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 +3135,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 +3194,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 +3241,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 +3253,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 +3276,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 +3289,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 +3298,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 +3306,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 +3332,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 +3351,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 +3424,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;
                }
 
@@ -3556,10 +3560,12 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
        if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
                if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
                        np->msi_flags |= NV_MSI_ENABLED;
+                       dev->irq = np->pci_dev->irq;
                        if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
                                printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
                                pci_disable_msi(np->pci_dev);
                                np->msi_flags &= ~NV_MSI_ENABLED;
+                               dev->irq = np->pci_dev->irq;
                                goto out_err;
                        }
 
@@ -3622,7 +3628,7 @@ static void nv_do_nic_poll(unsigned long data)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       disable_irq_lockdep(dev->irq);
+                       disable_irq_lockdep(np->pci_dev->irq);
                mask = np->irqmask;
        } else {
                if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
@@ -3640,6 +3646,8 @@ static void nv_do_nic_poll(unsigned long data)
        }
        np->nic_poll_irq = 0;
 
+       /* disable_irq() contains synchronize_irq, thus no irq handler can run now */
+
        if (np->recover_error) {
                np->recover_error = 0;
                printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
@@ -3676,7 +3684,6 @@ static void nv_do_nic_poll(unsigned long data)
                }
        }
 
-       /* FIXME: Do we need synchronize_irq(dev->irq) here? */
 
        writel(mask, base + NvRegIrqMask);
        pci_push(base);
@@ -3689,7 +3696,7 @@ static void nv_do_nic_poll(unsigned long data)
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
-                       enable_irq_lockdep(dev->irq);
+                       enable_irq_lockdep(np->pci_dev->irq);
        } else {
                if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
                        nv_nic_irq_rx(0, dev);
@@ -3727,7 +3734,7 @@ static void nv_do_stats_poll(unsigned long data)
 static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
        struct fe_priv *np = netdev_priv(dev);
-       strcpy(info->driver, "forcedeth");
+       strcpy(info->driver, DRV_NAME);
        strcpy(info->version, FORCEDETH_VERSION);
        strcpy(info->bus_info, pci_name(np->pci_dev));
 }
@@ -4333,16 +4340,26 @@ static int nv_set_sg(struct net_device *dev, u32 data)
                return -EOPNOTSUPP;
 }
 
-static int nv_get_stats_count(struct net_device *dev)
+static int nv_get_sset_count(struct net_device *dev, int sset)
 {
        struct fe_priv *np = netdev_priv(dev);
 
-       if (np->driver_data & DEV_HAS_STATISTICS_V1)
-               return NV_DEV_STATISTICS_V1_COUNT;
-       else if (np->driver_data & DEV_HAS_STATISTICS_V2)
-               return NV_DEV_STATISTICS_V2_COUNT;
-       else
-               return 0;
+       switch (sset) {
+       case ETH_SS_TEST:
+               if (np->driver_data & DEV_HAS_TEST_EXTENDED)
+                       return NV_TEST_COUNT_EXTENDED;
+               else
+                       return NV_TEST_COUNT_BASE;
+       case ETH_SS_STATS:
+               if (np->driver_data & DEV_HAS_STATISTICS_V1)
+                       return NV_DEV_STATISTICS_V1_COUNT;
+               else if (np->driver_data & DEV_HAS_STATISTICS_V2)
+                       return NV_DEV_STATISTICS_V2_COUNT;
+               else
+                       return 0;
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *buffer)
@@ -4352,17 +4369,7 @@ static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *e
        /* update stats */
        nv_do_stats_poll((unsigned long)dev);
 
-       memcpy(buffer, &np->estats, nv_get_stats_count(dev)*sizeof(u64));
-}
-
-static int nv_self_test_count(struct net_device *dev)
-{
-       struct fe_priv *np = netdev_priv(dev);
-
-       if (np->driver_data & DEV_HAS_TEST_EXTENDED)
-               return NV_TEST_COUNT_EXTENDED;
-       else
-               return NV_TEST_COUNT_BASE;
+       memcpy(buffer, &np->estats, nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(u64));
 }
 
 static int nv_link_test(struct net_device *dev)
@@ -4609,7 +4616,7 @@ static void nv_self_test(struct net_device *dev, struct ethtool_test *test, u64
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
        int result;
-       memset(buffer, 0, nv_self_test_count(dev)*sizeof(u64));
+       memset(buffer, 0, nv_get_sset_count(dev, ETH_SS_TEST)*sizeof(u64));
 
        if (!nv_link_test(dev)) {
                test->flags |= ETH_TEST_FL_FAILED;
@@ -4619,7 +4626,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 +4687,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);
                }
        }
@@ -4688,10 +4699,10 @@ static void nv_get_strings(struct net_device *dev, u32 stringset, u8 *buffer)
 {
        switch (stringset) {
        case ETH_SS_STATS:
-               memcpy(buffer, &nv_estats_str, nv_get_stats_count(dev)*sizeof(struct nv_ethtool_str));
+               memcpy(buffer, &nv_estats_str, nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(struct nv_ethtool_str));
                break;
        case ETH_SS_TEST:
-               memcpy(buffer, &nv_etests_str, nv_self_test_count(dev)*sizeof(struct nv_ethtool_str));
+               memcpy(buffer, &nv_etests_str, nv_get_sset_count(dev, ETH_SS_TEST)*sizeof(struct nv_ethtool_str));
                break;
        }
 }
@@ -4706,8 +4717,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,
        .set_ringparam = nv_set_ringparam,
@@ -4715,14 +4724,11 @@ static const struct ethtool_ops ops = {
        .set_pauseparam = nv_set_pauseparam,
        .get_rx_csum = nv_get_rx_csum,
        .set_rx_csum = nv_set_rx_csum,
-       .get_tx_csum = ethtool_op_get_tx_csum,
        .set_tx_csum = nv_set_tx_csum,
-       .get_sg = ethtool_op_get_sg,
        .set_sg = nv_set_sg,
        .get_strings = nv_get_strings,
-       .get_stats_count = nv_get_stats_count,
        .get_ethtool_stats = nv_get_ethtool_stats,
-       .self_test_count = nv_self_test_count,
+       .get_sset_count = nv_get_sset_count,
        .self_test = nv_self_test,
 };
 
@@ -4911,12 +4917,14 @@ 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);
        } else {
-               printk("%s: no link during initialization.\n", dev->name);
+               printk(KERN_INFO "%s: no link during initialization.\n", dev->name);
                netif_carrier_off(dev);
        }
        if (oom)
@@ -4942,8 +4950,10 @@ 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);
-       synchronize_irq(dev->irq);
+#ifdef CONFIG_FORCEDETH_NAPI
+       napi_disable(&np->napi);
+#endif
+       synchronize_irq(np->pci_dev->irq);
 
        del_timer_sync(&np->oom_kick);
        del_timer_sync(&np->nic_poll);
@@ -4987,6 +4997,12 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        u32 powerstate, txreg;
        u32 phystate_orig = 0, phystate;
        int phyinitialized = 0;
+       DECLARE_MAC_BUF(mac);
+       static int printed_version;
+
+       if (!printed_version++)
+               printk(KERN_INFO "%s: Reverse Engineered nForce ethernet"
+                      " driver. Version %s.\n", DRV_NAME, FORCEDETH_VERSION);
 
        dev = alloc_etherdev(sizeof(struct fe_priv));
        err = -ENOMEM;
@@ -4994,9 +5010,9 @@ 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);
        SET_NETDEV_DEV(dev, &pci_dev->dev);
 
        init_timer(&np->oom_kick);
@@ -5010,11 +5026,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        np->stats_poll.function = &nv_do_stats_poll;    /* timer handler */
 
        err = pci_enable_device(pci_dev);
-       if (err) {
-               printk(KERN_INFO "forcedeth: pci_enable_dev failed (%d) for device %s\n",
-                               err, pci_name(pci_dev));
+       if (err)
                goto out_free;
-       }
 
        pci_set_master(pci_dev);
 
@@ -5043,8 +5056,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                }
        }
        if (i == DEVICE_COUNT_RESOURCE) {
-               printk(KERN_INFO "forcedeth: Couldn't find register window for device %s.\n",
-                                       pci_name(pci_dev));
+               dev_printk(KERN_INFO, &pci_dev->dev,
+                          "Couldn't find register window\n");
                goto out_relreg;
        }
 
@@ -5057,16 +5070,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                np->desc_ver = DESC_VER_3;
                np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
                if (dma_64bit) {
-                       if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) {
-                               printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
-                                      pci_name(pci_dev));
-                       } else {
+                       if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK))
+                               dev_printk(KERN_INFO, &pci_dev->dev,
+                                       "64-bit DMA failed, using 32-bit addressing\n");
+                       else
                                dev->features |= NETIF_F_HIGHDMA;
-                               printk(KERN_INFO "forcedeth: using HIGHDMA\n");
-                       }
                        if (pci_set_consistent_dma_mask(pci_dev, DMA_39BIT_MASK)) {
-                               printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed, using 32-bit ring buffers for device %s.\n",
-                                      pci_name(pci_dev));
+                               dev_printk(KERN_INFO, &pci_dev->dev,
+                                       "64-bit DMA (consistent) failed, using 32-bit ring buffers\n");
                        }
                }
        } else if (id->driver_data & DEV_HAS_LARGEDESC) {
@@ -5137,12 +5148,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                        goto out_unmap;
                np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size];
        }
-       np->rx_skb = kmalloc(sizeof(struct nv_skb_map) * np->rx_ring_size, GFP_KERNEL);
-       np->tx_skb = kmalloc(sizeof(struct nv_skb_map) * np->tx_ring_size, GFP_KERNEL);
+       np->rx_skb = kcalloc(np->rx_ring_size, sizeof(struct nv_skb_map), GFP_KERNEL);
+       np->tx_skb = kcalloc(np->tx_ring_size, sizeof(struct nv_skb_map), GFP_KERNEL);
        if (!np->rx_skb || !np->tx_skb)
                goto out_freering;
-       memset(np->rx_skb, 0, sizeof(struct nv_skb_map) * np->rx_ring_size);
-       memset(np->tx_skb, 0, sizeof(struct nv_skb_map) * np->tx_ring_size);
 
        dev->open = nv_open;
        dev->stop = nv_close;
@@ -5157,9 +5166,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;
@@ -5174,7 +5182,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;
@@ -5203,20 +5212,19 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                 * Bad mac address. At least one bios sets the mac address
                 * to 01:23:45:67:89:ab
                 */
-               printk(KERN_ERR "%s: Invalid Mac address detected: %02x:%02x:%02x:%02x:%02x:%02x\n",
-                       pci_name(pci_dev),
-                       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-                       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
-               printk(KERN_ERR "Please complain to your hardware vendor. Switching to a random MAC.\n");
+               dev_printk(KERN_ERR, &pci_dev->dev,
+                       "Invalid Mac address detected: %s\n",
+                       print_mac(mac, dev->dev_addr));
+               dev_printk(KERN_ERR, &pci_dev->dev,
+                       "Please complain to your hardware vendor. Switching to a random MAC.\n");
                dev->dev_addr[0] = 0x00;
                dev->dev_addr[1] = 0x00;
                dev->dev_addr[2] = 0x6c;
                get_random_bytes(&dev->dev_addr[3], 3);
        }
 
-       dprintk(KERN_DEBUG "%s: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", pci_name(pci_dev),
-                       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-                       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+       dprintk(KERN_DEBUG "%s: MAC Address %s\n",
+               pci_name(pci_dev), print_mac(mac, dev->dev_addr));
 
        /* set mac address */
        nv_copy_mac_to_hw(dev);
@@ -5278,19 +5286,15 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_PHY_INIT) {
                        np->mac_in_use = readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_MGMT_ST;
                        dprintk(KERN_INFO "%s: mgmt unit is running. mac in use %x.\n", pci_name(pci_dev), np->mac_in_use);
-                       for (i = 0; i < 5000; i++) {
-                               msleep(1);
-                               if (nv_mgmt_acquire_sema(dev)) {
-                                       /* management unit setup the phy already? */
-                                       if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
-                                           NVREG_XMITCTL_SYNC_PHY_INIT) {
-                                               /* phy is inited by mgmt unit */
-                                               phyinitialized = 1;
-                                               dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
-                                       } else {
-                                               /* we need to init the phy */
-                                       }
-                                       break;
+                       if (nv_mgmt_acquire_sema(dev)) {
+                               /* management unit setup the phy already? */
+                               if ((readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
+                                   NVREG_XMITCTL_SYNC_PHY_INIT) {
+                                       /* phy is inited by mgmt unit */
+                                       phyinitialized = 1;
+                                       dprintk(KERN_INFO "%s: Phy already initialized by mgmt unit.\n", pci_name(pci_dev));
+                               } else {
+                                       /* we need to init the phy */
                                }
                        }
                }
@@ -5322,8 +5326,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                break;
        }
        if (i == 33) {
-               printk(KERN_INFO "%s: open: Could not find a valid PHY.\n",
-                      pci_name(pci_dev));
+               dev_printk(KERN_INFO, &pci_dev->dev,
+                       "open: Could not find a valid PHY.\n");
                goto out_error;
        }
 
@@ -5345,12 +5349,37 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 
        err = register_netdev(dev);
        if (err) {
-               printk(KERN_INFO "forcedeth: unable to register netdev: %d\n", err);
+               dev_printk(KERN_INFO, &pci_dev->dev,
+                          "unable to register netdev: %d\n", err);
                goto out_error;
        }
-       printk(KERN_INFO "%s: forcedeth.c: subsystem: %05x:%04x bound to %s\n",
-                       dev->name, pci_dev->subsystem_vendor, pci_dev->subsystem_device,
-                       pci_name(pci_dev));
+
+       dev_printk(KERN_INFO, &pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, "
+                  "addr %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+                  dev->name,
+                  np->phy_oui,
+                  np->phyaddr,
+                  dev->dev_addr[0],
+                  dev->dev_addr[1],
+                  dev->dev_addr[2],
+                  dev->dev_addr[3],
+                  dev->dev_addr[4],
+                  dev->dev_addr[5]);
+
+       dev_printk(KERN_INFO, &pci_dev->dev, "%s%s%s%s%s%s%s%s%s%sdesc-v%u\n",
+                  dev->features & NETIF_F_HIGHDMA ? "highdma " : "",
+                  dev->features & (NETIF_F_HW_CSUM | NETIF_F_SG) ?
+                       "csum " : "",
+                  dev->features & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX) ?
+                       "vlan " : "",
+                  id->driver_data & DEV_HAS_POWER_CNTRL ? "pwrctl " : "",
+                  id->driver_data & DEV_HAS_MGMT_UNIT ? "mgmt " : "",
+                  id->driver_data & DEV_NEED_TIMERIRQ ? "timirq " : "",
+                  np->gigabit == PHY_GIGABIT ? "gbit " : "",
+                  np->need_linktimer ? "lnktim " : "",
+                  np->msi_flags & NV_MSI_CAPABLE ? "msi " : "",
+                  np->msi_flags & NV_MSI_X_CAPABLE ? "msi-x " : "",
+                  np->desc_ver);
 
        return 0;
 
@@ -5502,67 +5531,114 @@ 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,
+       },
+       {       /* MCP77 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP77 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP77 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP77 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP79 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP79 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP79 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP79 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
        },
        {0,},
 };
 
 static struct pci_driver driver = {
-       .name = "forcedeth",
-       .id_table = pci_tbl,
-       .probe = nv_probe,
-       .remove = __devexit_p(nv_remove),
-       .suspend = nv_suspend,
-       .resume = nv_resume,
+       .name           = DRV_NAME,
+       .id_table       = pci_tbl,
+       .probe          = nv_probe,
+       .remove         = __devexit_p(nv_remove),
+       .suspend        = nv_suspend,
+       .resume         = nv_resume,
 };
 
 static int __init init_nic(void)
 {
-       printk(KERN_INFO "forcedeth.c: Reverse Engineered nForce ethernet driver. Version %s.\n", FORCEDETH_VERSION);
        return pci_register_driver(&driver);
 }