[VETH]: move veth.h to include/linux
[safe/jmp/linux-2.6] / drivers / net / forcedeth.c
index 16f7a07..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>
@@ -752,7 +752,6 @@ struct fe_priv {
 
        /* General data:
         * Locking: spin_lock(&np->lock); */
-       struct net_device_stats stats;
        struct nv_ethtool_stats estats;
        int in_shutdown;
        u32 linkspeed;
@@ -993,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);
@@ -1009,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);
@@ -1505,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;
 }
 
 /*
@@ -1607,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);
        }
@@ -1625,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);
        }
@@ -1733,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++;
        }
 }
 
@@ -2049,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;
@@ -2064,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;
@@ -2107,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;
                }
@@ -2308,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;
                                                }
@@ -2322,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;
                                        }
@@ -2343,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;
                                                }
@@ -2357,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;
                                        }
@@ -2389,8 +2389,8 @@ 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;
@@ -2408,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);
@@ -2507,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);
                }
@@ -2517,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)
@@ -3558,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;
                        }
 
@@ -3624,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) {
@@ -3642,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");
@@ -3678,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);
@@ -3691,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);
@@ -4948,7 +4953,7 @@ static int nv_close(struct net_device *dev)
 #ifdef CONFIG_FORCEDETH_NAPI
        napi_disable(&np->napi);
 #endif
-       synchronize_irq(dev->irq);
+       synchronize_irq(np->pci_dev->irq);
 
        del_timer_sync(&np->oom_kick);
        del_timer_sync(&np->nic_poll);
@@ -5281,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 */
                                }
                        }
                }
@@ -5592,6 +5593,38 @@ static struct pci_device_id pci_tbl[] = {
                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,},
 };