Skip to content

Commit 7ef8f68

Browse files
committed
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 <[email protected]> Link: https://msgid.link/20240415112355.4d34b6a31be7.Ie8453979f5805873a8411c99346bcc3810cd6476@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent 2d33ecf commit 7ef8f68

File tree

4 files changed

+403
-92
lines changed

4 files changed

+403
-92
lines changed

net/mac80211/driver-ops.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,9 @@ drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
11501150
if (!check_sdata_in_driver(sdata))
11511151
return -EIO;
11521152

1153+
if (!ieee80211_vif_link_active(&sdata->vif, ch_switch->link_id))
1154+
return 0;
1155+
11531156
trace_drv_pre_channel_switch(local, sdata, ch_switch);
11541157
if (local->ops->pre_channel_switch)
11551158
ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
@@ -1171,6 +1174,9 @@ drv_post_channel_switch(struct ieee80211_link_data *link)
11711174
if (!check_sdata_in_driver(sdata))
11721175
return -EIO;
11731176

1177+
if (!ieee80211_vif_link_active(&sdata->vif, link->link_id))
1178+
return 0;
1179+
11741180
trace_drv_post_channel_switch(local, sdata);
11751181
if (local->ops->post_channel_switch)
11761182
ret = local->ops->post_channel_switch(&local->hw, &sdata->vif,
@@ -1191,6 +1197,9 @@ drv_abort_channel_switch(struct ieee80211_link_data *link)
11911197
if (!check_sdata_in_driver(sdata))
11921198
return;
11931199

1200+
if (!ieee80211_vif_link_active(&sdata->vif, link->link_id))
1201+
return;
1202+
11941203
trace_drv_abort_channel_switch(local, sdata);
11951204

11961205
if (local->ops->abort_channel_switch)
@@ -1210,6 +1219,9 @@ drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata,
12101219
if (!check_sdata_in_driver(sdata))
12111220
return;
12121221

1222+
if (!ieee80211_vif_link_active(&sdata->vif, ch_switch->link_id))
1223+
return;
1224+
12131225
trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch);
12141226
if (local->ops->channel_switch_rx_beacon)
12151227
local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif,

net/mac80211/ieee80211_i.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ struct ieee80211_link_data_managed {
978978
bool csa_waiting_bcn;
979979
bool csa_ignored_same_chan;
980980
bool csa_blocked_tx;
981+
unsigned long csa_time;
981982
struct wiphy_delayed_work chswitch_work;
982983

983984
struct wiphy_work request_smps_work;

net/mac80211/link.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,18 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
357357
ieee80211_teardown_tdls_peers(link);
358358

359359
__ieee80211_link_release_channel(link, true);
360+
361+
/*
362+
* If CSA is (still) active while the link is deactivated,
363+
* just schedule the channel switch work for the time we
364+
* had previously calculated, and we'll take the process
365+
* from there.
366+
*/
367+
if (link->conf->csa_active)
368+
wiphy_delayed_work_queue(local->hw.wiphy,
369+
&link->u.mgd.chswitch_work,
370+
link->u.mgd.csa_time -
371+
jiffies);
360372
}
361373

362374
list_for_each_entry(sta, &local->sta_list, list) {

0 commit comments

Comments
 (0)