rtw89: WOW_CPUIO_RX_CTRL is never answered on RTL8851B
From: Maxim Skokov
Date: Sat Sep 12 2026 - 15:40:07 EST
On RTL8851BE every suspend/resume cycle with WoWLAN enabled spends about
20 seconds in firmware timeouts:
rtw89_8851be 0000:02:00.0: c2h reg timeout (x3)
rtw89_8851be 0000:02:00.0: Unknown wakeup reason 0
rtw89_8851be 0000:02:00.0: c2h reg timeout (x3)
With WoWLAN disabled the same suspend/resume path is silent. Both results
are 3 out of 3, using rtcwake so the cycles are identical.
A kretprobe on rtw89_fw_msg_reg() shows all six timeouts are the same
command:
h2c=10 ret=-110 3355 ms RTW89_FWCMD_H2CREG_FUNC_WOW_CPUIO_RX_CTRL
h2c=10 ret=-110 3345 ms
h2c=10 ret=-110 3344 ms
h2c=10 ret=-110 3315 ms
h2c=10 ret=-110 3305 ms
h2c=10 ret=-110 3307 ms
h2c=7 ret=0 0 ms AOAC_RPT_1
h2c=8 ret=0 1 ms AOAC_RPT_2
h2c=5 ret=0 0 ms SCH_TX_EN
h2c=5 ret=0 1 ms SCH_TX_EN
Other commands on the same h2creg channel are answered in 0 to 1 ms, so
the channel itself works. The firmware just never answers this one.
Six calls because rtw89_mac_cpu_io_rx() retries CPU_IO_RX_RETRY_CNT = 3
times and is called once on suspend and once on resume. Its return value
is ignored by rtw89_wow_config_mac_ax(), so WoWLAN setup is not aborted
and the only cost is the delay.
_rtw89_mac_cpu_io_rx() already has a way out:
if (RTW89_CHK_FW_FEATURE(NO_WOW_CPU_IO_RX, &rtwdev->fw))
return 0;
but rtw89_fw_feat_list only carries
__CFG_FW_FEAT(RTL8852A, lt, 0, 13, 37, 0, NO_WOW_CPU_IO_RX),
__CFG_FW_FEAT(RTL8852B, lt, 0, 29, 30, 0, NO_WOW_CPU_IO_RX),
and nothing for RTL8851B.
Should RTL8851B get an entry, and with what version boundary? The newest
firmware published for this chip in linux-firmware is 0.29.41.5, and it
does not answer the command either, so from here I cannot tell whether
support is planned for a later version. I am happy to send and test a
patch once I know which version to use.
One unrelated note from the same trace: "Unknown wakeup reason 0" is not
a failed AoAC read. AOAC_RPT_1 and AOAC_RPT_2 both succeed, and
rtw89_wow_show_wakeup_reason() reads the reason straight from
wow_reason_reg, which holds 0 because the card was not the wake source
here, the RTC alarm was. The switch has no case for that and falls
through to the warning.
Tested on:
RTL8851BE [10ec:b851], subsystem AzureWave [1a3b:6111]
wireless-next 13e51269b6, built with KASAN, UBSAN, PROVE_LOCKING and
DEBUG_OBJECTS; none of them fire during these cycles
firmware 0.29.41.3 (65cefb31), also reproduced with 0.29.41.5