]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/typhoon.c
[NET]: Make NAPI polling independent of struct net_device objects.
[linux-2.6-omap-h63xx.git] / drivers / net / typhoon.c
index 03587205546e71260ad81c10c76dee6d0674d719..0377b8b64c78e6fb71ae0f38842f8c612fe4d113 100644 (file)
@@ -284,6 +284,7 @@ struct typhoon {
        struct basic_ring       rxLoRing;
        struct pci_dev *        pdev;
        struct net_device *     dev;
+       struct napi_struct      napi;
        spinlock_t              state_lock;
        struct vlan_group *     vlgrp;
        struct basic_ring       rxHiRing;
@@ -1759,12 +1760,12 @@ typhoon_fill_free_ring(struct typhoon *tp)
 }
 
 static int
-typhoon_poll(struct net_device *dev, int *total_budget)
+typhoon_poll(struct napi_struct *napi, int budget)
 {
-       struct typhoon *tp = netdev_priv(dev);
+       struct typhoon *tp = container_of(napi, struct typhoon, napi);
+       struct net_device *dev = tp->dev;
        struct typhoon_indexes *indexes = tp->indexes;
-       int orig_budget = *total_budget;
-       int budget, work_done, done;
+       int work_done;
 
        rmb();
        if(!tp->awaiting_resp && indexes->respReady != indexes->respCleared)
@@ -1773,30 +1774,16 @@ typhoon_poll(struct net_device *dev, int *total_budget)
        if(le32_to_cpu(indexes->txLoCleared) != tp->txLoRing.lastRead)
                typhoon_tx_complete(tp, &tp->txLoRing, &indexes->txLoCleared);
 
-       if(orig_budget > dev->quota)
-               orig_budget = dev->quota;
-
-       budget = orig_budget;
        work_done = 0;
-       done = 1;
 
        if(indexes->rxHiCleared != indexes->rxHiReady) {
-               work_done = typhoon_rx(tp, &tp->rxHiRing, &indexes->rxHiReady,
+               work_done += typhoon_rx(tp, &tp->rxHiRing, &indexes->rxHiReady,
                                        &indexes->rxHiCleared, budget);
-               budget -= work_done;
        }
 
        if(indexes->rxLoCleared != indexes->rxLoReady) {
                work_done += typhoon_rx(tp, &tp->rxLoRing, &indexes->rxLoReady,
-                                       &indexes->rxLoCleared, budget);
-       }
-
-       if(work_done) {
-               *total_budget -= work_done;
-               dev->quota -= work_done;
-
-               if(work_done >= orig_budget)
-                       done = 0;
+                                       &indexes->rxLoCleared, budget - work_done);
        }
 
        if(le32_to_cpu(indexes->rxBuffCleared) == tp->rxBuffRing.lastWrite) {
@@ -1804,14 +1791,14 @@ typhoon_poll(struct net_device *dev, int *total_budget)
                typhoon_fill_free_ring(tp);
        }
 
-       if(done) {
-               netif_rx_complete(dev);
+       if (work_done < budget) {
+               netif_rx_complete(dev, napi);
                iowrite32(TYPHOON_INTR_NONE,
                                tp->ioaddr + TYPHOON_REG_INTR_MASK);
                typhoon_post_pci_writes(tp->ioaddr);
        }
 
-       return (done ? 0 : 1);
+       return work_done;
 }
 
 static irqreturn_t
@@ -1828,10 +1815,10 @@ typhoon_interrupt(int irq, void *dev_instance)
 
        iowrite32(intr_status, ioaddr + TYPHOON_REG_INTR_STATUS);
 
-       if(netif_rx_schedule_prep(dev)) {
+       if (netif_rx_schedule_prep(dev, &tp->napi)) {
                iowrite32(TYPHOON_INTR_ALL, ioaddr + TYPHOON_REG_INTR_MASK);
                typhoon_post_pci_writes(ioaddr);
-               __netif_rx_schedule(dev);
+               __netif_rx_schedule(dev, &tp->napi);
        } else {
                printk(KERN_ERR "%s: Error, poll already scheduled\n",
                        dev->name);
@@ -2119,9 +2106,13 @@ typhoon_open(struct net_device *dev)
        if(err < 0)
                goto out_sleep;
 
+       napi_enable(&tp->napi);
+
        err = typhoon_start_runtime(tp);
-       if(err < 0)
+       if(err < 0) {
+               napi_disable(&tp->napi);
                goto out_irq;
+       }
 
        netif_start_queue(dev);
        return 0;
@@ -2150,6 +2141,7 @@ typhoon_close(struct net_device *dev)
        struct typhoon *tp = netdev_priv(dev);
 
        netif_stop_queue(dev);
+       napi_disable(&tp->napi);
 
        if(typhoon_stop_runtime(tp, WaitSleep) < 0)
                printk(KERN_ERR "%s: unable to stop runtime\n", dev->name);
@@ -2521,8 +2513,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->stop               = typhoon_close;
        dev->set_multicast_list = typhoon_set_rx_mode;
        dev->tx_timeout         = typhoon_tx_timeout;
-       dev->poll               = typhoon_poll;
-       dev->weight             = 16;
+       netif_napi_add(dev, &tp->napi, typhoon_poll, 16);
        dev->watchdog_timeo     = TX_TIMEOUT;
        dev->get_stats          = typhoon_get_stats;
        dev->set_mac_address    = typhoon_set_mac_address;