1 /* 2 * hostapd / IEEE 802.11ac VHT 3 * Copyright (c) 2002-2009, Jouni Malinen <j (at) w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of BSD license 7 * 8 * See README and COPYING for more details. 9 */ 10 11 #include "utils/includes.h" 12 13 #include "utils/common.h" 14 #include "common/ieee802_11_defs.h" 15 #include "hostapd.h" 16 #include "ap_config.h" 17 #include "sta_info.h" 18 #include "beacon.h" 19 #include "ieee802_11.h" 20 #include "dfs.h" 21 22 23 u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid) 24 { 25 struct ieee80211_vht_capabilities *cap; 26 struct hostapd_hw_modes *mode = hapd->iface->current_mode; 27 u8 *pos = eid; 28 29 if (!mode) 30 return eid; 31 32 if (mode->mode == HOSTAPD_MODE_IEEE80211G && hapd->conf->vendor_vht && 33 mode->vht_capab == 0 && hapd->iface->hw_features) { 34 int i; 35 36 for (i = 0; i < hapd->iface->num_hw_features; i++) { 37 if (hapd->iface->hw_features[i].mode == 38 HOSTAPD_MODE_IEEE80211A) { 39 mode = &hapd->iface->hw_features[i]; 40 break; 41 } 42 } 43 } 44 45 *pos++ = WLAN_EID_VHT_CAP; 46 *pos++ = sizeof(*cap); 47 48 cap = (struct ieee80211_vht_capabilities *) pos; 49 os_memset(cap, 0, sizeof(*cap)); 50 cap->vht_capabilities_info = host_to_le32( 51 hapd->iface->conf->vht_capab); 52 53 /* Supported MCS set comes from hw */ 54 os_memcpy(&cap->vht_supported_mcs_set, mode->vht_mcs_set, 8); 55 56 pos += sizeof(*cap); 57 58 return pos; 59 } 60 61 62 u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid) 63 { 64 struct ieee80211_vht_operation *oper; 65 u8 *pos = eid; 66 67 *pos++ = WLAN_EID_VHT_OPERATION; 68 *pos++ = sizeof(*oper); 69 70 oper = (struct ieee80211_vht_operation *) pos; 71 os_memset(oper, 0, sizeof(*oper)); 72 73 /* 74 * center freq = 5 GHz + (5 * index) 75 * So index 42 gives center freq 5.210 GHz 76 * which is channel 42 in 5G band 77 */ 78 oper->vht_op_info_chan_center_freq_seg0_idx = 79 hapd->iconf->vht_oper_centr_freq_seg0_idx; 80 oper->vht_op_info_chan_center_freq_seg1_idx = 81 hapd->iconf->vht_oper_centr_freq_seg1_idx; 82 83 oper->vht_op_info_chwidth = hapd->iconf->vht_oper_chwidth; 84 if (hapd->iconf->vht_oper_chwidth == 2) { 85 /* 86 * Convert 160 MHz channel width to new style as interop 87 * workaround. 88 */ 89 oper->vht_op_info_chwidth = 1; 90 oper->vht_op_info_chan_center_freq_seg1_idx = 91 oper->vht_op_info_chan_center_freq_seg0_idx; 92 if (hapd->iconf->channel < 93 hapd->iconf->vht_oper_centr_freq_seg0_idx) 94 oper->vht_op_info_chan_center_freq_seg0_idx -= 8; 95 else 96 oper->vht_op_info_chan_center_freq_seg0_idx += 8; 97 } else if (hapd->iconf->vht_oper_chwidth == 3) { 98 /* 99 * Convert 80+80 MHz channel width to new style as interop 100 * workaround. 101 */ 102 oper->vht_op_info_chwidth = 1; 103 } 104 105 /* VHT Basic MCS set comes from hw */ 106 /* Hard code 1 stream, MCS0-7 is a min Basic VHT MCS rates */ 107 oper->vht_basic_mcs_set = host_to_le16(0xfffc); 108 pos += sizeof(*oper); 109 110 return pos; 111 } 112 113 114 static int check_valid_vht_mcs(struct hostapd_hw_modes *mode, 115 const u8 *sta_vht_capab) 116 { 117 const struct ieee80211_vht_capabilities *vht_cap; 118 struct ieee80211_vht_capabilities ap_vht_cap; 119 u16 sta_rx_mcs_set, ap_tx_mcs_set; 120 int i; 121 122 if (!mode) 123 return 1; 124 125 /* 126 * Disable VHT caps for STAs for which there is not even a single 127 * allowed MCS in any supported number of streams, i.e., STA is 128 * advertising 3 (not supported) as VHT MCS rates for all supported 129 * stream cases. 130 */ 131 os_memcpy(&ap_vht_cap.vht_supported_mcs_set, mode->vht_mcs_set, 132 sizeof(ap_vht_cap.vht_supported_mcs_set)); 133 vht_cap = (const struct ieee80211_vht_capabilities *) sta_vht_capab; 134 135 /* AP Tx MCS map vs. STA Rx MCS map */ 136 sta_rx_mcs_set = le_to_host16(vht_cap->vht_supported_mcs_set.rx_map); 137 ap_tx_mcs_set = le_to_host16(ap_vht_cap.vht_supported_mcs_set.tx_map); 138 139 for (i = 0; i < VHT_RX_NSS_MAX_STREAMS; i++) { 140 if ((ap_tx_mcs_set & (0x3 << (i * 2))) == 3) 141 continue; 142 143 if ((sta_rx_mcs_set & (0x3 << (i * 2))) == 3) 144 continue; 145 146 return 1; 147 } 148 149 wpa_printf(MSG_DEBUG, 150 "No matching VHT MCS found between AP TX and STA RX"); 151 return 0; 152 } 153 154 155 u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid) 156 { 157 u8 bw, chan1, chan2 = 0; 158 int freq1; 159 160 if (!hapd->cs_freq_params.channel || 161 !hapd->cs_freq_params.vht_enabled) 162 return eid; 163 164 /* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80 */ 165 switch (hapd->cs_freq_params.bandwidth) { 166 case 40: 167 bw = 0; 168 break; 169 case 80: 170 /* check if it's 80+80 */ 171 if (!hapd->cs_freq_params.center_freq2) 172 bw = 1; 173 else 174 bw = 3; 175 break; 176 case 160: 177 bw = 2; 178 break; 179 default: 180 /* not valid VHT bandwidth or not in CSA */ 181 return eid; 182 } 183 184 freq1 = hapd->cs_freq_params.center_freq1 ? 185 hapd->cs_freq_params.center_freq1 : 186 hapd->cs_freq_params.freq; 187 if (ieee80211_freq_to_chan(freq1, &chan1) != 188 HOSTAPD_MODE_IEEE80211A) 189 return eid; 190 191 if (hapd->cs_freq_params.center_freq2 && 192 ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2, 193 &chan2) != HOSTAPD_MODE_IEEE80211A) 194 return eid; 195 196 *eid++ = WLAN_EID_VHT_CHANNEL_SWITCH_WRAPPER; 197 *eid++ = 5; /* Length of Channel Switch Wrapper */ 198 *eid++ = WLAN_EID_VHT_WIDE_BW_CHSWITCH; 199 *eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */ 200 *eid++ = bw; /* New Channel Width */ 201 *eid++ = chan1; /* New Channel Center Frequency Segment 0 */ 202 *eid++ = chan2; /* New Channel Center Frequency Segment 1 */ 203 204 return eid; 205 } 206 207 208 u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid) 209 { 210 struct hostapd_iface *iface = hapd->iface; 211 struct hostapd_config *iconf = iface->conf; 212 struct hostapd_hw_modes *mode = iface->current_mode; 213 struct hostapd_channel_data *chan; 214 int dfs, i; 215 u8 channel, tx_pwr_count, local_pwr_constraint; 216 int max_tx_power; 217 u8 tx_pwr; 218 219 if (!mode) 220 return eid; 221 222 if (ieee80211_freq_to_chan(iface->freq, &channel) == NUM_HOSTAPD_MODES) 223 return eid; 224 225 for (i = 0; i < mode->num_channels; i++) { 226 if (mode->channels[i].freq == iface->freq) 227 break; 228 } 229 if (i == mode->num_channels) 230 return eid; 231 232 switch (iface->conf->vht_oper_chwidth) { 233 case VHT_CHANWIDTH_USE_HT: 234 if (iconf->secondary_channel == 0) { 235 /* Max Transmit Power count = 0 (20 MHz) */ 236 tx_pwr_count = 0; 237 } else { 238 /* Max Transmit Power count = 1 (20, 40 MHz) */ 239 tx_pwr_count = 1; 240 } 241 break; 242 case VHT_CHANWIDTH_80MHZ: 243 /* Max Transmit Power count = 2 (20, 40, and 80 MHz) */ 244 tx_pwr_count = 2; 245 break; 246 case VHT_CHANWIDTH_80P80MHZ: 247 case VHT_CHANWIDTH_160MHZ: 248 /* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */ 249 tx_pwr_count = 3; 250 break; 251 default: 252 return eid; 253 } 254 255 /* 256 * Below local_pwr_constraint logic is referred from 257 * hostapd_eid_pwr_constraint. 258 * 259 * Check if DFS is required by regulatory. 260 */ 261 dfs = hostapd_is_dfs_required(hapd->iface); 262 if (dfs < 0) 263 dfs = 0; 264 265 /* 266 * In order to meet regulations when TPC is not implemented using 267 * a transmit power that is below the legal maximum (including any 268 * mitigation factor) should help. In this case, indicate 3 dB below 269 * maximum allowed transmit power. 270 */ 271 if (hapd->iconf->local_pwr_constraint == -1) 272 local_pwr_constraint = (dfs == 0) ? 0 : 3; 273 else 274 local_pwr_constraint = hapd->iconf->local_pwr_constraint; 275 276 /* 277 * A STA that is not an AP shall use a transmit power less than or 278 * equal to the local maximum transmit power level for the channel. 279 * The local maximum transmit power can be calculated from the formula: 280 * local max TX pwr = max TX pwr - local pwr constraint 281 * Where max TX pwr is maximum transmit power level specified for 282 * channel in Country element and local pwr constraint is specified 283 * for channel in this Power Constraint element. 284 */ 285 chan = &mode->channels[i]; 286 max_tx_power = chan->max_tx_power - local_pwr_constraint; 287 288 /* 289 * Local Maximum Transmit power is encoded as two's complement 290 * with a 0.5 dB step. 291 */ 292 max_tx_power *= 2; /* in 0.5 dB steps */ 293 if (max_tx_power > 127) { 294 /* 63.5 has special meaning of 63.5 dBm or higher */ 295 max_tx_power = 127; 296 } 297 if (max_tx_power < -128) 298 max_tx_power = -128; 299 if (max_tx_power < 0) 300 tx_pwr = 0x80 + max_tx_power + 128; 301 else 302 tx_pwr = max_tx_power; 303 304 *eid++ = WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE; 305 *eid++ = 2 + tx_pwr_count; 306 307 /* 308 * Max Transmit Power count and 309 * Max Transmit Power units = 0 (EIRP) 310 */ 311 *eid++ = tx_pwr_count; 312 313 for (i = 0; i <= tx_pwr_count; i++) 314 *eid++ = tx_pwr; 315 316 return eid; 317 } 318 319 320 u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta, 321 const u8 *vht_capab) 322 { 323 /* Disable VHT caps for STAs associated to no-VHT BSSes. */ 324 if (!vht_capab || 325 hapd->conf->disable_11ac || 326 !check_valid_vht_mcs(hapd->iface->current_mode, vht_capab)) { 327 sta->flags &= ~WLAN_STA_VHT; 328 os_free(sta->vht_capabilities); 329 sta->vht_capabilities = NULL; 330 return WLAN_STATUS_SUCCESS; 331 } 332 333 if (sta->vht_capabilities == NULL) { 334 sta->vht_capabilities = 335 os_zalloc(sizeof(struct ieee80211_vht_capabilities)); 336 if (sta->vht_capabilities == NULL) 337 return WLAN_STATUS_UNSPECIFIED_FAILURE; 338 } 339 340 sta->flags |= WLAN_STA_VHT; 341 os_memcpy(sta->vht_capabilities, vht_capab, 342 sizeof(struct ieee80211_vht_capabilities)); 343 344 return WLAN_STATUS_SUCCESS; 345 } 346 347 348 u16 copy_sta_vendor_vht(struct hostapd_data *hapd, struct sta_info *sta, 349 const u8 *ie, size_t len) 350 { 351 const u8 *vht_capab; 352 unsigned int vht_capab_len; 353 354 if (!ie || len < 5 + 2 + sizeof(struct ieee80211_vht_capabilities) || 355 hapd->conf->disable_11ac) 356 goto no_capab; 357 358 /* The VHT Capabilities element embedded in vendor VHT */ 359 vht_capab = ie + 5; 360 if (vht_capab[0] != WLAN_EID_VHT_CAP) 361 goto no_capab; 362 vht_capab_len = vht_capab[1]; 363 if (vht_capab_len < sizeof(struct ieee80211_vht_capabilities) || 364 (int) vht_capab_len > ie + len - vht_capab - 2) 365 goto no_capab; 366 vht_capab += 2; 367 368 if (sta->vht_capabilities == NULL) { 369 sta->vht_capabilities = 370 os_zalloc(sizeof(struct ieee80211_vht_capabilities)); 371 if (sta->vht_capabilities == NULL) 372 return WLAN_STATUS_UNSPECIFIED_FAILURE; 373 } 374 375 sta->flags |= WLAN_STA_VHT | WLAN_STA_VENDOR_VHT; 376 os_memcpy(sta->vht_capabilities, vht_capab, 377 sizeof(struct ieee80211_vht_capabilities)); 378 return WLAN_STATUS_SUCCESS; 379 380 no_capab: 381 sta->flags &= ~WLAN_STA_VENDOR_VHT; 382 return WLAN_STATUS_SUCCESS; 383 } 384 385 386 u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid) 387 { 388 u8 *pos = eid; 389 390 if (!hapd->iface->current_mode) 391 return eid; 392 393 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 394 *pos++ = (5 + /* The Vendor OUI, type and subtype */ 395 2 + sizeof(struct ieee80211_vht_capabilities) + 396 2 + sizeof(struct ieee80211_vht_operation)); 397 398 WPA_PUT_BE32(pos, (OUI_BROADCOM << 8) | VENDOR_VHT_TYPE); 399 pos += 4; 400 *pos++ = VENDOR_VHT_SUBTYPE; 401 pos = hostapd_eid_vht_capabilities(hapd, pos); 402 pos = hostapd_eid_vht_operation(hapd, pos); 403 404 return pos; 405 } 406 407 408 u16 set_sta_vht_opmode(struct hostapd_data *hapd, struct sta_info *sta, 409 const u8 *vht_oper_notif) 410 { 411 if (!vht_oper_notif) { 412 sta->flags &= ~WLAN_STA_VHT_OPMODE_ENABLED; 413 return WLAN_STATUS_SUCCESS; 414 } 415 416 sta->flags |= WLAN_STA_VHT_OPMODE_ENABLED; 417 sta->vht_opmode = *vht_oper_notif; 418 return WLAN_STATUS_SUCCESS; 419 } 420 421 422 void hostapd_get_vht_capab(struct hostapd_data *hapd, 423 struct ieee80211_vht_capabilities *vht_cap, 424 struct ieee80211_vht_capabilities *neg_vht_cap) 425 { 426 u32 cap, own_cap, sym_caps; 427 428 if (vht_cap == NULL) 429 return; 430 os_memcpy(neg_vht_cap, vht_cap, sizeof(*neg_vht_cap)); 431 432 cap = le_to_host32(neg_vht_cap->vht_capabilities_info); 433 own_cap = hapd->iconf->vht_capab; 434 435 /* mask out symmetric VHT capabilities we don't support */ 436 sym_caps = VHT_CAP_SHORT_GI_80 | VHT_CAP_SHORT_GI_160; 437 cap &= ~sym_caps | (own_cap & sym_caps); 438 439 /* mask out beamformer/beamformee caps if not supported */ 440 if (!(own_cap & VHT_CAP_SU_BEAMFORMER_CAPABLE)) 441 cap &= ~(VHT_CAP_SU_BEAMFORMEE_CAPABLE | 442 VHT_CAP_BEAMFORMEE_STS_MAX); 443 444 if (!(own_cap & VHT_CAP_SU_BEAMFORMEE_CAPABLE)) 445 cap &= ~(VHT_CAP_SU_BEAMFORMER_CAPABLE | 446 VHT_CAP_SOUNDING_DIMENSION_MAX); 447 448 if (!(own_cap & VHT_CAP_MU_BEAMFORMER_CAPABLE)) 449 cap &= ~VHT_CAP_MU_BEAMFORMEE_CAPABLE; 450 451 if (!(own_cap & VHT_CAP_MU_BEAMFORMEE_CAPABLE)) 452 cap &= ~VHT_CAP_MU_BEAMFORMER_CAPABLE; 453 454 /* mask channel widths we don't support */ 455 switch (own_cap & VHT_CAP_SUPP_CHAN_WIDTH_MASK) { 456 case VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ: 457 break; 458 case VHT_CAP_SUPP_CHAN_WIDTH_160MHZ: 459 if (cap & VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) { 460 cap &= ~VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 461 cap |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; 462 } 463 break; 464 default: 465 cap &= ~VHT_CAP_SUPP_CHAN_WIDTH_MASK; 466 break; 467 } 468 469 if (!(cap & VHT_CAP_SUPP_CHAN_WIDTH_MASK)) 470 cap &= ~VHT_CAP_SHORT_GI_160; 471 472 /* 473 * if we don't support RX STBC, mask out TX STBC in the STA's HT caps 474 * if we don't support TX STBC, mask out RX STBC in the STA's HT caps 475 */ 476 if (!(own_cap & VHT_CAP_RXSTBC_MASK)) 477 cap &= ~VHT_CAP_TXSTBC; 478 if (!(own_cap & VHT_CAP_TXSTBC)) 479 cap &= ~VHT_CAP_RXSTBC_MASK; 480 481 neg_vht_cap->vht_capabilities_info = host_to_le32(cap); 482 } 483