Commit d74380ee authored by Aditya Kumar Singh's avatar Aditya Kumar Singh Committed by Johannes Berg
Browse files

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: default avatarAditya Kumar Singh <quic_adisi@quicinc.com>
Link: https://patch.msgid.link/20240906064426.2101315-7-quic_adisi@quicinc.com


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 81f67d60
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -3467,6 +3467,7 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
	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);
@@ -3474,16 +3475,20 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
	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;
@@ -3494,16 +3499,21 @@ static void ieee80211_end_cac(struct wiphy *wiphy,
{
	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;
		}
	}
}
+10 −0
Original line number Diff line number Diff line
@@ -77,6 +77,16 @@ void ieee80211_link_stop(struct ieee80211_link_data *link)
			  &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);
}

+19 −9
Original line number Diff line number Diff line
@@ -3471,20 +3471,30 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
{
	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) {
		for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS;
		     link_id++) {
			link = sdata_dereference(sdata->link[link_id],
						 sdata);
			if (!link)
				continue;

			wiphy_delayed_work_cancel(local->hw.wiphy,
					  &sdata->deflink.dfs_cac_timer_work);
						  &link->dfs_cac_timer_work);

			if (!sdata->wdev.links[link_id].cac_started)
				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,
			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);
		}
	}
}