diff options
Diffstat (limited to 'drivers/net/macb.c')
-rw-r--r-- | drivers/net/macb.c | 40 |
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 | ||
473 | static int macb_poll(struct net_device *dev, int *budget) | 473 | static 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 | ||
527 | static irqreturn_t macb_interrupt(int irq, void *dev_id) | 521 | static 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; |