[PATCH wireless] wifi: mt76: mt7925: fix MT7927 receive loss after a channel switch
Devin Wittmayer
lucid_duck at justthetip.ca
Mon Oct 12 19:38:10 PDT 2026
When the access point announces a channel switch, an MT7927 stays
connected but stops receiving until it reconnects.
To set the band, the driver deletes the MT7927's firmware interface and
adds it back whenever a single-link interface is put on a channel. A
channel switch does this mid-connection, and the connection is not
restored.
Skip it on a channel switch unless the band changes. Monitor mode still
needs it to retune.
Fixes: 05fd14885303 ("wifi: mt76: mt7925: sync MT7927 BSS band assignment")
Link: https://lore.kernel.org/linux-wireless/20260306-mt7927-wifi-support-v1-17-c77e7445511d@jetm.me/
Cc: stable at vger.kernel.org
Signed-off-by: Devin Wittmayer <lucid_duck at justthetip.ca>
---
Notes:
Tested on a Framework 13 with its built-in MT7927 and an MT7925, both
downloading while a WiFi 7 access point switched. Switches after which
the MT7927 needed a reconnect:
7.2.10 + fix 7.3-rc7 + fix
channel moved 10 of 10 0 of 10 10 of 10 0 of 10
width changed 26 of 26 0 of 26 26 of 26 0 of 26
puncturing removed 10 of 10 0 of 10 10 of 10 0 of 10
With the fix both cards can pause for up to three seconds at a switch,
as the MT7925 also does without it. Monitor mode, AP mode, joins and
moves between 2.4 and 5 GHz work as before, and the card still recovers
from a firmware reset and from suspend. Two other MediaTek cards on a
second machine came through every switch, stock and patched.
The series as first posted only resent the interface when the band
changed:
https://lore.kernel.org/linux-wireless/20260306-mt7927-wifi-support-v1-17-c77e7445511d@jetm.me/
.../net/wireless/mediatek/mt76/mt7925/main.c | 25 +++++++++++++------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index b46408f4aed2..bdd44b52f886 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -2401,10 +2401,11 @@ mt7927_reconfig_band(struct mt792x_dev *dev, struct ieee80211_vif *vif,
true);
}
-static int mt7925_assign_vif_chanctx(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_bss_conf *link_conf,
- struct ieee80211_chanctx_conf *ctx)
+static int __mt7925_assign_vif_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *link_conf,
+ struct ieee80211_chanctx_conf *ctx,
+ bool switching)
{
struct mt792x_chanctx *mctx = (struct mt792x_chanctx *)ctx->drv_priv;
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
@@ -2429,7 +2430,9 @@ static int mt7925_assign_vif_chanctx(struct ieee80211_hw *hw,
if (is_mt7927(&dev->mt76)) {
band_idx = mt7927_band_idx(ctx->def.chan->band);
- mt7927_reconfig_band(dev, vif, link_conf, mconf, band_idx);
+ if (!switching || mconf->mt76.band_idx != band_idx)
+ mt7927_reconfig_band(dev, vif, link_conf, mconf,
+ band_idx);
}
}
@@ -2441,6 +2444,14 @@ static int mt7925_assign_vif_chanctx(struct ieee80211_hw *hw,
return 0;
}
+static int mt7925_assign_vif_chanctx(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *link_conf,
+ struct ieee80211_chanctx_conf *ctx)
+{
+ return __mt7925_assign_vif_chanctx(hw, vif, link_conf, ctx, false);
+}
+
static void mt7925_unassign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf,
@@ -2491,8 +2502,8 @@ static int mt7925_switch_vif_chanctx(struct ieee80211_hw *hw,
int n_vifs,
enum ieee80211_chanctx_switch_mode mode)
{
- return mt7925_assign_vif_chanctx(hw, vifs->vif, vifs->link_conf,
- vifs->new_ctx);
+ return __mt7925_assign_vif_chanctx(hw, vifs->vif, vifs->link_conf,
+ vifs->new_ctx, true);
}
void mt7925_csa_work(struct work_struct *work)
--
2.56.0
More information about the Linux-mediatek
mailing list