Adjust the RSSI and throughput estimate in roaming algorithm

The max transmit power of Standard Power (SP) Access Points (AP) on
6 GHz band and APs on 2.4 GHz and 5 GHz bands is limited by effective
isotropic radiated power (EIRP), while the max transmit power of Low
Power Indoor (LPI) APs on 6 GHz Band is limited by power spectral
density (PSD). Therefore the max transmit power of LPI APs grows as the
channel width increases, similar to the noise power which has constant
PSD.

Adjust the RSSI, SNR and throughput estimate based on max transmit power
config and max channel width in the roaming algorithm.

Signed-off-by: Kaidong Wang <kaidong@chromium.org>
This commit is contained in:
Kaidong Wang 2023-11-08 03:58:06 +00:00 committed by Jouni Malinen
parent 790beb84ac
commit 77386f51ac
2 changed files with 71 additions and 17 deletions

View file

@ -2071,11 +2071,17 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
{
int min_diff, diff;
int to_5ghz, to_6ghz;
int cur_level;
int cur_level, sel_level;
unsigned int cur_est, sel_est;
struct wpa_signal_info si;
int cur_snr = 0;
int ret = 0;
const u8 *cur_ies = wpa_bss_ie_ptr(current_bss);
const u8 *sel_ies = wpa_bss_ie_ptr(selected);
size_t cur_ie_len = current_bss->ie_len ? current_bss->ie_len :
current_bss->beacon_ie_len;
size_t sel_ie_len = selected->ie_len ? selected->ie_len :
selected->beacon_ie_len;
wpa_dbg(wpa_s, MSG_DEBUG, "Considering within-ESS reassociation");
wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR
@ -2096,10 +2102,6 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
return 1;
}
cur_level = current_bss->level;
cur_est = current_bss->est_throughput;
sel_est = selected->est_throughput;
/*
* Try to poll the signal from the driver since this will allow to get
* more accurate values. In some cases, there can be big differences
@ -2117,8 +2119,15 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
*/
if (wpa_drv_signal_poll(wpa_s, &si) == 0 &&
(si.data.avg_beacon_signal || si.data.avg_signal)) {
/*
* Normalize avg_signal to the RSSI over 20 MHz, as the
* throughput is estimated based on the RSSI over 20 MHz
*/
cur_level = si.data.avg_beacon_signal ?
si.data.avg_beacon_signal : si.data.avg_signal;
si.data.avg_beacon_signal :
(si.data.avg_signal -
wpas_channel_width_rssi_bump(cur_ies, cur_ie_len,
si.chanwidth));
cur_snr = wpas_get_snr_signal_info(si.frequency, cur_level,
si.current_noise);
@ -2128,8 +2137,24 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
wpa_dbg(wpa_s, MSG_DEBUG,
"Using signal poll values for the current BSS: level=%d snr=%d est_throughput=%u",
cur_level, cur_snr, cur_est);
} else {
/* Level and SNR are measured over 20 MHz channel */
cur_level = current_bss->level;
cur_snr = current_bss->snr;
cur_est = current_bss->est_throughput;
}
/* Adjust the SNR of BSSes based on the channel width. */
cur_level += wpas_channel_width_rssi_bump(cur_ies, cur_ie_len,
current_bss->max_cw);
cur_snr = wpas_adjust_snr_by_chanwidth(cur_ies, cur_ie_len,
current_bss->max_cw, cur_snr);
sel_est = selected->est_throughput;
sel_level = selected->level +
wpas_channel_width_rssi_bump(sel_ies, sel_ie_len,
selected->max_cw);
if (sel_est > cur_est + 5000) {
wpa_dbg(wpa_s, MSG_DEBUG,
"Allow reassociation - selected BSS has better estimated throughput");
@ -2141,7 +2166,7 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
!is_6ghz_freq(current_bss->freq);
if (cur_level < 0 &&
cur_level > selected->level + to_5ghz * 2 + to_6ghz * 2 &&
cur_level > sel_level + to_5ghz * 2 + to_6ghz * 2 &&
sel_est < cur_est * 1.2) {
wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
"signal level");
@ -2195,7 +2220,7 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
min_diff -= 2;
if (to_6ghz)
min_diff -= 2;
diff = selected->level - cur_level;
diff = sel_level - cur_level;
if (diff < min_diff) {
wpa_dbg(wpa_s, MSG_DEBUG,
"Skip roam - too small difference in signal level (%d < %d)",
@ -2214,7 +2239,7 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
MAC2STR(current_bss->bssid),
current_bss->freq, cur_level, cur_est,
MAC2STR(selected->bssid),
selected->freq, selected->level, sel_est);
selected->freq, sel_level, sel_est);
return ret;
}

View file

@ -2872,6 +2872,12 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
struct hostapd_hw_modes *hw_mode;
unsigned int est, tmp;
const u8 *ie;
/*
* No need to apply a bump to the noise here because the
* minsnr_bitrate_entry tables are based on MCS tables where this has
* been taken into account.
*/
int adjusted_snr;
/* Limit based on estimated SNR */
if (rate > 1 * 2 && snr < 1)
@ -2933,7 +2939,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
if (ie && ie[1] >= 2 &&
(ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
*max_cw = CHAN_WIDTH_40;
tmp = max_ht40_rate(snr, false);
adjusted_snr = snr +
wpas_channel_width_rssi_bump(ies, ies_len,
CHAN_WIDTH_40);
tmp = max_ht40_rate(adjusted_snr, false);
if (tmp > est)
est = tmp;
}
@ -2956,7 +2965,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
(ie[3] &
HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
*max_cw = CHAN_WIDTH_40;
tmp = max_ht40_rate(snr, true) + 1;
adjusted_snr = snr +
wpas_channel_width_rssi_bump(
ies, ies_len, CHAN_WIDTH_40);
tmp = max_ht40_rate(adjusted_snr, true) + 1;
if (tmp > est)
est = tmp;
}
@ -2983,7 +2995,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
if (vht80) {
*max_cw = CHAN_WIDTH_80;
tmp = max_vht80_rate(snr) + 1;
adjusted_snr = snr +
wpas_channel_width_rssi_bump(
ies, ies_len, CHAN_WIDTH_80);
tmp = max_vht80_rate(adjusted_snr) + 1;
if (tmp > est)
est = tmp;
}
@ -2993,7 +3008,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
*max_cw = CHAN_WIDTH_160;
tmp = max_vht160_rate(snr) + 1;
adjusted_snr = snr +
wpas_channel_width_rssi_bump(
ies, ies_len, CHAN_WIDTH_160);
tmp = max_vht160_rate(adjusted_snr) + 1;
if (tmp > est)
est = tmp;
}
@ -3040,7 +3058,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
*max_cw < CHAN_WIDTH_40)
*max_cw = CHAN_WIDTH_40;
tmp = max_he_eht_rate(he40_table, snr, is_eht) + boost;
adjusted_snr = snr + wpas_channel_width_rssi_bump(
ies, ies_len, CHAN_WIDTH_40);
tmp = max_he_eht_rate(he40_table, adjusted_snr,
is_eht) + boost;
if (tmp > est)
est = tmp;
}
@ -3050,7 +3071,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
*max_cw < CHAN_WIDTH_80)
*max_cw = CHAN_WIDTH_80;
tmp = max_he_eht_rate(he80_table, snr, is_eht) + boost;
adjusted_snr = snr + wpas_channel_width_rssi_bump(
ies, ies_len, CHAN_WIDTH_80);
tmp = max_he_eht_rate(he80_table, adjusted_snr,
is_eht) + boost;
if (tmp > est)
est = tmp;
}
@ -3061,7 +3085,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
*max_cw < CHAN_WIDTH_160)
*max_cw = CHAN_WIDTH_160;
tmp = max_he_eht_rate(he160_table, snr, is_eht) + boost;
adjusted_snr = snr + wpas_channel_width_rssi_bump(
ies, ies_len, CHAN_WIDTH_160);
tmp = max_he_eht_rate(he160_table, adjusted_snr,
is_eht) + boost;
if (tmp > est)
est = tmp;
}
@ -3077,7 +3104,9 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
*max_cw < CHAN_WIDTH_320)
*max_cw = CHAN_WIDTH_320;
tmp = max_he_eht_rate(eht320_table, snr, true);
adjusted_snr = snr + wpas_channel_width_rssi_bump(
ies, ies_len, CHAN_WIDTH_320);
tmp = max_he_eht_rate(eht320_table, adjusted_snr, true);
if (tmp > est)
est = tmp;
}