]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: cfg80211: fix off channel operation allowed check for MLO
authorAditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com>
Mon, 14 Jul 2025 04:07:42 +0000 (09:37 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 15 Jul 2025 09:03:53 +0000 (11:03 +0200)
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 <aditya.kumar.singh@oss.qualcomm.com>
Signed-off-by: Amith A <quic_amitajit@quicinc.com>
Link: https://patch.msgid.link/20250714040742.538550-1-quic_amitajit@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/nl80211.c

index 1ee14592828db428e4d4f3e0697efed11d6fe6d9..e1df03e8ed5c1ef10e6428251155c16c374d4549 100644 (file)
@@ -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)