diff options
Diffstat (limited to 'drivers/net/starfire.c')
-rw-r--r-- | drivers/net/starfire.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 8b6478663a5..3b9336c3420 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c | |||
@@ -178,16 +178,13 @@ static int full_duplex[MAX_UNITS] = {0, }; | |||
178 | #define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1) | 178 | #define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1) |
179 | 179 | ||
180 | #ifdef HAVE_NETDEV_POLL | 180 | #ifdef HAVE_NETDEV_POLL |
181 | #define init_poll(dev) \ | 181 | #define init_poll(dev, np) \ |
182 | do { \ | 182 | netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work) |
183 | dev->poll = &netdev_poll; \ | 183 | #define netdev_rx(dev, np, ioaddr) \ |
184 | dev->weight = max_interrupt_work; \ | ||
185 | } while (0) | ||
186 | #define netdev_rx(dev, ioaddr) \ | ||
187 | do { \ | 184 | do { \ |
188 | u32 intr_enable; \ | 185 | u32 intr_enable; \ |
189 | if (netif_rx_schedule_prep(dev)) { \ | 186 | if (netif_rx_schedule_prep(dev, &np->napi)) { \ |
190 | __netif_rx_schedule(dev); \ | 187 | __netif_rx_schedule(dev, &np->napi); \ |
191 | intr_enable = readl(ioaddr + IntrEnable); \ | 188 | intr_enable = readl(ioaddr + IntrEnable); \ |
192 | intr_enable &= ~(IntrRxDone | IntrRxEmpty); \ | 189 | intr_enable &= ~(IntrRxDone | IntrRxEmpty); \ |
193 | writel(intr_enable, ioaddr + IntrEnable); \ | 190 | writel(intr_enable, ioaddr + IntrEnable); \ |
@@ -204,12 +201,12 @@ do { \ | |||
204 | } while (0) | 201 | } while (0) |
205 | #define netdev_receive_skb(skb) netif_receive_skb(skb) | 202 | #define netdev_receive_skb(skb) netif_receive_skb(skb) |
206 | #define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_receive_skb(skb, vlgrp, vlid) | 203 | #define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_receive_skb(skb, vlgrp, vlid) |
207 | static int netdev_poll(struct net_device *dev, int *budget); | 204 | static int netdev_poll(struct napi_struct *napi, int budget); |
208 | #else /* not HAVE_NETDEV_POLL */ | 205 | #else /* not HAVE_NETDEV_POLL */ |
209 | #define init_poll(dev) | 206 | #define init_poll(dev, np) |
210 | #define netdev_receive_skb(skb) netif_rx(skb) | 207 | #define netdev_receive_skb(skb) netif_rx(skb) |
211 | #define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_rx(skb, vlgrp, vlid) | 208 | #define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_rx(skb, vlgrp, vlid) |
212 | #define netdev_rx(dev, ioaddr) \ | 209 | #define netdev_rx(dev, np, ioaddr) \ |
213 | do { \ | 210 | do { \ |
214 | int quota = np->dirty_rx + RX_RING_SIZE - np->cur_rx; \ | 211 | int quota = np->dirty_rx + RX_RING_SIZE - np->cur_rx; \ |
215 | __netdev_rx(dev, "a);\ | 212 | __netdev_rx(dev, "a);\ |
@@ -599,6 +596,8 @@ struct netdev_private { | |||
599 | struct tx_done_desc *tx_done_q; | 596 | struct tx_done_desc *tx_done_q; |
600 | dma_addr_t tx_done_q_dma; | 597 | dma_addr_t tx_done_q_dma; |
601 | unsigned int tx_done; | 598 | unsigned int tx_done; |
599 | struct napi_struct napi; | ||
600 | struct net_device *dev; | ||
602 | struct net_device_stats stats; | 601 | struct net_device_stats stats; |
603 | struct pci_dev *pci_dev; | 602 | struct pci_dev *pci_dev; |
604 | #ifdef VLAN_SUPPORT | 603 | #ifdef VLAN_SUPPORT |
@@ -791,6 +790,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, | |||
791 | dev->irq = irq; | 790 | dev->irq = irq; |
792 | 791 | ||
793 | np = netdev_priv(dev); | 792 | np = netdev_priv(dev); |
793 | np->dev = dev; | ||
794 | np->base = base; | 794 | np->base = base; |
795 | spin_lock_init(&np->lock); | 795 | spin_lock_init(&np->lock); |
796 | pci_set_drvdata(pdev, dev); | 796 | pci_set_drvdata(pdev, dev); |
@@ -851,7 +851,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, | |||
851 | dev->hard_start_xmit = &start_tx; | 851 | dev->hard_start_xmit = &start_tx; |
852 | dev->tx_timeout = tx_timeout; | 852 | dev->tx_timeout = tx_timeout; |
853 | dev->watchdog_timeo = TX_TIMEOUT; | 853 | dev->watchdog_timeo = TX_TIMEOUT; |
854 | init_poll(dev); | 854 | init_poll(dev, np); |
855 | dev->stop = &netdev_close; | 855 | dev->stop = &netdev_close; |
856 | dev->get_stats = &get_stats; | 856 | dev->get_stats = &get_stats; |
857 | dev->set_multicast_list = &set_rx_mode; | 857 | dev->set_multicast_list = &set_rx_mode; |
@@ -1056,6 +1056,9 @@ static int netdev_open(struct net_device *dev) | |||
1056 | 1056 | ||
1057 | writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl); | 1057 | writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl); |
1058 | 1058 | ||
1059 | #ifdef HAVE_NETDEV_POLL | ||
1060 | napi_enable(&np->napi); | ||
1061 | #endif | ||
1059 | netif_start_queue(dev); | 1062 | netif_start_queue(dev); |
1060 | 1063 | ||
1061 | if (debug > 1) | 1064 | if (debug > 1) |
@@ -1330,7 +1333,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) | |||
1330 | handled = 1; | 1333 | handled = 1; |
1331 | 1334 | ||
1332 | if (intr_status & (IntrRxDone | IntrRxEmpty)) | 1335 | if (intr_status & (IntrRxDone | IntrRxEmpty)) |
1333 | netdev_rx(dev, ioaddr); | 1336 | netdev_rx(dev, np, ioaddr); |
1334 | 1337 | ||
1335 | /* Scavenge the skbuff list based on the Tx-done queue. | 1338 | /* Scavenge the skbuff list based on the Tx-done queue. |
1336 | There are redundant checks here that may be cleaned up | 1339 | There are redundant checks here that may be cleaned up |
@@ -1531,36 +1534,35 @@ static int __netdev_rx(struct net_device *dev, int *quota) | |||
1531 | 1534 | ||
1532 | 1535 | ||
1533 | #ifdef HAVE_NETDEV_POLL | 1536 | #ifdef HAVE_NETDEV_POLL |
1534 | static int netdev_poll(struct net_device *dev, int *budget) | 1537 | static int netdev_poll(struct napi_struct *napi, int budget) |
1535 | { | 1538 | { |
1539 | struct netdev_private *np = container_of(napi, struct netdev_private, napi); | ||
1540 | struct net_device *dev = np->dev; | ||
1536 | u32 intr_status; | 1541 | u32 intr_status; |
1537 | struct netdev_private *np = netdev_priv(dev); | ||
1538 | void __iomem *ioaddr = np->base; | 1542 | void __iomem *ioaddr = np->base; |
1539 | int retcode = 0, quota = dev->quota; | 1543 | int quota = budget; |
1540 | 1544 | ||
1541 | do { | 1545 | do { |
1542 | writel(IntrRxDone | IntrRxEmpty, ioaddr + IntrClear); | 1546 | writel(IntrRxDone | IntrRxEmpty, ioaddr + IntrClear); |
1543 | 1547 | ||
1544 | retcode = __netdev_rx(dev, "a); | 1548 | if (__netdev_rx(dev, "a)) |
1545 | *budget -= (dev->quota - quota); | ||
1546 | dev->quota = quota; | ||
1547 | if (retcode) | ||
1548 | goto out; | 1549 | goto out; |
1549 | 1550 | ||
1550 | intr_status = readl(ioaddr + IntrStatus); | 1551 | intr_status = readl(ioaddr + IntrStatus); |
1551 | } while (intr_status & (IntrRxDone | IntrRxEmpty)); | 1552 | } while (intr_status & (IntrRxDone | IntrRxEmpty)); |
1552 | 1553 | ||
1553 | netif_rx_complete(dev); | 1554 | netif_rx_complete(dev, napi); |
1554 | intr_status = readl(ioaddr + IntrEnable); | 1555 | intr_status = readl(ioaddr + IntrEnable); |
1555 | intr_status |= IntrRxDone | IntrRxEmpty; | 1556 | intr_status |= IntrRxDone | IntrRxEmpty; |
1556 | writel(intr_status, ioaddr + IntrEnable); | 1557 | writel(intr_status, ioaddr + IntrEnable); |
1557 | 1558 | ||
1558 | out: | 1559 | out: |
1559 | if (debug > 5) | 1560 | if (debug > 5) |
1560 | printk(KERN_DEBUG " exiting netdev_poll(): %d.\n", retcode); | 1561 | printk(KERN_DEBUG " exiting netdev_poll(): %d.\n", |
1562 | budget - quota); | ||
1561 | 1563 | ||
1562 | /* Restart Rx engine if stopped. */ | 1564 | /* Restart Rx engine if stopped. */ |
1563 | return retcode; | 1565 | return budget - quota; |
1564 | } | 1566 | } |
1565 | #endif /* HAVE_NETDEV_POLL */ | 1567 | #endif /* HAVE_NETDEV_POLL */ |
1566 | 1568 | ||
@@ -1904,6 +1906,9 @@ static int netdev_close(struct net_device *dev) | |||
1904 | int i; | 1906 | int i; |
1905 | 1907 | ||
1906 | netif_stop_queue(dev); | 1908 | netif_stop_queue(dev); |
1909 | #ifdef HAVE_NETDEV_POLL | ||
1910 | napi_disable(&np->napi); | ||
1911 | #endif | ||
1907 | 1912 | ||
1908 | if (debug > 1) { | 1913 | if (debug > 1) { |
1909 | printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n", | 1914 | printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n", |