[PATCH 1/2] wpa_supplicant: Support throughput estimation for EHT rates

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Nov 30 07:02:46 PST 2022


From: Ayala Beker <ayala.beker at intel.com>

Add support to consider EHT rates while calculating the estimated
throughput for scan results.

- The estimated EHT throughput uses the HE 0.8 usec GI rates from the
  relevant EHT-MCS tables from section 36.5 in Draft P802.11be_D2.0.
- The minimum SNR values for EHT rates (4096-QAM) are derived by adding
  the existing minimum SNR values of 1024-QAM rates from HE tables and
  the difference between the values of minimum sensitivity levels of
  1024-QAM rates and 4096-QAM rates defined in Table 36-67 (Receiver
  minimum input level sensitivity) in IEEE P802.11be_D2.0.

Signed-off-by: Ayala Beker <ayala.beker at intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/common/ieee802_11_defs.h |  2 +
 wpa_supplicant/scan.c        | 83 ++++++++++++++++++++++++++++++------
 2 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 310b7660e2..669f380d2f 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -2515,6 +2515,8 @@ struct ieee80211_eht_capabilities {
 	u8 optional[EHT_MCS_NSS_CAPAB_LEN + EHT_PPE_THRESH_CAPAB_LEN];
 } STRUCT_PACKED;
 
+#define IEEE80211_EHT_CAPAB_MIN_LEN (2 + 9)
+
 /* IEEE P802.11be/D2.1, 9.4.2.312 - Multi-Link element */
 
 /* Figure 9-1002f: Multi-Link Control field */
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 5b866ec914..39bc274846 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -2373,6 +2373,8 @@ static const struct minsnr_bitrate_entry vht160_table[] = {
 	{ -1, 780000 }  /* SNR > 37 */
 };
 
+/* EHT needs to be enabled in order to achieve MCS12 and MCS13 rates. */
+#define EHT_MCS 12
 
 static const struct minsnr_bitrate_entry he20_table[] = {
 	{ 0, 0 },
@@ -2388,7 +2390,9 @@ static const struct minsnr_bitrate_entry he20_table[] = {
 	{ 31, 114700 }, /* HE20 MCS9 */
 	{ 34, 129000 }, /* HE20 MCS10 */
 	{ 36, 143400 }, /* HE20 MCS11 */
-	{ -1, 143400 }  /* SNR > 29 */
+	{ 39, 154900 }, /* EHT20 MCS12 */
+	{ 42, 172100 }, /* EHT20 MCS13 */
+	{ -1, 172100 }  /* SNR > 42 */
 };
 
 static const struct minsnr_bitrate_entry he40_table[] = {
@@ -2405,7 +2409,9 @@ static const struct minsnr_bitrate_entry he40_table[] = {
 	{ 34, 229400 }, /* HE40 MCS9 */
 	{ 37, 258100 }, /* HE40 MCS10 */
 	{ 39, 286800 }, /* HE40 MCS11 */
-	{ -1, 286800 }  /* SNR > 34 */
+	{ 42, 309500 }, /* EHT40 MCS12 */
+	{ 45, 344100 }, /* EHT40 MCS13 */
+	{ -1, 344100 }  /* SNR > 45 */
 };
 
 static const struct minsnr_bitrate_entry he80_table[] = {
@@ -2422,7 +2428,9 @@ static const struct minsnr_bitrate_entry he80_table[] = {
 	{ 37, 480400 }, /* HE80 MCS9 */
 	{ 40, 540400 }, /* HE80 MCS10 */
 	{ 42, 600500 }, /* HE80 MCS11 */
-	{ -1, 600500 }  /* SNR > 37 */
+	{ 45, 648500 }, /* EHT80 MCS12 */
+	{ 48, 720600 }, /* EHT80 MCS13 */
+	{ -1, 720600 }  /* SNR > 48 */
 };
 
 
@@ -2440,9 +2448,30 @@ static const struct minsnr_bitrate_entry he160_table[] = {
 	{ 40, 960800 },  /* HE160 MCS9 */
 	{ 43, 1080900 }, /* HE160 MCS10 */
 	{ 45, 1201000 }, /* HE160 MCS11 */
-	{ -1, 1201000 }  /* SNR > 37 */
+	{ 48, 1297100 }, /* EHT160 MCS12 */
+	{ 51, 1441200 }, /* EHT160 MCS13 */
+	{ -1, 1441200 }  /* SNR > 51 */
 };
 
+/* See P802.11be_D2.0, Table 36-86: EHT-MCSs for 4x996-tone RU, NSS,u = 1 */
+static const struct minsnr_bitrate_entry eht320_table[] = {
+	{ 0, 0 },
+	{ 14, 144100 },   /* EHT320 MCS0 */
+	{ 17, 288200 },   /* EHT320 MCS1 */
+	{ 21, 432400 },   /* EHT320 MCS2 */
+	{ 23, 576500 },   /* EHT320 MCS3 */
+	{ 27, 864700 },   /* EHT320 MCS4 */
+	{ 30, 1152900 },  /* EHT320 MCS5 */
+	{ 32, 1297100 },  /* EHT320 MCS6 */
+	{ 37, 1441200 },  /* EHT320 MCS7 */
+	{ 41, 1729400 },  /* EHT320 MCS8 */
+	{ 43, 1921500 },  /* EHT320 MCS9 */
+	{ 46, 2161800 },  /* EHT320 MCS10 */
+	{ 48, 2401900 },  /* EHT320 MCS11 */
+	{ 51, 2594100 },  /* EHT320 MCS12 */
+	{ 54, 2882400 },  /* EHT320 MCS13 */
+	{ -1, 2882400 }   /* SNR > 54 */
+};
 
 static unsigned int interpolate_rate(int snr, int snr0, int snr1,
 				     int rate0, int rate1)
@@ -2494,17 +2523,18 @@ static unsigned int max_vht160_rate(int snr)
 }
 
 
-static unsigned int max_he_rate(const struct minsnr_bitrate_entry table[],
-				int snr)
+static unsigned int max_he_eht_rate(const struct minsnr_bitrate_entry table[],
+				    int snr, bool eht)
 {
 	const struct minsnr_bitrate_entry *prev, *entry = table;
 
-	while (entry->minsnr != -1 && snr >= entry->minsnr)
+	while (entry->minsnr != -1 && snr >= entry->minsnr &&
+	       (eht || entry - table <= EHT_MCS))
 		entry++;
 	if (entry == table)
 		return 0;
 	prev = entry - 1;
-	if (entry->minsnr == -1)
+	if (entry->minsnr == -1 || (!eht && entry - table > EHT_MCS))
 		return prev->bitrate;
 	return interpolate_rate(snr, prev->minsnr, entry->minsnr,
 				prev->bitrate, entry->bitrate);
@@ -2642,8 +2672,11 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 	if (hw_mode && hw_mode->he_capab[IEEE80211_MODE_INFRA].he_supported) {
 		/* Use +2 to assume HE is always faster than HT/VHT */
 		struct ieee80211_he_capabilities *he;
+		struct ieee80211_eht_capabilities *eht;
 		struct he_capabilities *own_he;
-		u8 cw;
+		u8 cw, boost = 2;
+		const u8 *eht_ie;
+		bool is_eht = false;
 
 		ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_HE_CAPABILITIES);
 		if (!ie || (ie[1] < 1 + IEEE80211_HE_CAPAB_MIN_LEN))
@@ -2651,7 +2684,18 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 		he = (struct ieee80211_he_capabilities *) &ie[3];
 		own_he = &hw_mode->he_capab[IEEE80211_MODE_INFRA];
 
-		tmp = max_he_rate(he20_table, snr) + 2;
+		/* Use +3 to assume EHT is always faster than HE */
+		if (hw_mode->eht_capab[IEEE80211_MODE_INFRA].eht_supported) {
+			eht_ie = get_ie_ext(ies, ies_len,
+					    WLAN_EID_EXT_EHT_CAPABILITIES);
+			if (eht_ie &&
+			    (eht_ie[1] >= 1 + IEEE80211_EHT_CAPAB_MIN_LEN)) {
+				is_eht = true;
+				boost = 3;
+			}
+		}
+
+		tmp = max_he_eht_rate(he20_table, snr, is_eht) + boost;
 		if (tmp > est)
 			est = tmp;
 
@@ -2660,14 +2704,14 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 		if (cw &
 		    (IS_2P4GHZ(freq) ? HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G :
 		     HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
-			tmp = max_he_rate(he40_table, snr) + 2;
+			tmp = max_he_eht_rate(he40_table, snr, is_eht) + boost;
 			if (tmp > est)
 				est = tmp;
 		}
 
 		if (!IS_2P4GHZ(freq) &&
 		    (cw & HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
-			tmp = max_he_rate(he80_table, snr) + 2;
+			tmp = max_he_eht_rate(he80_table, snr, is_eht) + boost;
 			if (tmp > est)
 				est = tmp;
 		}
@@ -2675,7 +2719,20 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
 		if (!IS_2P4GHZ(freq) &&
 		    (cw & (HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
 			   HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G))) {
-			tmp = max_he_rate(he160_table, snr) + 2;
+			tmp = max_he_eht_rate(he160_table, snr, is_eht) + boost;
+			if (tmp > est)
+				est = tmp;
+		}
+
+		if (!is_eht)
+			return est;
+
+		eht = (struct ieee80211_eht_capabilities *) &eht_ie[3];
+
+		if (is_6ghz_freq(freq) &&
+		    (eht->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] &
+		     EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK)) {
+			tmp = max_he_eht_rate(eht320_table, snr, true);
 			if (tmp > est)
 				est = tmp;
 		}
-- 
2.25.1




More information about the Hostap mailing list