[PATCH v2 2/2] Adjust the RSSI and throughput estimate in roaming algorithm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxx>
---
 wpa_supplicant/events.c | 44 +++++++++++++++++++++++++++++++---------
 wpa_supplicant/scan.c   | 45 +++++++++++++++++++++++++++++++++--------
 2 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 273f73d41..6ec57a558 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2105,12 +2105,19 @@ 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
 		" freq=%d level=%d snr=%d est_throughput=%u",
@@ -2130,10 +2137,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
@@ -2151,8 +2154,14 @@ 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);
 
@@ -2162,7 +2171,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,
@@ -2175,7 +2201,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");
@@ -2229,7 +2255,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)",
@@ -2248,7 +2274,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;
 }
 
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 9b8d1111c..124792f4a 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -2851,6 +2851,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)
@@ -2912,7 +2918,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;
 		}
@@ -2934,7 +2943,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;
 			}
@@ -2961,7 +2973,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;
 			}
@@ -2971,7 +2986,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;
 			}
@@ -3018,7 +3036,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 			    *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;
 		}
@@ -3029,7 +3050,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 			    *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;
 		}
@@ -3041,7 +3065,10 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 			    *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;
 		}
@@ -3058,7 +3085,9 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 			    *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;
 		}
-- 
2.42.0.869.gea05f2083d-goog


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux