135 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
 | 
						|
Date: Fri, 6 Sep 2024 12:14:24 +0530
 | 
						|
Subject: [PATCH] wifi: mac80211: handle DFS per link
 | 
						|
 | 
						|
In order to support DFS with MLO, handle the link ID now passed from
 | 
						|
cfg80211, adjust the code to do everything per link and call the
 | 
						|
notifications to cfg80211 correctly.
 | 
						|
 | 
						|
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
 | 
						|
Link: https://patch.msgid.link/20240906064426.2101315-7-quic_adisi@quicinc.com
 | 
						|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 | 
						|
---
 | 
						|
 | 
						|
--- a/net/mac80211/cfg.c
 | 
						|
+++ b/net/mac80211/cfg.c
 | 
						|
@@ -3464,6 +3464,7 @@ static int ieee80211_start_radar_detecti
 | 
						|
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 | 
						|
 	struct ieee80211_chan_req chanreq = { .oper = *chandef };
 | 
						|
 	struct ieee80211_local *local = sdata->local;
 | 
						|
+	struct ieee80211_link_data *link_data;
 | 
						|
 	int err;
 | 
						|
 
 | 
						|
 	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						|
@@ -3471,16 +3472,20 @@ static int ieee80211_start_radar_detecti
 | 
						|
 	if (!list_empty(&local->roc_list) || local->scanning)
 | 
						|
 		return -EBUSY;
 | 
						|
 
 | 
						|
+	link_data = sdata_dereference(sdata->link[link_id], sdata);
 | 
						|
+	if (!link_data)
 | 
						|
+		return -ENOLINK;
 | 
						|
+
 | 
						|
 	/* whatever, but channel contexts should not complain about that one */
 | 
						|
-	sdata->deflink.smps_mode = IEEE80211_SMPS_OFF;
 | 
						|
-	sdata->deflink.needed_rx_chains = local->rx_chains;
 | 
						|
+	link_data->smps_mode = IEEE80211_SMPS_OFF;
 | 
						|
+	link_data->needed_rx_chains = local->rx_chains;
 | 
						|
 
 | 
						|
-	err = ieee80211_link_use_channel(&sdata->deflink, &chanreq,
 | 
						|
+	err = ieee80211_link_use_channel(link_data, &chanreq,
 | 
						|
 					 IEEE80211_CHANCTX_SHARED);
 | 
						|
 	if (err)
 | 
						|
 		return err;
 | 
						|
 
 | 
						|
-	wiphy_delayed_work_queue(wiphy, &sdata->deflink.dfs_cac_timer_work,
 | 
						|
+	wiphy_delayed_work_queue(wiphy, &link_data->dfs_cac_timer_work,
 | 
						|
 				 msecs_to_jiffies(cac_time_ms));
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
@@ -3491,16 +3496,21 @@ static void ieee80211_end_cac(struct wip
 | 
						|
 {
 | 
						|
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 | 
						|
 	struct ieee80211_local *local = sdata->local;
 | 
						|
+	struct ieee80211_link_data *link_data;
 | 
						|
 
 | 
						|
 	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						|
 
 | 
						|
 	list_for_each_entry(sdata, &local->interfaces, list) {
 | 
						|
+		link_data = sdata_dereference(sdata->link[link_id], sdata);
 | 
						|
+		if (!link_data)
 | 
						|
+			continue;
 | 
						|
+
 | 
						|
 		wiphy_delayed_work_cancel(wiphy,
 | 
						|
-					  &sdata->deflink.dfs_cac_timer_work);
 | 
						|
+					  &link_data->dfs_cac_timer_work);
 | 
						|
 
 | 
						|
-		if (sdata->wdev.links[0].cac_started) {
 | 
						|
-			ieee80211_link_release_channel(&sdata->deflink);
 | 
						|
-			sdata->wdev.links[0].cac_started = false;
 | 
						|
+		if (sdata->wdev.links[link_id].cac_started) {
 | 
						|
+			ieee80211_link_release_channel(link_data);
 | 
						|
+			sdata->wdev.links[link_id].cac_started = false;
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 }
 | 
						|
--- a/net/mac80211/link.c
 | 
						|
+++ b/net/mac80211/link.c
 | 
						|
@@ -77,6 +77,16 @@ void ieee80211_link_stop(struct ieee8021
 | 
						|
 			  &link->color_change_finalize_work);
 | 
						|
 	wiphy_work_cancel(link->sdata->local->hw.wiphy,
 | 
						|
 			  &link->csa.finalize_work);
 | 
						|
+
 | 
						|
+	if (link->sdata->wdev.links[link->link_id].cac_started) {
 | 
						|
+		wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
 | 
						|
+					  &link->dfs_cac_timer_work);
 | 
						|
+		cfg80211_cac_event(link->sdata->dev,
 | 
						|
+				   &link->conf->chanreq.oper,
 | 
						|
+				   NL80211_RADAR_CAC_ABORTED,
 | 
						|
+				   GFP_KERNEL, link->link_id);
 | 
						|
+	}
 | 
						|
+
 | 
						|
 	ieee80211_link_release_channel(link);
 | 
						|
 }
 | 
						|
 
 | 
						|
--- a/net/mac80211/util.c
 | 
						|
+++ b/net/mac80211/util.c
 | 
						|
@@ -3455,20 +3455,30 @@ void ieee80211_dfs_cac_cancel(struct iee
 | 
						|
 {
 | 
						|
 	struct ieee80211_sub_if_data *sdata;
 | 
						|
 	struct cfg80211_chan_def chandef;
 | 
						|
+	struct ieee80211_link_data *link;
 | 
						|
+	unsigned int link_id;
 | 
						|
 
 | 
						|
 	lockdep_assert_wiphy(local->hw.wiphy);
 | 
						|
 
 | 
						|
 	list_for_each_entry(sdata, &local->interfaces, list) {
 | 
						|
-		wiphy_delayed_work_cancel(local->hw.wiphy,
 | 
						|
-					  &sdata->deflink.dfs_cac_timer_work);
 | 
						|
+		for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
 | 
						|
+		     link_id++) {
 | 
						|
+			link = sdata_dereference(sdata->link[link_id],
 | 
						|
+						 sdata);
 | 
						|
+			if (!link)
 | 
						|
+				continue;
 | 
						|
 
 | 
						|
-		if (sdata->wdev.links[0].cac_started) {
 | 
						|
-			chandef = sdata->vif.bss_conf.chanreq.oper;
 | 
						|
-			ieee80211_link_release_channel(&sdata->deflink);
 | 
						|
-			cfg80211_cac_event(sdata->dev,
 | 
						|
-					   &chandef,
 | 
						|
+			wiphy_delayed_work_cancel(local->hw.wiphy,
 | 
						|
+						  &link->dfs_cac_timer_work);
 | 
						|
+
 | 
						|
+			if (!sdata->wdev.links[link_id].cac_started)
 | 
						|
+				continue;
 | 
						|
+
 | 
						|
+			chandef = link->conf->chanreq.oper;
 | 
						|
+			ieee80211_link_release_channel(link);
 | 
						|
+			cfg80211_cac_event(sdata->dev, &chandef,
 | 
						|
 					   NL80211_RADAR_CAC_ABORTED,
 | 
						|
-					   GFP_KERNEL, 0);
 | 
						|
+					   GFP_KERNEL, link_id);
 | 
						|
 		}
 | 
						|
 	}
 | 
						|
 }
 |