[PATCH 18/18] MLD STA: Add support to indicate per link channel switch

Veerendranath Jakkam quic_vjakkam at quicinc.com
Thu Jul 28 06:45:47 PDT 2022


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 at quicinc.com>
---
 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 c581ecfe5..3602224b6 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -5295,6 +5295,24 @@ enum wpa_event_type {
 	 * EVENT_CCA_NOTIFY - Notification that CCA has completed
 	 */
 	EVENT_CCA_NOTIFY,
+
+	/**
+	 * 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,
 };
 
 
@@ -6010,6 +6028,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;
@@ -6018,6 +6037,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 84e6a9ebd..babf579bb 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -95,6 +95,8 @@ const char * event_to_string(enum wpa_event_type event)
 	E2S(CCA_STARTED_NOTIFY);
 	E2S(CCA_ABORTED_NOTIFY);
 	E2S(CCA_NOTIFY);
+	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 db62d6ed7..221091f3e 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -764,10 +764,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;
@@ -831,7 +831,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);
@@ -3191,6 +3211,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],
@@ -3201,6 +3222,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 a574aa8fc..0db2e8dd8 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5346,6 +5346,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




More information about the Hostap mailing list