diff options
Diffstat (limited to 'drivers/net/b44.c')
-rw-r--r-- | drivers/net/b44.c | 48 |
1 files changed, 18 insertions, 30 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 0795df235492..b92b3e25c42a 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -848,10 +848,11 @@ static int b44_rx(struct b44 *bp, int budget) | |||
848 | return received; | 848 | return received; |
849 | } | 849 | } |
850 | 850 | ||
851 | static int b44_poll(struct net_device *netdev, int *budget) | 851 | static int b44_poll(struct napi_struct *napi, int budget) |
852 | { | 852 | { |
853 | struct b44 *bp = netdev_priv(netdev); | 853 | struct b44 *bp = container_of(napi, struct b44, napi); |
854 | int done; | 854 | struct net_device *netdev = bp->dev; |
855 | int work_done; | ||
855 | 856 | ||
856 | spin_lock_irq(&bp->lock); | 857 | spin_lock_irq(&bp->lock); |
857 | 858 | ||
@@ -862,22 +863,9 @@ static int b44_poll(struct net_device *netdev, int *budget) | |||
862 | } | 863 | } |
863 | spin_unlock_irq(&bp->lock); | 864 | spin_unlock_irq(&bp->lock); |
864 | 865 | ||
865 | done = 1; | 866 | work_done = 0; |
866 | if (bp->istat & ISTAT_RX) { | 867 | if (bp->istat & ISTAT_RX) |
867 | int orig_budget = *budget; | 868 | work_done += b44_rx(bp, budget); |
868 | int work_done; | ||
869 | |||
870 | if (orig_budget > netdev->quota) | ||
871 | orig_budget = netdev->quota; | ||
872 | |||
873 | work_done = b44_rx(bp, orig_budget); | ||
874 | |||
875 | *budget -= work_done; | ||
876 | netdev->quota -= work_done; | ||
877 | |||
878 | if (work_done >= orig_budget) | ||
879 | done = 0; | ||
880 | } | ||
881 | 869 | ||
882 | if (bp->istat & ISTAT_ERRORS) { | 870 | if (bp->istat & ISTAT_ERRORS) { |
883 | unsigned long flags; | 871 | unsigned long flags; |
@@ -888,15 +876,15 @@ static int b44_poll(struct net_device *netdev, int *budget) | |||
888 | b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY); | 876 | b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY); |
889 | netif_wake_queue(bp->dev); | 877 | netif_wake_queue(bp->dev); |
890 | spin_unlock_irqrestore(&bp->lock, flags); | 878 | spin_unlock_irqrestore(&bp->lock, flags); |
891 | done = 1; | 879 | work_done = 0; |
892 | } | 880 | } |
893 | 881 | ||
894 | if (done) { | 882 | if (work_done < budget) { |
895 | netif_rx_complete(netdev); | 883 | netif_rx_complete(netdev, napi); |
896 | b44_enable_ints(bp); | 884 | b44_enable_ints(bp); |
897 | } | 885 | } |
898 | 886 | ||
899 | return (done ? 0 : 1); | 887 | return work_done; |
900 | } | 888 | } |
901 | 889 | ||
902 | static irqreturn_t b44_interrupt(int irq, void *dev_id) | 890 | static irqreturn_t b44_interrupt(int irq, void *dev_id) |
@@ -924,13 +912,13 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id) | |||
924 | goto irq_ack; | 912 | goto irq_ack; |
925 | } | 913 | } |
926 | 914 | ||
927 | if (netif_rx_schedule_prep(dev)) { | 915 | if (netif_rx_schedule_prep(dev, &bp->napi)) { |
928 | /* NOTE: These writes are posted by the readback of | 916 | /* NOTE: These writes are posted by the readback of |
929 | * the ISTAT register below. | 917 | * the ISTAT register below. |
930 | */ | 918 | */ |
931 | bp->istat = istat; | 919 | bp->istat = istat; |
932 | __b44_disable_ints(bp); | 920 | __b44_disable_ints(bp); |
933 | __netif_rx_schedule(dev); | 921 | __netif_rx_schedule(dev, &bp->napi); |
934 | } else { | 922 | } else { |
935 | printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", | 923 | printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", |
936 | dev->name); | 924 | dev->name); |
@@ -1420,6 +1408,8 @@ static int b44_open(struct net_device *dev) | |||
1420 | if (err) | 1408 | if (err) |
1421 | goto out; | 1409 | goto out; |
1422 | 1410 | ||
1411 | napi_enable(&bp->napi); | ||
1412 | |||
1423 | b44_init_rings(bp); | 1413 | b44_init_rings(bp); |
1424 | b44_init_hw(bp, B44_FULL_RESET); | 1414 | b44_init_hw(bp, B44_FULL_RESET); |
1425 | 1415 | ||
@@ -1427,6 +1417,7 @@ static int b44_open(struct net_device *dev) | |||
1427 | 1417 | ||
1428 | err = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); | 1418 | err = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); |
1429 | if (unlikely(err < 0)) { | 1419 | if (unlikely(err < 0)) { |
1420 | napi_disable(&bp->napi); | ||
1430 | b44_chip_reset(bp); | 1421 | b44_chip_reset(bp); |
1431 | b44_free_rings(bp); | 1422 | b44_free_rings(bp); |
1432 | b44_free_consistent(bp); | 1423 | b44_free_consistent(bp); |
@@ -1609,7 +1600,7 @@ static int b44_close(struct net_device *dev) | |||
1609 | 1600 | ||
1610 | netif_stop_queue(dev); | 1601 | netif_stop_queue(dev); |
1611 | 1602 | ||
1612 | netif_poll_disable(dev); | 1603 | napi_disable(&bp->napi); |
1613 | 1604 | ||
1614 | del_timer_sync(&bp->timer); | 1605 | del_timer_sync(&bp->timer); |
1615 | 1606 | ||
@@ -1626,8 +1617,6 @@ static int b44_close(struct net_device *dev) | |||
1626 | 1617 | ||
1627 | free_irq(dev->irq, dev); | 1618 | free_irq(dev->irq, dev); |
1628 | 1619 | ||
1629 | netif_poll_enable(dev); | ||
1630 | |||
1631 | if (bp->flags & B44_FLAG_WOL_ENABLE) { | 1620 | if (bp->flags & B44_FLAG_WOL_ENABLE) { |
1632 | b44_init_hw(bp, B44_PARTIAL_RESET); | 1621 | b44_init_hw(bp, B44_PARTIAL_RESET); |
1633 | b44_setup_wol(bp); | 1622 | b44_setup_wol(bp); |
@@ -2194,8 +2183,7 @@ static int __devinit b44_init_one(struct pci_dev *pdev, | |||
2194 | dev->set_mac_address = b44_set_mac_addr; | 2183 | dev->set_mac_address = b44_set_mac_addr; |
2195 | dev->do_ioctl = b44_ioctl; | 2184 | dev->do_ioctl = b44_ioctl; |
2196 | dev->tx_timeout = b44_tx_timeout; | 2185 | dev->tx_timeout = b44_tx_timeout; |
2197 | dev->poll = b44_poll; | 2186 | netif_napi_add(dev, &bp->napi, b44_poll, 64); |
2198 | dev->weight = 64; | ||
2199 | dev->watchdog_timeo = B44_TX_TIMEOUT; | 2187 | dev->watchdog_timeo = B44_TX_TIMEOUT; |
2200 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2188 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2201 | dev->poll_controller = b44_poll_controller; | 2189 | dev->poll_controller = b44_poll_controller; |