Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[safe/jmp/linux-2.6] / drivers / net / forcedeth.c
index b60a304..5c98f7c 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
+#include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/timer.h>
@@ -58,6 +59,7 @@
 #include <linux/init.h>
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
+#include <linux/slab.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -719,7 +721,8 @@ static const struct register_test nv_registers_test[] = {
 struct nv_skb_map {
        struct sk_buff *skb;
        dma_addr_t dma;
-       unsigned int dma_len;
+       unsigned int dma_len:31;
+       unsigned int dma_single:1;
        struct ring_desc_ex *first_tx_desc;
        struct nv_skb_map *next_tx_ctx;
 };
@@ -1912,6 +1915,7 @@ static void nv_init_tx(struct net_device *dev)
                np->tx_skb[i].skb = NULL;
                np->tx_skb[i].dma = 0;
                np->tx_skb[i].dma_len = 0;
+               np->tx_skb[i].dma_single = 0;
                np->tx_skb[i].first_tx_desc = NULL;
                np->tx_skb[i].next_tx_ctx = NULL;
        }
@@ -1930,23 +1934,30 @@ static int nv_init_ring(struct net_device *dev)
                return nv_alloc_rx_optimized(dev);
 }
 
-static int nv_release_txskb(struct net_device *dev, struct nv_skb_map* tx_skb)
+static void nv_unmap_txskb(struct fe_priv *np, struct nv_skb_map *tx_skb)
 {
-       struct fe_priv *np = netdev_priv(dev);
-
        if (tx_skb->dma) {
-               pci_unmap_page(np->pci_dev, tx_skb->dma,
-                              tx_skb->dma_len,
-                              PCI_DMA_TODEVICE);
+               if (tx_skb->dma_single)
+                       pci_unmap_single(np->pci_dev, tx_skb->dma,
+                                        tx_skb->dma_len,
+                                        PCI_DMA_TODEVICE);
+               else
+                       pci_unmap_page(np->pci_dev, tx_skb->dma,
+                                      tx_skb->dma_len,
+                                      PCI_DMA_TODEVICE);
                tx_skb->dma = 0;
        }
+}
+
+static int nv_release_txskb(struct fe_priv *np, struct nv_skb_map *tx_skb)
+{
+       nv_unmap_txskb(np, tx_skb);
        if (tx_skb->skb) {
                dev_kfree_skb_any(tx_skb->skb);
                tx_skb->skb = NULL;
                return 1;
-       } else {
-               return 0;
        }
+       return 0;
 }
 
 static void nv_drain_tx(struct net_device *dev)
@@ -1964,10 +1975,11 @@ static void nv_drain_tx(struct net_device *dev)
                        np->tx_ring.ex[i].bufhigh = 0;
                        np->tx_ring.ex[i].buflow = 0;
                }
-               if (nv_release_txskb(dev, &np->tx_skb[i]))
+               if (nv_release_txskb(np, &np->tx_skb[i]))
                        dev->stats.tx_dropped++;
                np->tx_skb[i].dma = 0;
                np->tx_skb[i].dma_len = 0;
+               np->tx_skb[i].dma_single = 0;
                np->tx_skb[i].first_tx_desc = NULL;
                np->tx_skb[i].next_tx_ctx = NULL;
        }
@@ -2127,7 +2139,7 @@ static void nv_gear_backoff_reseed(struct net_device *dev)
  * nv_start_xmit: dev->hard_start_xmit function
  * Called with netif_tx_lock held.
  */
-static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct fe_priv *np = netdev_priv(dev);
        u32 tx_flags = 0;
@@ -2171,6 +2183,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
                np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
                                                PCI_DMA_TODEVICE);
                np->put_tx_ctx->dma_len = bcnt;
+               np->put_tx_ctx->dma_single = 1;
                put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma);
                put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
 
@@ -2196,6 +2209,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt,
                                                           PCI_DMA_TODEVICE);
                        np->put_tx_ctx->dma_len = bcnt;
+                       np->put_tx_ctx->dma_single = 0;
                        put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma);
                        put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
 
@@ -2245,7 +2259,8 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return NETDEV_TX_OK;
 }
 
-static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
+                                          struct net_device *dev)
 {
        struct fe_priv *np = netdev_priv(dev);
        u32 tx_flags = 0;
@@ -2291,6 +2306,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
                np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
                                                PCI_DMA_TODEVICE);
                np->put_tx_ctx->dma_len = bcnt;
+               np->put_tx_ctx->dma_single = 1;
                put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma));
                put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma));
                put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
@@ -2317,6 +2333,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
                        np->put_tx_ctx->dma = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt,
                                                           PCI_DMA_TODEVICE);
                        np->put_tx_ctx->dma_len = bcnt;
+                       np->put_tx_ctx->dma_single = 0;
                        put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma));
                        put_tx->buflow = cpu_to_le32(dma_low(np->put_tx_ctx->dma));
                        put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
@@ -2434,10 +2451,7 @@ static int nv_tx_done(struct net_device *dev, int limit)
                dprintk(KERN_DEBUG "%s: nv_tx_done: flags 0x%x.\n",
                                        dev->name, flags);
 
-               pci_unmap_page(np->pci_dev, np->get_tx_ctx->dma,
-                              np->get_tx_ctx->dma_len,
-                              PCI_DMA_TODEVICE);
-               np->get_tx_ctx->dma = 0;
+               nv_unmap_txskb(np, np->get_tx_ctx);
 
                if (np->desc_ver == DESC_VER_1) {
                        if (flags & NV_TX_LASTPACKET) {
@@ -2502,10 +2516,7 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
                dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n",
                                        dev->name, flags);
 
-               pci_unmap_page(np->pci_dev, np->get_tx_ctx->dma,
-                              np->get_tx_ctx->dma_len,
-                              PCI_DMA_TODEVICE);
-               np->get_tx_ctx->dma = 0;
+               nv_unmap_txskb(np, np->get_tx_ctx);
 
                if (flags & NV_TX2_LASTPACKET) {
                        if (!(flags & NV_TX2_ERROR))
@@ -3085,7 +3096,7 @@ static void nv_set_multicast(struct net_device *dev)
        } else {
                pff |= NVREG_PFF_MYADDR;
 
-               if (dev->flags & IFF_ALLMULTI || dev->mc_list) {
+               if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) {
                        u32 alwaysOff[2];
                        u32 alwaysOn[2];
 
@@ -3095,8 +3106,7 @@ static void nv_set_multicast(struct net_device *dev)
                        } else {
                                struct dev_mc_list *walk;
 
-                               walk = dev->mc_list;
-                               while (walk != NULL) {
+                               netdev_for_each_mc_addr(walk, dev) {
                                        u32 a, b;
                                        a = le32_to_cpu(*(__le32 *) walk->dmi_addr);
                                        b = le16_to_cpu(*(__le16 *) (&walk->dmi_addr[4]));
@@ -3104,7 +3114,6 @@ static void nv_set_multicast(struct net_device *dev)
                                        alwaysOff[0] &= ~a;
                                        alwaysOn[1] &= b;
                                        alwaysOff[1] &= ~b;
-                                       walk = walk->next;
                                }
                        }
                        addr[0] = alwaysOn[0];
@@ -3506,11 +3515,13 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
        nv_msi_workaround(np);
 
 #ifdef CONFIG_FORCEDETH_NAPI
-       napi_schedule(&np->napi);
-
-       /* Disable furthur irq's
-          (msix not enabled with napi) */
-       writel(0, base + NvRegIrqMask);
+       if (napi_schedule_prep(&np->napi)) {
+               /*
+                * Disable further irq's (msix not enabled with napi)
+                */
+               writel(0, base + NvRegIrqMask);
+               __napi_schedule(&np->napi);
+       }
 
 #else
        do
@@ -3607,12 +3618,13 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
        nv_msi_workaround(np);
 
 #ifdef CONFIG_FORCEDETH_NAPI
-       napi_schedule(&np->napi);
-
-       /* Disable furthur irq's
-          (msix not enabled with napi) */
-       writel(0, base + NvRegIrqMask);
-
+       if (napi_schedule_prep(&np->napi)) {
+               /*
+                * Disable further irq's (msix not enabled with napi)
+                */
+               writel(0, base + NvRegIrqMask);
+               __napi_schedule(&np->napi);
+       }
 #else
        do
        {
@@ -3991,7 +4003,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
                                /* Request irq for rx handling */
                                sprintf(np->name_rx, "%s-rx", dev->name);
                                if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector,
-                                               &nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) {
+                                               nv_nic_irq_rx, IRQF_SHARED, np->name_rx, dev) != 0) {
                                        printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
                                        pci_disable_msix(np->pci_dev);
                                        np->msi_flags &= ~NV_MSI_X_ENABLED;
@@ -4000,7 +4012,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
                                /* Request irq for tx handling */
                                sprintf(np->name_tx, "%s-tx", dev->name);
                                if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector,
-                                               &nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) {
+                                               nv_nic_irq_tx, IRQF_SHARED, np->name_tx, dev) != 0) {
                                        printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret);
                                        pci_disable_msix(np->pci_dev);
                                        np->msi_flags &= ~NV_MSI_X_ENABLED;
@@ -4009,7 +4021,7 @@ static int nv_request_irq(struct net_device *dev, int intr_test)
                                /* Request irq for link and timer handling */
                                sprintf(np->name_other, "%s-other", dev->name);
                                if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector,
-                                               &nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) {
+                                               nv_nic_irq_other, IRQF_SHARED, np->name_other, dev) != 0) {
                                        printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret);
                                        pci_disable_msix(np->pci_dev);
                                        np->msi_flags &= ~NV_MSI_X_ENABLED;
@@ -5091,7 +5103,7 @@ static int nv_loopback_test(struct net_device *dev)
                dprintk(KERN_DEBUG "%s: loopback - did not receive test packet\n", dev->name);
        }
 
-       pci_unmap_page(np->pci_dev, test_dma_addr,
+       pci_unmap_single(np->pci_dev, test_dma_addr,
                       (skb_end_pointer(tx_skb) - tx_skb->data),
                       PCI_DMA_TODEVICE);
        dev_kfree_skb_any(tx_skb);
@@ -5808,10 +5820,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                        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);
+               random_ether_addr(dev->dev_addr);
        }
 
        dprintk(KERN_DEBUG "%s: MAC Address %pM\n",
@@ -5890,7 +5899,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        /* Limit the number of tx's outstanding for hw bug */
        if (id->driver_data & DEV_NEED_TX_LIMIT) {
                np->tx_limit = 1;
-               if ((id->driver_data & DEV_NEED_TX_LIMIT2) &&
+               if (((id->driver_data & DEV_NEED_TX_LIMIT2) == DEV_NEED_TX_LIMIT2) &&
                    pci_dev->revision >= 0xA2)
                        np->tx_limit = 0;
        }
@@ -6188,7 +6197,7 @@ static void nv_shutdown(struct pci_dev *pdev)
 #define nv_resume NULL
 #endif /* CONFIG_PM */
 
-static struct pci_device_id pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = {
        {       /* nForce Ethernet Controller */
                PCI_DEVICE(0x10DE, 0x01C3),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,