[NET]: Make NAPI polling independent of struct net_device objects.
[linux-3.10.git] / drivers / net / tsi108_eth.c
index 1aabc91..b3069ee 100644 (file)
@@ -79,6 +79,9 @@ struct tsi108_prv_data {
        void  __iomem *regs;    /* Base of normal regs */
        void  __iomem *phyregs; /* Base of register bank used for PHY access */
 
+       struct net_device *dev;
+       struct napi_struct napi;
+
        unsigned int phy;               /* Index of PHY for this interface */
        unsigned int irq_num;
        unsigned int id;
@@ -837,13 +840,13 @@ static int tsi108_refill_rx(struct net_device *dev, int budget)
        return done;
 }
 
-static int tsi108_poll(struct net_device *dev, int *budget)
+static int tsi108_poll(struct napi_struct *napi, int budget)
 {
-       struct tsi108_prv_data *data = netdev_priv(dev);
+       struct tsi108_prv_data *data = container_of(napi, struct tsi108_prv_data, napi);
+       struct net_device *dev = data->dev;
        u32 estat = TSI_READ(TSI108_EC_RXESTAT);
        u32 intstat = TSI_READ(TSI108_EC_INTSTAT);
-       int total_budget = min(*budget, dev->quota);
-       int num_received = 0, num_filled = 0, budget_used;
+       int num_received = 0, num_filled = 0;
 
        intstat &= TSI108_INT_RXQUEUE0 | TSI108_INT_RXTHRESH |
            TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR | TSI108_INT_RXWAIT;
@@ -852,7 +855,7 @@ static int tsi108_poll(struct net_device *dev, int *budget)
        TSI_WRITE(TSI108_EC_INTSTAT, intstat);
 
        if (data->rxpending || (estat & TSI108_EC_RXESTAT_Q0_DESCINT))
-               num_received = tsi108_complete_rx(dev, total_budget);
+               num_received = tsi108_complete_rx(dev, budget);
 
        /* This should normally fill no more slots than the number of
         * packets received in tsi108_complete_rx().  The exception
@@ -867,7 +870,7 @@ static int tsi108_poll(struct net_device *dev, int *budget)
         */
 
        if (data->rxfree < TSI108_RXRING_LEN)
-               num_filled = tsi108_refill_rx(dev, total_budget * 2);
+               num_filled = tsi108_refill_rx(dev, budget * 2);
 
        if (intstat & TSI108_INT_RXERROR) {
                u32 err = TSI_READ(TSI108_EC_RXERR);
@@ -890,14 +893,9 @@ static int tsi108_poll(struct net_device *dev, int *budget)
                spin_unlock_irq(&data->misclock);
        }
 
-       budget_used = max(num_received, num_filled / 2);
-
-       *budget -= budget_used;
-       dev->quota -= budget_used;
-
-       if (budget_used != total_budget) {
+       if (num_received < budget) {
                data->rxpending = 0;
-               netif_rx_complete(dev);
+               netif_rx_complete(dev, napi);
 
                TSI_WRITE(TSI108_EC_INTMASK,
                                     TSI_READ(TSI108_EC_INTMASK)
@@ -906,14 +904,11 @@ static int tsi108_poll(struct net_device *dev, int *budget)
                                         TSI108_INT_RXOVERRUN |
                                         TSI108_INT_RXERROR |
                                         TSI108_INT_RXWAIT));
-
-               /* IRQs are level-triggered, so no need to re-check */
-               return 0;
        } else {
                data->rxpending = 1;
        }
 
-       return 1;
+       return num_received;
 }
 
 static void tsi108_rx_int(struct net_device *dev)
@@ -931,7 +926,7 @@ static void tsi108_rx_int(struct net_device *dev)
         * from tsi108_check_rxring().
         */
 
-       if (netif_rx_schedule_prep(dev)) {
+       if (netif_rx_schedule_prep(dev, &data->napi)) {
                /* Mask, rather than ack, the receive interrupts.  The ack
                 * will happen in tsi108_poll().
                 */
@@ -942,7 +937,7 @@ static void tsi108_rx_int(struct net_device *dev)
                                     | TSI108_INT_RXTHRESH |
                                     TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR |
                                     TSI108_INT_RXWAIT);
-               __netif_rx_schedule(dev);
+               __netif_rx_schedule(dev, &data->napi);
        } else {
                if (!netif_running(dev)) {
                        /* This can happen if an interrupt occurs while the
@@ -1401,6 +1396,8 @@ static int tsi108_open(struct net_device *dev)
        TSI_WRITE(TSI108_EC_TXQ_PTRLOW, data->txdma);
        tsi108_init_phy(dev);
 
+       napi_enable(&data->napi);
+
        setup_timer(&data->timer, tsi108_timed_checker, (unsigned long)dev);
        mod_timer(&data->timer, jiffies + 1);
 
@@ -1425,6 +1422,7 @@ static int tsi108_close(struct net_device *dev)
        struct tsi108_prv_data *data = netdev_priv(dev);
 
        netif_stop_queue(dev);
+       napi_disable(&data->napi);
 
        del_timer_sync(&data->timer);
 
@@ -1562,6 +1560,7 @@ tsi108_init_one(struct platform_device *pdev)
 
        printk("tsi108_eth%d: probe...\n", pdev->id);
        data = netdev_priv(dev);
+       data->dev = dev;
 
        pr_debug("tsi108_eth%d:regs:phyresgs:phy:irq_num=0x%x:0x%x:0x%x:0x%x\n",
                        pdev->id, einfo->regs, einfo->phyregs,
@@ -1597,9 +1596,8 @@ tsi108_init_one(struct platform_device *pdev)
        dev->set_mac_address = tsi108_set_mac;
        dev->set_multicast_list = tsi108_set_rx_mode;
        dev->get_stats = tsi108_get_stats;
-       dev->poll = tsi108_poll;
+       netif_napi_add(dev, &data->napi, tsi108_poll, 64);
        dev->do_ioctl = tsi108_do_ioctl;
-       dev->weight = 64;  /* 64 is more suitable for GigE interface - klai */
 
        /* Apparently, the Linux networking code won't use scatter-gather
         * if the hardware doesn't do checksums.  However, it's faster