Bug 263638 - uath driver for Atheros AR5523 USB WiFi chipset fails to initialize
Summary: uath driver for Atheros AR5523 USB WiFi chipset fails to initialize
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: usb (show other bugs)
Version: 13.1-STABLE
Hardware: Any Any
: --- Affects Some People
Assignee: Hans Petter Selasky
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-04-28 21:06 UTC by Jeff Gibbons
Modified: 2023-04-30 06:59 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jeff Gibbons 2022-04-28 21:06:43 UTC
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
Comment 1 commit-hook freebsd_committer freebsd_triage 2022-04-30 09:23:48 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=6eb6aeef7e670bddc9cd52aaf32765a9ea85eee3

commit 6eb6aeef7e670bddc9cd52aaf32765a9ea85eee3
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-04-30 09:21:54 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-04-30 09:23:07 +0000

    uath(4): Fix incorrect byte-swapping and a buffer length check.

    PR:                     263638
    Reported by:            Jeff Gibbons <jgibbons@protogate.com>
    MFC after:              1 week
    Sponsored by:           NVIDIA Networking

 sys/dev/usb/wlan/if_uath.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
Comment 2 Hans Petter Selasky freebsd_committer freebsd_triage 2022-04-30 09:24:11 UTC
Thank you!

Your analysis looks right.

--HPS
Comment 3 commit-hook freebsd_committer freebsd_triage 2023-04-30 06:59:08 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=e7f8a67e1f88442d8d66a0a1c3de03ba8fc13078

commit e7f8a67e1f88442d8d66a0a1c3de03ba8fc13078
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-04-30 09:21:54 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2023-04-30 06:56:16 +0000

    uath(4): Fix incorrect byte-swapping and a buffer length check.

    PR:                     263638
    Reported by:            Jeff Gibbons <jgibbons@protogate.com>
    Sponsored by:           NVIDIA Networking

    (cherry picked from commit 6eb6aeef7e670bddc9cd52aaf32765a9ea85eee3)

 sys/dev/usb/wlan/if_uath.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)