diff options
Diffstat (limited to 'drivers/net/via-rhine.c')
-rw-r--r-- | drivers/net/via-rhine.c | 90 |
1 files changed, 77 insertions, 13 deletions
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index d3d0ec970318..ae971080e2e4 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c | |||
@@ -30,8 +30,8 @@ | |||
30 | */ | 30 | */ |
31 | 31 | ||
32 | #define DRV_NAME "via-rhine" | 32 | #define DRV_NAME "via-rhine" |
33 | #define DRV_VERSION "1.4.0" | 33 | #define DRV_VERSION "1.4.1" |
34 | #define DRV_RELDATE "June-27-2006" | 34 | #define DRV_RELDATE "July-24-2006" |
35 | 35 | ||
36 | 36 | ||
37 | /* A few user-configurable values. | 37 | /* A few user-configurable values. |
@@ -44,6 +44,10 @@ static int max_interrupt_work = 20; | |||
44 | Setting to > 1518 effectively disables this feature. */ | 44 | Setting to > 1518 effectively disables this feature. */ |
45 | static int rx_copybreak; | 45 | static int rx_copybreak; |
46 | 46 | ||
47 | /* Work-around for broken BIOSes: they are unable to get the chip back out of | ||
48 | power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */ | ||
49 | static int avoid_D3; | ||
50 | |||
47 | /* | 51 | /* |
48 | * In case you are looking for 'options[]' or 'full_duplex[]', they | 52 | * In case you are looking for 'options[]' or 'full_duplex[]', they |
49 | * are gone. Use ethtool(8) instead. | 53 | * are gone. Use ethtool(8) instead. |
@@ -63,7 +67,11 @@ static const int multicast_filter_limit = 32; | |||
63 | There are no ill effects from too-large receive rings. */ | 67 | There are no ill effects from too-large receive rings. */ |
64 | #define TX_RING_SIZE 16 | 68 | #define TX_RING_SIZE 16 |
65 | #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ | 69 | #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */ |
70 | #ifdef CONFIG_VIA_RHINE_NAPI | ||
71 | #define RX_RING_SIZE 64 | ||
72 | #else | ||
66 | #define RX_RING_SIZE 16 | 73 | #define RX_RING_SIZE 16 |
74 | #endif | ||
67 | 75 | ||
68 | 76 | ||
69 | /* Operational parameters that usually are not changed. */ | 77 | /* Operational parameters that usually are not changed. */ |
@@ -116,9 +124,11 @@ MODULE_LICENSE("GPL"); | |||
116 | module_param(max_interrupt_work, int, 0); | 124 | module_param(max_interrupt_work, int, 0); |
117 | module_param(debug, int, 0); | 125 | module_param(debug, int, 0); |
118 | module_param(rx_copybreak, int, 0); | 126 | module_param(rx_copybreak, int, 0); |
127 | module_param(avoid_D3, bool, 0); | ||
119 | MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt"); | 128 | MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt"); |
120 | MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)"); | 129 | MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)"); |
121 | MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames"); | 130 | MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames"); |
131 | MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)"); | ||
122 | 132 | ||
123 | /* | 133 | /* |
124 | Theory of Operation | 134 | Theory of Operation |
@@ -396,7 +406,7 @@ static void rhine_tx_timeout(struct net_device *dev); | |||
396 | static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev); | 406 | static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev); |
397 | static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs); | 407 | static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs); |
398 | static void rhine_tx(struct net_device *dev); | 408 | static void rhine_tx(struct net_device *dev); |
399 | static void rhine_rx(struct net_device *dev); | 409 | static int rhine_rx(struct net_device *dev, int limit); |
400 | static void rhine_error(struct net_device *dev, int intr_status); | 410 | static void rhine_error(struct net_device *dev, int intr_status); |
401 | static void rhine_set_rx_mode(struct net_device *dev); | 411 | static void rhine_set_rx_mode(struct net_device *dev); |
402 | static struct net_device_stats *rhine_get_stats(struct net_device *dev); | 412 | static struct net_device_stats *rhine_get_stats(struct net_device *dev); |
@@ -564,6 +574,32 @@ static void rhine_poll(struct net_device *dev) | |||
564 | } | 574 | } |
565 | #endif | 575 | #endif |
566 | 576 | ||
577 | #ifdef CONFIG_VIA_RHINE_NAPI | ||
578 | static int rhine_napipoll(struct net_device *dev, int *budget) | ||
579 | { | ||
580 | struct rhine_private *rp = netdev_priv(dev); | ||
581 | void __iomem *ioaddr = rp->base; | ||
582 | int done, limit = min(dev->quota, *budget); | ||
583 | |||
584 | done = rhine_rx(dev, limit); | ||
585 | *budget -= done; | ||
586 | dev->quota -= done; | ||
587 | |||
588 | if (done < limit) { | ||
589 | netif_rx_complete(dev); | ||
590 | |||
591 | iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | | ||
592 | IntrRxDropped | IntrRxNoBuf | IntrTxAborted | | ||
593 | IntrTxDone | IntrTxError | IntrTxUnderrun | | ||
594 | IntrPCIErr | IntrStatsMax | IntrLinkChange, | ||
595 | ioaddr + IntrEnable); | ||
596 | return 0; | ||
597 | } | ||
598 | else | ||
599 | return 1; | ||
600 | } | ||
601 | #endif | ||
602 | |||
567 | static void rhine_hw_init(struct net_device *dev, long pioaddr) | 603 | static void rhine_hw_init(struct net_device *dev, long pioaddr) |
568 | { | 604 | { |
569 | struct rhine_private *rp = netdev_priv(dev); | 605 | struct rhine_private *rp = netdev_priv(dev); |
@@ -744,6 +780,10 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, | |||
744 | #ifdef CONFIG_NET_POLL_CONTROLLER | 780 | #ifdef CONFIG_NET_POLL_CONTROLLER |
745 | dev->poll_controller = rhine_poll; | 781 | dev->poll_controller = rhine_poll; |
746 | #endif | 782 | #endif |
783 | #ifdef CONFIG_VIA_RHINE_NAPI | ||
784 | dev->poll = rhine_napipoll; | ||
785 | dev->weight = 64; | ||
786 | #endif | ||
747 | if (rp->quirks & rqRhineI) | 787 | if (rp->quirks & rqRhineI) |
748 | dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; | 788 | dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM; |
749 | 789 | ||
@@ -789,6 +829,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, | |||
789 | } | 829 | } |
790 | } | 830 | } |
791 | rp->mii_if.phy_id = phy_id; | 831 | rp->mii_if.phy_id = phy_id; |
832 | if (debug > 1 && avoid_D3) | ||
833 | printk(KERN_INFO "%s: No D3 power state at shutdown.\n", | ||
834 | dev->name); | ||
792 | 835 | ||
793 | return 0; | 836 | return 0; |
794 | 837 | ||
@@ -1014,6 +1057,8 @@ static void init_registers(struct net_device *dev) | |||
1014 | 1057 | ||
1015 | rhine_set_rx_mode(dev); | 1058 | rhine_set_rx_mode(dev); |
1016 | 1059 | ||
1060 | netif_poll_enable(dev); | ||
1061 | |||
1017 | /* Enable interrupts by setting the interrupt mask. */ | 1062 | /* Enable interrupts by setting the interrupt mask. */ |
1018 | iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | | 1063 | iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | |
1019 | IntrRxDropped | IntrRxNoBuf | IntrTxAborted | | 1064 | IntrRxDropped | IntrRxNoBuf | IntrTxAborted | |
@@ -1268,8 +1313,18 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs * | |||
1268 | dev->name, intr_status); | 1313 | dev->name, intr_status); |
1269 | 1314 | ||
1270 | if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped | | 1315 | if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped | |
1271 | IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) | 1316 | IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) { |
1272 | rhine_rx(dev); | 1317 | #ifdef CONFIG_VIA_RHINE_NAPI |
1318 | iowrite16(IntrTxAborted | | ||
1319 | IntrTxDone | IntrTxError | IntrTxUnderrun | | ||
1320 | IntrPCIErr | IntrStatsMax | IntrLinkChange, | ||
1321 | ioaddr + IntrEnable); | ||
1322 | |||
1323 | netif_rx_schedule(dev); | ||
1324 | #else | ||
1325 | rhine_rx(dev, RX_RING_SIZE); | ||
1326 | #endif | ||
1327 | } | ||
1273 | 1328 | ||
1274 | if (intr_status & (IntrTxErrSummary | IntrTxDone)) { | 1329 | if (intr_status & (IntrTxErrSummary | IntrTxDone)) { |
1275 | if (intr_status & IntrTxErrSummary) { | 1330 | if (intr_status & IntrTxErrSummary) { |
@@ -1367,13 +1422,12 @@ static void rhine_tx(struct net_device *dev) | |||
1367 | spin_unlock(&rp->lock); | 1422 | spin_unlock(&rp->lock); |
1368 | } | 1423 | } |
1369 | 1424 | ||
1370 | /* This routine is logically part of the interrupt handler, but isolated | 1425 | /* Process up to limit frames from receive ring */ |
1371 | for clarity and better register allocation. */ | 1426 | static int rhine_rx(struct net_device *dev, int limit) |
1372 | static void rhine_rx(struct net_device *dev) | ||
1373 | { | 1427 | { |
1374 | struct rhine_private *rp = netdev_priv(dev); | 1428 | struct rhine_private *rp = netdev_priv(dev); |
1429 | int count; | ||
1375 | int entry = rp->cur_rx % RX_RING_SIZE; | 1430 | int entry = rp->cur_rx % RX_RING_SIZE; |
1376 | int boguscnt = rp->dirty_rx + RX_RING_SIZE - rp->cur_rx; | ||
1377 | 1431 | ||
1378 | if (debug > 4) { | 1432 | if (debug > 4) { |
1379 | printk(KERN_DEBUG "%s: rhine_rx(), entry %d status %8.8x.\n", | 1433 | printk(KERN_DEBUG "%s: rhine_rx(), entry %d status %8.8x.\n", |
@@ -1382,16 +1436,18 @@ static void rhine_rx(struct net_device *dev) | |||
1382 | } | 1436 | } |
1383 | 1437 | ||
1384 | /* If EOP is set on the next entry, it's a new packet. Send it up. */ | 1438 | /* If EOP is set on the next entry, it's a new packet. Send it up. */ |
1385 | while (!(rp->rx_head_desc->rx_status & cpu_to_le32(DescOwn))) { | 1439 | for (count = 0; count < limit; ++count) { |
1386 | struct rx_desc *desc = rp->rx_head_desc; | 1440 | struct rx_desc *desc = rp->rx_head_desc; |
1387 | u32 desc_status = le32_to_cpu(desc->rx_status); | 1441 | u32 desc_status = le32_to_cpu(desc->rx_status); |
1388 | int data_size = desc_status >> 16; | 1442 | int data_size = desc_status >> 16; |
1389 | 1443 | ||
1444 | if (desc_status & DescOwn) | ||
1445 | break; | ||
1446 | |||
1390 | if (debug > 4) | 1447 | if (debug > 4) |
1391 | printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n", | 1448 | printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n", |
1392 | desc_status); | 1449 | desc_status); |
1393 | if (--boguscnt < 0) | 1450 | |
1394 | break; | ||
1395 | if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) { | 1451 | if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) { |
1396 | if ((desc_status & RxWholePkt) != RxWholePkt) { | 1452 | if ((desc_status & RxWholePkt) != RxWholePkt) { |
1397 | printk(KERN_WARNING "%s: Oversized Ethernet " | 1453 | printk(KERN_WARNING "%s: Oversized Ethernet " |
@@ -1460,7 +1516,11 @@ static void rhine_rx(struct net_device *dev) | |||
1460 | PCI_DMA_FROMDEVICE); | 1516 | PCI_DMA_FROMDEVICE); |
1461 | } | 1517 | } |
1462 | skb->protocol = eth_type_trans(skb, dev); | 1518 | skb->protocol = eth_type_trans(skb, dev); |
1519 | #ifdef CONFIG_VIA_RHINE_NAPI | ||
1520 | netif_receive_skb(skb); | ||
1521 | #else | ||
1463 | netif_rx(skb); | 1522 | netif_rx(skb); |
1523 | #endif | ||
1464 | dev->last_rx = jiffies; | 1524 | dev->last_rx = jiffies; |
1465 | rp->stats.rx_bytes += pkt_len; | 1525 | rp->stats.rx_bytes += pkt_len; |
1466 | rp->stats.rx_packets++; | 1526 | rp->stats.rx_packets++; |
@@ -1487,6 +1547,8 @@ static void rhine_rx(struct net_device *dev) | |||
1487 | } | 1547 | } |
1488 | rp->rx_ring[entry].rx_status = cpu_to_le32(DescOwn); | 1548 | rp->rx_ring[entry].rx_status = cpu_to_le32(DescOwn); |
1489 | } | 1549 | } |
1550 | |||
1551 | return count; | ||
1490 | } | 1552 | } |
1491 | 1553 | ||
1492 | /* | 1554 | /* |
@@ -1776,6 +1838,7 @@ static int rhine_close(struct net_device *dev) | |||
1776 | spin_lock_irq(&rp->lock); | 1838 | spin_lock_irq(&rp->lock); |
1777 | 1839 | ||
1778 | netif_stop_queue(dev); | 1840 | netif_stop_queue(dev); |
1841 | netif_poll_disable(dev); | ||
1779 | 1842 | ||
1780 | if (debug > 1) | 1843 | if (debug > 1) |
1781 | printk(KERN_DEBUG "%s: Shutting down ethercard, " | 1844 | printk(KERN_DEBUG "%s: Shutting down ethercard, " |
@@ -1857,7 +1920,8 @@ static void rhine_shutdown (struct pci_dev *pdev) | |||
1857 | } | 1920 | } |
1858 | 1921 | ||
1859 | /* Hit power state D3 (sleep) */ | 1922 | /* Hit power state D3 (sleep) */ |
1860 | iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW); | 1923 | if (!avoid_D3) |
1924 | iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW); | ||
1861 | 1925 | ||
1862 | /* TODO: Check use of pci_enable_wake() */ | 1926 | /* TODO: Check use of pci_enable_wake() */ |
1863 | 1927 | ||