aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.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/r8169.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/r8169.c')
-rw-r--r--drivers/net/r8169.c58
1 files changed, 32 insertions, 26 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index c76dd29c8e9a..3f2306e3f517 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -384,6 +384,7 @@ struct rtl8169_private {
384 void __iomem *mmio_addr; /* memory map physical address */ 384 void __iomem *mmio_addr; /* memory map physical address */
385 struct pci_dev *pci_dev; /* Index of PCI device */ 385 struct pci_dev *pci_dev; /* Index of PCI device */
386 struct net_device *dev; 386 struct net_device *dev;
387 struct napi_struct napi;
387 struct net_device_stats stats; /* statistics of net device */ 388 struct net_device_stats stats; /* statistics of net device */
388 spinlock_t lock; /* spin lock flag */ 389 spinlock_t lock; /* spin lock flag */
389 u32 msg_enable; 390 u32 msg_enable;
@@ -443,13 +444,13 @@ static void rtl_set_rx_mode(struct net_device *dev);
443static void rtl8169_tx_timeout(struct net_device *dev); 444static void rtl8169_tx_timeout(struct net_device *dev);
444static struct net_device_stats *rtl8169_get_stats(struct net_device *dev); 445static struct net_device_stats *rtl8169_get_stats(struct net_device *dev);
445static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, 446static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *,
446 void __iomem *); 447 void __iomem *, u32 budget);
447static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); 448static int rtl8169_change_mtu(struct net_device *dev, int new_mtu);
448static void rtl8169_down(struct net_device *dev); 449static void rtl8169_down(struct net_device *dev);
449static void rtl8169_rx_clear(struct rtl8169_private *tp); 450static void rtl8169_rx_clear(struct rtl8169_private *tp);
450 451
451#ifdef CONFIG_R8169_NAPI 452#ifdef CONFIG_R8169_NAPI
452static int rtl8169_poll(struct net_device *dev, int *budget); 453static int rtl8169_poll(struct napi_struct *napi, int budget);
453#endif 454#endif
454 455
455static const unsigned int rtl8169_rx_config = 456static const unsigned int rtl8169_rx_config =
@@ -1656,8 +1657,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1656 dev->set_mac_address = rtl_set_mac_address; 1657 dev->set_mac_address = rtl_set_mac_address;
1657 1658
1658#ifdef CONFIG_R8169_NAPI 1659#ifdef CONFIG_R8169_NAPI
1659 dev->poll = rtl8169_poll; 1660 netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
1660 dev->weight = R8169_NAPI_WEIGHT;
1661#endif 1661#endif
1662 1662
1663#ifdef CONFIG_R8169_VLAN 1663#ifdef CONFIG_R8169_VLAN
@@ -1777,6 +1777,10 @@ static int rtl8169_open(struct net_device *dev)
1777 if (retval < 0) 1777 if (retval < 0)
1778 goto err_release_ring_2; 1778 goto err_release_ring_2;
1779 1779
1780#ifdef CONFIG_R8169_NAPI
1781 napi_enable(&tp->napi);
1782#endif
1783
1780 rtl_hw_start(dev); 1784 rtl_hw_start(dev);
1781 1785
1782 rtl8169_request_timer(dev); 1786 rtl8169_request_timer(dev);
@@ -2082,7 +2086,9 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu)
2082 if (ret < 0) 2086 if (ret < 0)
2083 goto out; 2087 goto out;
2084 2088
2085 netif_poll_enable(dev); 2089#ifdef CONFIG_R8169_NAPI
2090 napi_enable(&tp->napi);
2091#endif
2086 2092
2087 rtl_hw_start(dev); 2093 rtl_hw_start(dev);
2088 2094
@@ -2274,11 +2280,15 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev)
2274 synchronize_irq(dev->irq); 2280 synchronize_irq(dev->irq);
2275 2281
2276 /* Wait for any pending NAPI task to complete */ 2282 /* Wait for any pending NAPI task to complete */
2277 netif_poll_disable(dev); 2283#ifdef CONFIG_R8169_NAPI
2284 napi_disable(&tp->napi);
2285#endif
2278 2286
2279 rtl8169_irq_mask_and_ack(ioaddr); 2287 rtl8169_irq_mask_and_ack(ioaddr);
2280 2288
2281 netif_poll_enable(dev); 2289#ifdef CONFIG_R8169_NAPI
2290 napi_enable(&tp->napi);
2291#endif
2282} 2292}
2283 2293
2284static void rtl8169_reinit_task(struct work_struct *work) 2294static void rtl8169_reinit_task(struct work_struct *work)
@@ -2322,7 +2332,7 @@ static void rtl8169_reset_task(struct work_struct *work)
2322 2332
2323 rtl8169_wait_for_quiescence(dev); 2333 rtl8169_wait_for_quiescence(dev);
2324 2334
2325 rtl8169_rx_interrupt(dev, tp, tp->mmio_addr); 2335 rtl8169_rx_interrupt(dev, tp, tp->mmio_addr, ~(u32)0);
2326 rtl8169_tx_clear(tp); 2336 rtl8169_tx_clear(tp);
2327 2337
2328 if (tp->dirty_rx == tp->cur_rx) { 2338 if (tp->dirty_rx == tp->cur_rx) {
@@ -2636,14 +2646,14 @@ out:
2636 2646
2637static int rtl8169_rx_interrupt(struct net_device *dev, 2647static int rtl8169_rx_interrupt(struct net_device *dev,
2638 struct rtl8169_private *tp, 2648 struct rtl8169_private *tp,
2639 void __iomem *ioaddr) 2649 void __iomem *ioaddr, u32 budget)
2640{ 2650{
2641 unsigned int cur_rx, rx_left; 2651 unsigned int cur_rx, rx_left;
2642 unsigned int delta, count; 2652 unsigned int delta, count;
2643 2653
2644 cur_rx = tp->cur_rx; 2654 cur_rx = tp->cur_rx;
2645 rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; 2655 rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
2646 rx_left = rtl8169_rx_quota(rx_left, (u32) dev->quota); 2656 rx_left = rtl8169_rx_quota(rx_left, budget);
2647 2657
2648 for (; rx_left > 0; rx_left--, cur_rx++) { 2658 for (; rx_left > 0; rx_left--, cur_rx++) {
2649 unsigned int entry = cur_rx % NUM_RX_DESC; 2659 unsigned int entry = cur_rx % NUM_RX_DESC;
@@ -2792,8 +2802,8 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
2792 RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); 2802 RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
2793 tp->intr_mask = ~tp->napi_event; 2803 tp->intr_mask = ~tp->napi_event;
2794 2804
2795 if (likely(netif_rx_schedule_prep(dev))) 2805 if (likely(netif_rx_schedule_prep(dev, &tp->napi)))
2796 __netif_rx_schedule(dev); 2806 __netif_rx_schedule(dev, &tp->napi);
2797 else if (netif_msg_intr(tp)) { 2807 else if (netif_msg_intr(tp)) {
2798 printk(KERN_INFO "%s: interrupt %04x in poll\n", 2808 printk(KERN_INFO "%s: interrupt %04x in poll\n",
2799 dev->name, status); 2809 dev->name, status);
@@ -2803,7 +2813,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
2803#else 2813#else
2804 /* Rx interrupt */ 2814 /* Rx interrupt */
2805 if (status & (RxOK | RxOverflow | RxFIFOOver)) 2815 if (status & (RxOK | RxOverflow | RxFIFOOver))
2806 rtl8169_rx_interrupt(dev, tp, ioaddr); 2816 rtl8169_rx_interrupt(dev, tp, ioaddr, ~(u32)0);
2807 2817
2808 /* Tx interrupt */ 2818 /* Tx interrupt */
2809 if (status & (TxOK | TxErr)) 2819 if (status & (TxOK | TxErr))
@@ -2826,20 +2836,18 @@ out:
2826} 2836}
2827 2837
2828#ifdef CONFIG_R8169_NAPI 2838#ifdef CONFIG_R8169_NAPI
2829static int rtl8169_poll(struct net_device *dev, int *budget) 2839static int rtl8169_poll(struct napi_struct *napi, int budget)
2830{ 2840{
2831 unsigned int work_done, work_to_do = min(*budget, dev->quota); 2841 struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi);
2832 struct rtl8169_private *tp = netdev_priv(dev); 2842 struct net_device *dev = tp->dev;
2833 void __iomem *ioaddr = tp->mmio_addr; 2843 void __iomem *ioaddr = tp->mmio_addr;
2844 int work_done;
2834 2845
2835 work_done = rtl8169_rx_interrupt(dev, tp, ioaddr); 2846 work_done = rtl8169_rx_interrupt(dev, tp, ioaddr, (u32) budget);
2836 rtl8169_tx_interrupt(dev, tp, ioaddr); 2847 rtl8169_tx_interrupt(dev, tp, ioaddr);
2837 2848
2838 *budget -= work_done; 2849 if (work_done < budget) {
2839 dev->quota -= work_done; 2850 netif_rx_complete(dev, napi);
2840
2841 if (work_done < work_to_do) {
2842 netif_rx_complete(dev);
2843 tp->intr_mask = 0xffff; 2851 tp->intr_mask = 0xffff;
2844 /* 2852 /*
2845 * 20040426: the barrier is not strictly required but the 2853 * 20040426: the barrier is not strictly required but the
@@ -2851,7 +2859,7 @@ static int rtl8169_poll(struct net_device *dev, int *budget)
2851 RTL_W16(IntrMask, tp->intr_event); 2859 RTL_W16(IntrMask, tp->intr_event);
2852 } 2860 }
2853 2861
2854 return (work_done >= work_to_do); 2862 return work_done;
2855} 2863}
2856#endif 2864#endif
2857 2865
@@ -2880,7 +2888,7 @@ core_down:
2880 synchronize_irq(dev->irq); 2888 synchronize_irq(dev->irq);
2881 2889
2882 if (!poll_locked) { 2890 if (!poll_locked) {
2883 netif_poll_disable(dev); 2891 napi_disable(&tp->napi);
2884 poll_locked++; 2892 poll_locked++;
2885 } 2893 }
2886 2894
@@ -2918,8 +2926,6 @@ static int rtl8169_close(struct net_device *dev)
2918 2926
2919 free_irq(dev->irq, dev); 2927 free_irq(dev->irq, dev);
2920 2928
2921 netif_poll_enable(dev);
2922
2923 pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray, 2929 pci_free_consistent(pdev, R8169_RX_RING_BYTES, tp->RxDescArray,
2924 tp->RxPhyAddr); 2930 tp->RxPhyAddr);
2925 pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray, 2931 pci_free_consistent(pdev, R8169_TX_RING_BYTES, tp->TxDescArray,