]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mt76: optimize ROC for same-channel case
authorFelix Fietkau <nbd@nbd.name>
Mon, 9 Mar 2026 06:07:25 +0000 (06:07 +0000)
committerFelix Fietkau <nbd@nbd.name>
Tue, 24 Mar 2026 15:49:31 +0000 (15:49 +0000)
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.

Link: https://patch.msgid.link/20260309060730.87840-6-nbd@nbd.name
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/channel.c
drivers/net/wireless/mediatek/mt76/mt76.h
drivers/net/wireless/mediatek/mt76/scan.c

index 8d2e72c68c6b899fcd61caadc30a75e85e3df22a..f42f251015448e39818059b966f59f5abcea3159 100644 (file)
@@ -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;
index ffeb4b4c425be58b620517da1c8c7de13e15bbce..c7c9ffd0dc3b9dd34929e95ae65d60fddd370e23 100644 (file)
@@ -1790,6 +1790,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);
index 2b5f30cef79517080c65ff290b99395a8e5060c4..5a67e9b8183a714e734ad545f4703d84bc6be4f8 100644 (file)
@@ -139,11 +139,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);