21143 media detection, revisited

B. James Phillippe bryan@terran.org
Sat Aug 1 21:08:58 1998


Hello,

	I have determined that the problem I was having a while back with a
3Com SuperStacker switch was not related to the tulip driver.  However,
this patch does seem to improve the robustness of tulip.c:v0.86I.  Can
anyone out there with a 21143 card (having media detection problems) try
this and let me know what the results are?  It seems to make my card work
better when switching from 10baseT and 100baseTx.

--- /home/bryan/tmp/tulip.c   Sun Jul 26 13:31:51 1998
+++ tulip.c Wed Jul 29 14:35:21 1998
@@ -280,6 +280,10 @@
 #define PCI_DEVICE_ID_DEC_TULIP_21142 0x0019
 #endif

+#ifndef PCI_VENDOR_ID_LITEON
+#define PCI_VENDOR_ID_LITEON 0x11ad
+#endif
+
 /* The rest of these values should never change. */

 static void tulip_timer(unsigned long data);
@@ -1788,13 +1792,28 @@
   struct tulip_private *tp = (struct tulip_private *)dev->priv;
   long ioaddr = dev->base_addr;
   int csr12 = inl(ioaddr + CSR12);
-  int next_tick = 60*HZ;
+  int next_tick = 4*HZ;
   int new_csr6 = 0;

   if (tulip_debug > 1)
      printk(KERN_INFO"%s: 21142 negotiation status %8.8x, %s.\n",
            dev->name, csr12, medianame[dev->if_port]);
-  if (dev->if_port == 3) {
+  if ((csr12 & 6) == 6) {
+     if (csr12 & 0x200) {
+        printk(KERN_INFO"%s: 21142 link establishment problem; trying
100baseTx.\n",
+              dev->name);
+        new_csr6 = 0x83860000;
+        dev->if_port = 3;
+        outl(0, ioaddr + CSR13);
+        if (new_csr6 != (tp->csr6 & ~0xD5)) {
+           tp->csr6 &= 0xD5;
+           tp->csr6 |= new_csr6;
+           outl(0x200, ioaddr + CSR12);
+           outl(tp->csr6|0x0002, ioaddr + CSR6);
+           outl(tp->csr6|0x2002, ioaddr + CSR6);
+        }
+     }
+  } else if (dev->if_port == 3) {
      if (csr12 & 2) {     /* No 100mbps link beat, revert to 10mbps. */
         new_csr6 = 0x82420200;
         outl(new_csr6, ioaddr + CSR6);
@@ -1874,8 +1893,21 @@
      if (!(csr12 & 2))
         printk(KERN_INFO"%s: 21142 100baseTx link beat good.\n",
               dev->name);
-     else
+     else {
+        if (tulip_debug > 1)
+           printk(KERN_INFO"%s: 21142 100baseTx link fail; trying
10baseT.\n",
+                 dev->name);
         dev->if_port = 0;
+        outl(0, ioaddr + CSR13);
+        tp->csr6 = 0x82420200;
+        outl(0x0003FFFF, ioaddr + CSR14);
+        outl(0x8, ioaddr + CSR15);
+        outl(0x1, ioaddr + CSR13);
+        outl(0x1301, ioaddr + CSR12);
+        outl(tp->csr6, ioaddr + CSR6);
+        outl(tp->csr6|0x2000, ioaddr + CSR6);
+        outl(tp->csr6|0x2002, ioaddr + CSR6);
+     }
   } else if (dev->if_port == 0) {
      if (!(csr12 & 4))
         printk(KERN_INFO"%s: 21142 10baseT link beat good.\n",
@@ -2339,7 +2371,13 @@
            if (tulip_debug > 1)
               printk(KERN_INFO"%s: 21142 link change, CSR5 = %8.8x.\n",
                     dev->name, csr5);
-           t21142_lnk_change(dev);
+           if (csr5 & TPLnkFail) {
+              printk(KERN_INFO"%s: 21142 looks disconnected.\n",
+                    dev->name);
+              outl(inl(ioaddr + CSR12)|0x200, ioaddr + CSR12);
+           }
+           else
+              t21142_lnk_change(dev);
         }
         /* Clear all error sources, included undocumented ones! */
         outl(0x0800f7ba, ioaddr + CSR5);

thanks,
-bp
--
B. James Phillippe <bryan@terran.org>
Linux Software Engineer, WGT Inc.
http://earth.terran.org/~bryan