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:
parent
790beb84ac
commit
77386f51ac
2 changed files with 71 additions and 17 deletions
|
@ -2071,11 +2071,17 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
int min_diff, diff;
|
int min_diff, diff;
|
||||||
int to_5ghz, to_6ghz;
|
int to_5ghz, to_6ghz;
|
||||||
int cur_level;
|
int cur_level, sel_level;
|
||||||
unsigned int cur_est, sel_est;
|
unsigned int cur_est, sel_est;
|
||||||
struct wpa_signal_info si;
|
struct wpa_signal_info si;
|
||||||
int cur_snr = 0;
|
int cur_snr = 0;
|
||||||
int ret = 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, "Considering within-ESS reassociation");
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR
|
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;
|
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
|
* 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
|
* 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 &&
|
if (wpa_drv_signal_poll(wpa_s, &si) == 0 &&
|
||||||
(si.data.avg_beacon_signal || si.data.avg_signal)) {
|
(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 ?
|
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,
|
cur_snr = wpas_get_snr_signal_info(si.frequency, cur_level,
|
||||||
si.current_noise);
|
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,
|
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||||
"Using signal poll values for the current BSS: level=%d snr=%d est_throughput=%u",
|
"Using signal poll values for the current BSS: level=%d snr=%d est_throughput=%u",
|
||||||
cur_level, cur_snr, cur_est);
|
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) {
|
if (sel_est > cur_est + 5000) {
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||||
"Allow reassociation - selected BSS has better estimated throughput");
|
"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);
|
!is_6ghz_freq(current_bss->freq);
|
||||||
|
|
||||||
if (cur_level < 0 &&
|
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) {
|
sel_est < cur_est * 1.2) {
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
|
wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
|
||||||
"signal level");
|
"signal level");
|
||||||
|
@ -2195,7 +2220,7 @@ int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s,
|
||||||
min_diff -= 2;
|
min_diff -= 2;
|
||||||
if (to_6ghz)
|
if (to_6ghz)
|
||||||
min_diff -= 2;
|
min_diff -= 2;
|
||||||
diff = selected->level - cur_level;
|
diff = sel_level - cur_level;
|
||||||
if (diff < min_diff) {
|
if (diff < min_diff) {
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||||
"Skip roam - too small difference in signal level (%d < %d)",
|
"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),
|
MAC2STR(current_bss->bssid),
|
||||||
current_bss->freq, cur_level, cur_est,
|
current_bss->freq, cur_level, cur_est,
|
||||||
MAC2STR(selected->bssid),
|
MAC2STR(selected->bssid),
|
||||||
selected->freq, selected->level, sel_est);
|
selected->freq, sel_level, sel_est);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2872,6 +2872,12 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
struct hostapd_hw_modes *hw_mode;
|
struct hostapd_hw_modes *hw_mode;
|
||||||
unsigned int est, tmp;
|
unsigned int est, tmp;
|
||||||
const u8 *ie;
|
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 */
|
/* Limit based on estimated SNR */
|
||||||
if (rate > 1 * 2 && snr < 1)
|
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 &&
|
if (ie && ie[1] >= 2 &&
|
||||||
(ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
|
(ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
|
||||||
*max_cw = CHAN_WIDTH_40;
|
*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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
@ -2956,7 +2965,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
(ie[3] &
|
(ie[3] &
|
||||||
HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
|
HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) {
|
||||||
*max_cw = CHAN_WIDTH_40;
|
*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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
@ -2983,7 +2995,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
if (vht80) {
|
if (vht80) {
|
||||||
*max_cw = CHAN_WIDTH_80;
|
*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)
|
if (tmp > est)
|
||||||
est = tmp;
|
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_160MHZ |
|
||||||
VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
|
VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
|
||||||
*max_cw = CHAN_WIDTH_160;
|
*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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
@ -3040,7 +3058,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
|
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
|
||||||
*max_cw < CHAN_WIDTH_40)
|
*max_cw < CHAN_WIDTH_40)
|
||||||
*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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
@ -3050,7 +3071,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
|
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
|
||||||
*max_cw < CHAN_WIDTH_80)
|
*max_cw < CHAN_WIDTH_80)
|
||||||
*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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
@ -3061,7 +3085,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
|
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
|
||||||
*max_cw < CHAN_WIDTH_160)
|
*max_cw < CHAN_WIDTH_160)
|
||||||
*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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
@ -3077,7 +3104,9 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
|
if (*max_cw == CHAN_WIDTH_UNKNOWN ||
|
||||||
*max_cw < CHAN_WIDTH_320)
|
*max_cw < CHAN_WIDTH_320)
|
||||||
*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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue