[PATCH 5/6] wpa_supplicant: derive freq_khz from freq_offset

James Ewing james at teledatics.com
Wed Oct 1 09:50:00 PDT 2025


---
 wpa_supplicant/bss.c              |  1 +
 wpa_supplicant/bss.h              |  2 ++
 wpa_supplicant/ctrl_iface.c       | 17 ++++++++++++++++
 wpa_supplicant/scan.c             | 32 +++++++++++++++++++------------
 wpa_supplicant/wpa_supplicant.c   |  3 +++
 wpa_supplicant/wpa_supplicant_i.h |  1 +
 6 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index 58adaf744..880db7606 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -384,6 +384,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_offset = src->freq_offset;
 	dst->max_cw = src->max_cw;
 	dst->beacon_int = src->beacon_int;
 	dst->caps = src->caps;
diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h
index 74ef3c858..c44e7fb1f 100644
--- a/wpa_supplicant/bss.h
+++ b/wpa_supplicant/bss.h
@@ -93,6 +93,8 @@ struct wpa_bss {
 	size_t ssid_len;
 	/** Frequency of the channel in MHz (e.g., 2412 = channel 1) */
 	int freq;
+	/** Frequency offset in kHz relative to @freq */
+	unsigned int freq_offset;
 	/** The max channel width supported by both the AP and the STA */
 	enum chan_width max_cw;
 	/** Beacon interval in TUs (host byte order) */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index ebcc5d7ee..5a547e924 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5383,10 +5383,27 @@ static int print_bss_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
 	}
 
 	if (mask & WPA_BSS_MASK_FREQ) {
+		unsigned int freq_khz =
+			mhz_to_khz_with_offset(bss->freq, bss->freq_offset);
+
 		ret = os_snprintf(pos, end - pos, "freq=%d\n", bss->freq);
 		if (os_snprintf_error(end - pos, ret))
 			return 0;
 		pos += ret;
+		if (freq_khz) {
+			ret = os_snprintf(pos, end - pos, "freq_khz=%u\n",
+					  freq_khz);
+			if (os_snprintf_error(end - pos, ret))
+				return 0;
+			pos += ret;
+		}
+		if (bss->freq_offset) {
+			ret = os_snprintf(pos, end - pos, "freq_offset=%u\n",
+					  bss->freq_offset);
+			if (os_snprintf_error(end - pos, ret))
+				return 0;
+			pos += ret;
+		}
 	}
 
 	if (mask & WPA_BSS_MASK_BEACON_INT) {
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index a4824678d..d1132163c 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -3303,9 +3303,11 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 		     (IS_2P4GHZ(freq) ?
 		      HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G :
 		      HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) && ht40) {
-			if (*max_cw == CHAN_WIDTH_UNKNOWN ||
-			    *max_cw < CHAN_WIDTH_40)
-				*max_cw = CHAN_WIDTH_40;
+		if (*max_cw == CHAN_WIDTH_UNKNOWN ||
+		    channel_width_to_int(*max_cw) <
+		    channel_width_to_int(CHAN_WIDTH_40)) {
+			*max_cw = CHAN_WIDTH_40;
+		}
 			adjusted_snr = snr + wpas_channel_width_rssi_bump(
 				ies, ies_len, CHAN_WIDTH_40);
 			tmp = max_he_eht_rate(he40_table, adjusted_snr,
@@ -3317,9 +3319,11 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 		if (!IS_2P4GHZ(freq) &&
 		    (cw & HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G) &&
 		    (!IS_5GHZ(freq) || vht80)) {
-			if (*max_cw == CHAN_WIDTH_UNKNOWN ||
-			    *max_cw < CHAN_WIDTH_80)
-				*max_cw = CHAN_WIDTH_80;
+		if (*max_cw == CHAN_WIDTH_UNKNOWN ||
+		    channel_width_to_int(*max_cw) <
+		    channel_width_to_int(CHAN_WIDTH_80)) {
+			*max_cw = CHAN_WIDTH_80;
+		}
 			adjusted_snr = snr + wpas_channel_width_rssi_bump(
 				ies, ies_len, CHAN_WIDTH_80);
 
@@ -3341,9 +3345,11 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 		    (cw & (HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
 			   HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G)) &&
 		    (!IS_5GHZ(freq) || vht160)) {
-			if (*max_cw == CHAN_WIDTH_UNKNOWN ||
-			    *max_cw < CHAN_WIDTH_160)
-				*max_cw = CHAN_WIDTH_160;
+		if (*max_cw == CHAN_WIDTH_UNKNOWN ||
+		    channel_width_to_int(*max_cw) <
+		    channel_width_to_int(CHAN_WIDTH_160)) {
+			*max_cw = CHAN_WIDTH_160;
+		}
 			adjusted_snr = snr + wpas_channel_width_rssi_bump(
 				ies, ies_len, CHAN_WIDTH_160);
 
@@ -3368,9 +3374,11 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 		if (is_6ghz_freq(freq) &&
 		    (eht->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] &
 		     EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK)) {
-			if (*max_cw == CHAN_WIDTH_UNKNOWN ||
-			    *max_cw < CHAN_WIDTH_320)
-				*max_cw = CHAN_WIDTH_320;
+		if (*max_cw == CHAN_WIDTH_UNKNOWN ||
+		    channel_width_to_int(*max_cw) <
+		    channel_width_to_int(CHAN_WIDTH_320)) {
+			*max_cw = CHAN_WIDTH_320;
+		}
 			adjusted_snr = snr + wpas_channel_width_rssi_bump(
 				ies, ies_len, CHAN_WIDTH_320);
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index d45002fd9..b33a9eb35 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3469,6 +3469,7 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
 	bool is_6ghz, is_24ghz;
 
 	freq->freq = ssid->frequency;
+	freq->freq_offset = 0;
 
 	if (ssid->mode == WPAS_MODE_IBSS && !ssid->fixed_freq) {
 		struct wpa_bss *bss = ibss_find_existing_bss(wpa_s, ssid);
@@ -3478,6 +3479,7 @@ void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
 				   "IBSS already found in scan results, adjust control freq: %d",
 				   bss->freq);
 			freq->freq = bss->freq;
+			freq->freq_offset = bss->freq_offset;
 			obss_scan = 0;
 		}
 	}
@@ -4640,6 +4642,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_offset = bss->freq_offset;
 		}
 		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 e7675a4ab..802e03140 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1003,6 +1003,7 @@ struct wpa_supplicant {
 		u8 ssid[SSID_MAX_LEN];
 		size_t ssid_len;
 		int freq;
+		unsigned int freq_offset;
 		u8 assoc_req_ie[1500];
 		size_t assoc_req_ie_len;
 		int mfp;
-- 
2.43.0




More information about the Hostap mailing list