From: Johannes Berg johannes.berg@intel.com
[ Upstream commit 9f33477b9a31a1edfe2df9f1a0359cccb0e16b4c ]
If an interface is set down or, per the previous patch, changes type, radar detection for it should be cancelled. This is done for AP mode in mac80211 (somewhat needlessly, since cfg80211 can do it, but didn't until now), but wasn't handled for mesh, so if radar detection was started and then the interface set down or its type switched (the latter sometimes happning in the hwsim test 'mesh_peer_connected_dfs'), radar detection would be around with the interface unknown to the driver, later leading to some warnings around chanctx usage.
Link: https://patch.msgid.link/20251121174021.290120e419e3.I2a5650c9062e29c988992d... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
## Summary and Analysis
### What the Bug Fixes This commit fixes a cleanup issue where radar detection (DFS CAC) was not properly stopped when a mesh interface was brought down or changed type. This left residual radar detection state that caused warnings about chanctx (channel context) usage, since the driver thought radar detection was still active for an interface that no longer existed.
### Technical Details The fix: 1. Adds a new `cfg80211_stop_radar_detection()` function in `mlme.c` that iterates through all valid links, ends CAC via `rdev_end_cac()`, and sends `NL80211_RADAR_CAC_ABORTED` notification 2. Calls this new function in `cfg80211_leave()` (the cleanup path when interfaces go down)
### Critical Dependencies The code uses **per-link DFS infrastructure** that was introduced in: - **Commit 62c16f219a73c** ("wifi: cfg80211: move DFS related members to links[] in wireless_dev") - September 2024, **first in v6.12**
This commit accesses `wdev->links[link_id].cac_started` - this structure only exists in 6.12+. In older kernels (6.11 and earlier), `cac_started` was a simple top-level member of `wireless_dev`, not per-link.
### Stable Backport Assessment
**Against backporting:** 1. **No `Cc: stable@vger.kernel.org`** - The maintainer (Johannes Berg) did not request stable backporting 2. **No `Fixes:` tag** - No specific commit is identified as introducing the bug 3. **Dependencies on recent code** - The per-link DFS infrastructure only exists in kernel 6.12+ 4. **Cannot apply to LTS trees** - Would require substantial rework for 6.6.y, 6.1.y, 5.15.y, etc. 5. **Not critical severity** - The bug causes kernel warnings, not crashes, security issues, or data corruption 6. **Niche use case** - Mesh networking combined with DFS channels is relatively uncommon 7. **Very new feature** - The affected MLO/per-link DFS code is only one release old
**Supporting backporting:** - Does fix a real bug that causes warnings - Small, localized change (~25 lines) - From a known/trusted maintainer
### Conclusion
This commit fixes a legitimate bug but does **not** meet stable kernel criteria: - The maintainer did not request stable backporting - The affected code only exists in kernel 6.12+, making it only relevant to the most recent stable branch if any - The bug severity (warnings, not crashes/corruption/security) does not warrant the backporting effort - It cannot be cleanly applied to most stable trees due to structural code differences
**NO**
net/wireless/core.c | 1 + net/wireless/core.h | 1 + net/wireless/mlme.c | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+)
diff --git a/net/wireless/core.c b/net/wireless/core.c index 54a34d8d356e0..5e5c1bc380a89 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1365,6 +1365,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
cfg80211_pmsr_wdev_down(wdev);
+ cfg80211_stop_radar_detection(wdev); cfg80211_stop_background_radar_detection(wdev);
switch (wdev->iftype) { diff --git a/net/wireless/core.h b/net/wireless/core.h index b6bd7f4d6385a..d5d78752227af 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -489,6 +489,7 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde struct wireless_dev *wdev, struct cfg80211_chan_def *chandef);
+void cfg80211_stop_radar_detection(struct wireless_dev *wdev); void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev);
void cfg80211_background_cac_done_wk(struct work_struct *work); diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 46394eb2086f6..3fc175f9f8686 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -1295,6 +1295,25 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde return 0; }
+void cfg80211_stop_radar_detection(struct wireless_dev *wdev) +{ + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + int link_id; + + for_each_valid_link(wdev, link_id) { + struct cfg80211_chan_def chandef; + + if (!wdev->links[link_id].cac_started) + continue; + + chandef = *wdev_chandef(wdev, link_id); + rdev_end_cac(rdev, wdev->netdev, link_id); + nl80211_radar_notify(rdev, &chandef, NL80211_RADAR_CAC_ABORTED, + wdev->netdev, GFP_KERNEL); + } +} + void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) { struct wiphy *wiphy = wdev->wiphy;