1 /* 2 * hostapd / IEEE 802.11ax HE 3 * Copyright (c) 2016-2017, Qualcomm Atheros, Inc. 4 * Copyright (c) 2019 John Crispin <john@phrozen.org> 5 * 6 * This software may be distributed under the terms of the BSD license. 7 * See README for more details. 8 */ 9 10 #include "utils/includes.h" 11 12 #include "utils/common.h" 13 #include "common/ieee802_11_defs.h" 14 #include "common/ieee802_11_common.h" 15 #include "common/hw_features_common.h" 16 #include "hostapd.h" 17 #include "ap_config.h" 18 #include "beacon.h" 19 #include "sta_info.h" 20 #include "ieee802_11.h" 21 #include "dfs.h" 22 23 static u8 ieee80211_he_ppet_size(u8 ppe_thres_hdr, const u8 *phy_cap_info) 24 { 25 u8 sz = 0, ru; 26 27 if ((phy_cap_info[HE_PHYCAP_PPE_THRESHOLD_PRESENT_IDX] & 28 HE_PHYCAP_PPE_THRESHOLD_PRESENT) == 0) 29 return 0; 30 31 ru = (ppe_thres_hdr >> HE_PPE_THRES_RU_INDEX_BITMASK_SHIFT) & 32 HE_PPE_THRES_RU_INDEX_BITMASK_MASK; 33 /* Count the number of 1 bits in RU Index Bitmask */ 34 while (ru) { 35 if (ru & 0x1) 36 sz++; 37 ru >>= 1; 38 } 39 40 /* fixed header of 3 (NSTS) + 4 (RU Index Bitmask) = 7 bits */ 41 /* 6 * (NSTS + 1) bits for bit 1 in RU Index Bitmask */ 42 sz *= 1 + (ppe_thres_hdr & HE_PPE_THRES_NSS_MASK); 43 sz = (sz * 6) + 7; 44 /* PPE Pad to count the number of needed full octets */ 45 sz = (sz + 7) / 8; 46 47 return sz; 48 } 49 50 51 static u8 ieee80211_he_mcs_set_size(const u8 *phy_cap_info) 52 { 53 u8 sz = 4; 54 55 if (phy_cap_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & 56 HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G) 57 sz += 4; 58 if (phy_cap_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & 59 HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) 60 sz += 4; 61 62 return sz; 63 } 64 65 66 static int ieee80211_invalid_he_cap_size(const u8 *buf, size_t len) 67 { 68 struct ieee80211_he_capabilities *cap; 69 size_t cap_len; 70 u8 ppe_thres_hdr; 71 72 cap = (struct ieee80211_he_capabilities *) buf; 73 cap_len = sizeof(*cap) - sizeof(cap->optional); 74 if (len < cap_len) 75 return 1; 76 77 cap_len += ieee80211_he_mcs_set_size(cap->he_phy_capab_info); 78 if (len < cap_len) 79 return 1; 80 81 ppe_thres_hdr = len > cap_len ? buf[cap_len] : 0xff; 82 cap_len += ieee80211_he_ppet_size(ppe_thres_hdr, 83 cap->he_phy_capab_info); 84 85 return len < cap_len; 86 } 87 88 89 u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid, 90 enum ieee80211_op_mode opmode) 91 { 92 struct ieee80211_he_capabilities *cap; 93 struct hostapd_hw_modes *mode = hapd->iface->current_mode; 94 u8 he_oper_chwidth = ~HE_PHYCAP_CHANNEL_WIDTH_MASK; 95 u8 *pos = eid; 96 u8 ie_size = 0, mcs_nss_size = 4, ppet_size = 0; 97 98 if (!mode) 99 return eid; 100 101 ie_size = sizeof(*cap) - sizeof(cap->optional); 102 ppet_size = ieee80211_he_ppet_size(mode->he_capab[opmode].ppet[0], 103 mode->he_capab[opmode].phy_cap); 104 105 switch (hapd->iface->conf->he_oper_chwidth) { 106 case CONF_OPER_CHWIDTH_80P80MHZ: 107 he_oper_chwidth |= 108 HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G; 109 mcs_nss_size += 4; 110 /* fall through */ 111 case CONF_OPER_CHWIDTH_160MHZ: 112 he_oper_chwidth |= HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G; 113 mcs_nss_size += 4; 114 /* fall through */ 115 case CONF_OPER_CHWIDTH_80MHZ: 116 case CONF_OPER_CHWIDTH_USE_HT: 117 he_oper_chwidth |= HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G | 118 HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; 119 break; 120 default: 121 break; 122 } 123 124 ie_size += mcs_nss_size + ppet_size; 125 126 *pos++ = WLAN_EID_EXTENSION; 127 *pos++ = 1 + ie_size; 128 *pos++ = WLAN_EID_EXT_HE_CAPABILITIES; 129 130 cap = (struct ieee80211_he_capabilities *) pos; 131 os_memset(cap, 0, sizeof(*cap)); 132 133 os_memcpy(cap->he_mac_capab_info, mode->he_capab[opmode].mac_cap, 134 HE_MAX_MAC_CAPAB_SIZE); 135 os_memcpy(cap->he_phy_capab_info, mode->he_capab[opmode].phy_cap, 136 HE_MAX_PHY_CAPAB_SIZE); 137 os_memcpy(cap->optional, mode->he_capab[opmode].mcs, mcs_nss_size); 138 if (ppet_size) 139 os_memcpy(&cap->optional[mcs_nss_size], 140 mode->he_capab[opmode].ppet, ppet_size); 141 142 if (hapd->iface->conf->he_phy_capab.he_su_beamformer) 143 cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] |= 144 HE_PHYCAP_SU_BEAMFORMER_CAPAB; 145 else 146 cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] &= 147 ~HE_PHYCAP_SU_BEAMFORMER_CAPAB; 148 149 if (hapd->iface->conf->he_phy_capab.he_su_beamformee) 150 cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX] |= 151 HE_PHYCAP_SU_BEAMFORMEE_CAPAB; 152 else 153 cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX] &= 154 ~HE_PHYCAP_SU_BEAMFORMEE_CAPAB; 155 156 if (hapd->iface->conf->he_phy_capab.he_mu_beamformer) 157 cap->he_phy_capab_info[HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX] |= 158 HE_PHYCAP_MU_BEAMFORMER_CAPAB; 159 else 160 cap->he_phy_capab_info[HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX] &= 161 ~HE_PHYCAP_MU_BEAMFORMER_CAPAB; 162 163 cap->he_phy_capab_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &= 164 he_oper_chwidth; 165 166 pos += ie_size; 167 168 return pos; 169 } 170 171 172 u8 * hostapd_eid_he_operation(struct hostapd_data *hapd, u8 *eid) 173 { 174 struct ieee80211_he_operation *oper; 175 u8 *pos = eid; 176 int oper_size = 6; 177 u32 params = 0; 178 179 if (!hapd->iface->current_mode) 180 return eid; 181 182 if (is_6ghz_op_class(hapd->iconf->op_class)) 183 oper_size += 5; 184 185 *pos++ = WLAN_EID_EXTENSION; 186 *pos++ = 1 + oper_size; 187 *pos++ = WLAN_EID_EXT_HE_OPERATION; 188 189 oper = (struct ieee80211_he_operation *) pos; 190 os_memset(oper, 0, sizeof(*oper)); 191 192 if (hapd->iface->conf->he_op.he_default_pe_duration) 193 params |= (hapd->iface->conf->he_op.he_default_pe_duration << 194 HE_OPERATION_DFLT_PE_DURATION_OFFSET); 195 196 if (hapd->iface->conf->he_op.he_twt_required) 197 params |= HE_OPERATION_TWT_REQUIRED; 198 199 if (hapd->iface->conf->he_op.he_rts_threshold) 200 params |= (hapd->iface->conf->he_op.he_rts_threshold << 201 HE_OPERATION_RTS_THRESHOLD_OFFSET); 202 203 if (hapd->iface->conf->he_op.he_er_su_disable) 204 params |= HE_OPERATION_ER_SU_DISABLE; 205 206 if (hapd->iface->conf->he_op.he_bss_color_disabled || 207 hapd->cca_in_progress) 208 params |= HE_OPERATION_BSS_COLOR_DISABLED; 209 if (hapd->iface->conf->he_op.he_bss_color_partial) 210 params |= HE_OPERATION_BSS_COLOR_PARTIAL; 211 params |= hapd->iface->conf->he_op.he_bss_color << 212 HE_OPERATION_BSS_COLOR_OFFSET; 213 214 /* HE minimum required basic MCS and NSS for STAs */ 215 oper->he_mcs_nss_set = 216 host_to_le16(hapd->iface->conf->he_op.he_basic_mcs_nss_set); 217 218 /* TODO: conditional MaxBSSID Indicator subfield */ 219 220 pos += 6; /* skip the fixed part */ 221 222 if (is_6ghz_op_class(hapd->iconf->op_class)) { 223 enum oper_chan_width oper_chwidth = 224 hostapd_get_oper_chwidth(hapd->iconf); 225 u8 seg0 = hapd->iconf->he_oper_centr_freq_seg0_idx; 226 u8 seg1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf); 227 u8 control; 228 #ifdef CONFIG_IEEE80211BE 229 u16 punct_bitmap = hostapd_get_punct_bitmap(hapd); 230 231 if (punct_bitmap) { 232 punct_update_legacy_bw(punct_bitmap, 233 hapd->iconf->channel, 234 &oper_chwidth, &seg0, &seg1); 235 } 236 #endif /* CONFIG_IEEE80211BE */ 237 238 if (!seg0) 239 seg0 = hapd->iconf->channel; 240 241 params |= HE_OPERATION_6GHZ_OPER_INFO; 242 243 /* 6 GHz Operation Information field 244 * IEEE Std 802.11ax-2021, 9.4.2.249 HE Operation element, 245 * Figure 9-788k 246 */ 247 *pos++ = hapd->iconf->channel; /* Primary Channel */ 248 249 /* Control: 250 * bits 0-1: Channel Width 251 * bit 2: Duplicate Beacon 252 * bits 3-5: Regulatory Info 253 */ 254 /* Channel Width */ 255 if (seg1) 256 control = 3; 257 else 258 control = center_idx_to_bw_6ghz(seg0); 259 260 control |= hapd->iconf->he_6ghz_reg_pwr_type << 261 HE_6GHZ_OPER_INFO_CTRL_REG_INFO_SHIFT; 262 263 *pos++ = control; 264 265 /* Channel Center Freq Seg0/Seg1 */ 266 if (oper_chwidth == CONF_OPER_CHWIDTH_160MHZ || 267 oper_chwidth == CONF_OPER_CHWIDTH_320MHZ) { 268 /* 269 * Seg 0 indicates the channel center frequency index of 270 * the 160 MHz channel. 271 */ 272 seg1 = seg0; 273 if (hapd->iconf->channel < seg0) 274 seg0 -= 8; 275 else 276 seg0 += 8; 277 } 278 279 *pos++ = seg0; 280 *pos++ = seg1; 281 /* Minimum Rate */ 282 *pos++ = 6; /* TODO: what should be set here? */ 283 } 284 285 oper->he_oper_params = host_to_le32(params); 286 287 return pos; 288 } 289 290 291 u8 * hostapd_eid_he_mu_edca_parameter_set(struct hostapd_data *hapd, u8 *eid) 292 { 293 struct ieee80211_he_mu_edca_parameter_set *edca; 294 u8 *pos; 295 size_t i; 296 297 pos = (u8 *) &hapd->iface->conf->he_mu_edca; 298 for (i = 0; i < sizeof(*edca); i++) { 299 if (pos[i]) 300 break; 301 } 302 if (i == sizeof(*edca)) 303 return eid; /* no MU EDCA Parameters configured */ 304 305 pos = eid; 306 *pos++ = WLAN_EID_EXTENSION; 307 *pos++ = 1 + sizeof(*edca); 308 *pos++ = WLAN_EID_EXT_HE_MU_EDCA_PARAMS; 309 310 edca = (struct ieee80211_he_mu_edca_parameter_set *) pos; 311 os_memcpy(edca, &hapd->iface->conf->he_mu_edca, sizeof(*edca)); 312 313 wpa_hexdump(MSG_DEBUG, "HE: MU EDCA Parameter Set element", 314 pos, sizeof(*edca)); 315 316 pos += sizeof(*edca); 317 318 return pos; 319 } 320 321 322 u8 * hostapd_eid_spatial_reuse(struct hostapd_data *hapd, u8 *eid) 323 { 324 struct ieee80211_spatial_reuse *spr; 325 u8 *pos = eid, *spr_param; 326 u8 sz = 1; 327 328 if (!hapd->iface->conf->spr.sr_control) 329 return eid; 330 331 if (hapd->iface->conf->spr.sr_control & 332 SPATIAL_REUSE_NON_SRG_OFFSET_PRESENT) 333 sz++; 334 335 if (hapd->iface->conf->spr.sr_control & 336 SPATIAL_REUSE_SRG_INFORMATION_PRESENT) 337 sz += 18; 338 339 *pos++ = WLAN_EID_EXTENSION; 340 *pos++ = 1 + sz; 341 *pos++ = WLAN_EID_EXT_SPATIAL_REUSE; 342 343 spr = (struct ieee80211_spatial_reuse *) pos; 344 os_memset(spr, 0, sizeof(*spr)); 345 346 spr->sr_ctrl = hapd->iface->conf->spr.sr_control; 347 pos++; 348 spr_param = spr->params; 349 if (spr->sr_ctrl & SPATIAL_REUSE_NON_SRG_OFFSET_PRESENT) { 350 *spr_param++ = 351 hapd->iface->conf->spr.non_srg_obss_pd_max_offset; 352 pos++; 353 } 354 if (spr->sr_ctrl & SPATIAL_REUSE_SRG_INFORMATION_PRESENT) { 355 *spr_param++ = hapd->iface->conf->spr.srg_obss_pd_min_offset; 356 *spr_param++ = hapd->iface->conf->spr.srg_obss_pd_max_offset; 357 os_memcpy(spr_param, 358 hapd->iface->conf->spr.srg_bss_color_bitmap, 8); 359 spr_param += 8; 360 os_memcpy(spr_param, 361 hapd->iface->conf->spr.srg_partial_bssid_bitmap, 8); 362 pos += 18; 363 } 364 365 return pos; 366 } 367 368 369 u8 * hostapd_eid_he_6ghz_band_cap(struct hostapd_data *hapd, u8 *eid) 370 { 371 struct hostapd_config *conf = hapd->iface->conf; 372 struct hostapd_hw_modes *mode = hapd->iface->current_mode; 373 struct he_capabilities *he_cap; 374 struct ieee80211_he_6ghz_band_cap *cap; 375 u16 capab; 376 u8 *pos; 377 378 if (!mode || !is_6ghz_op_class(hapd->iconf->op_class) || 379 !is_6ghz_freq(hapd->iface->freq)) 380 return eid; 381 382 he_cap = &mode->he_capab[IEEE80211_MODE_AP]; 383 capab = he_cap->he_6ghz_capa & HE_6GHZ_BAND_CAP_MIN_MPDU_START; 384 capab |= (conf->he_6ghz_max_ampdu_len_exp << 385 HE_6GHZ_BAND_CAP_MAX_AMPDU_LEN_EXP_SHIFT) & 386 HE_6GHZ_BAND_CAP_MAX_AMPDU_LEN_EXP_MASK; 387 capab |= (conf->he_6ghz_max_mpdu << 388 HE_6GHZ_BAND_CAP_MAX_MPDU_LEN_SHIFT) & 389 HE_6GHZ_BAND_CAP_MAX_MPDU_LEN_MASK; 390 capab |= HE_6GHZ_BAND_CAP_SMPS_DISABLED; 391 if (conf->he_6ghz_rx_ant_pat) 392 capab |= HE_6GHZ_BAND_CAP_RX_ANTPAT_CONS; 393 if (conf->he_6ghz_tx_ant_pat) 394 capab |= HE_6GHZ_BAND_CAP_TX_ANTPAT_CONS; 395 396 pos = eid; 397 *pos++ = WLAN_EID_EXTENSION; 398 *pos++ = 1 + sizeof(*cap); 399 *pos++ = WLAN_EID_EXT_HE_6GHZ_BAND_CAP; 400 401 cap = (struct ieee80211_he_6ghz_band_cap *) pos; 402 cap->capab = host_to_le16(capab); 403 pos += sizeof(*cap); 404 405 return pos; 406 } 407 408 409 void hostapd_get_he_capab(struct hostapd_data *hapd, 410 const struct ieee80211_he_capabilities *he_cap, 411 struct ieee80211_he_capabilities *neg_he_cap, 412 size_t he_capab_len) 413 { 414 if (!he_cap) 415 return; 416 417 if (he_capab_len > sizeof(*neg_he_cap)) 418 he_capab_len = sizeof(*neg_he_cap); 419 /* TODO: mask out unsupported features */ 420 421 os_memcpy(neg_he_cap, he_cap, he_capab_len); 422 } 423 424 425 static int check_valid_he_mcs(struct hostapd_data *hapd, const u8 *sta_he_capab, 426 enum ieee80211_op_mode opmode) 427 { 428 u16 sta_rx_mcs_set, ap_tx_mcs_set; 429 u8 mcs_count = 0; 430 const u16 *ap_mcs_set, *sta_mcs_set; 431 int i; 432 433 if (!hapd->iface->current_mode) 434 return 1; 435 ap_mcs_set = (u16 *) hapd->iface->current_mode->he_capab[opmode].mcs; 436 sta_mcs_set = (u16 *) ((const struct ieee80211_he_capabilities *) 437 sta_he_capab)->optional; 438 439 /* 440 * Disable HE capabilities for STAs for which there is not even a single 441 * allowed MCS in any supported number of streams, i.e., STA is 442 * advertising 3 (not supported) as HE MCS rates for all supported 443 * band/stream cases. 444 */ 445 switch (hapd->iface->conf->he_oper_chwidth) { 446 case CONF_OPER_CHWIDTH_80P80MHZ: 447 mcs_count = 3; 448 break; 449 case CONF_OPER_CHWIDTH_160MHZ: 450 mcs_count = 2; 451 break; 452 default: 453 mcs_count = 1; 454 break; 455 } 456 457 for (i = 0; i < mcs_count; i++) { 458 int j; 459 460 /* AP Tx MCS map vs. STA Rx MCS map */ 461 sta_rx_mcs_set = WPA_GET_LE16((const u8 *) &sta_mcs_set[i * 2]); 462 ap_tx_mcs_set = WPA_GET_LE16((const u8 *) 463 &ap_mcs_set[(i * 2) + 1]); 464 465 for (j = 0; j < HE_NSS_MAX_STREAMS; j++) { 466 if (((ap_tx_mcs_set >> (j * 2)) & 0x3) == 3) 467 continue; 468 469 if (((sta_rx_mcs_set >> (j * 2)) & 0x3) == 3) 470 continue; 471 472 return 1; 473 } 474 } 475 476 wpa_printf(MSG_DEBUG, 477 "No matching HE MCS found between AP TX and STA RX"); 478 479 return 0; 480 } 481 482 483 u16 copy_sta_he_capab(struct hostapd_data *hapd, struct sta_info *sta, 484 enum ieee80211_op_mode opmode, const u8 *he_capab, 485 size_t he_capab_len) 486 { 487 if (!he_capab || !(sta->flags & WLAN_STA_WMM) || 488 !hapd->iconf->ieee80211ax || hapd->conf->disable_11ax || 489 !check_valid_he_mcs(hapd, he_capab, opmode) || 490 ieee80211_invalid_he_cap_size(he_capab, he_capab_len) || 491 he_capab_len > sizeof(struct ieee80211_he_capabilities)) { 492 sta->flags &= ~WLAN_STA_HE; 493 os_free(sta->he_capab); 494 sta->he_capab = NULL; 495 return WLAN_STATUS_SUCCESS; 496 } 497 498 if (!sta->he_capab) { 499 sta->he_capab = 500 os_zalloc(sizeof(struct ieee80211_he_capabilities)); 501 if (!sta->he_capab) 502 return WLAN_STATUS_UNSPECIFIED_FAILURE; 503 } 504 505 sta->flags |= WLAN_STA_HE; 506 os_memset(sta->he_capab, 0, sizeof(struct ieee80211_he_capabilities)); 507 os_memcpy(sta->he_capab, he_capab, he_capab_len); 508 sta->he_capab_len = he_capab_len; 509 510 return WLAN_STATUS_SUCCESS; 511 } 512 513 514 u16 copy_sta_he_6ghz_capab(struct hostapd_data *hapd, struct sta_info *sta, 515 const u8 *he_6ghz_capab) 516 { 517 if (!he_6ghz_capab || !hapd->iconf->ieee80211ax || 518 hapd->conf->disable_11ax || 519 !is_6ghz_op_class(hapd->iconf->op_class)) { 520 sta->flags &= ~WLAN_STA_6GHZ; 521 os_free(sta->he_6ghz_capab); 522 sta->he_6ghz_capab = NULL; 523 return WLAN_STATUS_SUCCESS; 524 } 525 526 if (!sta->he_6ghz_capab) { 527 sta->he_6ghz_capab = 528 os_zalloc(sizeof(struct ieee80211_he_6ghz_band_cap)); 529 if (!sta->he_6ghz_capab) 530 return WLAN_STATUS_UNSPECIFIED_FAILURE; 531 } 532 533 sta->flags |= WLAN_STA_6GHZ; 534 os_memcpy(sta->he_6ghz_capab, he_6ghz_capab, 535 sizeof(struct ieee80211_he_6ghz_band_cap)); 536 537 return WLAN_STATUS_SUCCESS; 538 } 539 540 541 int hostapd_get_he_twt_responder(struct hostapd_data *hapd, 542 enum ieee80211_op_mode mode) 543 { 544 u8 *mac_cap; 545 546 if (!hapd->iface->current_mode || 547 !hapd->iface->current_mode->he_capab[mode].he_supported || 548 !hapd->iconf->ieee80211ax || hapd->conf->disable_11ax) 549 return 0; 550 551 mac_cap = hapd->iface->current_mode->he_capab[mode].mac_cap; 552 553 return !!(mac_cap[HE_MAC_CAPAB_0] & HE_MACCAP_TWT_RESPONDER) && 554 hapd->iface->conf->he_op.he_twt_responder; 555 } 556 557 558 u8 * hostapd_eid_cca(struct hostapd_data *hapd, u8 *eid) 559 { 560 if (!hapd->cca_in_progress) 561 return eid; 562 563 /* BSS Color Change Announcement element */ 564 *eid++ = WLAN_EID_EXTENSION; 565 *eid++ = 3; 566 *eid++ = WLAN_EID_EXT_COLOR_CHANGE_ANNOUNCEMENT; 567 *eid++ = hapd->cca_count; /* Color Switch Countdown */ 568 *eid++ = hapd->cca_color; /* New BSS Color Information */ 569 570 return eid; 571 } 572