diff options
Diffstat (limited to 'drivers/net/pcnet32.c')
-rw-r--r-- | drivers/net/pcnet32.c | 82 |
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 | ||
441 | static void pcnet32_netif_stop(struct net_device *dev) | 443 | static 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 | ||
448 | static void pcnet32_netif_start(struct net_device *dev) | 453 | static 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 | ||
1258 | static int pcnet32_rx(struct net_device *dev, int quota) | 1266 | static 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 |
1382 | static int pcnet32_poll(struct net_device *dev, int *budget) | 1390 | static 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 | ||