aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcnet32.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/pcnet32.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/pcnet32.c')
-rw-r--r--drivers/net/pcnet32.c82
1 files changed, 47 insertions, 35 deletions
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index e6a67531de99..a9973490dba9 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -280,6 +280,8 @@ struct pcnet32_private {
280 unsigned int dirty_rx, /* ring entries to be freed. */ 280 unsigned int dirty_rx, /* ring entries to be freed. */
281 dirty_tx; 281 dirty_tx;
282 282
283 struct net_device *dev;
284 struct napi_struct napi;
283 struct net_device_stats stats; 285 struct net_device_stats stats;
284 char tx_full; 286 char tx_full;
285 char phycount; /* number of phys found */ 287 char phycount; /* number of phys found */
@@ -440,15 +442,21 @@ static struct pcnet32_access pcnet32_dwio = {
440 442
441static void pcnet32_netif_stop(struct net_device *dev) 443static void pcnet32_netif_stop(struct net_device *dev)
442{ 444{
445 struct pcnet32_private *lp = netdev_priv(dev);
443 dev->trans_start = jiffies; 446 dev->trans_start = jiffies;
444 netif_poll_disable(dev); 447#ifdef CONFIG_PCNET32_NAPI
448 napi_disable(&lp->napi);
449#endif
445 netif_tx_disable(dev); 450 netif_tx_disable(dev);
446} 451}
447 452
448static void pcnet32_netif_start(struct net_device *dev) 453static void pcnet32_netif_start(struct net_device *dev)
449{ 454{
455 struct pcnet32_private *lp = netdev_priv(dev);
450 netif_wake_queue(dev); 456 netif_wake_queue(dev);
451 netif_poll_enable(dev); 457#ifdef CONFIG_PCNET32_NAPI
458 napi_enable(&lp->napi);
459#endif
452} 460}
453 461
454/* 462/*
@@ -816,7 +824,7 @@ static int pcnet32_set_ringparam(struct net_device *dev,
816 if ((1 << i) != lp->rx_ring_size) 824 if ((1 << i) != lp->rx_ring_size)
817 pcnet32_realloc_rx_ring(dev, lp, i); 825 pcnet32_realloc_rx_ring(dev, lp, i);
818 826
819 dev->weight = lp->rx_ring_size / 2; 827 lp->napi.weight = lp->rx_ring_size / 2;
820 828
821 if (netif_running(dev)) { 829 if (netif_running(dev)) {
822 pcnet32_netif_start(dev); 830 pcnet32_netif_start(dev);
@@ -1255,7 +1263,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
1255 return; 1263 return;
1256} 1264}
1257 1265
1258static int pcnet32_rx(struct net_device *dev, int quota) 1266static int pcnet32_rx(struct net_device *dev, int budget)
1259{ 1267{
1260 struct pcnet32_private *lp = netdev_priv(dev); 1268 struct pcnet32_private *lp = netdev_priv(dev);
1261 int entry = lp->cur_rx & lp->rx_mod_mask; 1269 int entry = lp->cur_rx & lp->rx_mod_mask;
@@ -1263,7 +1271,7 @@ static int pcnet32_rx(struct net_device *dev, int quota)
1263 int npackets = 0; 1271 int npackets = 0;
1264 1272
1265 /* If we own the next entry, it's a new packet. Send it up. */ 1273 /* If we own the next entry, it's a new packet. Send it up. */
1266 while (quota > npackets && (short)le16_to_cpu(rxp->status) >= 0) { 1274 while (npackets < budget && (short)le16_to_cpu(rxp->status) >= 0) {
1267 pcnet32_rx_entry(dev, lp, rxp, entry); 1275 pcnet32_rx_entry(dev, lp, rxp, entry);
1268 npackets += 1; 1276 npackets += 1;
1269 /* 1277 /*
@@ -1379,15 +1387,16 @@ static int pcnet32_tx(struct net_device *dev)
1379} 1387}
1380 1388
1381#ifdef CONFIG_PCNET32_NAPI 1389#ifdef CONFIG_PCNET32_NAPI
1382static int pcnet32_poll(struct net_device *dev, int *budget) 1390static int pcnet32_poll(struct napi_struct *napi, int budget)
1383{ 1391{
1384 struct pcnet32_private *lp = netdev_priv(dev); 1392 struct pcnet32_private *lp = container_of(napi, struct pcnet32_private, napi);
1385 int quota = min(dev->quota, *budget); 1393 struct net_device *dev = lp->dev;
1386 unsigned long ioaddr = dev->base_addr; 1394 unsigned long ioaddr = dev->base_addr;
1387 unsigned long flags; 1395 unsigned long flags;
1396 int work_done;
1388 u16 val; 1397 u16 val;
1389 1398
1390 quota = pcnet32_rx(dev, quota); 1399 work_done = pcnet32_rx(dev, budget);
1391 1400
1392 spin_lock_irqsave(&lp->lock, flags); 1401 spin_lock_irqsave(&lp->lock, flags);
1393 if (pcnet32_tx(dev)) { 1402 if (pcnet32_tx(dev)) {
@@ -1399,28 +1408,22 @@ static int pcnet32_poll(struct net_device *dev, int *budget)
1399 } 1408 }
1400 spin_unlock_irqrestore(&lp->lock, flags); 1409 spin_unlock_irqrestore(&lp->lock, flags);
1401 1410
1402 *budget -= quota; 1411 if (work_done < budget) {
1403 dev->quota -= quota; 1412 spin_lock_irqsave(&lp->lock, flags);
1404
1405 if (dev->quota == 0) {
1406 return 1;
1407 }
1408
1409 netif_rx_complete(dev);
1410
1411 spin_lock_irqsave(&lp->lock, flags);
1412 1413
1413 /* clear interrupt masks */ 1414 __netif_rx_complete(dev, napi);
1414 val = lp->a.read_csr(ioaddr, CSR3);
1415 val &= 0x00ff;
1416 lp->a.write_csr(ioaddr, CSR3, val);
1417 1415
1418 /* Set interrupt enable. */ 1416 /* clear interrupt masks */
1419 lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN); 1417 val = lp->a.read_csr(ioaddr, CSR3);
1420 mmiowb(); 1418 val &= 0x00ff;
1421 spin_unlock_irqrestore(&lp->lock, flags); 1419 lp->a.write_csr(ioaddr, CSR3, val);
1422 1420
1423 return 0; 1421 /* Set interrupt enable. */
1422 lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
1423 mmiowb();
1424 spin_unlock_irqrestore(&lp->lock, flags);
1425 }
1426 return work_done;
1424} 1427}
1425#endif 1428#endif
1426 1429
@@ -1815,6 +1818,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1815 } 1818 }
1816 lp->pci_dev = pdev; 1819 lp->pci_dev = pdev;
1817 1820
1821 lp->dev = dev;
1822
1818 spin_lock_init(&lp->lock); 1823 spin_lock_init(&lp->lock);
1819 1824
1820 SET_MODULE_OWNER(dev); 1825 SET_MODULE_OWNER(dev);
@@ -1843,6 +1848,10 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1843 lp->mii_if.mdio_read = mdio_read; 1848 lp->mii_if.mdio_read = mdio_read;
1844 lp->mii_if.mdio_write = mdio_write; 1849 lp->mii_if.mdio_write = mdio_write;
1845 1850
1851#ifdef CONFIG_PCNET32_NAPI
1852 netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2);
1853#endif
1854
1846 if (fdx && !(lp->options & PCNET32_PORT_ASEL) && 1855 if (fdx && !(lp->options & PCNET32_PORT_ASEL) &&
1847 ((cards_found >= MAX_UNITS) || full_duplex[cards_found])) 1856 ((cards_found >= MAX_UNITS) || full_duplex[cards_found]))
1848 lp->options |= PCNET32_PORT_FD; 1857 lp->options |= PCNET32_PORT_FD;
@@ -1953,10 +1962,6 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
1953 dev->ethtool_ops = &pcnet32_ethtool_ops; 1962 dev->ethtool_ops = &pcnet32_ethtool_ops;
1954 dev->tx_timeout = pcnet32_tx_timeout; 1963 dev->tx_timeout = pcnet32_tx_timeout;
1955 dev->watchdog_timeo = (5 * HZ); 1964 dev->watchdog_timeo = (5 * HZ);
1956 dev->weight = lp->rx_ring_size / 2;
1957#ifdef CONFIG_PCNET32_NAPI
1958 dev->poll = pcnet32_poll;
1959#endif
1960 1965
1961#ifdef CONFIG_NET_POLL_CONTROLLER 1966#ifdef CONFIG_NET_POLL_CONTROLLER
1962 dev->poll_controller = pcnet32_poll_controller; 1967 dev->poll_controller = pcnet32_poll_controller;
@@ -2276,6 +2281,10 @@ static int pcnet32_open(struct net_device *dev)
2276 goto err_free_ring; 2281 goto err_free_ring;
2277 } 2282 }
2278 2283
2284#ifdef CONFIG_PCNET32_NAPI
2285 napi_enable(&lp->napi);
2286#endif
2287
2279 /* Re-initialize the PCNET32, and start it when done. */ 2288 /* Re-initialize the PCNET32, and start it when done. */
2280 lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff)); 2289 lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
2281 lp->a.write_csr(ioaddr, 2, (lp->init_dma_addr >> 16)); 2290 lp->a.write_csr(ioaddr, 2, (lp->init_dma_addr >> 16));
@@ -2599,18 +2608,18 @@ pcnet32_interrupt(int irq, void *dev_id)
2599 /* unlike for the lance, there is no restart needed */ 2608 /* unlike for the lance, there is no restart needed */
2600 } 2609 }
2601#ifdef CONFIG_PCNET32_NAPI 2610#ifdef CONFIG_PCNET32_NAPI
2602 if (netif_rx_schedule_prep(dev)) { 2611 if (netif_rx_schedule_prep(dev, &lp->napi)) {
2603 u16 val; 2612 u16 val;
2604 /* set interrupt masks */ 2613 /* set interrupt masks */
2605 val = lp->a.read_csr(ioaddr, CSR3); 2614 val = lp->a.read_csr(ioaddr, CSR3);
2606 val |= 0x5f00; 2615 val |= 0x5f00;
2607 lp->a.write_csr(ioaddr, CSR3, val); 2616 lp->a.write_csr(ioaddr, CSR3, val);
2608 mmiowb(); 2617 mmiowb();
2609 __netif_rx_schedule(dev); 2618 __netif_rx_schedule(dev, &lp->napi);
2610 break; 2619 break;
2611 } 2620 }
2612#else 2621#else
2613 pcnet32_rx(dev, dev->weight); 2622 pcnet32_rx(dev, lp->napi.weight);
2614 if (pcnet32_tx(dev)) { 2623 if (pcnet32_tx(dev)) {
2615 /* reset the chip to clear the error condition, then restart */ 2624 /* reset the chip to clear the error condition, then restart */
2616 lp->a.reset(ioaddr); 2625 lp->a.reset(ioaddr);
@@ -2645,6 +2654,9 @@ static int pcnet32_close(struct net_device *dev)
2645 del_timer_sync(&lp->watchdog_timer); 2654 del_timer_sync(&lp->watchdog_timer);
2646 2655
2647 netif_stop_queue(dev); 2656 netif_stop_queue(dev);
2657#ifdef CONFIG_PCNET32_NAPI
2658 napi_disable(&lp->napi);
2659#endif
2648 2660
2649 spin_lock_irqsave(&lp->lock, flags); 2661 spin_lock_irqsave(&lp->lock, flags);
2650 2662