[PATCH 5/6] S1G: wpa_supplicant support for connection to S1G APs

Bassem Dawood bassem at morsemicro.com
Tue Oct 31 22:34:30 PDT 2023


This commit leverages previous changes that support freq_khz in order
to facilitate STA creating connections to S1G APs.
---
 src/common/privsep_commands.h     |  1 +
 src/drivers/driver.h              |  2 ++
 src/drivers/driver_nl80211.c      | 41 +++++++++++++++++++++++++------
 src/drivers/driver_privsep.c      |  1 +
 wpa_supplicant/ap.c               |  5 +++-
 wpa_supplicant/ap.h               |  4 +--
 wpa_supplicant/bss.c              |  7 ++++--
 wpa_supplicant/bss.h              |  2 ++
 wpa_supplicant/ctrl_iface.c       |  1 +
 wpa_supplicant/events.c           |  4 ++-
 wpa_supplicant/scan.c             |  4 +--
 wpa_supplicant/sme.c              |  9 +++++--
 wpa_supplicant/wpa_priv.c         |  1 +
 wpa_supplicant/wpa_supplicant.c   |  5 +++-
 wpa_supplicant/wpa_supplicant_i.h |  2 ++
 15 files changed, 70 insertions(+), 19 deletions(-)

diff --git a/src/common/privsep_commands.h b/src/common/privsep_commands.h
index d2c4bbd5e..bf996dff4 100644
--- a/src/common/privsep_commands.h
+++ b/src/common/privsep_commands.h
@@ -63,6 +63,7 @@ struct privsep_cmd_associate {
 	size_t ssid_len;
 	int hwmode;
 	int freq;
+	int freq_khz;
 	int channel;
 	int pairwise_suite;
 	int group_suite;
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 707764d70..16dabbac6 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -390,6 +390,7 @@ struct wpa_scan_res {
 	unsigned int flags;
 	u8 bssid[ETH_ALEN];
 	int freq;
+	int freq_offset;
 	u16 beacon_int;
 	u16 caps;
 	int qual;
@@ -718,6 +719,7 @@ struct wpa_driver_scan_params {
  */
 struct wpa_driver_auth_params {
 	int freq;
+	int freq_khz;
 	const u8 *bssid;
 	const u8 *ssid;
 	size_t ssid_len;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 4427cff03..5e7a30c98 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1516,6 +1516,7 @@ static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
 struct nl80211_get_assoc_freq_arg {
 	struct wpa_driver_nl80211_data *drv;
 	unsigned int assoc_freq;
+	unsigned int assoc_freq_offset;
 	unsigned int ibss_freq;
 	u8 assoc_bssid[ETH_ALEN];
 	u8 assoc_ssid[SSID_MAX_LEN];
@@ -1567,8 +1568,12 @@ static int nl80211_get_assoc_freq_handler(struct nl_msg *msg, void *arg)
 		if (!drv->sta_mlo_info.valid_links ||
 		    drv->sta_mlo_info.assoc_link_id == link_id) {
 			ctx->assoc_freq = freq;
-			wpa_printf(MSG_DEBUG, "nl80211: Associated on %u MHz",
-				   ctx->assoc_freq);
+			if (bss[NL80211_BSS_FREQUENCY_OFFSET])
+				ctx->assoc_freq_offset =
+					nla_get_u32(bss[NL80211_BSS_FREQUENCY_OFFSET]);
+
+			wpa_printf(MSG_DEBUG, "nl80211: Associated on %u.%u MHz",
+				   ctx->assoc_freq, ctx->assoc_freq_offset);
 		}
 	}
 	if (status == NL80211_BSS_STATUS_IBSS_JOINED &&
@@ -3953,8 +3958,17 @@ retry:
 		if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, params->bssid))
 			goto fail;
 	}
-	if (params->freq) {
-		wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq);
+	if (params->freq_khz) {
+		wpa_printf(MSG_DEBUG, "  * freq=%d kHz", params->freq_khz);
+		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
+				KHZ_TO_MHZ(params->freq_khz)))
+			goto fail;
+		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
+				KHZ_TO_S1G_OFFSET(params->freq_khz)))
+			goto fail;
+	}
+	else if(params->freq){
+		wpa_printf(MSG_DEBUG, "  * freq=%d MHz", params->freq);
 		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, params->freq))
 			goto fail;
 	}
@@ -5461,9 +5475,9 @@ static int nl80211_set_channel(struct i802_bss *bss,
 	int ret;
 
 	wpa_printf(MSG_DEBUG,
-		   "nl80211: Set freq %d (ht_enabled=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
-		   freq->freq, freq->ht_enabled, freq->vht_enabled,
-		   freq->he_enabled, freq->eht_enabled, freq->bandwidth,
+		   "nl80211: Set freq %d %s(ht_enabled=%d, vht_enabled=%d, he_enabled=%d, eht_enabled=%d, s1g_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)",
+		   freq->freq_khz ? freq->freq_khz : freq->freq, KHZ_PRINT_FREQ_UNITS(freq->freq_khz), freq->ht_enabled, freq->vht_enabled,
+		   freq->he_enabled, freq->eht_enabled, freq->s1g_enabled, freq->bandwidth,
 		   freq->center_freq1, freq->center_freq2);
 
 	msg = nl80211_drv_msg(drv, 0, set_chan ? NL80211_CMD_SET_CHANNEL :
@@ -6751,7 +6765,18 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
 			return -1;
 	}
 
-	if (params->freq.freq && !params->mld_params.mld_addr) {
+	if (params->freq.freq_khz && !params->mld_params.mld_addr) {
+		wpa_printf(MSG_DEBUG, "  * freq=%d.%d",
+			   KHZ_TO_MHZ(params->freq.freq_khz),
+			   KHZ_TO_S1G_OFFSET(params->freq.freq_khz));
+		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
+				KHZ_TO_MHZ(params->freq.freq_khz)))
+			return -1;
+		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
+				KHZ_TO_S1G_OFFSET(params->freq.freq_khz)))
+			return -1;
+		drv->assoc_freq = KHZ_TO_MHZ(params->freq.freq_khz);
+	} else if (params->freq.freq && !params->mld_params.mld_addr) {
 		wpa_printf(MSG_DEBUG, "  * freq=%d", params->freq.freq);
 		if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
 				params->freq.freq))
diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c
index d6735b49c..7eac3910b 100644
--- a/src/drivers/driver_privsep.c
+++ b/src/drivers/driver_privsep.c
@@ -320,6 +320,7 @@ static int wpa_driver_privsep_associate(
 	data->ssid_len = params->ssid_len;
 	data->hwmode = params->freq.mode;
 	data->freq = params->freq.freq;
+	data->freq_khz = params->freq.freq_khz;
 	data->channel = params->freq.channel;
 	data->pairwise_suite = params->pairwise_suite;
 	data->group_suite = params->group_suite;
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 10c2ece9e..2bc6d26eb 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -435,7 +435,9 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
 		{
 			if (iface == wpa_s ||
 			    iface->wpa_state < WPA_AUTHENTICATING ||
-			    (int) iface->assoc_freq != ssid->frequency)
+			    (int) iface->assoc_freq_khz != ssid->frequency_khz ||
+			    (ssid->frequency_khz == 0 &&
+			     (int) iface->assoc_freq != ssid->frequency))
 				continue;
 
 			/*
@@ -1143,6 +1145,7 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
 	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
 	os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
 	wpa_s->assoc_freq = ssid->frequency;
+	wpa_s->assoc_freq_khz = ssid->frequency_khz;
 	wpa_s->ap_iface->conf->enable_edmg = ssid->enable_edmg;
 	wpa_s->ap_iface->conf->edmg_channel = ssid->edmg_channel;
 
diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h
index 5835ecd87..612999fe8 100644
--- a/wpa_supplicant/ap.h
+++ b/wpa_supplicant/ap.h
@@ -72,8 +72,8 @@ void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s);
 int ap_switch_channel(struct wpa_supplicant *wpa_s,
 		      struct csa_settings *settings);
 int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *txtaddr);
-void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
-		       int offset, int width, int cf1, int cf2,
+void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int freq_khz,
+		       int ht, int offset, int width, int cf1, int cf2,
 		       u16 punct_bitmap, int finished);
 struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
 					     int ndef);
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 320441426..291a040d3 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -286,6 +286,7 @@ static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src,
 	dst->flags = src->flags;
 	os_memcpy(dst->bssid, src->bssid, ETH_ALEN);
 	dst->freq = src->freq;
+	dst->freq_khz = MHZ_TO_KHZ(src->freq) + src->freq_offset;
 	dst->beacon_int = src->beacon_int;
 	dst->caps = src->caps;
 	dst->qual = src->qual;
@@ -512,9 +513,11 @@ static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s,
 	}
 
 	wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Add new id %u BSSID " MACSTR
-		" SSID '%s' freq %d%s",
+		" SSID '%s' freq %d %s%s",
 		bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len),
-		bss->freq, extra);
+		bss->freq_khz ? bss->freq_khz : bss->freq,
+		KHZ_PRINT_FREQ_UNITS(bss->freq_khz),
+		extra);
 	wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
 	return bss;
 }
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index 611da8844..17c3fa9fd 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -96,6 +96,8 @@ struct wpa_bss {
 	size_t ssid_len;
 	/** Frequency of the channel in MHz (e.g., 2412 = channel 1) */
 	int freq;
+	/** Frequency of the channel in kHz */
+	int freq_khz;
 	/** Beacon interval in TUs (host byte order) */
 	u16 beacon_int;
 	/** Capability information field in host byte order */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index b14c78f80..f29d0c74c 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -10298,6 +10298,7 @@ static int wpas_ctrl_resend_assoc(struct wpa_supplicant *wpa_s)
 	params.ssid = wpa_s->sme.ssid;
 	params.ssid_len = wpa_s->sme.ssid_len;
 	params.freq.freq = wpa_s->sme.freq;
+	params.freq.freq_khz = wpa_s->sme.freq_khz;
 	if (wpa_s->last_assoc_req_wpa_ie) {
 		params.wpa_ie = wpabuf_head(wpa_s->last_assoc_req_wpa_ie);
 		params.wpa_ie_len = wpabuf_len(wpa_s->last_assoc_req_wpa_ie);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 2b3ff03c0..ec8d959f0 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -4447,8 +4447,10 @@ static void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data,
 	{
 		struct wpa_bss *bss;
 		bss = wpa_bss_get_bssid(wpa_s, target_ap_addr);
-		if (bss)
+		if (bss) {
 			wpa_s->sme.freq = bss->freq;
+			wpa_s->sme.freq_khz = bss->freq_khz;
+		}
 		wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT;
 		sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr,
 			      WLAN_AUTH_FT);
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index c3984a40c..6bb6afb10 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -2268,7 +2268,7 @@ static void dump_scan_res(struct wpa_scan_results *scan_res)
 				   " ssid=%s freq=%d qual=%d noise=%d%s level=%d snr=%d%s flags=0x%x age=%u est=%u",
 				   MAC2STR(r->bssid),
 				   wpa_ssid_txt(ssid, ssid_len),
-				   r->freq, r->qual,
+				   r->freq, r->freq_offset, r->qual,
 				   r->noise, noise_valid ? "" : "~", r->level,
 				   r->snr, r->snr >= GREAT_SNR ? "*" : "",
 				   r->flags,
@@ -2278,7 +2278,7 @@ static void dump_scan_res(struct wpa_scan_results *scan_res)
 				   " ssid=%s freq=%d qual=%d noise=%d level=%d flags=0x%x age=%u est=%u",
 				   MAC2STR(r->bssid),
 				   wpa_ssid_txt(ssid, ssid_len),
-				   r->freq, r->qual,
+				   r->freq, r->freq_offset, r->qual,
 				   r->noise, r->level, r->flags, r->age,
 				   r->est_throughput);
 		}
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index bb04652f5..292f2fae7 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -629,6 +629,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
 	wpa_s->reassociate = 0;
 
 	params.freq = bss->freq;
+	params.freq_khz = bss->freq_khz;
 	params.bssid = bss->bssid;
 	params.ssid = bss->ssid;
 	params.ssid_len = bss->ssid_len;
@@ -646,6 +647,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s,
 		wpa_s->sme.prev_bssid_set = 0;
 
 	wpa_s->sme.freq = params.freq;
+	wpa_s->sme.freq_khz = params.freq_khz;
 	os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len);
 	wpa_s->sme.ssid_len = params.ssid_len;
 
@@ -1164,8 +1166,10 @@ no_fils:
 	wpa_supplicant_cancel_scan(wpa_s);
 
 	wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR
-		" (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
-		wpa_ssid_txt(params.ssid, params.ssid_len), params.freq);
+		" (SSID='%s' freq=%d %s)", MAC2STR(params.bssid),
+		wpa_ssid_txt(params.ssid, params.ssid_len),
+		params.freq_khz ? params.freq_khz : params.freq,
+		params.freq_khz ? "kHz" : "MHz");
 
 	eapol_sm_notify_portValid(wpa_s->eapol, false);
 	wpa_clear_keys(wpa_s, bss->bssid);
@@ -2442,6 +2446,7 @@ mscs_fail:
 	params.ssid = wpa_s->sme.ssid;
 	params.ssid_len = wpa_s->sme.ssid_len;
 	params.freq.freq = wpa_s->sme.freq;
+	params.freq.freq_khz = wpa_s->sme.freq_khz;
 	params.bg_scan_period = ssid ? ssid->bg_scan_period : -1;
 	params.wpa_ie = wpa_s->sme.assoc_req_ie_len ?
 		wpa_s->sme.assoc_req_ie : NULL;
diff --git a/wpa_supplicant/wpa_priv.c b/wpa_supplicant/wpa_priv.c
index 31a9af650..402b64e38 100644
--- a/wpa_supplicant/wpa_priv.c
+++ b/wpa_supplicant/wpa_priv.c
@@ -322,6 +322,7 @@ static void wpa_priv_cmd_associate(struct wpa_priv_interface *iface,
 	params.ssid_len = assoc->ssid_len;
 	params.freq.mode = assoc->hwmode;
 	params.freq.freq = assoc->freq;
+	params.freq.freq_khz = assoc->freq_khz;
 	params.freq.channel = assoc->channel;
 	if (assoc->wpa_ie_len) {
 		params.wpa_ie = (u8 *) (assoc + 1);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index e2c78926a..a60449170 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2529,8 +2529,10 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 				"Driver does not support mesh mode");
 			return;
 		}
-		if (bss)
+		if (bss) {
 			ssid->frequency = bss->freq;
+			ssid->frequency_khz = bss->freq_khz;
+		}
 		if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
 			wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
 			wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
@@ -4135,6 +4137,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
 				   wpa_s->key_mgmt == WPA_KEY_MGMT_WPS);
 			params.bssid = bss->bssid;
 			params.freq.freq = bss->freq;
+                        params.freq.freq_khz = bss->freq_khz;
 		}
 		params.bssid_hint = bss->bssid;
 		params.freq_hint = bss->freq;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index c44413e4e..b50521480 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -729,6 +729,7 @@ struct wpa_supplicant {
 		unsigned int freq;
 		struct wpa_bss *bss;
 	} links[MAX_NUM_MLD_LINKS];
+        unsigned int assoc_freq_khz;
 	u8 *last_con_fail_realm;
 	size_t last_con_fail_realm_len;
 
@@ -979,6 +980,7 @@ struct wpa_supplicant {
 		u8 ssid[SSID_MAX_LEN];
 		size_t ssid_len;
 		int freq;
+                int freq_khz;
 		u8 assoc_req_ie[1500];
 		size_t assoc_req_ie_len;
 		int mfp;
-- 
2.25.1




More information about the Hostap mailing list