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 --- /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 _at__at_ -312,8 +312,10 _at__at_ 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); } _at__at_ -331,8 +333,10 _at__at_ 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)); } _at__at_ -340,6 +344,7 _at__at_ 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; _at__at_ -348,8 +353,8 _at__at_ 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); } } _at__at_ -357,6 +362,7 _at__at_ 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; _at__at_ -366,8 +372,8 _at__at_ 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); } } _at__at_ -484,7 +490,7 _at__at_ } 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); _at__at_ -606,8 +612,8 _at__at_ * 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. */Received on Thu Jul 30 2009 - 02:28:01 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:52 UTC