mmc: s3c6410: add new quirk in sdhci driver and update ADMA descriptor build
[safe/jmp/linux-2.6] / drivers / net / forcedeth.c
index 73fe977..268ea4d 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>
@@ -1102,20 +1104,16 @@ static void nv_disable_hw_interrupts(struct net_device *dev, u32 mask)
 
 static void nv_napi_enable(struct net_device *dev)
 {
-#ifdef CONFIG_FORCEDETH_NAPI
        struct fe_priv *np = get_nvpriv(dev);
 
        napi_enable(&np->napi);
-#endif
 }
 
 static void nv_napi_disable(struct net_device *dev)
 {
-#ifdef CONFIG_FORCEDETH_NAPI
        struct fe_priv *np = get_nvpriv(dev);
 
        napi_disable(&np->napi);
-#endif
 }
 
 #define MII_READ       (-1)
@@ -1808,7 +1806,6 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
 }
 
 /* If rx bufs are exhausted called after 50ms to attempt to refresh */
-#ifdef CONFIG_FORCEDETH_NAPI
 static void nv_do_rx_refill(unsigned long data)
 {
        struct net_device *dev = (struct net_device *) data;
@@ -1817,41 +1814,6 @@ static void nv_do_rx_refill(unsigned long data)
        /* Just reschedule NAPI rx processing */
        napi_schedule(&np->napi);
 }
-#else
-static void nv_do_rx_refill(unsigned long data)
-{
-       struct net_device *dev = (struct net_device *) data;
-       struct fe_priv *np = netdev_priv(dev);
-       int retcode;
-
-       if (!using_multi_irqs(dev)) {
-               if (np->msi_flags & NV_MSI_X_ENABLED)
-                       disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-               else
-                       disable_irq(np->pci_dev->irq);
-       } else {
-               disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
-       }
-       if (!nv_optimized(np))
-               retcode = nv_alloc_rx(dev);
-       else
-               retcode = nv_alloc_rx_optimized(dev);
-       if (retcode) {
-               spin_lock_irq(&np->lock);
-               if (!np->in_shutdown)
-                       mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-               spin_unlock_irq(&np->lock);
-       }
-       if (!using_multi_irqs(dev)) {
-               if (np->msi_flags & NV_MSI_X_ENABLED)
-                       enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-               else
-                       enable_irq(np->pci_dev->irq);
-       } else {
-               enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
-       }
-}
-#endif
 
 static void nv_init_rx(struct net_device *dev)
 {
@@ -2146,7 +2108,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
        unsigned int i;
        u32 offset = 0;
        u32 bcnt;
-       u32 size = skb->len-skb->data_len;
+       u32 size = skb_headlen(skb);
        u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
        u32 empty_slots;
        struct ring_desc* put_tx;
@@ -2252,7 +2214,6 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
                dprintk("\n");
        }
 
-       dev->trans_start = jiffies;
        writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
        return NETDEV_TX_OK;
 }
@@ -2267,7 +2228,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
        unsigned int i;
        u32 offset = 0;
        u32 bcnt;
-       u32 size = skb->len-skb->data_len;
+       u32 size = skb_headlen(skb);
        u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
        u32 empty_slots;
        struct ring_desc_ex* put_tx;
@@ -2407,7 +2368,6 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
                dprintk("\n");
        }
 
-       dev->trans_start = jiffies;
        writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
        return NETDEV_TX_OK;
 }
@@ -2814,11 +2774,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
                skb->protocol = eth_type_trans(skb, dev);
                dprintk(KERN_DEBUG "%s: nv_rx_process: %d bytes, proto %d accepted.\n",
                                        dev->name, len, skb->protocol);
-#ifdef CONFIG_FORCEDETH_NAPI
-               netif_receive_skb(skb);
-#else
-               netif_rx(skb);
-#endif
+               napi_gro_receive(&np->napi, skb);
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += len;
 next_pkt:
@@ -2907,27 +2863,14 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
                                dev->name, len, skb->protocol);
 
                        if (likely(!np->vlangrp)) {
-#ifdef CONFIG_FORCEDETH_NAPI
-                               netif_receive_skb(skb);
-#else
-                               netif_rx(skb);
-#endif
+                               napi_gro_receive(&np->napi, skb);
                        } else {
                                vlanflags = le32_to_cpu(np->get_rx.ex->buflow);
                                if (vlanflags & NV_RX3_VLAN_TAG_PRESENT) {
-#ifdef CONFIG_FORCEDETH_NAPI
-                                       vlan_hwaccel_receive_skb(skb, np->vlangrp,
-                                                                vlanflags & NV_RX3_VLAN_TAG_MASK);
-#else
-                                       vlan_hwaccel_rx(skb, np->vlangrp,
-                                                       vlanflags & NV_RX3_VLAN_TAG_MASK);
-#endif
+                                       vlan_gro_receive(&np->napi, np->vlangrp,
+                                                        vlanflags & NV_RX3_VLAN_TAG_MASK, skb);
                                } else {
-#ifdef CONFIG_FORCEDETH_NAPI
-                                       netif_receive_skb(skb);
-#else
-                                       netif_rx(skb);
-#endif
+                                       napi_gro_receive(&np->napi, skb);
                                }
                        }
 
@@ -3094,7 +3037,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];
 
@@ -3102,18 +3045,18 @@ static void nv_set_multicast(struct net_device *dev)
                        if (dev->flags & IFF_ALLMULTI) {
                                alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0;
                        } else {
-                               struct dev_mc_list *walk;
+                               struct netdev_hw_addr *ha;
 
-                               walk = dev->mc_list;
-                               while (walk != NULL) {
+                               netdev_for_each_mc_addr(ha, dev) {
+                                       unsigned char *addr = ha->addr;
                                        u32 a, b;
-                                       a = le32_to_cpu(*(__le32 *) walk->dmi_addr);
-                                       b = le16_to_cpu(*(__le16 *) (&walk->dmi_addr[4]));
+
+                                       a = le32_to_cpu(*(__le32 *) addr);
+                                       b = le16_to_cpu(*(__le16 *) (&addr[4]));
                                        alwaysOn[0] &= a;
                                        alwaysOff[0] &= ~a;
                                        alwaysOn[1] &= b;
                                        alwaysOff[1] &= ~b;
-                                       walk = walk->next;
                                }
                        }
                        addr[0] = alwaysOn[0];
@@ -3494,10 +3437,6 @@ static irqreturn_t nv_nic_irq(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);
-#ifndef CONFIG_FORCEDETH_NAPI
-       int total_work = 0;
-       int loop_count = 0;
-#endif
 
        dprintk(KERN_DEBUG "%s: nv_nic_irq\n", dev->name);
 
@@ -3514,7 +3453,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
 
        nv_msi_workaround(np);
 
-#ifdef CONFIG_FORCEDETH_NAPI
        if (napi_schedule_prep(&np->napi)) {
                /*
                 * Disable further irq's (msix not enabled with napi)
@@ -3523,65 +3461,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
                __napi_schedule(&np->napi);
        }
 
-#else
-       do
-       {
-               int work = 0;
-               if ((work = nv_rx_process(dev, RX_WORK_PER_LOOP))) {
-                       if (unlikely(nv_alloc_rx(dev))) {
-                               spin_lock(&np->lock);
-                               if (!np->in_shutdown)
-                                       mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-                               spin_unlock(&np->lock);
-                       }
-               }
-
-               spin_lock(&np->lock);
-               work += nv_tx_done(dev, TX_WORK_PER_LOOP);
-               spin_unlock(&np->lock);
-
-               if (!work)
-                       break;
-
-               total_work += work;
-
-               loop_count++;
-       }
-       while (loop_count < max_interrupt_work);
-
-       if (nv_change_interrupt_mode(dev, total_work)) {
-               /* setup new irq mask */
-               writel(np->irqmask, base + NvRegIrqMask);
-       }
-
-       if (unlikely(np->events & NVREG_IRQ_LINK)) {
-               spin_lock(&np->lock);
-               nv_link_irq(dev);
-               spin_unlock(&np->lock);
-       }
-       if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
-               spin_lock(&np->lock);
-               nv_linkchange(dev);
-               spin_unlock(&np->lock);
-               np->link_timeout = jiffies + LINK_TIMEOUT;
-       }
-       if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
-               spin_lock(&np->lock);
-               /* disable interrupts on the nic */
-               if (!(np->msi_flags & NV_MSI_X_ENABLED))
-                       writel(0, base + NvRegIrqMask);
-               else
-                       writel(np->irqmask, base + NvRegIrqMask);
-               pci_push(base);
-
-               if (!np->in_shutdown) {
-                       np->nic_poll_irq = np->irqmask;
-                       np->recover_error = 1;
-                       mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
-               }
-               spin_unlock(&np->lock);
-       }
-#endif
        dprintk(KERN_DEBUG "%s: nv_nic_irq completed\n", dev->name);
 
        return IRQ_HANDLED;
@@ -3597,10 +3476,6 @@ static irqreturn_t nv_nic_irq_optimized(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);
-#ifndef CONFIG_FORCEDETH_NAPI
-       int total_work = 0;
-       int loop_count = 0;
-#endif
 
        dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized\n", dev->name);
 
@@ -3617,7 +3492,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
 
        nv_msi_workaround(np);
 
-#ifdef CONFIG_FORCEDETH_NAPI
        if (napi_schedule_prep(&np->napi)) {
                /*
                 * Disable further irq's (msix not enabled with napi)
@@ -3625,66 +3499,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
                writel(0, base + NvRegIrqMask);
                __napi_schedule(&np->napi);
        }
-#else
-       do
-       {
-               int work = 0;
-               if ((work = nv_rx_process_optimized(dev, RX_WORK_PER_LOOP))) {
-                       if (unlikely(nv_alloc_rx_optimized(dev))) {
-                               spin_lock(&np->lock);
-                               if (!np->in_shutdown)
-                                       mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-                               spin_unlock(&np->lock);
-                       }
-               }
-
-               spin_lock(&np->lock);
-               work += nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
-               spin_unlock(&np->lock);
-
-               if (!work)
-                       break;
-
-               total_work += work;
-
-               loop_count++;
-       }
-       while (loop_count < max_interrupt_work);
-
-       if (nv_change_interrupt_mode(dev, total_work)) {
-               /* setup new irq mask */
-               writel(np->irqmask, base + NvRegIrqMask);
-       }
-
-       if (unlikely(np->events & NVREG_IRQ_LINK)) {
-               spin_lock(&np->lock);
-               nv_link_irq(dev);
-               spin_unlock(&np->lock);
-       }
-       if (unlikely(np->need_linktimer && time_after(jiffies, np->link_timeout))) {
-               spin_lock(&np->lock);
-               nv_linkchange(dev);
-               spin_unlock(&np->lock);
-               np->link_timeout = jiffies + LINK_TIMEOUT;
-       }
-       if (unlikely(np->events & NVREG_IRQ_RECOVER_ERROR)) {
-               spin_lock(&np->lock);
-               /* disable interrupts on the nic */
-               if (!(np->msi_flags & NV_MSI_X_ENABLED))
-                       writel(0, base + NvRegIrqMask);
-               else
-                       writel(np->irqmask, base + NvRegIrqMask);
-               pci_push(base);
-
-               if (!np->in_shutdown) {
-                       np->nic_poll_irq = np->irqmask;
-                       np->recover_error = 1;
-                       mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
-               }
-               spin_unlock(&np->lock);
-       }
-
-#endif
        dprintk(KERN_DEBUG "%s: nv_nic_irq_optimized completed\n", dev->name);
 
        return IRQ_HANDLED;
@@ -3733,7 +3547,6 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data)
        return IRQ_RETVAL(i);
 }
 
-#ifdef CONFIG_FORCEDETH_NAPI
 static int nv_napi_poll(struct napi_struct *napi, int budget)
 {
        struct fe_priv *np = container_of(napi, struct fe_priv, napi);
@@ -3741,23 +3554,27 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
        u8 __iomem *base = get_hwbase(dev);
        unsigned long flags;
        int retcode;
-       int tx_work, rx_work;
+       int rx_count, tx_work=0, rx_work=0;
 
-       if (!nv_optimized(np)) {
-               spin_lock_irqsave(&np->lock, flags);
-               tx_work = nv_tx_done(dev, np->tx_ring_size);
-               spin_unlock_irqrestore(&np->lock, flags);
+       do {
+               if (!nv_optimized(np)) {
+                       spin_lock_irqsave(&np->lock, flags);
+                       tx_work += nv_tx_done(dev, np->tx_ring_size);
+                       spin_unlock_irqrestore(&np->lock, flags);
 
-               rx_work = nv_rx_process(dev, budget);
-               retcode = nv_alloc_rx(dev);
-       } else {
-               spin_lock_irqsave(&np->lock, flags);
-               tx_work = nv_tx_done_optimized(dev, np->tx_ring_size);
-               spin_unlock_irqrestore(&np->lock, flags);
+                       rx_count = nv_rx_process(dev, budget - rx_work);
+                       retcode = nv_alloc_rx(dev);
+               } else {
+                       spin_lock_irqsave(&np->lock, flags);
+                       tx_work += nv_tx_done_optimized(dev, np->tx_ring_size);
+                       spin_unlock_irqrestore(&np->lock, flags);
 
-               rx_work = nv_rx_process_optimized(dev, budget);
-               retcode = nv_alloc_rx_optimized(dev);
-       }
+                       rx_count = nv_rx_process_optimized(dev,
+                           budget - rx_work);
+                       retcode = nv_alloc_rx_optimized(dev);
+               }
+       } while (retcode == 0 &&
+                rx_count > 0 && (rx_work += rx_count) < budget);
 
        if (retcode) {
                spin_lock_irqsave(&np->lock, flags);
@@ -3800,7 +3617,6 @@ static int nv_napi_poll(struct napi_struct *napi, int budget)
        }
        return rx_work;
 }
-#endif
 
 static irqreturn_t nv_nic_irq_rx(int foo, void *data)
 {
@@ -4003,7 +3819,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;
@@ -4012,7 +3828,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;
@@ -4021,7 +3837,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;
@@ -5706,6 +5522,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_IP_CSUM | NETIF_F_SG;
                dev->features |= NETIF_F_TSO;
+               dev->features |= NETIF_F_GRO;
        }
 
        np->vlanctl_bits = 0;
@@ -5758,9 +5575,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        else
                dev->netdev_ops = &nv_netdev_ops_optimized;
 
-#ifdef CONFIG_FORCEDETH_NAPI
        netif_napi_add(dev, &np->napi, nv_napi_poll, RX_WORK_PER_LOOP);
-#endif
        SET_ETHTOOL_OPS(dev, &ops);
        dev->watchdog_timeo = NV_WATCHDOG_TIMEO;
 
@@ -5863,7 +5678,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                /* msix has had reported issues when modifying irqmask
                   as in the case of napi, therefore, disable for now
                */
-#ifndef CONFIG_FORCEDETH_NAPI
+#if 0
                np->msi_flags |= NV_MSI_X_CAPABLE;
 #endif
        }
@@ -5899,7 +5714,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;
        }
@@ -6197,7 +6012,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,