[NET]: Make NAPI polling independent of struct net_device objects.
[safe/jmp/linux-2.6] / drivers / net / typhoon.c
index f2dd776..0377b8b 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;
@@ -639,7 +640,7 @@ typhoon_issue_command(struct typhoon *tp, int num_cmd, struct cmd_desc *cmd,
 
        typhoon_inc_cmd_index(&ring->lastWrite, num_cmd);
 
-       /* "I feel a presence... another warrior is on the the mesa."
+       /* "I feel a presence... another warrior is on the mesa."
         */
        wmb();
        iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY);
@@ -741,15 +742,6 @@ typhoon_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
        spin_unlock_bh(&tp->state_lock);
 }
 
-static void
-typhoon_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-       struct typhoon *tp = netdev_priv(dev);
-       spin_lock_bh(&tp->state_lock);
-       vlan_group_set_device(tp->vlgrp, vid, NULL);
-       spin_unlock_bh(&tp->state_lock);
-}
-
 static inline void
 typhoon_tso_fill(struct sk_buff *skb, struct transmit_ring *txRing,
                        u32 ring_dma)
@@ -1712,7 +1704,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile u32 * ready,
                        pci_dma_sync_single_for_cpu(tp->pdev, dma_addr,
                                                    PKT_BUF_SZ,
                                                    PCI_DMA_FROMDEVICE);
-                       eth_copy_and_sum(new_skb, skb->data, pkt_len, 0);
+                       skb_copy_to_linear_data(new_skb, skb->data, pkt_len);
                        pci_dma_sync_single_for_device(tp->pdev, dma_addr,
                                                       PKT_BUF_SZ,
                                                       PCI_DMA_FROMDEVICE);
@@ -1768,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)
@@ -1782,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) {
@@ -1813,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
@@ -1837,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);
@@ -2128,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;
@@ -2159,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);
@@ -2276,12 +2259,6 @@ need_resume:
        typhoon_resume(pdev);
        return -EBUSY;
 }
-
-static int
-typhoon_enable_wake(struct pci_dev *pdev, pci_power_t state, int enable)
-{
-       return pci_enable_wake(pdev, state, enable);
-}
 #endif
 
 static int __devinit
@@ -2536,13 +2513,12 @@ 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;
        dev->vlan_rx_register   = typhoon_vlan_rx_register;
-       dev->vlan_rx_kill_vid   = typhoon_vlan_rx_kill_vid;
+
        SET_ETHTOOL_OPS(dev, &typhoon_ethtool_ops);
 
        /* We can handle scatter gather, up to 16 entries, and
@@ -2645,7 +2621,6 @@ static struct pci_driver typhoon_driver = {
 #ifdef CONFIG_PM
        .suspend        = typhoon_suspend,
        .resume         = typhoon_resume,
-       .enable_wake    = typhoon_enable_wake,
 #endif
 };