[Bug 263638] uath driver for Atheros AR5523 USB WiFi chipset fails to initialize

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 28 Apr 2022 21:06:43 UTC

            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
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

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) {
                                    "%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) {
                            "%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:/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.