[Bug 263638] uath driver for Atheros AR5523 USB WiFi chipset fails to initialize
Date: Thu, 28 Apr 2022 21:06:43 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263638 Bug ID: 263638 Summary: uath driver for Atheros AR5523 USB WiFi chipset fails to initialize Product: Base System Version: 13.1-STABLE Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: usb Assignee: usb@FreeBSD.org Reporter: jgibbons@protogate.com uath devices fail to initialize, with lines such as these in the dmesg output: ugen1.4: <Atheros Communications Inc WPN111> at usbus1 uath0 on uhub3 uath0: <Atheros Communications Inc WPN111, rev 2.00/0.01, addr 4> on usbus1 uath0: uath_cmdeof: invalid WDC msg length 671088640; msg ignored uath0: timeout waiting for reply to cmd 0x4 (4) uath0: could not read capability 2 uath0: could not get device capabilities device_attach: uath0 attach returned 35 The problem is caused by code which was added to /usr/src/sys/dev/usb/wlan/if_uath.c several years ago ( git 6acad03d6f245dd60ef4f50d03483dad08aff5f9 ), which added an extra swapping of the byte-order of a hdr->len field from big-endian to the host's native byte order BEFORE calling a uath_cmdeof() function which expects that hdr->len field to still be in big-endian format. uath_cmdeof() then calls be32toh() to swap that field again, which puts it back into the wrong byte-order, and subsequent operations all fail (as can be seen by the "invalid WDC msg length 671088640" error message above: 671088640 is the 32-bit-byte-swapped version of the decimal number 40). Below is a patch which fixes this problem, and makes my Netgear WPN111 useable: diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index df7e1d7c396..b285ae06260 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -2244,7 +2244,7 @@ uath_cmdeof(struct uath_softc *sc, struct uath_cmd *cmd) u_int olen; if (sizeof(*hdr) > hdr->len || - hdr->len >= UATH_MAX_CMDSZ) { + hdr->len > UATH_MAX_CMDSZ) { device_printf(sc->sc_dev, "%s: invalid WDC msg length %u; " "msg ignored\n", __func__, hdr->len); @@ -2360,11 +2360,12 @@ uath_intr_rx_callback(struct usb_xfer *xfer, usb_error_t error) usbd_copy_out(pc, 0, cmd->buf, actlen); hdr = (struct uath_cmd_hdr *)cmd->buf; - hdr->len = be32toh(hdr->len); - if (hdr->len > (uint32_t)actlen) { + // hdr->len = be32toh(hdr->len); // Don't do this here! + // Later code expects it to remain big-endian! + if (be32toh(hdr->len) > (uint32_t)actlen) { device_printf(sc->sc_dev, "%s: truncated xfer (len %u, actlen %d)\n", - __func__, hdr->len, actlen); + __func__, be32toh(hdr->len), actlen); goto setup; } My version of FreeBSD, and the USB WiFi device I tested this with, is here: root@romulus:/usr/src/sys/dev/usb/wlan # uname -a FreeBSD romulus.jag.protogate.com 13.1-STABLE FreeBSD 13.1-STABLE #0 stable/13-n250407-0ae09fb966d: Wed Apr 13 07:40:07 PDT 2022 root@romulus.jag.protogate.com:/usr/obj/usr/src/amd64.amd64/sys/JAG_KERNEL_A64 amd64 root@romulus:/usr/src/sys/dev/usb/wlan # usbconfig -d 6.2 dump_device_desc ugen6.2: <Atheros Communications Inc WPN111> at usbus6, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (500mA) bLength = 0x0012 bDescriptorType = 0x0001 bcdUSB = 0x0200 bDeviceClass = 0x00ff <Vendor specific> bDeviceSubClass = 0x0000 bDeviceProtocol = 0x0000 bMaxPacketSize0 = 0x0040 idVendor = 0x1385 idProduct = 0x5f00 bcdDevice = 0x0001 iManufacturer = 0x0001 <Atheros Communications Inc> iProduct = 0x0002 <WPN111> iSerialNumber = 0x0003 <1.0> bNumConfigurations = 0x0001 -- You are receiving this mail because: You are the assignee for the bug.