From 273c6f60cc8eea7d48c3b0519e3018ac7ea38ac0 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 7 Mar 2026 13:51:56 +0000 Subject: [PATCH] wifi: mt76: optimize ROC for same-channel case mt76_remain_on_channel() always creates an HT20 chandef and goes offchannel, even when the ROC channel matches the operating channel. This unnecessarily narrows bandwidth and triggers beacon stop/restart. When the ROC channel matches the current operating channel, preserve the full chandef and skip the offchannel transition, matching the optimization already present in the scan code. Extract the shared same-channel detection into mt76_offchannel_chandef() and use it in both ROC and scan paths. Signed-off-by: Felix Fietkau --- channel.c | 4 ++-- mt76.h | 12 ++++++++++++ scan.c | 6 +----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/channel.c b/channel.c index 8d2e72c6..f42f2510 100644 --- a/channel.c +++ b/channel.c @@ -392,8 +392,8 @@ int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mlink->mvif->roc_phy = phy; phy->roc_vif = vif; phy->roc_link = mlink; - cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20); - ret = __mt76_set_channel(phy, &chandef, true); + ret = __mt76_set_channel(phy, &chandef, + mt76_offchannel_chandef(phy, chan, &chandef)); if (ret) { mlink->mvif->roc_phy = NULL; phy->roc_vif = NULL; diff --git a/mt76.h b/mt76.h index df66b70b..306cdf31 100644 --- a/mt76.h +++ b/mt76.h @@ -1802,6 +1802,18 @@ void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_entry *e); int __mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, bool offchannel); + +static inline bool +mt76_offchannel_chandef(struct mt76_phy *phy, struct ieee80211_channel *chan, + struct cfg80211_chan_def *chandef) +{ + cfg80211_chandef_create(chandef, chan, NL80211_CHAN_HT20); + if (phy->main_chandef.chan != chan) + return true; + + *chandef = phy->main_chandef; + return false; +} int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, bool offchannel); void mt76_scan_work(struct work_struct *work); diff --git a/scan.c b/scan.c index ed50bd6c..8be286b8 100644 --- a/scan.c +++ b/scan.c @@ -128,11 +128,7 @@ void mt76_scan_work(struct work_struct *work) } dev->scan.chan = req->channels[dev->scan.chan_idx++]; - cfg80211_chandef_create(&chandef, dev->scan.chan, NL80211_CHAN_HT20); - if (phy->main_chandef.chan == dev->scan.chan) { - chandef = phy->main_chandef; - offchannel = false; - } + offchannel = mt76_offchannel_chandef(phy, dev->scan.chan, &chandef); mt76_set_channel(phy, &chandef, offchannel);