Download raw body.
urtwn(4) firmware commands, what should get vs. what is written
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<PROTECTED>: 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, <radiotap v0, tsf 3791646655, 1Mbit/s, chan 4, 11n, sig 23dBm, antenna 1>
18:22:16.893635 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3792548329, 1Mbit/s, chan 4, 11n, sig 24dBm, antenna 1>
18:22:17.896273 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3793550930, 1Mbit/s, chan 4, 11n, sig 29dBm, antenna 1>
18:22:18.898270 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3794782236, 1Mbit/s, chan 4, 11n, sig 30dBm, antenna 1>
18:22:19.894258 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3795581598, 1Mbit/s, chan 4, 11n, sig 28dBm, antenna 1>
18:22:20.653136 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3796340405, 1Mbit/s, chan 4, 11n, sig 25dBm, antenna 1>
18:22:20.893715 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3796548271, 1Mbit/s, chan 4, 11n, sig 22dBm, antenna 1>
18:22:21.713099 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3797400413, 1Mbit/s, chan 4, 11n, sig 21dBm, antenna 1>
18:22:21.714606 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3797401964, 1Mbit/s, chan 4, 11n, sig 24dBm, antenna 1>
18:22:21.893617 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3797548153, 1Mbit/s, chan 4, 11n, sig 25dBm, antenna 1>
18:22:22.893903 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3798581191, 1Mbit/s, chan 4, 11n, sig 25dBm, antenna 1>
18:22:23.893799 802.11 flags=41<PROTECTED>: 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, <radiotap v0, tsf 3799548301, 1Mbit/s, chan 4, 11n, sig 24dBm, antenna 1>
Short output of tcpdump with above diff:
18:06:27.196792 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2842867828, 9Mbit/s, chan 4, 11n, sig 28dBm, antenna 1>
18:06:27.284422 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843184690, 1Mbit/s, chan 4, 11n, sig 24dBm, antenna 1>
18:06:27.292957 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843193286, 12Mbit/s, chan 4, 11n, sig 28dBm, antenna 1>
18:06:27.400987 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843072008, 18Mbit/s, chan 4, 11n, sig 26dBm, antenna 1>
18:06:27.500596 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843204352, 1Mbit/s, chan 4, 11n, sig 23dBm, antenna 1>
18:06:27.501732 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843205551, 12Mbit/s, chan 4, 11n, sig 28dBm, antenna 1>
18:06:27.694236 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843463485, 9Mbit/s, chan 4, 11n, sig 27dBm, antenna 1>
18:06:27.695056 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843464406, 9Mbit/s, chan 4, 11n, sig 26dBm, antenna 1>
18:06:27.778746 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843449768, 18Mbit/s, chan 4, 11n, sig 26dBm, antenna 1>
18:06:27.893757 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843597548, 6Mbit/s, chan 4, 11n, sig 27dBm, antenna 1>
18:06:28.091212 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2852118072, 18Mbit/s, chan 4, 11n, sig 26dBm, antenna 1>
18:06:28.276489 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843980195, 6Mbit/s, chan 4, 11n, sig 26dBm, antenna 1>
18:06:28.293698 802.11 flags=49<RETRY,PROTECTED>: 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, <radiotap v0, tsf 2843997346, 6Mbit/s, chan 4, 11n, sig 26dBm, antenna 1>
--
Regards,
Mikolaj
urtwn(4) firmware commands, what should get vs. what is written