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 --- net/wireless/mlme.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 3fc175f9f868..212178d04efa 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -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) -- 2.43.0