[NET]: Make NAPI polling independent of struct net_device objects.
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / net / 8139too.c
index f4e4298d24b96ef40ab305fb3270855b388360d4..20af6baecfcb58b01ec4826533c69823b24f40b9 100644 (file)
@@ -573,6 +573,8 @@ struct rtl8139_private {
        int drv_flags;
        struct pci_dev *pci_dev;
        u32 msg_enable;
+       struct napi_struct napi;
+       struct net_device *dev;
        struct net_device_stats stats;
        unsigned char *rx_ring;
        unsigned int cur_rx;    /* Index into the Rx buffer of next Rx pkt. */
@@ -625,10 +627,10 @@ static void rtl8139_tx_timeout (struct net_device *dev);
 static void rtl8139_init_ring (struct net_device *dev);
 static int rtl8139_start_xmit (struct sk_buff *skb,
                               struct net_device *dev);
-static int rtl8139_poll(struct net_device *dev, int *budget);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void rtl8139_poll_controller(struct net_device *dev);
 #endif
+static int rtl8139_poll(struct napi_struct *napi, int budget);
 static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
 static int rtl8139_close (struct net_device *dev);
 static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
@@ -963,6 +965,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
 
        assert (dev != NULL);
        tp = netdev_priv(dev);
+       tp->dev = dev;
 
        ioaddr = tp->mmio_addr;
        assert (ioaddr != NULL);
@@ -976,8 +979,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        /* The Rtl8139-specific entries in the device structure. */
        dev->open = rtl8139_open;
        dev->hard_start_xmit = rtl8139_start_xmit;
-       dev->poll = rtl8139_poll;
-       dev->weight = 64;
+       netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
        dev->stop = rtl8139_close;
        dev->get_stats = rtl8139_get_stats;
        dev->set_multicast_list = rtl8139_set_rx_mode;
@@ -1332,6 +1334,8 @@ static int rtl8139_open (struct net_device *dev)
 
        }
 
+       napi_enable(&tp->napi);
+
        tp->mii.full_duplex = tp->mii.force_media;
        tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
 
@@ -2103,39 +2107,32 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
        }
 }
 
-static int rtl8139_poll(struct net_device *dev, int *budget)
+static int rtl8139_poll(struct napi_struct *napi, int budget)
 {
-       struct rtl8139_private *tp = netdev_priv(dev);
+       struct rtl8139_private *tp = container_of(napi, struct rtl8139_private, napi);
+       struct net_device *dev = tp->dev;
        void __iomem *ioaddr = tp->mmio_addr;
-       int orig_budget = min(*budget, dev->quota);
-       int done = 1;
+       int work_done;
 
        spin_lock(&tp->rx_lock);
-       if (likely(RTL_R16(IntrStatus) & RxAckBits)) {
-               int work_done;
-
-               work_done = rtl8139_rx(dev, tp, orig_budget);
-               if (likely(work_done > 0)) {
-                       *budget -= work_done;
-                       dev->quota -= work_done;
-                       done = (work_done < orig_budget);
-               }
-       }
+       work_done = 0;
+       if (likely(RTL_R16(IntrStatus) & RxAckBits))
+               work_done += rtl8139_rx(dev, tp, budget);
 
-       if (done) {
+       if (work_done < budget) {
                unsigned long flags;
                /*
                 * Order is important since data can get interrupted
                 * again when we think we are done.
                 */
-               local_irq_save(flags);
+               spin_lock_irqsave(&tp->lock, flags);
                RTL_W16_F(IntrMask, rtl8139_intr_mask);
-               __netif_rx_complete(dev);
-               local_irq_restore(flags);
+               __netif_rx_complete(dev, napi);
+               spin_unlock_irqrestore(&tp->lock, flags);
        }
        spin_unlock(&tp->rx_lock);
 
-       return !done;
+       return work_done;
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
@@ -2180,9 +2177,9 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
        /* Receive packets are processed by poll routine.
           If not running start it now. */
        if (status & RxAckBits){
-               if (netif_rx_schedule_prep(dev)) {
+               if (netif_rx_schedule_prep(dev, &tp->napi)) {
                        RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
-                       __netif_rx_schedule (dev);
+                       __netif_rx_schedule(dev, &tp->napi);
                }
        }
 
@@ -2223,7 +2220,8 @@ static int rtl8139_close (struct net_device *dev)
        void __iomem *ioaddr = tp->mmio_addr;
        unsigned long flags;
 
-       netif_stop_queue (dev);
+       netif_stop_queue(dev);
+       napi_disable(&tp->napi);
 
        if (netif_msg_ifdown(tp))
                printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",