Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Jul 2009 00:11:40 -0400
From:      john hood <jh@sandstorm.net>
To:        Dr Josef Karthauser <joe@tao.org.uk>, freebsd-usb@freebsd.org, freebsd-current@freebsd.org
Subject:   bug fix for aue driver
Message-ID:  <4A711D7C.2060100@sandstorm.net>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------050903090106080603080204
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

I have a D-Link DSB-650 USB ethernet adapter, which uses an ADMtek AN986 
USB MAC, a Broadcom BCM5201 PHY device, and the aue driver.

Recent versions of FreeBSD (7.1, 7.2, 8 beta 2) all get stuck on "aue0: 
MII read timed out" errors after you try and bring the interface up.  
(The system continues to run, but you get long waits performing ioctls 
on the device, and no actual packets.)

I think I've found the problem; the device is getting mis-initialized, 
and has been ever since the early days of the driver.  The old code 
mis-sets a power-down configuration line on the PHY just as it's 
resetting it.

I think I have a fix; it 1) does the right thing for ADMtek's reference 
design, 2) matches (better) what the Linux driver does (successfully, 
for me), 3) matches the actual circuit of the DSB-650, 4) makes sense 
when you read it.  I suspect it will improve the situation for most 
users of Pegasus-based Ethernet adapters, and probably resolve most of 
the weird media- and PHY-related issues the driver's had for its entire 
life.

Would people try the attached patch?  (If anyone cares much about an 
obsolete Ethernet adapter-- I used this mostly as an excuse to wade into 
the USB stack and understand it a little better...)  If you get 
debugging spew, please forward it to me.  If it just works (or not), 
tell me that too.

The patch is against 8.0-beta2.  It won't apply to the old, pre-USB2 
driver in sys/dev/usb/if_aue.c, but the significant change is the reset 
code in the last hunk of the patch; trying that on whatever version of 
FreeBSD you're using is worthwhile.

Thanks,

  --jh


--------------050903090106080603080204
Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
 name="aue.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="aue.diff"

--- /sys/dev/usb/net/if_aue.c	2009-06-26 07:45:06.000000000 -0400
+++ if_aue.c	2009-07-21 23:30:12.000000000 -0400
@@ -312,8 +312,10 @@
 	USETW(req.wLength, 1);
 
 	err = uether_do_request(&sc->sc_ue, &req, &val, 1000);
-	if (err)
+	if (err) {
+		DPRINTF("%s(%04x): %04x ", __func__, reg, err);
 		return (0);
+	}
 	return (val);
 }
 
@@ -331,8 +333,10 @@
 	USETW(req.wLength, 2);
 
 	err = uether_do_request(&sc->sc_ue, &req, &val, 1000);
-	if (err)
+	if (err) {
+		DPRINTF("%s(%04x): %04x ", __func__, reg, err);
 		return (0);
+	}
 	return (le16toh(val));
 }
 
@@ -340,6 +344,7 @@
 aue_csr_write_1(struct aue_softc *sc, uint16_t reg, uint8_t val)
 {
 	struct usb_device_request req;
+	usb_error_t err;
 
 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
 	req.bRequest = AUE_UR_WRITEREG;
@@ -348,8 +353,8 @@
 	USETW(req.wIndex, reg);
 	USETW(req.wLength, 1);
 
-	if (uether_do_request(&sc->sc_ue, &req, &val, 1000)) {
-		/* error ignored */
+	if ((err = uether_do_request(&sc->sc_ue, &req, &val, 1000))) {
+		DPRINTF("%s(%04x,%02x): %04x ", __func__, reg, val, err);
 	}
 }
 
@@ -357,6 +362,7 @@
 aue_csr_write_2(struct aue_softc *sc, uint16_t reg, uint16_t val)
 {
 	struct usb_device_request req;
+	usb_error_t err;
 
 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
 	req.bRequest = AUE_UR_WRITEREG;
@@ -366,8 +372,8 @@
 
 	val = htole16(val);
 
-	if (uether_do_request(&sc->sc_ue, &req, &val, 1000)) {
-		/* error ignored */
+	if ((err = uether_do_request(&sc->sc_ue, &req, &val, 1000))) {
+		DPRINTF("%s(%04x,%04x): %04x ", __func__, reg, val, err);
 	}
 }
 
@@ -484,7 +490,7 @@
 	}
 
 	if (i == AUE_TIMEOUT)
-		device_printf(sc->sc_ue.ue_dev, "MII read timed out\n");
+		device_printf(sc->sc_ue.ue_dev, "MII write timed out\n");
 
 	if (!locked)
 		AUE_UNLOCK(sc);
@@ -606,8 +612,8 @@
 	 * Note: We force all of the GPIO pins low first, *then*
 	 * enable the ones we want.
 	 */
-	aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0);
-	aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_OUT0|AUE_GPIO_SEL0|AUE_GPIO_SEL1);
+	aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1);
+	aue_csr_write_1(sc, AUE_GPIO0, AUE_GPIO_SEL0|AUE_GPIO_SEL1|AUE_GPIO_OUT0);
 
 	if (sc->sc_flags & AUE_FLAG_LSYS) {
 		/* Grrr. LinkSys has to be different from everyone else. */

--------------050903090106080603080204--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4A711D7C.2060100>