diff mbox series

[9/9] wifi: mac80211: abort active CAC while freeing the links during MLO

Message ID 20240619040959.1457547-10-quic_adisi@quicinc.com
State Superseded
Headers show
Series wifi: cfg80211/mac80211: add DFS support for MLO | expand

Commit Message

Aditya Kumar Singh June 19, 2024, 4:09 a.m. UTC
If CAC is started and the interface is brought down, currently, CAC
started on link 0 is aborted in function ieee80211_do_stop(). Technically,
by the time execution reaches the above function, all links are already
teared down and hence link 0 (or deflink) alone is handled. Also, since
links are teared down, information on other links is also not available.
Hence there is a need to handle this in function ieee80211_free_links().

Add changes in ieee80211_free_links() function which cancels any scheduled
dfs_cac_timer_work on the link and if CAC is started, aborts it.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
 net/mac80211/link.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index 8871cc1a0454..6c68887f051c 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -111,10 +111,32 @@  static void ieee80211_tear_down_links(struct ieee80211_sub_if_data *sdata,
 static void ieee80211_free_links(struct ieee80211_sub_if_data *sdata,
 				 struct link_container **links)
 {
+	struct ieee80211_bss_conf *link_conf;
+	struct ieee80211_link_data *link_data;
+	struct cfg80211_chan_def chandef;
 	unsigned int link_id;
 
-	for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
+	for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
+		link_data = &links[link_id]->data;
+		link_conf = &links[link_id]->conf;
+
+		if (!link_data || !link_conf)
+			continue;
+
+		wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
+					  &link_data->dfs_cac_timer_work);
+
+		if (sdata->wdev.links[link_id].cac_started) {
+			chandef = link_conf->chanreq.oper;
+			ieee80211_link_release_channel(link_data);
+			cfg80211_cac_event(sdata->dev,
+					   &chandef,
+					   NL80211_RADAR_CAC_ABORTED,
+					   GFP_KERNEL, link_id);
+		}
+
 		kfree(links[link_id]);
+	}
 }
 
 static int ieee80211_check_dup_link_addrs(struct ieee80211_sub_if_data *sdata)