aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/8139too.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/8139too.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/8139too.c')
-rw-r--r--drivers/net/8139too.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index f4e4298d24b..20af6baecfc 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -573,6 +573,8 @@ struct rtl8139_private {
573 int drv_flags; 573 int drv_flags;
574 struct pci_dev *pci_dev; 574 struct pci_dev *pci_dev;
575 u32 msg_enable; 575 u32 msg_enable;
576 struct napi_struct napi;
577 struct net_device *dev;
576 struct net_device_stats stats; 578 struct net_device_stats stats;
577 unsigned char *rx_ring; 579 unsigned char *rx_ring;
578 unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ 580 unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */
@@ -625,10 +627,10 @@ static void rtl8139_tx_timeout (struct net_device *dev);
625static void rtl8139_init_ring (struct net_device *dev); 627static void rtl8139_init_ring (struct net_device *dev);
626static int rtl8139_start_xmit (struct sk_buff *skb, 628static int rtl8139_start_xmit (struct sk_buff *skb,
627 struct net_device *dev); 629 struct net_device *dev);
628static int rtl8139_poll(struct net_device *dev, int *budget);
629#ifdef CONFIG_NET_POLL_CONTROLLER 630#ifdef CONFIG_NET_POLL_CONTROLLER
630static void rtl8139_poll_controller(struct net_device *dev); 631static void rtl8139_poll_controller(struct net_device *dev);
631#endif 632#endif
633static int rtl8139_poll(struct napi_struct *napi, int budget);
632static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance); 634static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
633static int rtl8139_close (struct net_device *dev); 635static int rtl8139_close (struct net_device *dev);
634static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); 636static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
@@ -963,6 +965,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
963 965
964 assert (dev != NULL); 966 assert (dev != NULL);
965 tp = netdev_priv(dev); 967 tp = netdev_priv(dev);
968 tp->dev = dev;
966 969
967 ioaddr = tp->mmio_addr; 970 ioaddr = tp->mmio_addr;
968 assert (ioaddr != NULL); 971 assert (ioaddr != NULL);
@@ -976,8 +979,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
976 /* The Rtl8139-specific entries in the device structure. */ 979 /* The Rtl8139-specific entries in the device structure. */
977 dev->open = rtl8139_open; 980 dev->open = rtl8139_open;
978 dev->hard_start_xmit = rtl8139_start_xmit; 981 dev->hard_start_xmit = rtl8139_start_xmit;
979 dev->poll = rtl8139_poll; 982 netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
980 dev->weight = 64;
981 dev->stop = rtl8139_close; 983 dev->stop = rtl8139_close;
982 dev->get_stats = rtl8139_get_stats; 984 dev->get_stats = rtl8139_get_stats;
983 dev->set_multicast_list = rtl8139_set_rx_mode; 985 dev->set_multicast_list = rtl8139_set_rx_mode;
@@ -1332,6 +1334,8 @@ static int rtl8139_open (struct net_device *dev)
1332 1334
1333 } 1335 }
1334 1336
1337 napi_enable(&tp->napi);
1338
1335 tp->mii.full_duplex = tp->mii.force_media; 1339 tp->mii.full_duplex = tp->mii.force_media;
1336 tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000; 1340 tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
1337 1341
@@ -2103,39 +2107,32 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
2103 } 2107 }
2104} 2108}
2105 2109
2106static int rtl8139_poll(struct net_device *dev, int *budget) 2110static int rtl8139_poll(struct napi_struct *napi, int budget)
2107{ 2111{
2108 struct rtl8139_private *tp = netdev_priv(dev); 2112 struct rtl8139_private *tp = container_of(napi, struct rtl8139_private, napi);
2113 struct net_device *dev = tp->dev;
2109 void __iomem *ioaddr = tp->mmio_addr; 2114 void __iomem *ioaddr = tp->mmio_addr;
2110 int orig_budget = min(*budget, dev->quota); 2115 int work_done;
2111 int done = 1;
2112 2116
2113 spin_lock(&tp->rx_lock); 2117 spin_lock(&tp->rx_lock);
2114 if (likely(RTL_R16(IntrStatus) & RxAckBits)) { 2118 work_done = 0;
2115 int work_done; 2119 if (likely(RTL_R16(IntrStatus) & RxAckBits))
2116 2120 work_done += rtl8139_rx(dev, tp, budget);
2117 work_done = rtl8139_rx(dev, tp, orig_budget);
2118 if (likely(work_done > 0)) {
2119 *budget -= work_done;
2120 dev->quota -= work_done;
2121 done = (work_done < orig_budget);
2122 }
2123 }
2124 2121
2125 if (done) { 2122 if (work_done < budget) {
2126 unsigned long flags; 2123 unsigned long flags;
2127 /* 2124 /*
2128 * Order is important since data can get interrupted 2125 * Order is important since data can get interrupted
2129 * again when we think we are done. 2126 * again when we think we are done.
2130 */ 2127 */
2131 local_irq_save(flags); 2128 spin_lock_irqsave(&tp->lock, flags);
2132 RTL_W16_F(IntrMask, rtl8139_intr_mask); 2129 RTL_W16_F(IntrMask, rtl8139_intr_mask);
2133 __netif_rx_complete(dev); 2130 __netif_rx_complete(dev, napi);
2134 local_irq_restore(flags); 2131 spin_unlock_irqrestore(&tp->lock, flags);
2135 } 2132 }
2136 spin_unlock(&tp->rx_lock); 2133 spin_unlock(&tp->rx_lock);
2137 2134
2138 return !done; 2135 return work_done;
2139} 2136}
2140 2137
2141/* The interrupt handler does all of the Rx thread work and cleans up 2138/* The interrupt handler does all of the Rx thread work and cleans up
@@ -2180,9 +2177,9 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
2180 /* Receive packets are processed by poll routine. 2177 /* Receive packets are processed by poll routine.
2181 If not running start it now. */ 2178 If not running start it now. */
2182 if (status & RxAckBits){ 2179 if (status & RxAckBits){
2183 if (netif_rx_schedule_prep(dev)) { 2180 if (netif_rx_schedule_prep(dev, &tp->napi)) {
2184 RTL_W16_F (IntrMask, rtl8139_norx_intr_mask); 2181 RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
2185 __netif_rx_schedule (dev); 2182 __netif_rx_schedule(dev, &tp->napi);
2186 } 2183 }
2187 } 2184 }
2188 2185
@@ -2223,7 +2220,8 @@ static int rtl8139_close (struct net_device *dev)
2223 void __iomem *ioaddr = tp->mmio_addr; 2220 void __iomem *ioaddr = tp->mmio_addr;
2224 unsigned long flags; 2221 unsigned long flags;
2225 2222
2226 netif_stop_queue (dev); 2223 netif_stop_queue(dev);
2224 napi_disable(&tp->napi);
2227 2225
2228 if (netif_msg_ifdown(tp)) 2226 if (netif_msg_ifdown(tp))
2229 printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n", 2227 printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",