aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/via-rhine.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-10-03 19:41:36 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:47:45 -0400
commitbea3348eef27e6044b6161fd04c3152215f96411 (patch)
treef0990b263e5ce42505d290a4c346fe990bcd4c33 /drivers/net/via-rhine.c
parentdde4e47e8fe333a5649a3fa0e7db1fa7c08d6158 (diff)
[NET]: Make NAPI polling independent of struct net_device objects.
Several devices have multiple independant RX queues per net device, and some have a single interrupt doorbell for several queues. In either case, it's easier to support layouts like that if the structure representing the poll is independant from the net device itself. The signature of the ->poll() call back goes from: int foo_poll(struct net_device *dev, int *budget) to int foo_poll(struct napi_struct *napi, int budget) The caller is returned the number of RX packets processed (or the number of "NAPI credits" consumed if you want to get abstract). The callee no longer messes around bumping dev->quota, *budget, etc. because that is all handled in the caller upon return. The napi_struct is to be embedded in the device driver private data structures. Furthermore, it is the driver's responsibility to disable all NAPI instances in it's ->stop() device close handler. Since the napi_struct is privatized into the driver's private data structures, only the driver knows how to get at all of the napi_struct instances it may have per-device. With lots of help and suggestions from Rusty Russell, Roland Dreier, Michael Chan, Jeff Garzik, and Jamal Hadi Salim. Bug fixes from Thomas Graf, Roland Dreier, Peter Zijlstra, Joseph Fannin, Scott Wood, Hans J. Koch, and Michael Chan. [ Ported to current tree and all drivers converted. Integrated Stephen's follow-on kerneldoc additions, and restored poll_list handling to the old style to fix mutual exclusion issues. -DaveM ] Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/via-rhine.c')
-rw-r--r--drivers/net/via-rhine.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index b56dff26772d..7a5899059c44 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -389,6 +389,8 @@ struct rhine_private {
389 389
390 struct pci_dev *pdev; 390 struct pci_dev *pdev;
391 long pioaddr; 391 long pioaddr;
392 struct net_device *dev;
393 struct napi_struct napi;
392 struct net_device_stats stats; 394 struct net_device_stats stats;
393 spinlock_t lock; 395 spinlock_t lock;
394 396
@@ -582,28 +584,25 @@ static void rhine_poll(struct net_device *dev)
582#endif 584#endif
583 585
584#ifdef CONFIG_VIA_RHINE_NAPI 586#ifdef CONFIG_VIA_RHINE_NAPI
585static int rhine_napipoll(struct net_device *dev, int *budget) 587static int rhine_napipoll(struct napi_struct *napi, int budget)
586{ 588{
587 struct rhine_private *rp = netdev_priv(dev); 589 struct rhine_private *rp = container_of(napi, struct rhine_private, napi);
590 struct net_device *dev = rp->dev;
588 void __iomem *ioaddr = rp->base; 591 void __iomem *ioaddr = rp->base;
589 int done, limit = min(dev->quota, *budget); 592 int work_done;
590 593
591 done = rhine_rx(dev, limit); 594 work_done = rhine_rx(dev, budget);
592 *budget -= done;
593 dev->quota -= done;
594 595
595 if (done < limit) { 596 if (work_done < budget) {
596 netif_rx_complete(dev); 597 netif_rx_complete(dev, napi);
597 598
598 iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | 599 iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
599 IntrRxDropped | IntrRxNoBuf | IntrTxAborted | 600 IntrRxDropped | IntrRxNoBuf | IntrTxAborted |
600 IntrTxDone | IntrTxError | IntrTxUnderrun | 601 IntrTxDone | IntrTxError | IntrTxUnderrun |
601 IntrPCIErr | IntrStatsMax | IntrLinkChange, 602 IntrPCIErr | IntrStatsMax | IntrLinkChange,
602 ioaddr + IntrEnable); 603 ioaddr + IntrEnable);
603 return 0;
604 } 604 }
605 else 605 return work_done;
606 return 1;
607} 606}
608#endif 607#endif
609 608
@@ -707,6 +706,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
707 SET_NETDEV_DEV(dev, &pdev->dev); 706 SET_NETDEV_DEV(dev, &pdev->dev);
708 707
709 rp = netdev_priv(dev); 708 rp = netdev_priv(dev);
709 rp->dev = dev;
710 rp->quirks = quirks; 710 rp->quirks = quirks;
711 rp->pioaddr = pioaddr; 711 rp->pioaddr = pioaddr;
712 rp->pdev = pdev; 712 rp->pdev = pdev;
@@ -785,8 +785,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
785 dev->poll_controller = rhine_poll; 785 dev->poll_controller = rhine_poll;
786#endif 786#endif
787#ifdef CONFIG_VIA_RHINE_NAPI 787#ifdef CONFIG_VIA_RHINE_NAPI
788 dev->poll = rhine_napipoll; 788 netif_napi_add(dev, &rp->napi, rhine_napipoll, 64);
789 dev->weight = 64;
790#endif 789#endif
791 if (rp->quirks & rqRhineI) 790 if (rp->quirks & rqRhineI)
792 dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; 791 dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
@@ -1061,7 +1060,9 @@ static void init_registers(struct net_device *dev)
1061 1060
1062 rhine_set_rx_mode(dev); 1061 rhine_set_rx_mode(dev);
1063 1062
1064 netif_poll_enable(dev); 1063#ifdef CONFIG_VIA_RHINE_NAPI
1064 napi_enable(&rp->napi);
1065#endif
1065 1066
1066 /* Enable interrupts by setting the interrupt mask. */ 1067 /* Enable interrupts by setting the interrupt mask. */
1067 iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | 1068 iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
@@ -1196,6 +1197,10 @@ static void rhine_tx_timeout(struct net_device *dev)
1196 /* protect against concurrent rx interrupts */ 1197 /* protect against concurrent rx interrupts */
1197 disable_irq(rp->pdev->irq); 1198 disable_irq(rp->pdev->irq);
1198 1199
1200#ifdef CONFIG_VIA_RHINE_NAPI
1201 napi_disable(&rp->napi);
1202#endif
1203
1199 spin_lock(&rp->lock); 1204 spin_lock(&rp->lock);
1200 1205
1201 /* clear all descriptors */ 1206 /* clear all descriptors */
@@ -1324,7 +1329,7 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
1324 IntrPCIErr | IntrStatsMax | IntrLinkChange, 1329 IntrPCIErr | IntrStatsMax | IntrLinkChange,
1325 ioaddr + IntrEnable); 1330 ioaddr + IntrEnable);
1326 1331
1327 netif_rx_schedule(dev); 1332 netif_rx_schedule(dev, &rp->napi);
1328#else 1333#else
1329 rhine_rx(dev, RX_RING_SIZE); 1334 rhine_rx(dev, RX_RING_SIZE);
1330#endif 1335#endif
@@ -1837,7 +1842,9 @@ static int rhine_close(struct net_device *dev)
1837 spin_lock_irq(&rp->lock); 1842 spin_lock_irq(&rp->lock);
1838 1843
1839 netif_stop_queue(dev); 1844 netif_stop_queue(dev);
1840 netif_poll_disable(dev); 1845#ifdef CONFIG_VIA_RHINE_NAPI
1846 napi_disable(&rp->napi);
1847#endif
1841 1848
1842 if (debug > 1) 1849 if (debug > 1)
1843 printk(KERN_DEBUG "%s: Shutting down ethercard, " 1850 printk(KERN_DEBUG "%s: Shutting down ethercard, "
@@ -1936,6 +1943,9 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state)
1936 if (!netif_running(dev)) 1943 if (!netif_running(dev))
1937 return 0; 1944 return 0;
1938 1945
1946#ifdef CONFIG_VIA_RHINE_NAPI
1947 napi_disable(&rp->napi);
1948#endif
1939 netif_device_detach(dev); 1949 netif_device_detach(dev);
1940 pci_save_state(pdev); 1950 pci_save_state(pdev);
1941 1951