lkml.org 
[lkml]   [2000]   [Sep]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] 3c59x.c
This patch fixes some long-standing problems which people
have been experiencing on collisiony half-duplex 10baseT LANs.

It also syncs up some device names and types with the latest
pcmcia_cs release.

Many thanks to David Hinds for sorting all this out.


Changelog entry (maintained at
http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3):


LK1.1.9 2 Sep 2000

- Fixed a bug where, if vp->tx_full is set when the interface
is downed, it remains set when the interface is upped. Bad things
happen.

- Backed out the tx_reset_resume code. It has become obsolete.

- Resetting the transmitter on TxReclaim errors is not
necessary. Removed it from vortex_error.

- Lots of work on the maxCollisions code.

The 3com NICs have a suspect backoff algorithm, so they are
quite collisiony on half=duplex 10baseT LANs. Running a

ping -f -s 50000 hostname

from another machine generates a LOT of collisions.
Sometimes, 16 in a row, which triggers the maxCollisions error.

Some NICs get stuck after a maxCollisions error and need a TxReset.

It turns out that a full TxReset is not needed. We only need
to reset the interface (not the download logic). Hence the code
to reestablish the state of the download engine after the TxReset
was removed, and we now only do the partial TxReset on
maxCollisions if the NIC is a Tornado.

I didn't use IS_TORNADO for this: created a new driver flag
MAX_COLLISIONS_RESET for flexibility.

David Hinds' 3Com contacts say the requirement to do the
partial TxReset after maxCollisions is only a Tornado requirement,
but it is actually not needed on my 3c905C Tornado. It appears to
be specific to Cardbus NICs.

Still, enabling this for other NICs is simple and doesn't
cause any problems, except for Boomerang NICs. If the partial
TxReset is to be used on a Boomerang NIC, the TxReset command
should be masked with 0x0148, not 0x0108.

You will still see the occasional Tx timeout when using a 3com
NIC on a collisiony 10baseT LAN. These are genuine: if the LAN
traffic is heavy enough, the NIC can't transmit a single packet
for 400 milliseconds and the timeout is triggered. The driver
should recover OK. If desired, you can extend the timeout
interval to, say, 1000 milliseconds with

modprobe 3c59x watchdog=1000

or

options 3c59x watchdog=1000

in /etc/modules.conf

- Rejigged some of the driver flags and device names for
Cardbus NICs based on pcmcia_cs-3.1.20.




--- linux-2.4.0-test8-pre1/drivers/net/3c59x.c Thu Aug 24 21:07:19 2000
+++ linux-akpm/drivers/net/3c59x.c Sat Sep 2 17:05:30 2000
@@ -98,6 +98,18 @@
- Added INVERT_LED_PWR, used it.
- Backed out the extra_reset stuff

+ LK1.1.9 2 Sep 2000 andrewm
+ - Backed out the tx_reset_resume flags. It was a no-op.
+ - In vortex_error, don't reset the Tx on txReclaim errors
+ - In vortex_error, don't reset the Tx on maxCollisions errors.
+ Hence backed out all the DownListPtr logic here.
+ - In vortex_error, give Tornado cards a partial TxReset on
+ maxCollisions (David Hinds). Defined MAX_COLLISION_RESET for this.
+ - Redid some driver flags and device names based on pcmcia_cs-3.1.20.
+ - Fixed a bug where, if vp->tx_full is set when the interface
+ is downed, it remains set when the interface is upped. Bad
+ things happen.
+
- See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details.
- Also see Documentation/networking/vortex.txt
*/
@@ -183,7 +195,7 @@
#include <linux/delay.h>

static char version[] __devinitdata =
-"3c59x.c:LK1.1.8 13 Aug 2000 Donald Becker and others. http://www.scyld.com/network/vortex.html " "$Revision: 1.102.2.25 $\n";
+"3c59x.c:LK1.1.9 2 Sep 2000 Donald Becker and others. http://www.scyld.com/network/vortex.html " "$Revision: 1.102.2.38 $\n";

MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
MODULE_DESCRIPTION("3Com 3c59x/3c90x/3c575 series Vortex/Boomerang/Cyclone driver");
@@ -303,7 +315,7 @@
enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8,
EEPROM_8BIT=0x10, /* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */
HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
- INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400 };
+ INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800 };


enum vortex_chips {
@@ -415,14 +427,14 @@

{"3CCFE575BT Cyclone CardBus",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_LED_PWR, 128, },
- {"3CCFE575CT Cyclone CardBus",
- PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR, 128, },
+ {"3CCFE575CT Tornado CardBus",
+ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|MAX_COLLISION_RESET, 128, },
{"3CCFE656 Cyclone CardBus",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|INVERT_LED_PWR, 128, },
{"3CCFEM656B Cyclone+Winmodem CardBus",
PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|INVERT_LED_PWR, 128, },
- {"3CCFE656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */
- PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR, 128, },
+ {"3CXFEM656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */
+ PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|MAX_COLLISION_RESET, 128, },

{"3c450 HomePNA Tornado", /* AKPM: from Don's 0.99Q */
PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY, 128, },
@@ -652,7 +664,6 @@
open:1,
must_free_region:1; /* Flag: if zero, Cardbus owns the I/O region */
int drv_flags;
- int tx_reset_resume; /* Flag to retart timer after vortex_error handling */
u16 status_enable;
u16 intr_enable;
u16 available_media; /* From Wn3_Options. */
@@ -1369,6 +1380,7 @@

vortex_up(dev);
vp->open = 1;
+ vp->tx_full = 0;
return 0;

out_free_irq:
@@ -1570,7 +1582,7 @@
{
struct vortex_private *vp = (struct vortex_private *)dev->priv;
long ioaddr = dev->base_addr;
- int do_tx_reset = 0;
+ int do_tx_reset = 0, reset_mask = 0;
unsigned char tx_status = 0;

if (vortex_debug > 2) {
@@ -1589,10 +1601,14 @@
if (tx_status & 0x14) vp->stats.tx_fifo_errors++;
if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
outb(0, ioaddr + TxStatus);
- if (tx_status & 0x3a) /* TxReset after 16 collisions, despite what the manual says */
- do_tx_reset = 1; /* Also reset on reclaim errors */
- else /* Merely re-enable the transmitter. */
+ if (tx_status & 0x30) { /* txJabber or txUnderrun */
+ do_tx_reset = 1;
+ } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */
+ do_tx_reset = 1;
+ reset_mask = 0x0108; /* Reset interface logic, but not download logic */
+ } else { /* Merely re-enable the transmitter. */
outw(TxEnable, ioaddr + EL3_CMD);
+ }
}

if (status & RxEarly) { /* Rx early is unused. */
@@ -1644,40 +1660,11 @@
}
}

- /*
- * Black magic. If we're resetting the transmitter, remember the current downlist
- * pointer and restore it afterwards. We can't usr cur_tx because that could
- * lag the actual hardware index.
- */
if (do_tx_reset) {
- if (vp->full_bus_master_tx) {
- unsigned long old_down_list_ptr;
-
- wait_for_completion(dev, DownStall);
- old_down_list_ptr = inl(ioaddr + DownListPtr);
- wait_for_completion(dev, TxReset);
- outw(TxEnable, ioaddr + EL3_CMD);
-
- /* Restart DMA if necessary */
- outl(old_down_list_ptr, ioaddr + DownListPtr);
- if (vortex_debug > 2)
- printk(KERN_DEBUG "reset DMA to 0x%08x\n", inl(ioaddr + DownListPtr));
- outw(DownUnstall, ioaddr + EL3_CMD);
-
- /*
- * Here we make a single attempt to prevent a timeout by
- * restarting the timer if we think that the ISR has a good
- * chance of unjamming things.
- */
- if (vp->tx_reset_resume == 0 && vp->tx_full) {
- vp->tx_reset_resume = 1;
- dev->trans_start = jiffies;
- }
- } else {
- wait_for_completion(dev, TxReset);
- outw(TxEnable, ioaddr + EL3_CMD);
+ wait_for_completion(dev, TxReset|reset_mask);
+ outw(TxEnable, ioaddr + EL3_CMD);
+ if (!vp->full_bus_master_tx)
netif_wake_queue(dev);
- }
}
}

@@ -1785,7 +1772,6 @@
/* netif_start_queue (dev); */ /* AKPM: redundant? */
}
outw(DownUnstall, ioaddr + EL3_CMD);
- vp->tx_reset_resume = 0;
spin_unlock_irqrestore(&vp->lock, flags);
dev->trans_start = jiffies;
return 0;
--- linux-2.4.0-test8-pre1/drivers/pci/pci.ids Thu Aug 24 21:07:20 2000
+++ linux-akpm/drivers/pci/pci.ids Sat Sep 2 16:12:28 2000
@@ -1471,9 +1471,9 @@
6055 3c556 Laptop Hurricane
5057 3c575 [Megahertz] 10/100 LAN CardBus
10b7 5a57 3C575 Megahertz 10/100 LAN Cardbus PC Card
- 5157 3c575 [Megahertz] 10/100 LAN CardBus
+ 5157 3CCFE575BT Cyclone CardBus
10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
- 5257 3CCFE575CT Cyclone CardBus
+ 5257 3CCFE575CT Tornado CardBus
5900 3c590 10BaseT [Vortex]
5920 3c592 EISA 10mbps Demon/Vortex
5950 3c595 100BaseTX [Vortex]
@@ -1483,8 +1483,8 @@
5b57 3c595 [Megahertz] 10/100 LAN CardBus
10b7 5b57 3C575 Megahertz 10/100 LAN Cardbus PC Card
6560 3CCFE656 Cyclone CardBus
- 6562 3CCFEM656 [id 6562] Cyclone CardBus
- 6564 3CCFEM656 [id 6564] Cyclone CardBus
+ 6562 3CCFEM656B Cyclone CardBus
+ 6564 3CXFEM656C Tornado CardBus
7646 3cSOHO100-TX Hurricane
8811 Token ring
9000 3c900 10BaseT [Boomerang]
--- linux-2.4.0-test8-pre1/Documentation/networking/vortex.txt Thu Aug 24 21:07:14 2000
+++ linux-akpm/Documentation/networking/vortex.txt Thu Aug 24 21:24:27 2000
@@ -166,8 +166,9 @@

Sets the time duration (in milliseconds) after which the kernel
decides that the transmitter has become stuck and needs to be reset.
- This is mainly for debugging purposes. The default value is 400 (0.4
- seconds).
+ This is mainly for debugging purposes, although it may be advantageous
+ to increase this value on LANs which have very high collision rates.
+ The default value is 400 (0.4 seconds).

Additional resources
--------------------
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 12:38    [W:0.054 / U:0.440 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site