diff options
Diffstat (limited to 'drivers/net/pcnet32.c')
-rw-r--r-- | drivers/net/pcnet32.c | 132 |
1 files changed, 104 insertions, 28 deletions
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index bf72aa80ccb6..de05aeb734da 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c | |||
@@ -21,9 +21,15 @@ | |||
21 | * | 21 | * |
22 | *************************************************************************/ | 22 | *************************************************************************/ |
23 | 23 | ||
24 | #include <linux/config.h> | ||
25 | |||
24 | #define DRV_NAME "pcnet32" | 26 | #define DRV_NAME "pcnet32" |
25 | #define DRV_VERSION "1.32" | 27 | #ifdef CONFIG_PCNET32_NAPI |
26 | #define DRV_RELDATE "18.Mar.2006" | 28 | #define DRV_VERSION "1.33-NAPI" |
29 | #else | ||
30 | #define DRV_VERSION "1.33" | ||
31 | #endif | ||
32 | #define DRV_RELDATE "27.Jun.2006" | ||
27 | #define PFX DRV_NAME ": " | 33 | #define PFX DRV_NAME ": " |
28 | 34 | ||
29 | static const char *const version = | 35 | static const char *const version = |
@@ -882,7 +888,11 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
882 | rc = 1; /* default to fail */ | 888 | rc = 1; /* default to fail */ |
883 | 889 | ||
884 | if (netif_running(dev)) | 890 | if (netif_running(dev)) |
891 | #ifdef CONFIG_PCNET32_NAPI | ||
892 | pcnet32_netif_stop(dev); | ||
893 | #else | ||
885 | pcnet32_close(dev); | 894 | pcnet32_close(dev); |
895 | #endif | ||
886 | 896 | ||
887 | spin_lock_irqsave(&lp->lock, flags); | 897 | spin_lock_irqsave(&lp->lock, flags); |
888 | lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */ | 898 | lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); /* stop the chip */ |
@@ -1014,6 +1024,16 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
1014 | x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ | 1024 | x = a->read_bcr(ioaddr, 32); /* reset internal loopback */ |
1015 | a->write_bcr(ioaddr, 32, (x & ~0x0002)); | 1025 | a->write_bcr(ioaddr, 32, (x & ~0x0002)); |
1016 | 1026 | ||
1027 | #ifdef CONFIG_PCNET32_NAPI | ||
1028 | if (netif_running(dev)) { | ||
1029 | pcnet32_netif_start(dev); | ||
1030 | pcnet32_restart(dev, CSR0_NORMAL); | ||
1031 | } else { | ||
1032 | pcnet32_purge_rx_ring(dev); | ||
1033 | lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ | ||
1034 | } | ||
1035 | spin_unlock_irqrestore(&lp->lock, flags); | ||
1036 | #else | ||
1017 | if (netif_running(dev)) { | 1037 | if (netif_running(dev)) { |
1018 | spin_unlock_irqrestore(&lp->lock, flags); | 1038 | spin_unlock_irqrestore(&lp->lock, flags); |
1019 | pcnet32_open(dev); | 1039 | pcnet32_open(dev); |
@@ -1022,6 +1042,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1) | |||
1022 | lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ | 1042 | lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */ |
1023 | spin_unlock_irqrestore(&lp->lock, flags); | 1043 | spin_unlock_irqrestore(&lp->lock, flags); |
1024 | } | 1044 | } |
1045 | #endif | ||
1025 | 1046 | ||
1026 | return (rc); | 1047 | return (rc); |
1027 | } /* end pcnet32_loopback_test */ | 1048 | } /* end pcnet32_loopback_test */ |
@@ -1227,23 +1248,25 @@ static void pcnet32_rx_entry(struct net_device *dev, | |||
1227 | } | 1248 | } |
1228 | lp->stats.rx_bytes += skb->len; | 1249 | lp->stats.rx_bytes += skb->len; |
1229 | skb->protocol = eth_type_trans(skb, dev); | 1250 | skb->protocol = eth_type_trans(skb, dev); |
1251 | #ifdef CONFIG_PCNET32_NAPI | ||
1252 | netif_receive_skb(skb); | ||
1253 | #else | ||
1230 | netif_rx(skb); | 1254 | netif_rx(skb); |
1255 | #endif | ||
1231 | dev->last_rx = jiffies; | 1256 | dev->last_rx = jiffies; |
1232 | lp->stats.rx_packets++; | 1257 | lp->stats.rx_packets++; |
1233 | return; | 1258 | return; |
1234 | } | 1259 | } |
1235 | 1260 | ||
1236 | 1261 | static int pcnet32_rx(struct net_device *dev, int quota) | |
1237 | static void pcnet32_rx(struct net_device *dev) | ||
1238 | { | 1262 | { |
1239 | struct pcnet32_private *lp = dev->priv; | 1263 | struct pcnet32_private *lp = dev->priv; |
1240 | int entry = lp->cur_rx & lp->rx_mod_mask; | 1264 | int entry = lp->cur_rx & lp->rx_mod_mask; |
1241 | struct pcnet32_rx_head *rxp = &lp->rx_ring[entry]; | 1265 | struct pcnet32_rx_head *rxp = &lp->rx_ring[entry]; |
1242 | int npackets = 0; | 1266 | int npackets = 0; |
1243 | int boguscnt = lp->rx_ring_size / 2; | ||
1244 | 1267 | ||
1245 | /* If we own the next entry, it's a new packet. Send it up. */ | 1268 | /* If we own the next entry, it's a new packet. Send it up. */ |
1246 | while (boguscnt > npackets && (short)le16_to_cpu(rxp->status) >= 0) { | 1269 | while (quota > npackets && (short)le16_to_cpu(rxp->status) >= 0) { |
1247 | pcnet32_rx_entry(dev, lp, rxp, entry); | 1270 | pcnet32_rx_entry(dev, lp, rxp, entry); |
1248 | npackets += 1; | 1271 | npackets += 1; |
1249 | /* | 1272 | /* |
@@ -1257,10 +1280,10 @@ static void pcnet32_rx(struct net_device *dev) | |||
1257 | rxp = &lp->rx_ring[entry]; | 1280 | rxp = &lp->rx_ring[entry]; |
1258 | } | 1281 | } |
1259 | 1282 | ||
1260 | return; | 1283 | return npackets; |
1261 | } | 1284 | } |
1262 | 1285 | ||
1263 | static int pcnet32_tx(struct net_device *dev, u16 csr0) | 1286 | static int pcnet32_tx(struct net_device *dev) |
1264 | { | 1287 | { |
1265 | struct pcnet32_private *lp = dev->priv; | 1288 | struct pcnet32_private *lp = dev->priv; |
1266 | unsigned int dirty_tx = lp->dirty_tx; | 1289 | unsigned int dirty_tx = lp->dirty_tx; |
@@ -1298,8 +1321,8 @@ static int pcnet32_tx(struct net_device *dev, u16 csr0) | |||
1298 | /* Remove this verbosity later! */ | 1321 | /* Remove this verbosity later! */ |
1299 | if (netif_msg_tx_err(lp)) | 1322 | if (netif_msg_tx_err(lp)) |
1300 | printk(KERN_ERR | 1323 | printk(KERN_ERR |
1301 | "%s: Tx FIFO error! CSR0=%4.4x\n", | 1324 | "%s: Tx FIFO error!\n", |
1302 | dev->name, csr0); | 1325 | dev->name); |
1303 | must_restart = 1; | 1326 | must_restart = 1; |
1304 | } | 1327 | } |
1305 | #else | 1328 | #else |
@@ -1310,8 +1333,8 @@ static int pcnet32_tx(struct net_device *dev, u16 csr0) | |||
1310 | /* Remove this verbosity later! */ | 1333 | /* Remove this verbosity later! */ |
1311 | if (netif_msg_tx_err(lp)) | 1334 | if (netif_msg_tx_err(lp)) |
1312 | printk(KERN_ERR | 1335 | printk(KERN_ERR |
1313 | "%s: Tx FIFO error! CSR0=%4.4x\n", | 1336 | "%s: Tx FIFO error!\n", |
1314 | dev->name, csr0); | 1337 | dev->name); |
1315 | must_restart = 1; | 1338 | must_restart = 1; |
1316 | } | 1339 | } |
1317 | } | 1340 | } |
@@ -1358,6 +1381,52 @@ static int pcnet32_tx(struct net_device *dev, u16 csr0) | |||
1358 | return must_restart; | 1381 | return must_restart; |
1359 | } | 1382 | } |
1360 | 1383 | ||
1384 | #ifdef CONFIG_PCNET32_NAPI | ||
1385 | static int pcnet32_poll(struct net_device *dev, int *budget) | ||
1386 | { | ||
1387 | struct pcnet32_private *lp = dev->priv; | ||
1388 | int quota = min(dev->quota, *budget); | ||
1389 | unsigned long ioaddr = dev->base_addr; | ||
1390 | unsigned long flags; | ||
1391 | u16 val; | ||
1392 | |||
1393 | quota = pcnet32_rx(dev, quota); | ||
1394 | |||
1395 | spin_lock_irqsave(&lp->lock, flags); | ||
1396 | if (pcnet32_tx(dev)) { | ||
1397 | /* reset the chip to clear the error condition, then restart */ | ||
1398 | lp->a.reset(ioaddr); | ||
1399 | lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */ | ||
1400 | pcnet32_restart(dev, CSR0_START); | ||
1401 | netif_wake_queue(dev); | ||
1402 | } | ||
1403 | spin_unlock_irqrestore(&lp->lock, flags); | ||
1404 | |||
1405 | *budget -= quota; | ||
1406 | dev->quota -= quota; | ||
1407 | |||
1408 | if (dev->quota == 0) { | ||
1409 | return 1; | ||
1410 | } | ||
1411 | |||
1412 | netif_rx_complete(dev); | ||
1413 | |||
1414 | spin_lock_irqsave(&lp->lock, flags); | ||
1415 | |||
1416 | /* clear interrupt masks */ | ||
1417 | val = lp->a.read_csr(ioaddr, CSR3); | ||
1418 | val &= 0x00ff; | ||
1419 | lp->a.write_csr(ioaddr, CSR3, val); | ||
1420 | |||
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 0; | ||
1427 | } | ||
1428 | #endif | ||
1429 | |||
1361 | #define PCNET32_REGS_PER_PHY 32 | 1430 | #define PCNET32_REGS_PER_PHY 32 |
1362 | #define PCNET32_MAX_PHYS 32 | 1431 | #define PCNET32_MAX_PHYS 32 |
1363 | static int pcnet32_get_regs_len(struct net_device *dev) | 1432 | static int pcnet32_get_regs_len(struct net_device *dev) |
@@ -1894,6 +1963,10 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) | |||
1894 | dev->ethtool_ops = &pcnet32_ethtool_ops; | 1963 | dev->ethtool_ops = &pcnet32_ethtool_ops; |
1895 | dev->tx_timeout = pcnet32_tx_timeout; | 1964 | dev->tx_timeout = pcnet32_tx_timeout; |
1896 | dev->watchdog_timeo = (5 * HZ); | 1965 | dev->watchdog_timeo = (5 * HZ); |
1966 | dev->weight = lp->rx_ring_size / 2; | ||
1967 | #ifdef CONFIG_PCNET32_NAPI | ||
1968 | dev->poll = pcnet32_poll; | ||
1969 | #endif | ||
1897 | 1970 | ||
1898 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1971 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1899 | dev->poll_controller = pcnet32_poll_controller; | 1972 | dev->poll_controller = pcnet32_poll_controller; |
@@ -2497,7 +2570,6 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2497 | unsigned long ioaddr; | 2570 | unsigned long ioaddr; |
2498 | u16 csr0; | 2571 | u16 csr0; |
2499 | int boguscnt = max_interrupt_work; | 2572 | int boguscnt = max_interrupt_work; |
2500 | int must_restart; | ||
2501 | 2573 | ||
2502 | if (!dev) { | 2574 | if (!dev) { |
2503 | if (pcnet32_debug & NETIF_MSG_INTR) | 2575 | if (pcnet32_debug & NETIF_MSG_INTR) |
@@ -2519,20 +2591,11 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2519 | /* Acknowledge all of the current interrupt sources ASAP. */ | 2591 | /* Acknowledge all of the current interrupt sources ASAP. */ |
2520 | lp->a.write_csr(ioaddr, CSR0, csr0 & ~0x004f); | 2592 | lp->a.write_csr(ioaddr, CSR0, csr0 & ~0x004f); |
2521 | 2593 | ||
2522 | must_restart = 0; | ||
2523 | |||
2524 | if (netif_msg_intr(lp)) | 2594 | if (netif_msg_intr(lp)) |
2525 | printk(KERN_DEBUG | 2595 | printk(KERN_DEBUG |
2526 | "%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n", | 2596 | "%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n", |
2527 | dev->name, csr0, lp->a.read_csr(ioaddr, CSR0)); | 2597 | dev->name, csr0, lp->a.read_csr(ioaddr, CSR0)); |
2528 | 2598 | ||
2529 | if (csr0 & 0x0400) /* Rx interrupt */ | ||
2530 | pcnet32_rx(dev); | ||
2531 | |||
2532 | if (csr0 & 0x0200) { /* Tx-done interrupt */ | ||
2533 | must_restart = pcnet32_tx(dev, csr0); | ||
2534 | } | ||
2535 | |||
2536 | /* Log misc errors. */ | 2599 | /* Log misc errors. */ |
2537 | if (csr0 & 0x4000) | 2600 | if (csr0 & 0x4000) |
2538 | lp->stats.tx_errors++; /* Tx babble. */ | 2601 | lp->stats.tx_errors++; /* Tx babble. */ |
@@ -2546,10 +2609,8 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2546 | * sometimes problems and will fill up the receive | 2609 | * sometimes problems and will fill up the receive |
2547 | * ring with error descriptors. In this situation we | 2610 | * ring with error descriptors. In this situation we |
2548 | * don't get a rx interrupt, but a missed frame | 2611 | * don't get a rx interrupt, but a missed frame |
2549 | * interrupt sooner or later. So we try to clean up | 2612 | * interrupt sooner or later. |
2550 | * our receive ring here. | ||
2551 | */ | 2613 | */ |
2552 | pcnet32_rx(dev); | ||
2553 | lp->stats.rx_errors++; /* Missed a Rx frame. */ | 2614 | lp->stats.rx_errors++; /* Missed a Rx frame. */ |
2554 | } | 2615 | } |
2555 | if (csr0 & 0x0800) { | 2616 | if (csr0 & 0x0800) { |
@@ -2559,19 +2620,34 @@ pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2559 | dev->name, csr0); | 2620 | dev->name, csr0); |
2560 | /* unlike for the lance, there is no restart needed */ | 2621 | /* unlike for the lance, there is no restart needed */ |
2561 | } | 2622 | } |
2562 | 2623 | #ifdef CONFIG_PCNET32_NAPI | |
2563 | if (must_restart) { | 2624 | if (netif_rx_schedule_prep(dev)) { |
2625 | u16 val; | ||
2626 | /* set interrupt masks */ | ||
2627 | val = lp->a.read_csr(ioaddr, CSR3); | ||
2628 | val |= 0x5f00; | ||
2629 | lp->a.write_csr(ioaddr, CSR3, val); | ||
2630 | mmiowb(); | ||
2631 | __netif_rx_schedule(dev); | ||
2632 | break; | ||
2633 | } | ||
2634 | #else | ||
2635 | pcnet32_rx(dev, dev->weight); | ||
2636 | if (pcnet32_tx(dev)) { | ||
2564 | /* reset the chip to clear the error condition, then restart */ | 2637 | /* reset the chip to clear the error condition, then restart */ |
2565 | lp->a.reset(ioaddr); | 2638 | lp->a.reset(ioaddr); |
2566 | lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */ | 2639 | lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */ |
2567 | pcnet32_restart(dev, CSR0_START); | 2640 | pcnet32_restart(dev, CSR0_START); |
2568 | netif_wake_queue(dev); | 2641 | netif_wake_queue(dev); |
2569 | } | 2642 | } |
2643 | #endif | ||
2570 | csr0 = lp->a.read_csr(ioaddr, CSR0); | 2644 | csr0 = lp->a.read_csr(ioaddr, CSR0); |
2571 | } | 2645 | } |
2572 | 2646 | ||
2647 | #ifndef CONFIG_PCNET32_NAPI | ||
2573 | /* Set interrupt enable. */ | 2648 | /* Set interrupt enable. */ |
2574 | lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN); | 2649 | lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN); |
2650 | #endif | ||
2575 | 2651 | ||
2576 | if (netif_msg_intr(lp)) | 2652 | if (netif_msg_intr(lp)) |
2577 | printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", | 2653 | printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n", |