From: Vamsi Krishna Date: Tue, 4 May 2021 19:15:30 +0000 (+0530) Subject: Check local supported features for estimating BSS throughputs accurately X-Git-Tag: hostap_2_10~284 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d2118b5095e061b11dd5f08111bde17829f165a;p=thirdparty%2Fhostap.git Check local supported features for estimating BSS throughputs accurately Add checks for features supported by the specific hardware mode of the local device that has the channel for which the throughput is being estimated instead of assuming the local device supports all optional features. This is more accurate for cases where the local capabilities might differ based on the band. In addition, this is in preparation for extending rate estimates to cover optional VHT and HE features. Signed-off-by: Jouni Malinen --- 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);