Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH wireless] wifi: mac80211: fix channel changes for active monitors
@ 2026-09-01  2:55 Matheus Alves de Almeida
  2026-09-01 19:22 ` Devin Wittmayer
  0 siblings, 1 reply; 3+ messages in thread
From: Matheus Alves de Almeida @ 2026-09-01  2:55 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Matheus Alves de Almeida

Active monitor interfaces are added to the driver as real VIFs so that
frames addressed to their MAC address can be acknowledged. However,
ieee80211_set_monitor_channel() redirects monitor channel changes to the
hidden monitor_sdata whenever the driver does not set
NO_VIRTUAL_MONITOR.

An active-only monitor does not create monitor_sdata, so the function can
return success after only updating monitor_chanreq. The active monitor
itself never gets a channel context, making channel changes ineffective.

Use the active monitor VIF directly when changing channels, while keeping
monitor_chanreq private to the hidden virtual monitor. Also treat active
monitors as valid directly channel-bound monitor interfaces in channel
width and SMPS accounting.

This fixes active monitor channel switching with mac80211_hwsim. Before
this change, an active monitor failed to discover any APs while scanning.
With the fix applied, scanning works across channels 1, 6 and 11 with both
channels=1 and channels=2, and authentication and association on channel 6
succeed without mac80211 or hwsim warnings.

Fixes: 0a44dfc07074 ("wifi: mac80211: simplify non-chanctx drivers")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br>
---
 net/mac80211/cfg.c  | 9 +++++++--
 net/mac80211/chan.c | 8 ++++++--
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 43f142624d33..c844ae2abcb4 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1064,12 +1064,16 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
 	struct ieee80211_local *local = wiphy_priv(wiphy);
 	struct ieee80211_sub_if_data *sdata;
 	struct ieee80211_chan_req chanreq = { .oper = *chandef };
+	bool use_virtual_monitor;
 	int ret;
 
 	lockdep_assert_wiphy(local->hw.wiphy);
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-	if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
+	use_virtual_monitor =
+		!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
+		!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE);
+	if (use_virtual_monitor) {
 		if (cfg80211_chandef_identical(&local->monitor_chanreq.oper,
 					       &chanreq.oper))
 			return 0;
@@ -1090,7 +1094,8 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
 	if (ret)
 		return ret;
 done:
-	local->monitor_chanreq = chanreq;
+	if (use_virtual_monitor)
+		local->monitor_chanreq = chanreq;
 	return 0;
 }
 
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 5152b84a3357..800b7585c010 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -543,7 +543,9 @@ ieee80211_get_width_of_link(struct ieee80211_link_data *link)
 	case NL80211_IFTYPE_P2P_DEVICE:
 		break;
 	case NL80211_IFTYPE_MONITOR:
-		WARN_ON_ONCE(!ieee80211_hw_check(&local->hw,
+		WARN_ON_ONCE(!(link->sdata->u.mntr.flags &
+			       MONITOR_FLAG_ACTIVE) &&
+			     !ieee80211_hw_check(&local->hw,
 						 NO_VIRTUAL_MONITOR));
 		fallthrough;
 	case NL80211_IFTYPE_ADHOC:
@@ -1279,7 +1281,9 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
 				continue;
 			break;
 		case NL80211_IFTYPE_MONITOR:
-			if (!ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
+			if (!(iter.sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
+			    !ieee80211_hw_check(&local->hw,
+						NO_VIRTUAL_MONITOR))
 				continue;
 			break;
 		case NL80211_IFTYPE_AP:
-- 
2.47.3


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

* Re: [PATCH wireless] wifi: mac80211: fix channel changes for active monitors
  2026-09-01  2:55 [PATCH wireless] wifi: mac80211: fix channel changes for active monitors Matheus Alves de Almeida
@ 2026-09-01 19:22 ` Devin Wittmayer
  2026-09-01 20:25   ` Matheus Alves de Almeida
  0 siblings, 1 reply; 3+ messages in thread
From: Devin Wittmayer @ 2026-09-01 19:22 UTC (permalink / raw)
  To: Matheus Alves de Almeida; +Cc: Johannes Berg, linux-wireless

Nice catch. This has been sitting there since early 2024 and it is good
to see it on the list.

Tested-by: Devin Wittmayer <lucid_duck@justthetip.ca>

Two MediaTek USB adapters on the same chip, before and after on each.
One on 7.2.2, where it applies clean and I tested it as posted. One on
a Pi 5 on 6.18.34, which needs two small edits, since that tree has not
had the chan.c refactor and calls the iterator link instead of iter.

Before, the monitor sits on one frequency and every channel request is
accepted and thrown away. Eight cells across the two machines, hundreds
of frames, not one on the channel I asked for, and nothing in the log to
say so. After, it goes where it is told, every time, on both.

I went through this in March on the same chip and wrote it up with diffs
and results, three defects in all:

  https://github.com/morrownr/USB-WiFi/issues/682#issuecomment-4115109552

Yours is the third, and the SMPS hunk is a piece I did not have. Still
open is that an active monitor gets no channel at all when it is
created, only when something later asks for one. Your patch covers that
in practice for anything that sets a channel.

The iface.c hunk there gives it one at creation, but do not take it
alone. On mt76 the sniffer is armed only when the channel changes,
never when it is first assigned. So once the interface starts life on
the right channel, asking for that channel changes nothing and it hears
nothing: four runs, zero frames every time, with a passive monitor on
the same channel hearing traffic in all four. Ask for a different
channel and it works. The driver half is mine.

Good to have another pair of eyes on the monitor paths, they do not get
many.

Devin

On Mon, Sep 1, 2026 at 2:55 AM Matheus Alves de Almeida
<matheus.aalmeida@inf.ufrgs.br> wrote:

> Active monitor interfaces are added to the driver as real VIFs so that
> frames addressed to their MAC address can be acknowledged. However,
> ieee80211_set_monitor_channel() redirects monitor channel changes to the
> hidden monitor_sdata whenever the driver does not set
> NO_VIRTUAL_MONITOR.
>
> An active-only monitor does not create monitor_sdata, so the function can
> return success after only updating monitor_chanreq. The active monitor
> itself never gets a channel context, making channel changes ineffective.
>
> Use the active monitor VIF directly when changing channels, while keeping
> monitor_chanreq private to the hidden virtual monitor. Also treat active
> monitors as valid directly channel-bound monitor interfaces in channel
> width and SMPS accounting.
>
> This fixes active monitor channel switching with mac80211_hwsim. Before
> this change, an active monitor failed to discover any APs while scanning.
> With the fix applied, scanning works across channels 1, 6 and 11 with both
> channels=1 and channels=2, and authentication and association on channel 6
> succeed without mac80211 or hwsim warnings.
>
> Fixes: 0a44dfc07074 ("wifi: mac80211: simplify non-chanctx drivers")
> Assisted-by: Codex:gpt-5.6-sol
> Signed-off-by: Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br>

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

* Re: [PATCH wireless] wifi: mac80211: fix channel changes for active monitors
  2026-09-01 19:22 ` Devin Wittmayer
@ 2026-09-01 20:25   ` Matheus Alves de Almeida
  0 siblings, 0 replies; 3+ messages in thread
From: Matheus Alves de Almeida @ 2026-09-01 20:25 UTC (permalink / raw)
  To: Devin Wittmayer; +Cc: Johannes Berg, linux-wireless

> Tested-by: Devin Wittmayer <...>
> 
> Two MediaTek USB adapters ...

Thanks for testing this, especially on real hardware and on both kernel
versions.

I originally ran into this while writing my own 802.11 stack and had only
tested the fix with mac80211_hwsim, so it's good to see the same issue
reproduced and fixed on actual hardware as well.

> Still open is that an active monitor gets no channel at all when it is
> created ...

The initial-channel case is interesting too. That sounds like a separate
issue, so I’ll keep this patch focused on channel changes.

Matheus

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

end of thread, other threads:[~2026-09-01 20:25 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-01  2:55 [PATCH wireless] wifi: mac80211: fix channel changes for active monitors Matheus Alves de Almeida
2026-09-01 19:22 ` Devin Wittmayer
2026-09-01 20:25   ` Matheus Alves de Almeida

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