[PATCH] libertas: remove incorrect vi modelines
[safe/jmp/linux-2.6] / drivers / net / forcedeth.c
index 9f6b9d4..7a01802 100644 (file)
  *     0.57: 14 May 2006: Mac address set in probe/remove and order corrections.
  *     0.58: 30 Oct 2006: Added support for sideband management unit.
  *     0.59: 30 Oct 2006: Added support for recoverable error.
+ *     0.60: 20 Jan 2007: Code optimizations for rings, rx & tx data paths, and stats.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
 #else
 #define DRIVERNAPI
 #endif
-#define FORCEDETH_VERSION              "0.59"
+#define FORCEDETH_VERSION              "0.60"
 #define DRV_NAME                       "forcedeth"
 
 #include <linux/module.h>
@@ -838,7 +839,7 @@ enum {
        NV_MSIX_INT_DISABLED,
        NV_MSIX_INT_ENABLED
 };
-static int msix = NV_MSIX_INT_ENABLED;
+static int msix = NV_MSIX_INT_DISABLED;
 
 /*
  * DMA 64bit
@@ -1351,10 +1352,19 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
 {
        struct fe_priv *np = netdev_priv(dev);
 
-       /* It seems that the nic always generates interrupts and doesn't
-        * accumulate errors internally. Thus the current values in np->stats
-        * are already up to date.
-        */
+       /* If the nic supports hw counters then retrieve latest values */
+       if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) {
+               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;
 }
 
@@ -1375,11 +1385,12 @@ static int nv_alloc_rx(struct net_device *dev)
        while (np->put_rx.orig != less_rx) {
                struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
                if (skb) {
-                       skb->dev = dev;
                        np->put_rx_ctx->skb = skb;
-                       np->put_rx_ctx->dma = pci_map_single(np->pci_dev, skb->data,
-                                                            skb->end-skb->data, PCI_DMA_FROMDEVICE);
-                       np->put_rx_ctx->dma_len = skb->end-skb->data;
+                       np->put_rx_ctx->dma = pci_map_single(np->pci_dev,
+                                                            skb->data,
+                                                            skb_tailroom(skb),
+                                                            PCI_DMA_FROMDEVICE);
+                       np->put_rx_ctx->dma_len = skb_tailroom(skb);
                        np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
                        wmb();
                        np->put_rx.orig->flaglen = cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL);
@@ -1406,11 +1417,12 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
        while (np->put_rx.ex != less_rx) {
                struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
                if (skb) {
-                       skb->dev = dev;
                        np->put_rx_ctx->skb = skb;
-                       np->put_rx_ctx->dma = pci_map_single(np->pci_dev, skb->data,
-                                                            skb->end-skb->data, PCI_DMA_FROMDEVICE);
-                       np->put_rx_ctx->dma_len = skb->end-skb->data;
+                       np->put_rx_ctx->dma = pci_map_single(np->pci_dev,
+                                                            skb->data,
+                                                            skb_tailroom(skb),
+                                                            PCI_DMA_FROMDEVICE);
+                       np->put_rx_ctx->dma_len = skb_tailroom(skb);
                        np->put_rx.ex->bufhigh = cpu_to_le64(np->put_rx_ctx->dma) >> 32;
                        np->put_rx.ex->buflow = cpu_to_le64(np->put_rx_ctx->dma) & 0x0FFFFFFFF;
                        wmb();
@@ -1594,8 +1606,9 @@ static void nv_drain_rx(struct net_device *dev)
                wmb();
                if (np->rx_skb[i].skb) {
                        pci_unmap_single(np->pci_dev, np->rx_skb[i].dma,
-                                               np->rx_skb[i].skb->end-np->rx_skb[i].skb->data,
-                                               PCI_DMA_FROMDEVICE);
+                                        (skb_end_pointer(np->rx_skb[i].skb) -
+                                         np->rx_skb[i].skb->data),
+                                        PCI_DMA_FROMDEVICE);
                        dev_kfree_skb(np->rx_skb[i].skb);
                        np->rx_skb[i].skb = NULL;
                }
@@ -1944,16 +1957,8 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
                np->get_tx_ctx->dma = 0;
 
                if (flags & NV_TX2_LASTPACKET) {
-                       if (flags & NV_TX2_ERROR) {
-                               if (flags & NV_TX2_UNDERFLOW)
-                                       np->stats.tx_fifo_errors++;
-                               if (flags & NV_TX2_CARRIERLOST)
-                                       np->stats.tx_carrier_errors++;
-                               np->stats.tx_errors++;
-                       } else {
+                       if (!(flags & NV_TX2_ERROR))
                                np->stats.tx_packets++;
-                               np->stats.tx_bytes += np->get_tx_ctx->skb->len;
-                       }
                        dev_kfree_skb_any(np->get_tx_ctx->skb);
                        np->get_tx_ctx->skb = NULL;
                }
@@ -2048,9 +2053,10 @@ static void nv_tx_timeout(struct net_device *dev)
                nv_drain_tx(dev);
                nv_init_tx(dev);
                setup_hw_rings(dev, NV_SETUP_TX_RING);
-               netif_wake_queue(dev);
        }
 
+       netif_wake_queue(dev);
+
        /* 4) restart tx engine */
        nv_start_tx(dev);
        spin_unlock_irq(&np->lock);
@@ -2290,7 +2296,6 @@ static int nv_rx_process_optimized(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_kfree_skb(skb);
                                                goto next_pkt;
                                        }
@@ -2303,11 +2308,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
                                }
                                /* the rest are hard errors */
                                else {
-                                       if (flags & NV_RX2_CRCERR)
-                                               np->stats.rx_crc_errors++;
-                                       if (flags & NV_RX2_OVERFLOW)
-                                               np->stats.rx_over_errors++;
-                                       np->stats.rx_errors++;
                                        dev_kfree_skb(skb);
                                        goto next_pkt;
                                }
@@ -3108,13 +3108,17 @@ static int nv_napi_poll(struct net_device *dev, int *budget)
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
        unsigned long flags;
+       int retcode;
 
-       if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+       if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
                pkts = nv_rx_process(dev, limit);
-       else
+               retcode = nv_alloc_rx(dev);
+       } else {
                pkts = nv_rx_process_optimized(dev, limit);
+               retcode = nv_alloc_rx_optimized(dev);
+       }
 
-       if (nv_alloc_rx(dev)) {
+       if (retcode) {
                spin_lock_irqsave(&np->lock, flags);
                if (!np->in_shutdown)
                        mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
@@ -3536,7 +3540,10 @@ static void nv_do_nic_poll(unsigned long data)
        pci_push(base);
 
        if (!using_multi_irqs(dev)) {
-               nv_nic_irq(0, dev);
+               if (np->desc_ver == DESC_VER_3)
+                       nv_nic_irq_optimized(0, dev);
+               else
+                       nv_nic_irq(0, dev);
                if (np->msi_flags & NV_MSI_X_ENABLED)
                        enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
                else
@@ -4372,11 +4379,12 @@ static int nv_loopback_test(struct net_device *dev)
                ret = 0;
                goto out;
        }
+       test_dma_addr = pci_map_single(np->pci_dev, tx_skb->data,
+                                      skb_tailroom(tx_skb),
+                                      PCI_DMA_FROMDEVICE);
        pkt_data = skb_put(tx_skb, pkt_len);
        for (i = 0; i < pkt_len; i++)
                pkt_data[i] = (u8)(i & 0xff);
-       test_dma_addr = pci_map_single(np->pci_dev, tx_skb->data,
-                                      tx_skb->end-tx_skb->data, PCI_DMA_FROMDEVICE);
 
        if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
                np->tx_ring.orig[0].buf = cpu_to_le32(test_dma_addr);
@@ -4433,7 +4441,7 @@ static int nv_loopback_test(struct net_device *dev)
        }
 
        pci_unmap_page(np->pci_dev, test_dma_addr,
-                      tx_skb->end-tx_skb->data,
+                      (skb_end_pointer(tx_skb) - tx_skb->data),
                       PCI_DMA_TODEVICE);
        dev_kfree_skb_any(tx_skb);
  out:
@@ -4941,7 +4949,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
                dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
                dev->features |= NETIF_F_TSO;
-       }
+       }
 
        np->vlanctl_bits = 0;
        if (id->driver_data & DEV_HAS_VLAN) {
@@ -5374,19 +5382,19 @@ static struct pci_device_id pci_tbl[] = {
        },
        {       /* 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_CHECKSUM|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,
        },
        {       /* 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_CHECKSUM|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,
        },
        {       /* 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_CHECKSUM|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,
        },
        {       /* 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_CHECKSUM|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,
        },
        {       /* MCP67 Ethernet Controller */
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),