From: Mikolaj Kucharski Subject: urtwn(4) firmware commands, what should get vs. what is written To: tech@openbsd.org Date: Mon, 19 Oct 2026 18:42:38 +0000 Hi. I'm trying to figure out issues with urtwn(4) stalls and timeouts. I am getting huge help from Claude. I'm used following patch for debugging: Index: sys/dev/ic/rtwn.c =================================================================== RCS file: /cvs/src/sys/dev/ic/rtwn.c,v diff -u -p -r1.61 rtwn.c --- sys/dev/ic/rtwn.c 20 Aug 2025 14:24:05 -0000 1.61 +++ sys/dev/ic/rtwn.c 19 Oct 2026 16:10:35 -0000 @@ -395,7 +395,8 @@ int rtwn_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len) { struct r92c_fw_cmd cmd; - int ntries; + uint8_t *p; + int ntries, i; /* Wait for current FW box to be empty. */ for (ntries = 0; ntries < 100; ntries++) { @@ -414,6 +415,17 @@ rtwn_fw_cmd(struct rtwn_softc *sc, uint8 cmd.id |= R92C_CMD_FLAG_EXT; KASSERT(len <= sizeof(cmd.msg)); memcpy(cmd.msg, buf, len); + + /* DEBUG: what the FW should get vs. what is written below. */ + p = (uint8_t *)&cmd; + printf("%s: fw cmd 0x%02x len %d msg", sc->sc_pdev->dv_xname, + cmd.id, len); + for (i = 0; i < len; i++) + printf(" %02x", cmd.msg[i]); + printf(": EXT want 0x%04x wrote 0x%04x, BOX want 0x%08x wrote 0x%08x\n", + p[4] | p[5] << 8, *((uint8_t *)&cmd + 4), + p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24, + *((uint8_t *)&cmd + 0)); /* Write the first word last since that will trigger the FW. */ if (sc->chip & RTWN_CHIP_92E) which produces following dmesg messages: urtwn0: fw cmd 0x86 len 5 msg 00 00 00 40 84: EXT want 0x8440 wrote 0x0040, BOX want 0x00000086 wrote 0x00000086 urtwn0: fw cmd 0x86 len 5 msg f0 0f 00 40 80: EXT want 0x8040 wrote 0x0040, BOX want 0x000ff086 wrote 0x00000086 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 19: EXT want 0x0000 wrote 0x0000, BOX want 0x19000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1b: EXT want 0x0000 wrote 0x0000, BOX want 0x1b000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1b: EXT want 0x0000 wrote 0x0000, BOX want 0x1b000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 19: EXT want 0x0000 wrote 0x0000, BOX want 0x19000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 19: EXT want 0x0000 wrote 0x0000, BOX want 0x19000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 19: EXT want 0x0000 wrote 0x0000, BOX want 0x19000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1c: EXT want 0x0000 wrote 0x0000, BOX want 0x1c000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1d: EXT want 0x0000 wrote 0x0000, BOX want 0x1d000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1a: EXT want 0x0000 wrote 0x0000, BOX want 0x1a000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1d: EXT want 0x0000 wrote 0x0000, BOX want 0x1d000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 18: EXT want 0x0000 wrote 0x0000, BOX want 0x18000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1c: EXT want 0x0000 wrote 0x0000, BOX want 0x1c000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1c: EXT want 0x0000 wrote 0x0000, BOX want 0x1c000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1c: EXT want 0x0000 wrote 0x0000, BOX want 0x1c000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1d: EXT want 0x0000 wrote 0x0000, BOX want 0x1d000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1c: EXT want 0x0000 wrote 0x0000, BOX want 0x1c000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1c: EXT want 0x0000 wrote 0x0000, BOX want 0x1c000005 wrote 0x00000005 urtwn0: fw cmd 0x05 len 3 msg 00 00 1e: EXT want 0x0000 wrote 0x0000, BOX want 0x1e000005 wrote 0x00000005 urtwn0: fw cmd 0x86 len 5 msg 0f 00 00 40 84: EXT want 0x8440 wrote 0x0040, BOX want 0x00000f86 wrote 0x00000086 Based on above, the below diff addresses: - Extended commands (len > 3) use the wrong byte layout on R92C - Command bytes are truncated --- sys/dev/ic/rtwn.c +++ sys/dev/ic/rtwn.c @@ -409,21 +409,33 @@ rtwn_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len) return (ETIMEDOUT); } memset(&cmd, 0, sizeof(cmd)); cmd.id = id; - if (len > 3) - cmd.id |= R92C_CMD_FLAG_EXT; KASSERT(len <= sizeof(cmd.msg)); - memcpy(cmd.msg, buf, len); + if (len > 3 && + !(sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_88F | RTWN_CHIP_92E))) { + /* + * R92C firmware expects extended commands as + * [id : byte2 : byte3 : byte4] [byte0 : byte1], + * i.e. the first two payload bytes go into HMEBOX_EXT. + */ + cmd.id |= R92C_CMD_FLAG_EXT; + memcpy(cmd.msg, (const uint8_t *)buf + 2, len - 2); + memcpy(cmd.msg + 3, buf, 2); + } else { + if (len > 3) + cmd.id |= R92C_CMD_FLAG_EXT; + memcpy(cmd.msg, buf, len); + } /* Write the first word last since that will trigger the FW. */ if (sc->chip & RTWN_CHIP_92E) rtwn_write_2(sc, R88E_HMEBOX_EXT(sc->fwcur), - *((uint8_t *)&cmd + 4)); + LE_READ_2((uint8_t *)&cmd + 4)); else rtwn_write_2(sc, R92C_HMEBOX_EXT(sc->fwcur), - *((uint8_t *)&cmd + 4)); - rtwn_write_4(sc, R92C_HMEBOX(sc->fwcur), *((uint8_t *)&cmd + 0)); + LE_READ_2((uint8_t *)&cmd + 4)); + rtwn_write_4(sc, R92C_HMEBOX(sc->fwcur), LE_READ_4((uint8_t *)&cmd)); sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX; if (sc->chip & RTWN_CHIP_PCI) { However I'm getting so often `urtwn0: device timeout` with my USB Wi-Fi card, which I belive is not related to above code it's hard to teset. I'm planning to come back to it, when I figure out the device timeout issues. However if you see this is correct, I would be glad to get this committed, so this particular problem is out of my queue. With tcpdump on access point I see without my diff `1Mbit/s`, but with my diff I see `1Mbit/s 6Mbit/s 9Mbit/s 12Mbit/s 18Mbit/s`. Rates are taken from accesspoint# tcpdump -l -c1000 -s4096 -vvv -nni athn0 -y IEEE802_11_RADIO \ wlan addr2 00:13:ef:40:51:2a and type data so I think above diff does fix one small issue. Tested only on: urtwn0 at uhub0 port 4 configuration 1 interface 0 "Realtek 802.11n WLAN Adapter" rev 2.00/2.00 addr 3 urtwn0: MAC/BB RTL8188CUS, RF 6052 1T1R, address 00:13:ef:40:51:2a Short output of tcpdump without the diff: 18:22:15.893709 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 94 I (s=0,r=16,C) len=108, 18:22:16.893635 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 95 I (s=0,r=16,C) len=108, 18:22:17.896273 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 96 I (s=0,r=16,C) len=108, 18:22:18.898270 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 97 I (s=0,r=16,C) len=108, 18:22:19.894258 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 98 I (s=0,r=16,C) len=108, 18:22:20.653136 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 99 I (s=0,r=16,C) len=100, 18:22:20.893715 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 9a I (s=0,r=16,C) len=108, 18:22:21.713099 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 9b I (s=0,r=16,C) len=100, 18:22:21.714606 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 9c I (s=0,r=16,C) len=100, 18:22:21.893617 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 9d I (s=0,r=16,C) len=108, 18:22:22.893903 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 9e I (s=0,r=16,C) len=108, 18:22:23.893799 802.11 flags=41: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 9f I (s=0,r=16,C) len=108, Short output of tcpdump with above diff: 18:06:27.196792 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > ff:ff:ff:ff:ff:ff sap 02 I (s=0,r=16,C) len=352, 18:06:27.284422 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 03 I (s=0,r=16,C) len=108, 18:06:27.292957 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 04 I (s=0,r=16,C) len=108, 18:06:27.400987 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 05 I (s=0,r=16,C) len=164, 18:06:27.500596 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 06 I (s=0,r=16,C) len=108, 18:06:27.501732 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 07 I (s=0,r=16,C) len=164, 18:06:27.694236 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 08 I (s=0,r=16,C) len=108, 18:06:27.695056 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 09 I (s=0,r=16,C) len=108, 18:06:27.778746 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 0a I (s=0,r=16,C) len=164, 18:06:27.893757 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 0b I (s=0,r=16,C) len=108, 18:06:28.091212 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 0c I (s=0,r=16,C) len=108, 18:06:28.276489 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 0d I (s=0,r=16,C) len=108, 18:06:28.293698 802.11 flags=49: data: 00:13:ef:40:51:2a sap 00 > 04:f0:21:45:6a:c4 sap 0e I (s=0,r=16,C) len=108, -- Regards, Mikolaj