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@xxxxxxxxxxx> --- net/mac80211/link.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) 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) -- 2.34.1