{ -1, 1441200 } /* SNR > 51 */
};
+/* See IEEE P802.11be/D7.0, Table 36-78 - EHT-MCSs for 484+242-tone MRU,
+ * NSS,u = 1
+ */
+static const struct minsnr_bitrate_entry eht60_table[] = {
+ { 0, 0 },
+ { 8, 25800 }, /* EHT80 with 20 MHz punctured MCS0 */
+ { 11, 51600 }, /* EHT80 with 20 MHz punctured MCS1 */
+ { 15, 77400 }, /* EHT80 with 20 MHz punctured MCS2 */
+ { 17, 103200 }, /* EHT80 with 20 MHz punctured MCS3 */
+ { 21, 154900 }, /* EHT80 with 20 MHz punctured MCS4 */
+ { 24, 206500 }, /* EHT80 with 20 MHz punctured MCS5 */
+ { 26, 232300 }, /* EHT80 with 20 MHz punctured MCS6 */
+ { 31, 258100 }, /* EHT80 with 20 MHz punctured MCS7 */
+ { 35, 309700 }, /* EHT80 with 20 MHz punctured MCS8 */
+ { 37, 344100 }, /* EHT80 with 20 MHz punctured MCS9 */
+ { 40, 387100 }, /* EHT80 with 20 MHz punctured MCS10 */
+ { 42, 430100 }, /* EHT80 with 20 MHz punctured MCS11 */
+ { 45, 464600 }, /* EHT80 with 20 MHz punctured MCS12 */
+ { 48, 516200 }, /* EHT80 with 20 MHz punctured MCS13 */
+ { -1, 516200 } /* SNR > 48 */
+};
+
+/* See IEEE P802.11be/D7.0, Table 36-80 - EHT-MCSs for 996+484-tone MRU,
+ * NSS,u = 1
+ */
+static const struct minsnr_bitrate_entry eht120_table[] = {
+ { 0, 0 },
+ { 11, 53200 }, /* EHT160 with 40 MHz punctured MCS0 */
+ { 14, 106500 }, /* EHT160 with 40 MHz punctured MCS1 */
+ { 18, 159700 }, /* EHT160 with 40 MHz punctured MCS2 */
+ { 20, 212900 }, /* EHT160 with 40 MHz punctured MCS3 */
+ { 24, 319400 }, /* EHT160 with 40 MHz punctured MCS4 */
+ { 27, 425900 }, /* EHT160 with 40 MHz punctured MCS5 */
+ { 29, 479100 }, /* EHT160 with 40 MHz punctured MCS6 */
+ { 34, 532400 }, /* EHT160 with 40 MHz punctured MCS7 */
+ { 38, 638800 }, /* EHT160 with 40 MHz punctured MCS8 */
+ { 40, 709800 }, /* EHT160 with 40 MHz punctured MCS9 */
+ { 43, 798500 }, /* EHT160 with 40 MHz punctured MCS10 */
+ { 45, 887200 }, /* EHT160 with 40 MHz punctured MCS11 */
+ { 48, 958200 }, /* EHT160 with 40 MHz punctured MCS12 */
+ { 51, 1064700 }, /* EHT160 with 40 MHz punctured MCS13 */
+ { -1, 1064700 } /* SNR > 51 */
+};
+
+/* See IEEE P802.11be/D7.0, Table 36-81 - EHT-MCSs for 996+484+242-tone MRU,
+ * NSS,u = 1
+ */
+static const struct minsnr_bitrate_entry eht140_table[] = {
+ { 0, 0 },
+ { 11, 61800 }, /* EHT160 with 20 MHz punctured MCS0 */
+ { 14, 123700 }, /* EHT160 with 20 MHz punctured MCS1 */
+ { 18, 185500 }, /* EHT160 with 20 MHz punctured MCS2 */
+ { 20, 247400 }, /* EHT160 with 20 MHz punctured MCS3 */
+ { 24, 371000 }, /* EHT160 with 20 MHz punctured MCS4 */
+ { 27, 494700 }, /* EHT160 with 20 MHz punctured MCS5 */
+ { 29, 556500 }, /* EHT160 with 20 MHz punctured MCS6 */
+ { 34, 618400 }, /* EHT160 with 20 MHz punctured MCS7 */
+ { 38, 742100 }, /* EHT160 with 20 MHz punctured MCS8 */
+ { 40, 824500 }, /* EHT160 with 20 MHz punctured MCS9 */
+ { 43, 927600 }, /* EHT160 with 20 MHz punctured MCS10 */
+ { 45, 1030600 }, /* EHT160 with 20 MHz punctured MCS11 */
+ { 48, 1113100 }, /* EHT160 with 20 MHz punctured MCS12 */
+ { 51, 1236800 }, /* EHT160 with 20 MHz punctured MCS13 */
+ { -1, 1236800 } /* SNR > 51 */
+};
+
+/* See IEEE P802.11be/D7.0, Table 36-83 - EHT-MCSs for 2x996+484-tone NRU,
+ * NSS,u = 1
+ */
+static const struct minsnr_bitrate_entry eht200_table[] = {
+ { 0, 0 },
+ { 14, 89300 }, /* EHT320 with 120 MHz punctured MCS0 */
+ { 17, 178500 }, /* EHT320 with 120 MHz punctured MCS1 */
+ { 21, 267800 }, /* EHT320 with 120 MHz punctured MCS2 */
+ { 23, 357100 }, /* EHT320 with 120 MHz punctured MCS3 */
+ { 27, 535600 }, /* EHT320 with 120 MHz punctured MCS4 */
+ { 30, 714100 }, /* EHT320 with 120 MHz punctured MCS5 */
+ { 32, 803400 }, /* EHT320 with 120 MHz punctured MCS6 */
+ { 37, 892600 }, /* EHT320 with 120 MHz punctured MCS7 */
+ { 41, 1071200 }, /* EHT320 with 120 MHz punctured MCS8 */
+ { 43, 1190100 }, /* EHT320 with 120 MHz punctured MCS9 */
+ { 46, 1339000 }, /* EHT320 with 120 MHz punctured MCS10 */
+ { 48, 1487700 }, /* EHT320 with 120 MHz punctured MCS11 */
+ { 51, 1606800 }, /* EHT320 with 120 MHz punctured MCS12 */
+ { 54, 1785300 }, /* EHT320 with 120 MHz punctured MCS13 */
+ { -1, 1785300 } /* SNR > 54 */
+};
+
+/* See IEEE P802.11be/D7.0, Table 36-84 - EHT-MCSs for 3x996-tone MRU,
+ * NSS,u = 1
+ */
+static const struct minsnr_bitrate_entry eht240_table[] = {
+ { 0, 0 },
+ { 14, 108100 }, /* EHT320 with 80 MHz punctured MCS0 */
+ { 17, 216200 }, /* EHT320 with 80 MHz punctured MCS1 */
+ { 21, 324300 }, /* EHT320 with 80 MHz punctured MCS2 */
+ { 23, 432400 }, /* EHT320 with 80 MHz punctured MCS3 */
+ { 27, 648500 }, /* EHT320 with 80 MHz punctured MCS4 */
+ { 30, 864700 }, /* EHT320 with 80 MHz punctured MCS5 */
+ { 32, 972800 }, /* EHT320 with 80 MHz punctured MCS6 */
+ { 37, 1080900 }, /* EHT320 with 80 MHz punctured MCS7 */
+ { 41, 1297100 }, /* EHT320 with 80 MHz punctured MCS8 */
+ { 43, 1441200 }, /* EHT320 with 80 MHz punctured MCS9 */
+ { 46, 1621300 }, /* EHT320 with 80 MHz punctured MCS10 */
+ { 48, 1801500 }, /* EHT320 with 80 MHz punctured MCS11 */
+ { 51, 1945600 }, /* EHT320 with 80 MHz punctured MCS12 */
+ { 54, 2161800 }, /* EHT320 with 80 MHz punctured MCS13 */
+ { -1, 2161800 } /* SNR > 54 */
+};
+
+/* See IEEE P802.11be/D7.0, Table 36-85: EHT-MCSs for 3x996+484-tone MRU,
+ * NSS,u = 1
+ */
+static const struct minsnr_bitrate_entry eht280_table[] = {
+ { 0, 0 },
+ { 14, 125300 }, /* EHT320 with 40 MHz punctured MCS0 */
+ { 17, 250600 }, /* EHT320 with 40 MHz punctured MCS1 */
+ { 21, 375900 }, /* EHT320 with 40 MHz punctured MCS2 */
+ { 23, 501200 }, /* EHT320 with 40 MHz punctured MCS3 */
+ { 27, 751800 }, /* EHT320 with 40 MHz punctured MCS4 */
+ { 30, 1002400 }, /* EHT320 with 40 MHz punctured MCS5 */
+ { 32, 1127600 }, /* EHT320 with 40 MHz punctured MCS6 */
+ { 37, 1252900 }, /* EHT320 with 40 MHz punctured MCS7 */
+ { 41, 1503500 }, /* EHT320 with 40 MHz punctured MCS8 */
+ { 43, 1670600 }, /* EHT320 with 40 MHz punctured MCS9 */
+ { 46, 1879400 }, /* EHT320 with 40 MHz punctured MCS10 */
+ { 48, 2088200 }, /* EHT320 with 40 MHz punctured MCS11 */
+ { 51, 2255300 }, /* EHT320 with 40 MHz punctured MCS12 */
+ { 54, 2505900 }, /* EHT320 with 40 MHz punctured MCS13 */
+ { -1, 2505900 } /* SNR > 54 */
+};
+
/* 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[] = {
}
+static unsigned int get_eht_punctured_rate(enum chan_width cw,
+ u8 num_punct_bits, int adjusted_snr,
+ u8 boost)
+{
+ const struct minsnr_bitrate_entry *eht_table;
+
+ switch (cw) {
+ case CHAN_WIDTH_80:
+ switch (num_punct_bits) {
+ case 1:
+ /* EHT80 with 20 MHz punctured */
+ eht_table = eht60_table;
+ break;
+ default:
+ eht_table = he80_table;
+ break;
+ }
+ break;
+ case CHAN_WIDTH_160:
+ switch (num_punct_bits) {
+ case 2:
+ /* EHT160 with 40 MHz punctured */
+ eht_table = eht120_table;
+ break;
+ case 1:
+ /* EHT160 with 20 MHz punctured */
+ eht_table = eht140_table;
+ break;
+ default:
+ eht_table = he160_table;
+ break;
+ }
+ break;
+ case CHAN_WIDTH_320:
+ switch (num_punct_bits) {
+ case 6:
+ /* EHT320 with 120 MHz punctured */
+ eht_table = eht200_table;
+ break;
+ case 4:
+ /* EHT320 with 80 MHz punctured */
+ eht_table = eht240_table;
+ break;
+ case 2:
+ /* EHT320 with 40 MHz punctured */
+ eht_table = eht280_table;
+ break;
+ default:
+ eht_table = eht320_table;
+ break;
+ }
+ break;
+ default:
+ /* Puncturing is not supported for the channel width */
+ return 0;
+ }
+
+ return max_he_eht_rate(eht_table, adjusted_snr, true) + boost;
+}
+
+
+static u8 get_eht_num_punct_bits(const u8 *ies, size_t ies_len)
+{
+ const u8 *eht_ie;
+
+ eht_ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_EHT_OPERATION);
+ if (eht_ie && eht_ie[1] >= 1 + IEEE80211_EHT_OP_MIN_LEN) {
+ struct ieee80211_eht_operation *eht_op;
+
+ eht_op = (struct ieee80211_eht_operation *) &eht_ie[3];
+
+ if (eht_op->oper_params &
+ EHT_OPER_DISABLED_SUBCHAN_BITMAP_PRESENT) {
+ u16 punct_bitmap;
+ u8 count = 0;
+
+ punct_bitmap = le_to_host16(
+ eht_op->oper_info.disabled_chan_bitmap);
+ while (punct_bitmap) {
+ count += punct_bitmap & 1;
+ punct_bitmap >>= 1;
+ }
+ return count;
+ }
+ }
+
+ return 0;
+}
+
+
unsigned int wpas_get_est_tpt(const struct wpa_supplicant *wpa_s,
const u8 *ies, size_t ies_len, int rate,
int snr, int freq, enum chan_width *max_cw)
struct ieee80211_eht_capabilities *eht;
struct he_capabilities *own_he;
u8 cw, boost = 2;
- const u8 *eht_ie;
+ const u8 *eht_ie = NULL;
bool is_eht = false;
+ u8 num_punct_bits;
ie = get_ie_ext(ies, ies_len, WLAN_EID_EXT_HE_CAPABILITIES);
if (!ie || (ie[1] < 1 + IEEE80211_HE_CAPAB_MIN_LEN))
*max_cw = CHAN_WIDTH_80;
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;
+
+ num_punct_bits = get_eht_num_punct_bits(ies, ies_len);
+ if (is_eht && num_punct_bits)
+ tmp = get_eht_punctured_rate(CHAN_WIDTH_80,
+ num_punct_bits,
+ adjusted_snr,
+ boost);
+ else
+ tmp = max_he_eht_rate(he80_table, adjusted_snr,
+ is_eht) + boost;
+
if (tmp > est)
est = tmp;
}
*max_cw = CHAN_WIDTH_160;
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;
+
+ num_punct_bits = get_eht_num_punct_bits(ies, ies_len);
+ if (is_eht && num_punct_bits)
+ tmp = get_eht_punctured_rate(CHAN_WIDTH_160,
+ num_punct_bits,
+ adjusted_snr,
+ boost);
+ else
+ tmp = max_he_eht_rate(he160_table, adjusted_snr,
+ is_eht) + boost;
if (tmp > est)
est = tmp;
}
- if (!is_eht)
+ if (!is_eht || !eht_ie)
return est;
eht = (struct ieee80211_eht_capabilities *) &eht_ie[3];
*max_cw = CHAN_WIDTH_320;
adjusted_snr = snr + wpas_channel_width_rssi_bump(
ies, ies_len, CHAN_WIDTH_320);
- tmp = max_he_eht_rate(eht320_table, adjusted_snr, true);
+
+ num_punct_bits = get_eht_num_punct_bits(ies, ies_len);
+ if (num_punct_bits)
+ tmp = get_eht_punctured_rate(CHAN_WIDTH_320,
+ num_punct_bits,
+ adjusted_snr,
+ 0);
+ else
+ tmp = max_he_eht_rate(eht320_table, adjusted_snr,
+ true);
if (tmp > est)
est = tmp;
}