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 <[EMAIL PROTECTED]>");
 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 [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to