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