[vortex] Re: Case 254686: GX150 autonegotiate problem

Andrew Morton akpm@zip.com.au
Tue Jan 29 22:55:01 2002


Bill Cattey wrote:
> 
> Summary:
> 
> I read a fair bit of code and am discovering this is perhaps a more
> complex problem than it seemed at first.
> 

No only for you...

Here's a diff against the current kernel.org driver.  I'll
send you the whole file off-list.


The diff merges in most of Donald's recent PHY-related changes.
I don't even know what these do yet - as far as I know, no
description is available of what they do, or what problems they
are solving.   But if we can converge on a particular chunk or
set of chunks which fixes your problem, I can work on getting
that into the official kernel.


Index: drivers/net/3c59x.c
===================================================================
RCS file: /opt/cvs/lk/drivers/net/3c59x.c,v
retrieving revision 1.74.2.5
diff -u -r1.74.2.5 3c59x.c
--- drivers/net/3c59x.c	2002/01/29 20:58:15	1.74.2.5
+++ drivers/net/3c59x.c	2002/01/30 03:45:45
@@ -1248,11 +1248,11 @@
 	} else
 		dev->if_port = vp->default_media;
 
-	if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
+	if (vp->has_nway || dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
 		int phy, phy_idx = 0;
 		EL3WINDOW(4);
-		mii_preamble_required++;
 		mii_preamble_required++;
+		mdio_sync(ioaddr, 32);
 		mdio_read(dev, 24, 1);
 		for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
 			int mii_status, phyx;
@@ -1268,7 +1268,7 @@
 			else
 				phyx = phy;
 			mii_status = mdio_read(dev, phyx, 1);
-			if (mii_status  &&  mii_status != 0xffff) {
+			if ((mii_status & 0xf800)  &&  mii_status != 0xffff) {
 				vp->phys[phy_idx++] = phyx;
 				if (print_info) {
 					printk(KERN_INFO "  MII transceiver found at address %d,"
@@ -2822,7 +2822,7 @@
 		outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
-	/* Read the two transition, 16 data, and wire-idle bits. */
+	/* Read the two transition and 16 data bits. */
 	for (i = 19; i > 0; i--) {
 		outw(MDIO_ENB_IN, mdio_addr);
 		mdio_delay();
@@ -2856,12 +2856,7 @@
 		mdio_delay();
 	}
 	/* Leave the interface idle. */
-	for (i = 1; i >= 0; i--) {
-		outw(MDIO_ENB_IN, mdio_addr);
-		mdio_delay();
-		outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
-		mdio_delay();
-	}
+	mdio_sync(ioaddr, 32);
 	spin_unlock_bh(&vp->mdio_lock);
 	return;
 }