aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/amd8111e.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/amd8111e.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/amd8111e.c')
-rw-r--r--drivers/net/amd8111e.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index a61b2f89fc33..cf06fc067e92 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -723,9 +723,10 @@ static int amd8111e_tx(struct net_device *dev)
723 723
724#ifdef CONFIG_AMD8111E_NAPI 724#ifdef CONFIG_AMD8111E_NAPI
725/* This function handles the driver receive operation in polling mode */ 725/* This function handles the driver receive operation in polling mode */
726static int amd8111e_rx_poll(struct net_device *dev, int * budget) 726static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
727{ 727{
728 struct amd8111e_priv *lp = netdev_priv(dev); 728 struct amd8111e_priv *lp = container_of(napi, struct amd8111e_priv, napi);
729 struct net_device *dev = lp->amd8111e_net_dev;
729 int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK; 730 int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK;
730 void __iomem *mmio = lp->mmio; 731 void __iomem *mmio = lp->mmio;
731 struct sk_buff *skb,*new_skb; 732 struct sk_buff *skb,*new_skb;
@@ -737,7 +738,7 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget)
737#if AMD8111E_VLAN_TAG_USED 738#if AMD8111E_VLAN_TAG_USED
738 short vtag; 739 short vtag;
739#endif 740#endif
740 int rx_pkt_limit = dev->quota; 741 int rx_pkt_limit = budget;
741 unsigned long flags; 742 unsigned long flags;
742 743
743 do{ 744 do{
@@ -838,21 +839,14 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget)
838 } while(intr0 & RINT0); 839 } while(intr0 & RINT0);
839 840
840 /* Receive descriptor is empty now */ 841 /* Receive descriptor is empty now */
841 dev->quota -= num_rx_pkt;
842 *budget -= num_rx_pkt;
843
844 spin_lock_irqsave(&lp->lock, flags); 842 spin_lock_irqsave(&lp->lock, flags);
845 netif_rx_complete(dev); 843 __netif_rx_complete(dev, napi);
846 writel(VAL0|RINTEN0, mmio + INTEN0); 844 writel(VAL0|RINTEN0, mmio + INTEN0);
847 writel(VAL2 | RDMD0, mmio + CMD0); 845 writel(VAL2 | RDMD0, mmio + CMD0);
848 spin_unlock_irqrestore(&lp->lock, flags); 846 spin_unlock_irqrestore(&lp->lock, flags);
849 return 0;
850 847
851rx_not_empty: 848rx_not_empty:
852 /* Do not call a netif_rx_complete */ 849 return num_rx_pkt;
853 dev->quota -= num_rx_pkt;
854 *budget -= num_rx_pkt;
855 return 1;
856} 850}
857 851
858#else 852#else
@@ -1287,11 +1281,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
1287 /* Check if Receive Interrupt has occurred. */ 1281 /* Check if Receive Interrupt has occurred. */
1288#ifdef CONFIG_AMD8111E_NAPI 1282#ifdef CONFIG_AMD8111E_NAPI
1289 if(intr0 & RINT0){ 1283 if(intr0 & RINT0){
1290 if(netif_rx_schedule_prep(dev)){ 1284 if(netif_rx_schedule_prep(dev, &lp->napi)){
1291 /* Disable receive interupts */ 1285 /* Disable receive interupts */
1292 writel(RINTEN0, mmio + INTEN0); 1286 writel(RINTEN0, mmio + INTEN0);
1293 /* Schedule a polling routine */ 1287 /* Schedule a polling routine */
1294 __netif_rx_schedule(dev); 1288 __netif_rx_schedule(dev, &lp->napi);
1295 } 1289 }
1296 else if (intren0 & RINTEN0) { 1290 else if (intren0 & RINTEN0) {
1297 printk("************Driver bug! \ 1291 printk("************Driver bug! \
@@ -1345,6 +1339,8 @@ static int amd8111e_close(struct net_device * dev)
1345 struct amd8111e_priv *lp = netdev_priv(dev); 1339 struct amd8111e_priv *lp = netdev_priv(dev);
1346 netif_stop_queue(dev); 1340 netif_stop_queue(dev);
1347 1341
1342 napi_disable(&lp->napi);
1343
1348 spin_lock_irq(&lp->lock); 1344 spin_lock_irq(&lp->lock);
1349 1345
1350 amd8111e_disable_interrupt(lp); 1346 amd8111e_disable_interrupt(lp);
@@ -1375,12 +1371,15 @@ static int amd8111e_open(struct net_device * dev )
1375 dev->name, dev)) 1371 dev->name, dev))
1376 return -EAGAIN; 1372 return -EAGAIN;
1377 1373
1374 napi_enable(&lp->napi);
1375
1378 spin_lock_irq(&lp->lock); 1376 spin_lock_irq(&lp->lock);
1379 1377
1380 amd8111e_init_hw_default(lp); 1378 amd8111e_init_hw_default(lp);
1381 1379
1382 if(amd8111e_restart(dev)){ 1380 if(amd8111e_restart(dev)){
1383 spin_unlock_irq(&lp->lock); 1381 spin_unlock_irq(&lp->lock);
1382 napi_disable(&lp->napi);
1384 if (dev->irq) 1383 if (dev->irq)
1385 free_irq(dev->irq, dev); 1384 free_irq(dev->irq, dev);
1386 return -ENOMEM; 1385 return -ENOMEM;
@@ -2031,8 +2030,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
2031 dev->tx_timeout = amd8111e_tx_timeout; 2030 dev->tx_timeout = amd8111e_tx_timeout;
2032 dev->watchdog_timeo = AMD8111E_TX_TIMEOUT; 2031 dev->watchdog_timeo = AMD8111E_TX_TIMEOUT;
2033#ifdef CONFIG_AMD8111E_NAPI 2032#ifdef CONFIG_AMD8111E_NAPI
2034 dev->poll = amd8111e_rx_poll; 2033 netif_napi_add(dev, &lp->napi, amd8111e_rx_poll, 32);
2035 dev->weight = 32;
2036#endif 2034#endif
2037#ifdef CONFIG_NET_POLL_CONTROLLER 2035#ifdef CONFIG_NET_POLL_CONTROLLER
2038 dev->poll_controller = amd8111e_poll; 2036 dev->poll_controller = amd8111e_poll;