From e9a896d498506af16d52ee33b80c1cdb4f36350d Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Mon, 14 Jul 2025 09:37:42 +0530 Subject: [PATCH] wifi: cfg80211: fix off channel operation allowed check for MLO In cfg80211_off_channel_oper_allowed(), the current logic disallows off-channel operations if any link operates on a radar channel, assuming such channels cannot be vacated. This assumption holds for non-MLO interfaces but not for MLO. With MLO and multi-radio devices, different links may operate on separate radios. This allows one link to scan off-channel while another remains on a radar channel. For example, in a 5 GHz split-phy setup, the lower band can scan while the upper band stays on a radar channel. Off-channel operations can be allowed if the radio/link onto which the input channel falls is different from the radio/link which has an active radar channel. Therefore, fix cfg80211_off_channel_oper_allowed() by returning false only if the requested channel maps to the same radio as an active radar channel. Allow off-channel operations when the requested channel is on a different radio, as in MLO with multi-radio setups. Signed-off-by: Aditya Kumar Singh Signed-off-by: Amith A Link: https://patch.msgid.link/20250714040742.538550-1-quic_amitajit@quicinc.com Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1ee14592828db..e1df03e8ed5c1 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -9761,6 +9761,7 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev, { unsigned int link_id; bool all_ok = true; + int radio_idx; lockdep_assert_wiphy(wdev->wiphy); @@ -9770,8 +9771,10 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev, if (!cfg80211_beaconing_iface_active(wdev)) return true; + radio_idx = cfg80211_get_radio_idx_by_chan(wdev->wiphy, chan); + /* - * FIXME: check if we have a free HW resource/link for chan + * FIXME: check if we have a free radio/link for chan * * This, as well as the FIXME below, requires knowing the link * capabilities of the hardware. @@ -9780,20 +9783,28 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev, /* we cannot leave radar channels */ for_each_valid_link(wdev, link_id) { struct cfg80211_chan_def *chandef; + int link_radio_idx; chandef = wdev_chandef(wdev, link_id); if (!chandef || !chandef->chan) continue; + if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR)) + continue; + /* - * FIXME: don't require all_ok, but rather check only the - * correct HW resource/link onto which 'chan' falls, - * as only that link leaves the channel for doing - * the off-channel operation. + * chandef->chan is a radar channel. If the radio/link onto + * which this radar channel falls is the same radio/link onto + * which the input 'chan' falls, off-channel operation should + * not be allowed. Hence, set 'all_ok' to false. */ - if (chandef->chan->flags & IEEE80211_CHAN_RADAR) + link_radio_idx = cfg80211_get_radio_idx_by_chan(wdev->wiphy, + chandef->chan); + if (link_radio_idx == radio_idx) { all_ok = false; + break; + } } if (all_ok) -- 2.51.0