]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: cfg80211: fix background CAC
authorJanusz Dziedzic <janusz.dziedzic@gmail.com>
Fri, 6 Feb 2026 17:15:48 +0000 (18:15 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 2 Mar 2026 08:10:28 +0000 (09:10 +0100)
Fix:
- Send CAC_ABORT event when background CAC is canceled
- Cancel CAC done workqueue when radar is detected
- Release background wdev ownership when CAC is aborted or passed
- Clean lower layer background radar state when CAC is aborted or passed
- Prevent sending abort event when radar event is sent

Signed-off-by: Janusz Dziedzic <janusz.dziedzic@gmail.com>
Link: https://patch.msgid.link/20260206171830.553879-2-janusz.dziedzic@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/mlme.c

index 3fc175f9f868614c2f7eda5dc47b3b40726e41a2..212178d04efaf15959d248547abde9a784b6375e 100644 (file)
@@ -1115,8 +1115,10 @@ void __cfg80211_radar_event(struct wiphy *wiphy,
         */
        cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
 
-       if (offchan)
+       if (offchan) {
+               cancel_delayed_work(&rdev->background_cac_done_wk);
                queue_work(cfg80211_wq, &rdev->background_cac_abort_wk);
+       }
 
        cfg80211_sched_dfs_chan_update(rdev);
 
@@ -1187,21 +1189,16 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
        if (!cfg80211_chandef_valid(chandef))
                return;
 
-       if (!rdev->background_radar_wdev)
-               return;
-
        switch (event) {
        case NL80211_RADAR_CAC_FINISHED:
                cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
                memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef));
                queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
                cfg80211_sched_dfs_chan_update(rdev);
-               wdev = rdev->background_radar_wdev;
                break;
        case NL80211_RADAR_CAC_ABORTED:
                if (!cancel_delayed_work(&rdev->background_cac_done_wk))
                        return;
-               wdev = rdev->background_radar_wdev;
                break;
        case NL80211_RADAR_CAC_STARTED:
                break;
@@ -1213,17 +1210,6 @@ __cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
        nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL);
 }
 
-static void
-cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
-                             const struct cfg80211_chan_def *chandef,
-                             enum nl80211_radar_event event)
-{
-       guard(wiphy)(&rdev->wiphy);
-
-       __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev,
-                                       chandef, event);
-}
-
 void cfg80211_background_cac_done_wk(struct work_struct *work)
 {
        struct delayed_work *delayed_work = to_delayed_work(work);
@@ -1231,18 +1217,30 @@ void cfg80211_background_cac_done_wk(struct work_struct *work)
 
        rdev = container_of(delayed_work, struct cfg80211_registered_device,
                            background_cac_done_wk);
-       cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef,
-                                     NL80211_RADAR_CAC_FINISHED);
+
+       guard(wiphy)(&rdev->wiphy);
+
+       rdev_set_radar_background(rdev, NULL);
+       rdev->background_radar_wdev = NULL;
+
+       __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev,
+                                       &rdev->background_radar_chandef,
+                                       NL80211_RADAR_CAC_FINISHED);
 }
 
 void cfg80211_background_cac_abort_wk(struct work_struct *work)
 {
        struct cfg80211_registered_device *rdev;
+       struct wireless_dev *wdev;
 
        rdev = container_of(work, struct cfg80211_registered_device,
                            background_cac_abort_wk);
-       cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef,
-                                     NL80211_RADAR_CAC_ABORTED);
+
+       guard(wiphy)(&rdev->wiphy);
+
+       wdev = rdev->background_radar_wdev;
+       if (wdev)
+               cfg80211_stop_background_radar_detection(wdev);
 }
 
 void cfg80211_background_cac_abort(struct wiphy *wiphy)