wifi: mac80211: mlme: handle cross-link CSA

If we see a channel switch announcement on one link for
another, handle that case and start the CSA. The driver
can react to this in whatever way it needs. The stack
will have the ability to track it via the RNR/MLE in the
reporting link's beacon if it sees it for inactive links
and adjust everything accordingly.

Note that currently the timings for the CSA aren't set,
the values are only used by the Intel drivers, and they
don't need this for newer devices that support MLO, so
I've left it out for now.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240415112355.4d34b6a31be7.Ie8453979f5805873a8411c99346bcc3810cd6476@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Johannes Berg
2024-05-23 11:28:49 +02:00
parent 2d33ecf5d0
commit 7ef8f6821d
4 changed files with 403 additions and 92 deletions
+12
View File
@@ -1150,6 +1150,9 @@ drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
if (!check_sdata_in_driver(sdata))
return -EIO;
if (!ieee80211_vif_link_active(&sdata->vif, ch_switch->link_id))
return 0;
trace_drv_pre_channel_switch(local, sdata, ch_switch);
if (local->ops->pre_channel_switch)
ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
@@ -1171,6 +1174,9 @@ drv_post_channel_switch(struct ieee80211_link_data *link)
if (!check_sdata_in_driver(sdata))
return -EIO;
if (!ieee80211_vif_link_active(&sdata->vif, link->link_id))
return 0;
trace_drv_post_channel_switch(local, sdata);
if (local->ops->post_channel_switch)
ret = local->ops->post_channel_switch(&local->hw, &sdata->vif,
@@ -1191,6 +1197,9 @@ drv_abort_channel_switch(struct ieee80211_link_data *link)
if (!check_sdata_in_driver(sdata))
return;
if (!ieee80211_vif_link_active(&sdata->vif, link->link_id))
return;
trace_drv_abort_channel_switch(local, sdata);
if (local->ops->abort_channel_switch)
@@ -1210,6 +1219,9 @@ drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata,
if (!check_sdata_in_driver(sdata))
return;
if (!ieee80211_vif_link_active(&sdata->vif, ch_switch->link_id))
return;
trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch);
if (local->ops->channel_switch_rx_beacon)
local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif,
+1
View File
@@ -978,6 +978,7 @@ struct ieee80211_link_data_managed {
bool csa_waiting_bcn;
bool csa_ignored_same_chan;
bool csa_blocked_tx;
unsigned long csa_time;
struct wiphy_delayed_work chswitch_work;
struct wiphy_work request_smps_work;
+12
View File
@@ -357,6 +357,18 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
ieee80211_teardown_tdls_peers(link);
__ieee80211_link_release_channel(link, true);
/*
* If CSA is (still) active while the link is deactivated,
* just schedule the channel switch work for the time we
* had previously calculated, and we'll take the process
* from there.
*/
if (link->conf->csa_active)
wiphy_delayed_work_queue(local->hw.wiphy,
&link->u.mgd.chswitch_work,
link->u.mgd.csa_time -
jiffies);
}
list_for_each_entry(sta, &local->sta_list, list) {
+378 -92
View File
File diff suppressed because it is too large Load Diff