Parse link id info from channel switch events and indicate the info to control interface using new per link channel switch events. If channel switch happens on the link which used during association both legacy and new per-link channel switch events will be reported. Signed-off-by: Veerendranath Jakkam <quic_vjakkam@xxxxxxxxxxx> --- src/common/wpa_ctrl.h | 9 ++++++++ src/drivers/driver.h | 20 ++++++++++++++++++ src/drivers/driver_common.c | 2 ++ src/drivers/driver_nl80211_event.c | 32 +++++++++++++++++++++++----- wpa_supplicant/events.c | 34 ++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index 343508424..ba54da544 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -92,6 +92,15 @@ extern "C" { #define WPA_EVENT_CHANNEL_SWITCH_STARTED "CTRL-EVENT-STARTED-CHANNEL-SWITCH " /** Channel switch (followed by freq=<MHz> and other channel parameters) */ #define WPA_EVENT_CHANNEL_SWITCH "CTRL-EVENT-CHANNEL-SWITCH " +/** MLO link channel switch started (followed by freq=<MHz> and other channel + * parameters) + */ +#define WPA_EVENT_LINK_CHANNEL_SWITCH_STARTED \ + "CTRL-EVENT-STARTED-LINK-CHANNEL-SWITCH " +/** MLO link channel switch (followed by freq=<MHz> and other channel + * parameters) + */ +#define WPA_EVENT_LINK_CHANNEL_SWITCH "CTRL-EVENT-LINK-CHANNEL-SWITCH " /** SAE authentication failed due to unknown password identifier */ #define WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER \ "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER " diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 525c7763d..b182d24cb 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -5428,6 +5428,24 @@ enum wpa_event_type { * PASN authentication and secure ranging context for multiple peers. */ EVENT_PASN_AUTH, + + /** + * EVENT_LINK_CH_SWITCH - MLD AP link decided to switch channels + * + * Described in wpa_event_data.ch_switch + * + */ + EVENT_LINK_CH_SWITCH, + + /** + * EVENT_LINK_CH_SWITCH_STARTED - MLD AP link started to switch channels + * + * This is a pre-switch event indicating the shortly following switch + * of operating channels. + * + * Described in wpa_event_data.ch_switch + */ + EVENT_LINK_CH_SWITCH_STARTED, }; @@ -6143,6 +6161,7 @@ union wpa_event_data { * @ch_width: Channel width * @cf1: Center frequency 1 * @cf2: Center frequency 2 + * @link_id: link ID of the MLO link */ struct ch_switch { int freq; @@ -6151,6 +6170,7 @@ union wpa_event_data { enum chan_width ch_width; int cf1; int cf2; + int link_id; } ch_switch; /** diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c index 93b35a6d3..0ac0aa6de 100644 --- a/src/drivers/driver_common.c +++ b/src/drivers/driver_common.c @@ -96,6 +96,8 @@ const char * event_to_string(enum wpa_event_type event) E2S(CCA_ABORTED_NOTIFY); E2S(CCA_NOTIFY); E2S(PASN_AUTH); + E2S(LINK_CH_SWITCH); + E2S(LINK_CH_SWITCH_STARTED); } return "UNKNOWN"; diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 00ef51413..c4cffe051 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -780,10 +780,10 @@ static int calculate_chan_offset(int width, int freq, int cf1, int cf2) static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, - struct nlattr *ifindex, struct nlattr *freq, - struct nlattr *type, struct nlattr *bw, - struct nlattr *cf1, struct nlattr *cf2, - int finished) + struct nlattr *ifindex, struct nlattr *link, + struct nlattr *freq, struct nlattr *type, + struct nlattr *bw, struct nlattr *cf1, + struct nlattr *cf2, int finished) { struct i802_bss *bss; union wpa_event_data data; @@ -847,7 +847,27 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, if (finished) bss->freq = data.ch_switch.freq; - drv->assoc_freq = data.ch_switch.freq; + + if (link) { + u8 link_id = nla_get_u8(link); + + if (drv->sta_mlo_info.valid_links & BIT(link_id)) { + data.ch_switch.link_id = link_id; + drv->sta_mlo_info.links[link_id].freq = + data.ch_switch.freq; + wpa_supplicant_event(bss->ctx, + finished ? + EVENT_LINK_CH_SWITCH : + EVENT_LINK_CH_SWITCH_STARTED, &data); + } + + if (link_id == drv->mlo_assoc_link_id) + drv->assoc_freq = data.ch_switch.freq; + else + return; + } else { + drv->assoc_freq = data.ch_switch.freq; + } wpa_supplicant_event(bss->ctx, finished ? EVENT_CH_SWITCH : EVENT_CH_SWITCH_STARTED, &data); @@ -3301,6 +3321,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, case NL80211_CMD_CH_SWITCH_STARTED_NOTIFY: mlme_event_ch_switch(drv, tb[NL80211_ATTR_IFINDEX], + tb[NL80211_ATTR_MLO_LINK_ID], tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE], tb[NL80211_ATTR_CHANNEL_WIDTH], @@ -3311,6 +3332,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, case NL80211_CMD_CH_SWITCH_NOTIFY: mlme_event_ch_switch(drv, tb[NL80211_ATTR_IFINDEX], + tb[NL80211_ATTR_MLO_LINK_ID], tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE], tb[NL80211_ATTR_CHANNEL_WIDTH], diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index fc662a770..f94662007 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -5369,6 +5369,40 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, break; #endif /* CONFIG_AP */ + case EVENT_LINK_CH_SWITCH_STARTED: + case EVENT_LINK_CH_SWITCH: + if (!data || !wpa_s->current_ssid || + !(wpa_s->valid_links & BIT(data->ch_switch.link_id))) + break; + + wpa_msg(wpa_s, MSG_INFO, + "%sfreq=%d link_id=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d", + event == EVENT_LINK_CH_SWITCH ? + WPA_EVENT_LINK_CHANNEL_SWITCH : + WPA_EVENT_LINK_CHANNEL_SWITCH_STARTED, + data->ch_switch.freq, + data->ch_switch.link_id, + data->ch_switch.ht_enabled, + data->ch_switch.ch_offset, + channel_width_to_string(data->ch_switch.ch_width), + data->ch_switch.cf1, + data->ch_switch.cf2); + if (event == EVENT_LINK_CH_SWITCH_STARTED) + break; + + wpa_s->links[data->ch_switch.link_id].freq = + data->ch_switch.freq; + if (wpa_s->links[data->ch_switch.link_id].bss && + wpa_s->links[data->ch_switch.link_id].bss->freq != + data->ch_switch.freq) { + wpa_s->links[data->ch_switch.link_id].bss->freq = + data->ch_switch.freq; + notify_bss_changes( + wpa_s, WPA_BSS_FREQ_CHANGED_FLAG, + wpa_s->links[data->ch_switch.link_id].bss); + } + + break; case EVENT_CH_SWITCH_STARTED: case EVENT_CH_SWITCH: if (!data || !wpa_s->current_ssid) -- 2.25.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap