mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH wireless 0/2] wifi: rtw88: channel and control frame filter lost on interface restart
@ 2026-10-07  9:12 Jeremy Fareau
  2026-10-07  9:12 ` [PATCH wireless 1/2] wifi: rtw88: program the channel when the device is started Jeremy Fareau
  2026-10-07  9:12 ` [PATCH wireless 2/2] wifi: rtw88: restore the control frame filter " Jeremy Fareau
  0 siblings, 2 replies; 3+ messages in thread
From: Jeremy Fareau @ 2026-10-07  9:12 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: linux-wireless, linux-kernel, Kalle Valo, Brian Norris, Jeremy Fareau

Two fixes for rtw88, both with the same root cause: after an interface
stop/start cycle the chip is reset by power_off()/power_on(), but
mac80211 only calls config() and configure_filter() when its own state
changes. After the cycle nothing has changed from mac80211's point of
view, so neither the radio channel nor the control frame filter is
reprogrammed.

The user-visible effect is that iw reports the configured channel while
the adapter listens elsewhere, with no error anywhere. This makes an
RTL8814AU look like broken hardware in monitor mode.

Patch 1 programs the channel in rtw_ops_start(). The IPS resume path
already does this in rtw_ips_pwr_up(); only the ieee80211_ops::start()
path was missing it. It is deliberately not placed in rtw_core_start()
so that the IPS path, and its rtw_coex_ips_notify(COEX_IPS_LEAVE)
ordering, is left untouched.

Patch 2 restores REG_RXFLTMAP1 in rtw_core_start(), next to the RCR
restore that exists for the same reason. It applies on top of
ed51a86b787f ("wifi: rtw88: Enable receiving control frames in monitor
mode"), which enables the filter but does not restore it after the chip
is powered back on.

Test setup
==========

Raspberry Pi 4B, aarch64, Ubuntu 26.04.1, kernel 7.0.0-1020-raspi,
in-kernel rtw88 with ed51a86b787f backported. Two adapters on the same
host, both in monitor mode on channel 6, captured in parallel:

  - ALFA AWUS1900     RTL8814AU   rtw88_8814au
  - Linksys WUSB6300  RTL8812AU   rtw88_8812au

Isolating the channel defect. Six runs, full USB unbind/rebind between
each, 25 s captures:

  run  sequence after "ip link up"          frames
   1   set channel 6                             3
   2   set channel 6 again                       0
   3   set channel 6 twice in a row              3
   4   no set channel at all                     3
   5   set channel 11 - a real change          431
   6   WUSB6300 control, same as run 1        2438

Only an actual channel change reaches the hardware.

Both patches applied, five consecutive down/up cycles, 25 s captures,
total frames and control frames:

  cycle   AWUS1900            WUSB6300
    1     6639 / 4556         2274 / 1506
    2     9622 / 7754         2937 / 2214
    3     6847 / 4985         2166 / 1475
    4     7420 / 5542         2493 / 1789
    5     7703 / 5250         2440 / 1625

Without the patches the control counts are 0 on both adapters, and the
AWUS1900 total drops to 0-4 from the first cycle on.

Also verified
=============

  - rtw_set_channel() takes no lock and every caller already holds
    rtwdev->mutex, so the added call in rtw_ops_start() is correctly
    serialised.
  - Station mode unaffected: scans return 28 then 34 BSS (AWUS1900),
    10 then 11 (WUSB6300).
  - Three rmmod/insmod cycles, clean.
  - dmesg: no WARNING, BUG, Oops or call trace.
  - checkpatch.pl --strict: 0 errors, 0 warnings, 0 checks.
  - Build: no code warnings.

NOT verified
============

  - PCI and SDIO paths. Patch 2 touches rtw_core_start(), shared by all
    bus types. Only USB was exercised; no PCI or SDIO hardware was
    available.
  - lockdep. CONFIG_PROVE_LOCKING is not enabled on the test kernel, so
    the absence of a deadlock rests on code review and on use, not on
    instrumentation.
  - Other chips. Only RTL8814AU and RTL8812AU were exercised. Patch 2
    also concerns RTL8723D, RTL8703B and RTL8821A by construction.
  - Bisection. The Fixes: tag on patch 1 was derived by reading the
    history, not by bisecting.

The series is based on mainline 69f80fef3153 (v7.3-rc7). Happy to rebase
onto wireless/main if that is preferred.

Tooling disclosure
==================

Per Documentation/process/generated-content.rst: the diagnosis, the code
and the commit messages in this series were produced by an AI coding
assistant over an interactive session. I was investigating why an
RTL8814AU adapter captured nothing in monitor mode while an RTL8812AU on
the same host captured normally; the assistant proposed and discarded
two incorrect hypotheses (USB power, then a first-configuration-only
effect) before the measurement table above isolated the real mechanism.
It then wrote the fixes, built them, and ran the tests listed here on
the hardware described. All numbers quoted are from that hardware, not
from the model.

I have read and understood both changes and I am taking responsibility
for them; the Signed-off-by tags below are mine. Both patches also carry
Assisted-by: LLM per Documentation/process/coding-assistants.rst.

The patches, the raw measurements and this summary are also at
https://github.com/jeremyfa55/rtw88-monitor-fixes

Jeremy Fareau (2):
  wifi: rtw88: program the channel when the device is started
  wifi: rtw88: restore the control frame filter when the device is
    started

 drivers/net/wireless/realtek/rtw88/mac80211.c | 16 ++++++++++++++--
 drivers/net/wireless/realtek/rtw88/main.c     |  8 ++++++++
 drivers/net/wireless/realtek/rtw88/main.h     |  1 +
 3 files changed, 23 insertions(+), 2 deletions(-)

-- 
2.51.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH wireless 1/2] wifi: rtw88: program the channel when the device is started
  2026-10-07  9:12 [PATCH wireless 0/2] wifi: rtw88: channel and control frame filter lost on interface restart Jeremy Fareau
@ 2026-10-07  9:12 ` Jeremy Fareau
  2026-10-07  9:12 ` [PATCH wireless 2/2] wifi: rtw88: restore the control frame filter " Jeremy Fareau
  1 sibling, 0 replies; 3+ messages in thread
From: Jeremy Fareau @ 2026-10-07  9:12 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: linux-wireless, linux-kernel, Kalle Valo, Brian Norris, Jeremy Fareau

The chip is reset by power_off()/power_on(), but mac80211 only calls
ieee80211_ops::config() when its own channel state changes.  After a
stop/start cycle, such as

    ip link set <dev> down
    ip link set <dev> up

the channel is unchanged from mac80211's point of view, so the radio is
never reprogrammed.  The device then listens on whatever channel the
hardware came up on while iw reports the configured one, and receives
almost nothing.

Observed with an RTL8814AU (ALFA AWUS1900) in monitor mode on an
aarch64 host.  A 25 s capture on channel 6 after a down/up cycle yields
3 frames, and 431 frames as soon as any real channel change is
requested.  An RTL8812AU (Linksys WUSB6300) on the same host, the same
channel and the same second yields 2438 frames.

Program the channel in rtw_ops_start(), like rtw_ips_pwr_up() already
does when leaving IPS.

Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver")
Assisted-by: LLM
Signed-off-by: Jeremy Fareau <jeremy.fareau@gmail.com>
---
 drivers/net/wireless/realtek/rtw88/mac80211.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index b01b98d24b0a..827f38390969 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -57,6 +57,17 @@ static int rtw_ops_start(struct ieee80211_hw *hw)
 
 	mutex_lock(&rtwdev->mutex);
 	ret = rtw_core_start(rtwdev);
+
+	/* The chip is reset by power_off()/power_on(), but mac80211 only calls
+	 * ieee80211_ops::config() when its own channel state changes. After a
+	 * stop/start cycle the channel is unchanged from mac80211's point of
+	 * view, so the radio would never be reprogrammed and the device would
+	 * receive nothing. Program it here, like rtw_ips_pwr_up() already does
+	 * when leaving IPS.
+	 */
+	if (!ret && hw->conf.chandef.chan)
+		rtw_set_channel(rtwdev);
+
 	mutex_unlock(&rtwdev->mutex);
 
 	return ret;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH wireless 2/2] wifi: rtw88: restore the control frame filter when the device is started
  2026-10-07  9:12 [PATCH wireless 0/2] wifi: rtw88: channel and control frame filter lost on interface restart Jeremy Fareau
  2026-10-07  9:12 ` [PATCH wireless 1/2] wifi: rtw88: program the channel when the device is started Jeremy Fareau
@ 2026-10-07  9:12 ` Jeremy Fareau
  1 sibling, 0 replies; 3+ messages in thread
From: Jeremy Fareau @ 2026-10-07  9:12 UTC (permalink / raw)
  To: Ping-Ke Shih
  Cc: linux-wireless, linux-kernel, Kalle Valo, Brian Norris, Jeremy Fareau

Commit ed51a86b787f ("wifi: rtw88: Enable receiving control frames in
monitor mode") writes REG_RXFLTMAP1 from configure_filter(), but that
register is reset to the chip default by the chip's mac_init() during
power_on().  mac80211 only calls ieee80211_ops::configure_filter() when
its own filter flags change, so after a stop/start cycle the flags are
unchanged and the control frame filter silently reverts: monitor mode
stops delivering control frames again.

Keep track of the value configure_filter() last asked for and restore
it in rtw_core_start(), next to the RCR restore, which exists for the
same reason.

Measured on an RTL8814AU and an RTL8812AU in monitor mode on channel 6,
40 s captures taken after a down/up cycle.  Control frames go from 0 to
23184 and from 0 to 483 respectively; without this change both are 0.

Fixes: ed51a86b787f ("wifi: rtw88: Enable receiving control frames in monitor mode")
Assisted-by: LLM
Signed-off-by: Jeremy Fareau <jeremy.fareau@gmail.com>
---
 drivers/net/wireless/realtek/rtw88/mac80211.c | 5 +++--
 drivers/net/wireless/realtek/rtw88/main.c     | 8 ++++++++
 drivers/net/wireless/realtek/rtw88/main.h     | 1 +
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 827f38390969..84d869f1efe0 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -300,9 +300,10 @@ static void rtw_ops_configure_filter(struct ieee80211_hw *hw,
 
 	if (changed_flags & FIF_CONTROL) {
 		if (*new_flags & FIF_CONTROL)
-			rtw_write16(rtwdev, REG_RXFLTMAP1, 0xffff);
+			rtwdev->hal.rxfltmap1_cur = 0xffff;
 		else
-			rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1);
+			rtwdev->hal.rxfltmap1_cur = rtwdev->hal.rxfltmap1;
+		rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1_cur);
 	}
 	if (changed_flags & FIF_ALLMULTI) {
 		if (*new_flags & FIF_ALLMULTI)
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c
index cd9254370fcc..ea61020a0622 100644
--- a/drivers/net/wireless/realtek/rtw88/main.c
+++ b/drivers/net/wireless/realtek/rtw88/main.c
@@ -1528,6 +1528,14 @@ int rtw_core_start(struct rtw_dev *rtwdev)
 	/* rcr reset after powered on */
 	rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
 
+	/* REG_RXFLTMAP1 is reset by the chip's mac_init() during power_on(),
+	 * and mac80211 only calls ieee80211_ops::configure_filter() when its
+	 * own filter flags change.  After a stop/start cycle the flags are
+	 * unchanged, so restore the value configure_filter() last asked for.
+	 */
+	if (rtwdev->hal.rxfltmap1_cur)
+		rtw_write16(rtwdev, REG_RXFLTMAP1, rtwdev->hal.rxfltmap1_cur);
+
 	ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work,
 				     RTW_WATCH_DOG_DELAY_TIME);
 
diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h
index c6e981ba7986..5a9bcc4fdff9 100644
--- a/drivers/net/wireless/realtek/rtw88/main.h
+++ b/drivers/net/wireless/realtek/rtw88/main.h
@@ -1964,6 +1964,7 @@ struct rtw_sar {
 struct rtw_hal {
 	u32 rcr;
 	u16 rxfltmap1;
+	u16 rxfltmap1_cur;
 
 	u32 chip_version;
 	u8 cut_version;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-07  9:13 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-07  9:12 [PATCH wireless 0/2] wifi: rtw88: channel and control frame filter lost on interface restart Jeremy Fareau
2026-10-07  9:12 ` [PATCH wireless 1/2] wifi: rtw88: program the channel when the device is started Jeremy Fareau
2026-10-07  9:12 ` [PATCH wireless 2/2] wifi: rtw88: restore the control frame filter " Jeremy Fareau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®