aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/macb.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/macb.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/macb.c')
-rw-r--r--drivers/net/macb.c40
1 files changed, 18 insertions, 22 deletions
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index a4bb0264180a..74c3f7a7ae4a 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -470,47 +470,41 @@ static int macb_rx(struct macb *bp, int budget)
470 return received; 470 return received;
471} 471}
472 472
473static int macb_poll(struct net_device *dev, int *budget) 473static int macb_poll(struct napi_struct *napi, int budget)
474{ 474{
475 struct macb *bp = netdev_priv(dev); 475 struct macb *bp = container_of(napi, struct macb, napi);
476 int orig_budget, work_done, retval = 0; 476 struct net_device *dev = bp->dev;
477 int work_done;
477 u32 status; 478 u32 status;
478 479
479 status = macb_readl(bp, RSR); 480 status = macb_readl(bp, RSR);
480 macb_writel(bp, RSR, status); 481 macb_writel(bp, RSR, status);
481 482
483 work_done = 0;
482 if (!status) { 484 if (!status) {
483 /* 485 /*
484 * This may happen if an interrupt was pending before 486 * This may happen if an interrupt was pending before
485 * this function was called last time, and no packets 487 * this function was called last time, and no packets
486 * have been received since. 488 * have been received since.
487 */ 489 */
488 netif_rx_complete(dev); 490 netif_rx_complete(dev, napi);
489 goto out; 491 goto out;
490 } 492 }
491 493
492 dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n", 494 dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
493 (unsigned long)status, *budget); 495 (unsigned long)status, budget);
494 496
495 if (!(status & MACB_BIT(REC))) { 497 if (!(status & MACB_BIT(REC))) {
496 dev_warn(&bp->pdev->dev, 498 dev_warn(&bp->pdev->dev,
497 "No RX buffers complete, status = %02lx\n", 499 "No RX buffers complete, status = %02lx\n",
498 (unsigned long)status); 500 (unsigned long)status);
499 netif_rx_complete(dev); 501 netif_rx_complete(dev, napi);
500 goto out; 502 goto out;
501 } 503 }
502 504
503 orig_budget = *budget; 505 work_done = macb_rx(bp, budget);
504 if (orig_budget > dev->quota) 506 if (work_done < budget)
505 orig_budget = dev->quota; 507 netif_rx_complete(dev, napi);
506
507 work_done = macb_rx(bp, orig_budget);
508 if (work_done < orig_budget) {
509 netif_rx_complete(dev);
510 retval = 0;
511 } else {
512 retval = 1;
513 }
514 508
515 /* 509 /*
516 * We've done what we can to clean the buffers. Make sure we 510 * We've done what we can to clean the buffers. Make sure we
@@ -521,7 +515,7 @@ out:
521 515
522 /* TODO: Handle errors */ 516 /* TODO: Handle errors */
523 517
524 return retval; 518 return work_done;
525} 519}
526 520
527static irqreturn_t macb_interrupt(int irq, void *dev_id) 521static irqreturn_t macb_interrupt(int irq, void *dev_id)
@@ -545,7 +539,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
545 } 539 }
546 540
547 if (status & MACB_RX_INT_FLAGS) { 541 if (status & MACB_RX_INT_FLAGS) {
548 if (netif_rx_schedule_prep(dev)) { 542 if (netif_rx_schedule_prep(dev, &bp->napi)) {
549 /* 543 /*
550 * There's no point taking any more interrupts 544 * There's no point taking any more interrupts
551 * until we have processed the buffers 545 * until we have processed the buffers
@@ -553,7 +547,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
553 macb_writel(bp, IDR, MACB_RX_INT_FLAGS); 547 macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
554 dev_dbg(&bp->pdev->dev, 548 dev_dbg(&bp->pdev->dev,
555 "scheduling RX softirq\n"); 549 "scheduling RX softirq\n");
556 __netif_rx_schedule(dev); 550 __netif_rx_schedule(dev, &bp->napi);
557 } 551 }
558 } 552 }
559 553
@@ -937,6 +931,8 @@ static int macb_open(struct net_device *dev)
937 return err; 931 return err;
938 } 932 }
939 933
934 napi_enable(&bp->napi);
935
940 macb_init_rings(bp); 936 macb_init_rings(bp);
941 macb_init_hw(bp); 937 macb_init_hw(bp);
942 938
@@ -954,6 +950,7 @@ static int macb_close(struct net_device *dev)
954 unsigned long flags; 950 unsigned long flags;
955 951
956 netif_stop_queue(dev); 952 netif_stop_queue(dev);
953 napi_disable(&bp->napi);
957 954
958 if (bp->phy_dev) 955 if (bp->phy_dev)
959 phy_stop(bp->phy_dev); 956 phy_stop(bp->phy_dev);
@@ -1146,8 +1143,7 @@ static int __devinit macb_probe(struct platform_device *pdev)
1146 dev->get_stats = macb_get_stats; 1143 dev->get_stats = macb_get_stats;
1147 dev->set_multicast_list = macb_set_rx_mode; 1144 dev->set_multicast_list = macb_set_rx_mode;
1148 dev->do_ioctl = macb_ioctl; 1145 dev->do_ioctl = macb_ioctl;
1149 dev->poll = macb_poll; 1146 netif_napi_add(dev, &bp->napi, macb_poll, 64);
1150 dev->weight = 64;
1151 dev->ethtool_ops = &macb_ethtool_ops; 1147 dev->ethtool_ops = &macb_ethtool_ops;
1152 1148
1153 dev->base_addr = regs->start; 1149 dev->base_addr = regs->start;