aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/forcedeth.c
diff options
context:
space:
mode:
authorManfred Spraul <manfred@colorfullife.com>2005-07-31 12:29:47 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-07-31 12:59:56 -0400
commitc2dba06dae7d6c4d15b83ea12d8c601cffd0aee9 (patch)
treeed0a3caa4bb6e601bd92643188d992213567c3b9 /drivers/net/forcedeth.c
parentdc8216c192795b62f30ca34299fb79e897438372 (diff)
[PATCH] forcedeth: rewritten tx irq handling
This is a multi-part message in MIME format. Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r--drivers/net/forcedeth.c111
1 files changed, 63 insertions, 48 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 9c49c5ec89bf..746ad0178f8c 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -87,6 +87,8 @@
87 * 0.35: 26 Jun 2005: Support for MCP55 added. 87 * 0.35: 26 Jun 2005: Support for MCP55 added.
88 * 0.36: 28 Jun 2005: Add jumbo frame support. 88 * 0.36: 28 Jun 2005: Add jumbo frame support.
89 * 0.37: 10 Jul 2005: Additional ethtool support, cleanup of pci id list 89 * 0.37: 10 Jul 2005: Additional ethtool support, cleanup of pci id list
90 * 0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of
91 * per-packet flags.
90 * 92 *
91 * Known bugs: 93 * Known bugs:
92 * We suspect that on some hardware no TX done interrupts are generated. 94 * We suspect that on some hardware no TX done interrupts are generated.
@@ -98,7 +100,7 @@
98 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few 100 * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
99 * superfluous timer interrupts from the nic. 101 * superfluous timer interrupts from the nic.
100 */ 102 */
101#define FORCEDETH_VERSION "0.37" 103#define FORCEDETH_VERSION "0.38"
102#define DRV_NAME "forcedeth" 104#define DRV_NAME "forcedeth"
103 105
104#include <linux/module.h> 106#include <linux/module.h>
@@ -133,12 +135,9 @@
133 * Hardware access: 135 * Hardware access:
134 */ 136 */
135 137
136#define DEV_NEED_LASTPACKET1 0x0001 /* set LASTPACKET1 in tx flags */ 138#define DEV_NEED_TIMERIRQ 0x0001 /* set the timer irq flag in the irq mask */
137#define DEV_IRQMASK_1 0x0002 /* use NVREG_IRQMASK_WANTED_1 for irq mask */ 139#define DEV_NEED_LINKTIMER 0x0002 /* poll link settings. Relies on the timer irq */
138#define DEV_IRQMASK_2 0x0004 /* use NVREG_IRQMASK_WANTED_2 for irq mask */ 140#define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */
139#define DEV_NEED_TIMERIRQ 0x0008 /* set the timer irq flag in the irq mask */
140#define DEV_NEED_LINKTIMER 0x0010 /* poll link settings. Relies on the timer irq */
141#define DEV_HAS_LARGEDESC 0x0020 /* device supports jumbo frames and needs packet format 2 */
142 141
143enum { 142enum {
144 NvRegIrqStatus = 0x000, 143 NvRegIrqStatus = 0x000,
@@ -149,13 +148,16 @@ enum {
149#define NVREG_IRQ_RX 0x0002 148#define NVREG_IRQ_RX 0x0002
150#define NVREG_IRQ_RX_NOBUF 0x0004 149#define NVREG_IRQ_RX_NOBUF 0x0004
151#define NVREG_IRQ_TX_ERR 0x0008 150#define NVREG_IRQ_TX_ERR 0x0008
152#define NVREG_IRQ_TX2 0x0010 151#define NVREG_IRQ_TX_OK 0x0010
153#define NVREG_IRQ_TIMER 0x0020 152#define NVREG_IRQ_TIMER 0x0020
154#define NVREG_IRQ_LINK 0x0040 153#define NVREG_IRQ_LINK 0x0040
154#define NVREG_IRQ_TX_ERROR 0x0080
155#define NVREG_IRQ_TX1 0x0100 155#define NVREG_IRQ_TX1 0x0100
156#define NVREG_IRQMASK_WANTED_1 0x005f 156#define NVREG_IRQMASK_WANTED 0x00df
157#define NVREG_IRQMASK_WANTED_2 0x0147 157
158#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) 158#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \
159 NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX_ERROR| \
160 NVREG_IRQ_TX1))
159 161
160 NvRegUnknownSetupReg6 = 0x008, 162 NvRegUnknownSetupReg6 = 0x008,
161#define NVREG_UNKSETUP6_VAL 3 163#define NVREG_UNKSETUP6_VAL 3
@@ -296,7 +298,7 @@ struct ring_desc {
296 298
297#define NV_TX_LASTPACKET (1<<16) 299#define NV_TX_LASTPACKET (1<<16)
298#define NV_TX_RETRYERROR (1<<19) 300#define NV_TX_RETRYERROR (1<<19)
299#define NV_TX_LASTPACKET1 (1<<24) 301#define NV_TX_FORCED_INTERRUPT (1<<24)
300#define NV_TX_DEFERRED (1<<26) 302#define NV_TX_DEFERRED (1<<26)
301#define NV_TX_CARRIERLOST (1<<27) 303#define NV_TX_CARRIERLOST (1<<27)
302#define NV_TX_LATECOLLISION (1<<28) 304#define NV_TX_LATECOLLISION (1<<28)
@@ -306,7 +308,7 @@ struct ring_desc {
306 308
307#define NV_TX2_LASTPACKET (1<<29) 309#define NV_TX2_LASTPACKET (1<<29)
308#define NV_TX2_RETRYERROR (1<<18) 310#define NV_TX2_RETRYERROR (1<<18)
309#define NV_TX2_LASTPACKET1 (1<<23) 311#define NV_TX2_FORCED_INTERRUPT (1<<30)
310#define NV_TX2_DEFERRED (1<<25) 312#define NV_TX2_DEFERRED (1<<25)
311#define NV_TX2_CARRIERLOST (1<<26) 313#define NV_TX2_CARRIERLOST (1<<26)
312#define NV_TX2_LATECOLLISION (1<<27) 314#define NV_TX2_LATECOLLISION (1<<27)
@@ -1013,9 +1015,39 @@ static void nv_tx_timeout(struct net_device *dev)
1013 struct fe_priv *np = get_nvpriv(dev); 1015 struct fe_priv *np = get_nvpriv(dev);
1014 u8 __iomem *base = get_hwbase(dev); 1016 u8 __iomem *base = get_hwbase(dev);
1015 1017
1016 dprintk(KERN_DEBUG "%s: Got tx_timeout. irq: %08x\n", dev->name, 1018 printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name,
1017 readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK); 1019 readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK);
1018 1020
1021 {
1022 int i;
1023
1024 printk(KERN_INFO "%s: Ring at %lx: next %d nic %d\n",
1025 dev->name, (unsigned long)np->ring_addr,
1026 np->next_tx, np->nic_tx);
1027 printk(KERN_INFO "%s: Dumping tx registers\n", dev->name);
1028 for (i=0;i<0x400;i+= 32) {
1029 printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
1030 i,
1031 readl(base + i + 0), readl(base + i + 4),
1032 readl(base + i + 8), readl(base + i + 12),
1033 readl(base + i + 16), readl(base + i + 20),
1034 readl(base + i + 24), readl(base + i + 28));
1035 }
1036 printk(KERN_INFO "%s: Dumping tx ring\n", dev->name);
1037 for (i=0;i<TX_RING;i+= 4) {
1038 printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n",
1039 i,
1040 le32_to_cpu(np->tx_ring[i].PacketBuffer),
1041 le32_to_cpu(np->tx_ring[i].FlagLen),
1042 le32_to_cpu(np->tx_ring[i+1].PacketBuffer),
1043 le32_to_cpu(np->tx_ring[i+1].FlagLen),
1044 le32_to_cpu(np->tx_ring[i+2].PacketBuffer),
1045 le32_to_cpu(np->tx_ring[i+2].FlagLen),
1046 le32_to_cpu(np->tx_ring[i+3].PacketBuffer),
1047 le32_to_cpu(np->tx_ring[i+3].FlagLen));
1048 }
1049 }
1050
1019 spin_lock_irq(&np->lock); 1051 spin_lock_irq(&np->lock);
1020 1052
1021 /* 1) stop tx engine */ 1053 /* 1) stop tx engine */
@@ -1557,7 +1589,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
1557 if (!(events & np->irqmask)) 1589 if (!(events & np->irqmask))
1558 break; 1590 break;
1559 1591
1560 if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX2|NVREG_IRQ_TX_ERR)) { 1592 if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_ERR)) {
1561 spin_lock(&np->lock); 1593 spin_lock(&np->lock);
1562 nv_tx_done(dev); 1594 nv_tx_done(dev);
1563 spin_unlock(&np->lock); 1595 spin_unlock(&np->lock);
@@ -2213,17 +2245,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
2213 2245
2214 if (np->desc_ver == DESC_VER_1) { 2246 if (np->desc_ver == DESC_VER_1) {
2215 np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID; 2247 np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID;
2216 if (id->driver_data & DEV_NEED_LASTPACKET1)
2217 np->tx_flags |= NV_TX_LASTPACKET1;
2218 } else { 2248 } else {
2219 np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID; 2249 np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID;
2220 if (id->driver_data & DEV_NEED_LASTPACKET1)
2221 np->tx_flags |= NV_TX2_LASTPACKET1;
2222 } 2250 }
2223 if (id->driver_data & DEV_IRQMASK_1) 2251 np->irqmask = NVREG_IRQMASK_WANTED;
2224 np->irqmask = NVREG_IRQMASK_WANTED_1;
2225 if (id->driver_data & DEV_IRQMASK_2)
2226 np->irqmask = NVREG_IRQMASK_WANTED_2;
2227 if (id->driver_data & DEV_NEED_TIMERIRQ) 2252 if (id->driver_data & DEV_NEED_TIMERIRQ)
2228 np->irqmask |= NVREG_IRQ_TIMER; 2253 np->irqmask |= NVREG_IRQ_TIMER;
2229 if (id->driver_data & DEV_NEED_LINKTIMER) { 2254 if (id->driver_data & DEV_NEED_LINKTIMER) {
@@ -2329,73 +2354,63 @@ static void __devexit nv_remove(struct pci_dev *pci_dev)
2329static struct pci_device_id pci_tbl[] = { 2354static struct pci_device_id pci_tbl[] = {
2330 { /* nForce Ethernet Controller */ 2355 { /* nForce Ethernet Controller */
2331 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1), 2356 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1),
2332 .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, 2357 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
2333 }, 2358 },
2334 { /* nForce2 Ethernet Controller */ 2359 { /* nForce2 Ethernet Controller */
2335 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_2), 2360 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_2),
2336 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, 2361 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
2337 }, 2362 },
2338 { /* nForce3 Ethernet Controller */ 2363 { /* nForce3 Ethernet Controller */
2339 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_3), 2364 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_3),
2340 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, 2365 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
2341 }, 2366 },
2342 { /* nForce3 Ethernet Controller */ 2367 { /* nForce3 Ethernet Controller */
2343 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4), 2368 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
2344 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2369 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2345 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2346 }, 2370 },
2347 { /* nForce3 Ethernet Controller */ 2371 { /* nForce3 Ethernet Controller */
2348 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5), 2372 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
2349 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2373 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2350 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2351 }, 2374 },
2352 { /* nForce3 Ethernet Controller */ 2375 { /* nForce3 Ethernet Controller */
2353 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6), 2376 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
2354 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2377 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2355 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2356 }, 2378 },
2357 { /* nForce3 Ethernet Controller */ 2379 { /* nForce3 Ethernet Controller */
2358 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7), 2380 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
2359 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2381 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2360 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2361 }, 2382 },
2362 { /* CK804 Ethernet Controller */ 2383 { /* CK804 Ethernet Controller */
2363 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8), 2384 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
2364 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2385 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2365 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2366 }, 2386 },
2367 { /* CK804 Ethernet Controller */ 2387 { /* CK804 Ethernet Controller */
2368 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9), 2388 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
2369 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2389 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2370 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2371 }, 2390 },
2372 { /* MCP04 Ethernet Controller */ 2391 { /* MCP04 Ethernet Controller */
2373 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10), 2392 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
2374 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2393 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2375 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2376 }, 2394 },
2377 { /* MCP04 Ethernet Controller */ 2395 { /* MCP04 Ethernet Controller */
2378 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11), 2396 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
2379 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2397 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2380 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2381 }, 2398 },
2382 { /* MCP51 Ethernet Controller */ 2399 { /* MCP51 Ethernet Controller */
2383 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), 2400 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
2384 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, 2401 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
2385 }, 2402 },
2386 { /* MCP51 Ethernet Controller */ 2403 { /* MCP51 Ethernet Controller */
2387 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), 2404 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13),
2388 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, 2405 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
2389 }, 2406 },
2390 { /* MCP55 Ethernet Controller */ 2407 { /* MCP55 Ethernet Controller */
2391 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), 2408 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
2392 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2409 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2393 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2394 }, 2410 },
2395 { /* MCP55 Ethernet Controller */ 2411 { /* MCP55 Ethernet Controller */
2396 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), 2412 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
2397 .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ| 2413 .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2398 DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
2399 }, 2414 },
2400 {0,}, 2415 {0,},
2401}; 2416};