diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index b3c07f926..b511d1cc1 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1853,7 +1853,7 @@ wpas_get_est_throughput_from_bss_snr(const struct wpa_supplicant *wpa_s, const u8 *ies = wpa_bss_ie_ptr(bss); size_t ie_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len; - return wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr); + return wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr, bss->freq); } diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index c53474dae..63e59fe87 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -2322,9 +2322,9 @@ static unsigned int max_vht80_rate(int snr) unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s, const u8 *ies, size_t ies_len, int rate, - int snr) + int snr, int freq) { - enum local_hw_capab capab = wpa_s->hw_capab; + struct hostapd_hw_modes *hw_mode; unsigned int est, tmp; const u8 *ie; @@ -2369,7 +2369,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s, rate = 54 * 2; est = rate * 500; - if (capab == CAPAB_HT || capab == CAPAB_HT40 || capab == CAPAB_VHT) { + hw_mode = get_mode_with_freq(wpa_s->hw.modes, wpa_s->hw.num_modes, + freq); + + if (hw_mode && hw_mode->ht_capab) { ie = get_ie(ies, ies_len, WLAN_EID_HT_CAP); if (ie) { tmp = max_ht20_rate(snr, false); @@ -2378,7 +2381,8 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s, } } - if (capab == CAPAB_HT40 || capab == CAPAB_VHT) { + if (hw_mode && + (hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) { ie = get_ie(ies, ies_len, WLAN_EID_HT_OPERATION); if (ie && ie[1] >= 2 && (ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) { @@ -2388,7 +2392,7 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s, } } - if (capab == CAPAB_VHT) { + if (hw_mode && hw_mode->vht_capab) { /* Use +1 to assume VHT is always faster than HT */ ie = get_ie(ies, ies_len, WLAN_EID_VHT_CAP); if (ie) { @@ -2436,7 +2440,7 @@ void scan_est_throughput(struct wpa_supplicant *wpa_s, if (!ie_len) ie_len = res->beacon_ie_len; res->est_throughput = - wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr); + wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr, res->freq); /* TODO: channel utilization and AP load (e.g., from AP Beacon) */ } diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h index 8eb5c73e2..36ca6371a 100644 --- a/wpa_supplicant/scan.h +++ b/wpa_supplicant/scan.h @@ -84,7 +84,7 @@ void scan_est_throughput(struct wpa_supplicant *wpa_s, struct wpa_scan_res *res); unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s, const u8 *ies, size_t ies_len, int rate, - int snr); + int snr, int freq); void wpa_supplicant_set_default_scan_ies(struct wpa_supplicant *wpa_s); int wpa_add_scan_freqs_list(struct wpa_supplicant *wpa_s, enum hostapd_hw_mode band, diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 835b33575..aed576c0b 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -8111,6 +8111,22 @@ struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, } +struct hostapd_hw_modes * get_mode_with_freq(struct hostapd_hw_modes *modes, + u16 num_modes, int freq) +{ + int i, j; + + for (i = 0; i < num_modes; i++) { + for (j = 0; j < modes[i].num_channels; j++) { + if (freq == modes[i].channels[j].freq) + return &modes[i]; + } + } + + return NULL; +} + + static struct wpa_bss_tmp_disallowed * wpas_get_disallowed_bss(struct wpa_supplicant *wpa_s, const u8 *bssid) diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 49007cfc2..6877f5a99 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1701,6 +1701,8 @@ int wpas_sched_scan_plans_set(struct wpa_supplicant *wpa_s, const char *cmd); struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, u16 num_modes, enum hostapd_hw_mode mode, bool is_6ghz); +struct hostapd_hw_modes * get_mode_with_freq(struct hostapd_hw_modes *modes, + u16 num_modes, int freq); void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid, unsigned int sec, int rssi_threshold);