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>
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;
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);
}
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);