wpa_supplicant: Support throughput estimation for EHT rates
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 IEEE P802.11be/D2.0, 36.5. - 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@intel.com> Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
This commit is contained in:
parent
755aaeb97f
commit
9a2781f243
2 changed files with 73 additions and 13 deletions
|
@ -2515,6 +2515,8 @@ struct ieee80211_eht_capabilities {
|
||||||
u8 optional[EHT_MCS_NSS_CAPAB_LEN + EHT_PPE_THRESH_CAPAB_LEN];
|
u8 optional[EHT_MCS_NSS_CAPAB_LEN + EHT_PPE_THRESH_CAPAB_LEN];
|
||||||
} STRUCT_PACKED;
|
} STRUCT_PACKED;
|
||||||
|
|
||||||
|
#define IEEE80211_EHT_CAPAB_MIN_LEN (2 + 9)
|
||||||
|
|
||||||
/* IEEE P802.11be/D2.1, 9.4.2.312 - Multi-Link element */
|
/* IEEE P802.11be/D2.1, 9.4.2.312 - Multi-Link element */
|
||||||
|
|
||||||
/* Figure 9-1002f: Multi-Link Control field */
|
/* Figure 9-1002f: Multi-Link Control field */
|
||||||
|
|
|
@ -2373,6 +2373,8 @@ static const struct minsnr_bitrate_entry vht160_table[] = {
|
||||||
{ -1, 780000 } /* SNR > 37 */
|
{ -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[] = {
|
static const struct minsnr_bitrate_entry he20_table[] = {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
|
@ -2388,7 +2390,9 @@ static const struct minsnr_bitrate_entry he20_table[] = {
|
||||||
{ 31, 114700 }, /* HE20 MCS9 */
|
{ 31, 114700 }, /* HE20 MCS9 */
|
||||||
{ 34, 129000 }, /* HE20 MCS10 */
|
{ 34, 129000 }, /* HE20 MCS10 */
|
||||||
{ 36, 143400 }, /* HE20 MCS11 */
|
{ 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[] = {
|
static const struct minsnr_bitrate_entry he40_table[] = {
|
||||||
|
@ -2405,7 +2409,9 @@ static const struct minsnr_bitrate_entry he40_table[] = {
|
||||||
{ 34, 229400 }, /* HE40 MCS9 */
|
{ 34, 229400 }, /* HE40 MCS9 */
|
||||||
{ 37, 258100 }, /* HE40 MCS10 */
|
{ 37, 258100 }, /* HE40 MCS10 */
|
||||||
{ 39, 286800 }, /* HE40 MCS11 */
|
{ 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[] = {
|
static const struct minsnr_bitrate_entry he80_table[] = {
|
||||||
|
@ -2422,7 +2428,9 @@ static const struct minsnr_bitrate_entry he80_table[] = {
|
||||||
{ 37, 480400 }, /* HE80 MCS9 */
|
{ 37, 480400 }, /* HE80 MCS9 */
|
||||||
{ 40, 540400 }, /* HE80 MCS10 */
|
{ 40, 540400 }, /* HE80 MCS10 */
|
||||||
{ 42, 600500 }, /* HE80 MCS11 */
|
{ 42, 600500 }, /* HE80 MCS11 */
|
||||||
{ -1, 600500 } /* SNR > 37 */
|
{ 45, 648500 }, /* EHT80 MCS12 */
|
||||||
|
{ 48, 720600 }, /* EHT80 MCS13 */
|
||||||
|
{ -1, 720600 } /* SNR > 48 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2440,9 +2448,31 @@ static const struct minsnr_bitrate_entry he160_table[] = {
|
||||||
{ 40, 960800 }, /* HE160 MCS9 */
|
{ 40, 960800 }, /* HE160 MCS9 */
|
||||||
{ 43, 1080900 }, /* HE160 MCS10 */
|
{ 43, 1080900 }, /* HE160 MCS10 */
|
||||||
{ 45, 1201000 }, /* HE160 MCS11 */
|
{ 45, 1201000 }, /* HE160 MCS11 */
|
||||||
{ -1, 1201000 } /* SNR > 37 */
|
{ 48, 1297100 }, /* EHT160 MCS12 */
|
||||||
|
{ 51, 1441200 }, /* EHT160 MCS13 */
|
||||||
|
{ -1, 1441200 } /* SNR > 51 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* See IEEE 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,
|
static unsigned int interpolate_rate(int snr, int snr0, int snr1,
|
||||||
int rate0, int rate1)
|
int rate0, int rate1)
|
||||||
|
@ -2494,17 +2524,18 @@ static unsigned int max_vht160_rate(int snr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned int max_he_rate(const struct minsnr_bitrate_entry table[],
|
static unsigned int max_he_eht_rate(const struct minsnr_bitrate_entry table[],
|
||||||
int snr)
|
int snr, bool eht)
|
||||||
{
|
{
|
||||||
const struct minsnr_bitrate_entry *prev, *entry = table;
|
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++;
|
entry++;
|
||||||
if (entry == table)
|
if (entry == table)
|
||||||
return 0;
|
return 0;
|
||||||
prev = entry - 1;
|
prev = entry - 1;
|
||||||
if (entry->minsnr == -1)
|
if (entry->minsnr == -1 || (!eht && entry - table > EHT_MCS))
|
||||||
return prev->bitrate;
|
return prev->bitrate;
|
||||||
return interpolate_rate(snr, prev->minsnr, entry->minsnr,
|
return interpolate_rate(snr, prev->minsnr, entry->minsnr,
|
||||||
prev->bitrate, entry->bitrate);
|
prev->bitrate, entry->bitrate);
|
||||||
|
@ -2642,8 +2673,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) {
|
if (hw_mode && hw_mode->he_capab[IEEE80211_MODE_INFRA].he_supported) {
|
||||||
/* Use +2 to assume HE is always faster than HT/VHT */
|
/* Use +2 to assume HE is always faster than HT/VHT */
|
||||||
struct ieee80211_he_capabilities *he;
|
struct ieee80211_he_capabilities *he;
|
||||||
|
struct ieee80211_eht_capabilities *eht;
|
||||||
struct he_capabilities *own_he;
|
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);
|
ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_HE_CAPABILITIES);
|
||||||
if (!ie || (ie[1] < 1 + IEEE80211_HE_CAPAB_MIN_LEN))
|
if (!ie || (ie[1] < 1 + IEEE80211_HE_CAPAB_MIN_LEN))
|
||||||
|
@ -2651,7 +2685,18 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
he = (struct ieee80211_he_capabilities *) &ie[3];
|
he = (struct ieee80211_he_capabilities *) &ie[3];
|
||||||
own_he = &hw_mode->he_capab[IEEE80211_MODE_INFRA];
|
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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
|
|
||||||
|
@ -2660,14 +2705,14 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
if (cw &
|
if (cw &
|
||||||
(IS_2P4GHZ(freq) ? HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G :
|
(IS_2P4GHZ(freq) ? HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G :
|
||||||
HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
|
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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_2P4GHZ(freq) &&
|
if (!IS_2P4GHZ(freq) &&
|
||||||
(cw & HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G)) {
|
(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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
@ -2675,7 +2720,20 @@ unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
|
||||||
if (!IS_2P4GHZ(freq) &&
|
if (!IS_2P4GHZ(freq) &&
|
||||||
(cw & (HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
|
(cw & (HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
|
||||||
HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_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)
|
if (tmp > est)
|
||||||
est = tmp;
|
est = tmp;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue