1 /* 2 * hostapd / Hardware feature query and different modes 3 * Copyright 2002-2003, Instant802 Networks, Inc. 4 * Copyright 2005-2006, Devicescape Software, Inc. 5 * Copyright (c) 2008-2012, Jouni Malinen <j@w1.fi> 6 * 7 * This software may be distributed under the terms of the BSD license. 8 * See README for more details. 9 */ 10 11 #include "utils/includes.h" 12 13 #include "utils/common.h" 14 #include "utils/eloop.h" 15 #include "common/ieee802_11_defs.h" 16 #include "common/ieee802_11_common.h" 17 #include "common/wpa_ctrl.h" 18 #include "common/hw_features_common.h" 19 #include "hostapd.h" 20 #include "ap_config.h" 21 #include "ap_drv_ops.h" 22 #include "acs.h" 23 #include "ieee802_11.h" 24 #include "beacon.h" 25 #include "hw_features.h" 26 27 hostapd_free_hw_features(struct hostapd_hw_modes * hw_features,size_t num_hw_features)28 void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features, 29 size_t num_hw_features) 30 { 31 size_t i; 32 33 if (hw_features == NULL) 34 return; 35 36 for (i = 0; i < num_hw_features; i++) { 37 os_free(hw_features[i].channels); 38 os_free(hw_features[i].rates); 39 } 40 41 os_free(hw_features); 42 } 43 44 45 #ifndef CONFIG_NO_STDOUT_DEBUG dfs_info(struct hostapd_channel_data * chan)46 static char * dfs_info(struct hostapd_channel_data *chan) 47 { 48 static char info[256]; 49 char *state; 50 51 switch (chan->flag & HOSTAPD_CHAN_DFS_MASK) { 52 case HOSTAPD_CHAN_DFS_UNKNOWN: 53 state = "unknown"; 54 break; 55 case HOSTAPD_CHAN_DFS_USABLE: 56 state = "usable"; 57 break; 58 case HOSTAPD_CHAN_DFS_UNAVAILABLE: 59 state = "unavailable"; 60 break; 61 case HOSTAPD_CHAN_DFS_AVAILABLE: 62 state = "available"; 63 break; 64 default: 65 return ""; 66 } 67 os_snprintf(info, sizeof(info), " (DFS state = %s)", state); 68 info[sizeof(info) - 1] = '\0'; 69 70 return info; 71 } 72 #endif /* CONFIG_NO_STDOUT_DEBUG */ 73 74 hostapd_get_hw_features(struct hostapd_iface * iface)75 int hostapd_get_hw_features(struct hostapd_iface *iface) 76 { 77 struct hostapd_data *hapd = iface->bss[0]; 78 int i, j; 79 unsigned int k; 80 u16 num_modes, flags; 81 struct hostapd_hw_modes *modes; 82 u8 dfs_domain; 83 enum hostapd_hw_mode mode = HOSTAPD_MODE_IEEE80211ANY; 84 bool is_6ghz = false; 85 bool orig_mode_valid = false; 86 struct hostapd_multi_hw_info *multi_hw_info; 87 unsigned int num_multi_hws; 88 89 if (hostapd_drv_none(hapd)) 90 return -1; 91 modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags, 92 &dfs_domain); 93 if (modes == NULL) { 94 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 95 HOSTAPD_LEVEL_DEBUG, 96 "Fetching hardware channel/rate support not " 97 "supported."); 98 return -1; 99 } 100 101 iface->hw_flags = flags; 102 iface->dfs_domain = dfs_domain; 103 104 if (iface->current_mode) { 105 /* 106 * Received driver event CHANNEL_LIST_CHANGED when the current 107 * hw mode is valid. Clear iface->current_mode temporarily as 108 * the mode instance will be replaced with a new instance and 109 * the current pointer would be pointing to freed memory. 110 */ 111 orig_mode_valid = true; 112 mode = iface->current_mode->mode; 113 is_6ghz = iface->current_mode->is_6ghz; 114 iface->current_mode = NULL; 115 } 116 hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); 117 iface->hw_features = modes; 118 iface->num_hw_features = num_modes; 119 120 for (i = 0; i < num_modes; i++) { 121 struct hostapd_hw_modes *feature = &modes[i]; 122 int dfs_enabled = hapd->iconf->ieee80211h && 123 (iface->drv_flags & WPA_DRIVER_FLAGS_RADAR); 124 125 /* Restore orignal mode if possible */ 126 if (orig_mode_valid && feature->mode == mode && 127 feature->num_channels > 0 && 128 is_6ghz == is_6ghz_freq(feature->channels[0].freq)) 129 iface->current_mode = feature; 130 131 /* set flag for channels we can use in current regulatory 132 * domain */ 133 for (j = 0; j < feature->num_channels; j++) { 134 int dfs = 0; 135 136 /* 137 * Disable all channels that are marked not to allow 138 * to initiate radiation (a.k.a. passive scan and no 139 * IBSS). 140 * Use radar channels only if the driver supports DFS. 141 */ 142 if ((feature->channels[j].flag & 143 HOSTAPD_CHAN_RADAR) && dfs_enabled) { 144 dfs = 1; 145 } else if (((feature->channels[j].flag & 146 HOSTAPD_CHAN_RADAR) && 147 !(iface->drv_flags & 148 WPA_DRIVER_FLAGS_DFS_OFFLOAD)) || 149 (feature->channels[j].flag & 150 HOSTAPD_CHAN_NO_IR)) { 151 feature->channels[j].flag |= 152 HOSTAPD_CHAN_DISABLED; 153 } 154 155 if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED) 156 continue; 157 158 wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d " 159 "chan=%d freq=%d MHz max_tx_power=%d dBm%s", 160 feature->mode, 161 feature->channels[j].chan, 162 feature->channels[j].freq, 163 feature->channels[j].max_tx_power, 164 dfs ? dfs_info(&feature->channels[j]) : ""); 165 } 166 } 167 168 if (orig_mode_valid && !iface->current_mode) { 169 wpa_printf(MSG_ERROR, 170 "%s: Could not update iface->current_mode", 171 __func__); 172 } 173 174 multi_hw_info = hostapd_get_multi_hw_info(hapd, &num_multi_hws); 175 if (!multi_hw_info) 176 return 0; 177 178 hostapd_free_multi_hw_info(iface->multi_hw_info); 179 iface->multi_hw_info = multi_hw_info; 180 iface->num_multi_hws = num_multi_hws; 181 182 wpa_printf(MSG_DEBUG, "Multiple underlying hardwares info:"); 183 184 for (k = 0; k < num_multi_hws; k++) { 185 struct hostapd_multi_hw_info *hw_info = &multi_hw_info[k]; 186 187 wpa_printf(MSG_DEBUG, 188 " %d. hw_idx=%u, frequency range: %d-%d MHz", 189 k + 1, hw_info->hw_idx, hw_info->start_freq, 190 hw_info->end_freq); 191 } 192 193 return 0; 194 } 195 196 hostapd_prepare_rates(struct hostapd_iface * iface,struct hostapd_hw_modes * mode)197 int hostapd_prepare_rates(struct hostapd_iface *iface, 198 struct hostapd_hw_modes *mode) 199 { 200 int i, num_basic_rates = 0; 201 int basic_rates_a[] = { 60, 120, 240, -1 }; 202 int basic_rates_b[] = { 10, 20, -1 }; 203 int basic_rates_g[] = { 10, 20, 55, 110, -1 }; 204 int *basic_rates; 205 206 if (iface->conf->basic_rates) 207 basic_rates = iface->conf->basic_rates; 208 else switch (mode->mode) { 209 case HOSTAPD_MODE_IEEE80211A: 210 basic_rates = basic_rates_a; 211 break; 212 case HOSTAPD_MODE_IEEE80211B: 213 basic_rates = basic_rates_b; 214 break; 215 case HOSTAPD_MODE_IEEE80211G: 216 basic_rates = basic_rates_g; 217 break; 218 case HOSTAPD_MODE_IEEE80211AD: 219 return 0; /* No basic rates for 11ad */ 220 default: 221 return -1; 222 } 223 224 i = 0; 225 while (basic_rates[i] >= 0) 226 i++; 227 if (i) 228 i++; /* -1 termination */ 229 os_free(iface->basic_rates); 230 iface->basic_rates = os_malloc(i * sizeof(int)); 231 if (iface->basic_rates) 232 os_memcpy(iface->basic_rates, basic_rates, i * sizeof(int)); 233 234 os_free(iface->current_rates); 235 iface->num_rates = 0; 236 237 iface->current_rates = 238 os_calloc(mode->num_rates, sizeof(struct hostapd_rate_data)); 239 if (!iface->current_rates) { 240 wpa_printf(MSG_ERROR, "Failed to allocate memory for rate " 241 "table."); 242 return -1; 243 } 244 245 for (i = 0; i < mode->num_rates; i++) { 246 struct hostapd_rate_data *rate; 247 248 if (iface->conf->supported_rates && 249 !hostapd_rate_found(iface->conf->supported_rates, 250 mode->rates[i])) 251 continue; 252 253 rate = &iface->current_rates[iface->num_rates]; 254 rate->rate = mode->rates[i]; 255 if (hostapd_rate_found(basic_rates, rate->rate)) { 256 rate->flags |= HOSTAPD_RATE_BASIC; 257 num_basic_rates++; 258 } 259 wpa_printf(MSG_DEBUG, "RATE[%d] rate=%d flags=0x%x", 260 iface->num_rates, rate->rate, rate->flags); 261 iface->num_rates++; 262 } 263 264 if ((iface->num_rates == 0 || num_basic_rates == 0) && 265 (!iface->conf->ieee80211n || !iface->conf->require_ht)) { 266 wpa_printf(MSG_ERROR, "No rates remaining in supported/basic " 267 "rate sets (%d,%d).", 268 iface->num_rates, num_basic_rates); 269 return -1; 270 } 271 272 return 0; 273 } 274 275 ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface * iface)276 static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface) 277 { 278 int pri_freq, sec_freq; 279 struct hostapd_channel_data *p_chan, *s_chan; 280 281 pri_freq = iface->freq; 282 sec_freq = pri_freq + iface->conf->secondary_channel * 20; 283 284 if (!iface->current_mode) 285 return 0; 286 287 p_chan = hw_get_channel_freq(iface->current_mode->mode, pri_freq, NULL, 288 iface->hw_features, 289 iface->num_hw_features); 290 291 s_chan = hw_get_channel_freq(iface->current_mode->mode, sec_freq, NULL, 292 iface->hw_features, 293 iface->num_hw_features); 294 295 return allowed_ht40_channel_pair(iface->current_mode->mode, 296 p_chan, s_chan); 297 } 298 299 ieee80211n_switch_pri_sec(struct hostapd_iface * iface)300 static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface) 301 { 302 if (iface->conf->secondary_channel > 0) { 303 iface->conf->channel += 4; 304 iface->freq += 20; 305 iface->conf->secondary_channel = -1; 306 } else { 307 iface->conf->channel -= 4; 308 iface->freq -= 20; 309 iface->conf->secondary_channel = 1; 310 } 311 } 312 313 ieee80211n_check_40mhz_5g(struct hostapd_iface * iface,struct wpa_scan_results * scan_res)314 static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface, 315 struct wpa_scan_results *scan_res) 316 { 317 unsigned int pri_freq, sec_freq; 318 int res; 319 struct hostapd_channel_data *pri_chan, *sec_chan; 320 321 pri_freq = iface->freq; 322 sec_freq = pri_freq + iface->conf->secondary_channel * 20; 323 324 if (!iface->current_mode) 325 return 0; 326 pri_chan = hw_get_channel_freq(iface->current_mode->mode, pri_freq, 327 NULL, iface->hw_features, 328 iface->num_hw_features); 329 sec_chan = hw_get_channel_freq(iface->current_mode->mode, sec_freq, 330 NULL, iface->hw_features, 331 iface->num_hw_features); 332 333 res = check_40mhz_5g(scan_res, pri_chan, sec_chan); 334 335 if (res == 2) { 336 if (iface->conf->no_pri_sec_switch) { 337 wpa_printf(MSG_DEBUG, 338 "Cannot switch PRI/SEC channels due to local constraint"); 339 } else { 340 ieee80211n_switch_pri_sec(iface); 341 } 342 } 343 344 return !!res; 345 } 346 347 ieee80211n_check_40mhz_2g4(struct hostapd_iface * iface,struct wpa_scan_results * scan_res)348 static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface, 349 struct wpa_scan_results *scan_res) 350 { 351 int pri_chan, sec_chan; 352 353 pri_chan = iface->conf->channel; 354 sec_chan = pri_chan + iface->conf->secondary_channel * 4; 355 356 return check_40mhz_2g4(iface->current_mode, scan_res, pri_chan, 357 sec_chan); 358 } 359 360 ieee80211n_check_scan(struct hostapd_iface * iface)361 static void ieee80211n_check_scan(struct hostapd_iface *iface) 362 { 363 struct wpa_scan_results *scan_res; 364 int oper40; 365 int res = 0; 366 367 /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is 368 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */ 369 370 iface->scan_cb = NULL; 371 372 scan_res = hostapd_driver_get_scan_results(iface->bss[0]); 373 if (scan_res == NULL) { 374 hostapd_setup_interface_complete(iface, 1); 375 return; 376 } 377 378 if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A) 379 oper40 = ieee80211n_check_40mhz_5g(iface, scan_res); 380 else 381 oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res); 382 wpa_scan_results_free(scan_res); 383 384 iface->secondary_ch = iface->conf->secondary_channel; 385 if (!oper40) { 386 wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on " 387 "channel pri=%d sec=%d based on overlapping BSSes", 388 iface->conf->channel, 389 iface->conf->channel + 390 iface->conf->secondary_channel * 4); 391 iface->conf->secondary_channel = 0; 392 if (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX) { 393 /* 394 * TODO: Could consider scheduling another scan to check 395 * if channel width can be changed if no coex reports 396 * are received from associating stations. 397 */ 398 } 399 } 400 401 #ifdef CONFIG_IEEE80211AX 402 if (iface->conf->secondary_channel && 403 iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G && 404 iface->conf->ieee80211ax) { 405 struct he_capabilities *he_cap; 406 407 he_cap = &iface->current_mode->he_capab[IEEE80211_MODE_AP]; 408 if (!(he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & 409 HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G)) { 410 wpa_printf(MSG_DEBUG, 411 "HE: 40 MHz channel width is not supported in 2.4 GHz; clear secondary channel configuration"); 412 iface->conf->secondary_channel = 0; 413 } 414 } 415 #endif /* CONFIG_IEEE80211AX */ 416 417 if (iface->conf->secondary_channel) 418 res = ieee80211n_allowed_ht40_channel_pair(iface); 419 if (!res) { 420 iface->conf->secondary_channel = 0; 421 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, 0); 422 hostapd_set_oper_centr_freq_seg1_idx(iface->conf, 0); 423 hostapd_set_oper_chwidth(iface->conf, CONF_OPER_CHWIDTH_USE_HT); 424 res = 1; 425 wpa_printf(MSG_INFO, "Fallback to 20 MHz"); 426 } 427 428 hostapd_setup_interface_complete(iface, !res); 429 } 430 431 ieee80211n_scan_channels_2g4(struct hostapd_iface * iface,struct wpa_driver_scan_params * params)432 static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface, 433 struct wpa_driver_scan_params *params) 434 { 435 /* Scan only the affected frequency range */ 436 int pri_freq, sec_freq; 437 int affected_start, affected_end; 438 int i, pos; 439 struct hostapd_hw_modes *mode; 440 441 if (iface->current_mode == NULL) 442 return; 443 444 pri_freq = iface->freq; 445 if (iface->conf->secondary_channel > 0) 446 sec_freq = pri_freq + 20; 447 else 448 sec_freq = pri_freq - 20; 449 /* 450 * Note: Need to find the PRI channel also in cases where the affected 451 * channel is the SEC channel of a 40 MHz BSS, so need to include the 452 * scanning coverage here to be 40 MHz from the center frequency. 453 */ 454 affected_start = (pri_freq + sec_freq) / 2 - 40; 455 affected_end = (pri_freq + sec_freq) / 2 + 40; 456 wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz", 457 affected_start, affected_end); 458 459 mode = iface->current_mode; 460 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 461 if (params->freqs == NULL) 462 return; 463 pos = 0; 464 465 for (i = 0; i < mode->num_channels; i++) { 466 struct hostapd_channel_data *chan = &mode->channels[i]; 467 if (chan->flag & HOSTAPD_CHAN_DISABLED) 468 continue; 469 if (chan->freq < affected_start || 470 chan->freq > affected_end) 471 continue; 472 params->freqs[pos++] = chan->freq; 473 } 474 } 475 476 ieee80211n_scan_channels_5g(struct hostapd_iface * iface,struct wpa_driver_scan_params * params)477 static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface, 478 struct wpa_driver_scan_params *params) 479 { 480 /* Scan only the affected frequency range */ 481 int pri_freq; 482 int affected_start, affected_end; 483 int i, pos; 484 struct hostapd_hw_modes *mode; 485 486 if (iface->current_mode == NULL) 487 return; 488 489 pri_freq = iface->freq; 490 if (iface->conf->secondary_channel > 0) { 491 affected_start = pri_freq - 10; 492 affected_end = pri_freq + 30; 493 } else { 494 affected_start = pri_freq - 30; 495 affected_end = pri_freq + 10; 496 } 497 wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz", 498 affected_start, affected_end); 499 500 mode = iface->current_mode; 501 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 502 if (params->freqs == NULL) 503 return; 504 pos = 0; 505 506 for (i = 0; i < mode->num_channels; i++) { 507 struct hostapd_channel_data *chan = &mode->channels[i]; 508 if (chan->flag & HOSTAPD_CHAN_DISABLED) 509 continue; 510 if (chan->freq < affected_start || 511 chan->freq > affected_end) 512 continue; 513 params->freqs[pos++] = chan->freq; 514 } 515 } 516 517 ap_ht40_scan_retry(void * eloop_data,void * user_data)518 static void ap_ht40_scan_retry(void *eloop_data, void *user_data) 519 { 520 #define HT2040_COEX_SCAN_RETRY 15 521 struct hostapd_iface *iface = eloop_data; 522 struct wpa_driver_scan_params params; 523 int ret; 524 525 os_memset(¶ms, 0, sizeof(params)); 526 if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 527 ieee80211n_scan_channels_2g4(iface, ¶ms); 528 else 529 ieee80211n_scan_channels_5g(iface, ¶ms); 530 531 ret = hostapd_driver_scan(iface->bss[0], ¶ms); 532 iface->num_ht40_scan_tries++; 533 os_free(params.freqs); 534 535 if (ret == -EBUSY && 536 iface->num_ht40_scan_tries < HT2040_COEX_SCAN_RETRY) { 537 wpa_printf(MSG_ERROR, 538 "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)", 539 ret, strerror(-ret), iface->num_ht40_scan_tries); 540 eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL); 541 return; 542 } 543 544 if (ret == 0) { 545 iface->scan_cb = ieee80211n_check_scan; 546 iface->bss[0]->scan_cookie = params.scan_cookie; 547 return; 548 } 549 550 wpa_printf(MSG_DEBUG, 551 "Failed to request a scan in device, bringing up in HT20 mode"); 552 iface->conf->secondary_channel = 0; 553 iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; 554 hostapd_setup_interface_complete(iface, 0); 555 } 556 557 hostapd_stop_setup_timers(struct hostapd_iface * iface)558 void hostapd_stop_setup_timers(struct hostapd_iface *iface) 559 { 560 eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL); 561 } 562 563 ieee80211n_check_40mhz(struct hostapd_iface * iface)564 static int ieee80211n_check_40mhz(struct hostapd_iface *iface) 565 { 566 struct wpa_driver_scan_params params; 567 int ret; 568 569 /* Check that HT40 is used and PRI / SEC switch is allowed */ 570 if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch) 571 return 0; 572 573 hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); 574 wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling " 575 "40 MHz channel"); 576 os_memset(¶ms, 0, sizeof(params)); 577 if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 578 ieee80211n_scan_channels_2g4(iface, ¶ms); 579 else 580 ieee80211n_scan_channels_5g(iface, ¶ms); 581 582 ret = hostapd_driver_scan(iface->bss[0], ¶ms); 583 os_free(params.freqs); 584 585 if (ret == -EBUSY) { 586 wpa_printf(MSG_ERROR, 587 "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again", 588 ret, strerror(-ret)); 589 iface->num_ht40_scan_tries = 1; 590 eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL); 591 eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL); 592 return 1; 593 } 594 595 if (ret < 0) { 596 wpa_printf(MSG_ERROR, 597 "Failed to request a scan of neighboring BSSes ret=%d (%s)", 598 ret, strerror(-ret)); 599 return -1; 600 } 601 602 iface->scan_cb = ieee80211n_check_scan; 603 iface->bss[0]->scan_cookie = params.scan_cookie; 604 return 1; 605 } 606 607 ieee80211n_supported_ht_capab(struct hostapd_iface * iface)608 static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface) 609 { 610 u16 hw = iface->current_mode->ht_capab; 611 u16 conf = iface->conf->ht_capab; 612 613 if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) && 614 !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) { 615 wpa_printf(MSG_ERROR, "Driver does not support configured " 616 "HT capability [LDPC]"); 617 return 0; 618 } 619 620 /* 621 * Driver ACS chosen channel may not be HT40 due to internal driver 622 * restrictions. 623 */ 624 if (!iface->conf->acs && (conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) && 625 !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) { 626 wpa_printf(MSG_ERROR, "Driver does not support configured " 627 "HT capability [HT40*]"); 628 return 0; 629 } 630 631 if ((conf & HT_CAP_INFO_GREEN_FIELD) && 632 !(hw & HT_CAP_INFO_GREEN_FIELD)) { 633 wpa_printf(MSG_ERROR, "Driver does not support configured " 634 "HT capability [GF]"); 635 return 0; 636 } 637 638 if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) && 639 !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) { 640 wpa_printf(MSG_ERROR, "Driver does not support configured " 641 "HT capability [SHORT-GI-20]"); 642 return 0; 643 } 644 645 if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) && 646 !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) { 647 wpa_printf(MSG_ERROR, "Driver does not support configured " 648 "HT capability [SHORT-GI-40]"); 649 return 0; 650 } 651 652 if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) { 653 wpa_printf(MSG_ERROR, "Driver does not support configured " 654 "HT capability [TX-STBC]"); 655 return 0; 656 } 657 658 if ((conf & HT_CAP_INFO_RX_STBC_MASK) > 659 (hw & HT_CAP_INFO_RX_STBC_MASK)) { 660 wpa_printf(MSG_ERROR, "Driver does not support configured " 661 "HT capability [RX-STBC*]"); 662 return 0; 663 } 664 665 if ((conf & HT_CAP_INFO_DELAYED_BA) && 666 !(hw & HT_CAP_INFO_DELAYED_BA)) { 667 wpa_printf(MSG_ERROR, "Driver does not support configured " 668 "HT capability [DELAYED-BA]"); 669 return 0; 670 } 671 672 if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) && 673 !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) { 674 wpa_printf(MSG_ERROR, "Driver does not support configured " 675 "HT capability [MAX-AMSDU-7935]"); 676 return 0; 677 } 678 679 if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) && 680 !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) { 681 wpa_printf(MSG_ERROR, "Driver does not support configured " 682 "HT capability [DSSS_CCK-40]"); 683 return 0; 684 } 685 686 if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) && 687 !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) { 688 wpa_printf(MSG_ERROR, "Driver does not support configured " 689 "HT capability [LSIG-TXOP-PROT]"); 690 return 0; 691 } 692 693 return 1; 694 } 695 696 697 #ifdef CONFIG_IEEE80211AC ieee80211ac_supported_vht_capab(struct hostapd_iface * iface)698 static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface) 699 { 700 struct hostapd_hw_modes *mode = iface->current_mode; 701 u32 hw = mode->vht_capab; 702 u32 conf = iface->conf->vht_capab; 703 704 wpa_printf(MSG_DEBUG, "hw vht capab: 0x%x, conf vht capab: 0x%x", 705 hw, conf); 706 707 if (mode->mode == HOSTAPD_MODE_IEEE80211G && 708 iface->conf->bss[0]->vendor_vht && 709 mode->vht_capab == 0 && iface->hw_features) { 710 int i; 711 712 for (i = 0; i < iface->num_hw_features; i++) { 713 if (iface->hw_features[i].mode == 714 HOSTAPD_MODE_IEEE80211A) { 715 mode = &iface->hw_features[i]; 716 hw = mode->vht_capab; 717 wpa_printf(MSG_DEBUG, 718 "update hw vht capab based on 5 GHz band: 0x%x", 719 hw); 720 break; 721 } 722 } 723 } 724 725 return ieee80211ac_cap_check(hw, conf); 726 } 727 #endif /* CONFIG_IEEE80211AC */ 728 729 730 #ifdef CONFIG_IEEE80211AX ieee80211ax_supported_he_capab(struct hostapd_iface * iface)731 static int ieee80211ax_supported_he_capab(struct hostapd_iface *iface) 732 { 733 return 1; 734 } 735 #endif /* CONFIG_IEEE80211AX */ 736 737 hostapd_check_ht_capab(struct hostapd_iface * iface)738 int hostapd_check_ht_capab(struct hostapd_iface *iface) 739 { 740 int ret; 741 742 if (is_6ghz_freq(iface->freq)) 743 return 0; 744 if (!iface->conf->ieee80211n) 745 return 0; 746 747 if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211B && 748 iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G && 749 (iface->conf->ht_capab & HT_CAP_INFO_DSSS_CCK40MHZ)) { 750 wpa_printf(MSG_DEBUG, 751 "Disable HT capability [DSSS_CCK-40] on 5 GHz band"); 752 iface->conf->ht_capab &= ~HT_CAP_INFO_DSSS_CCK40MHZ; 753 } 754 755 if (!ieee80211n_supported_ht_capab(iface)) 756 return -1; 757 #ifdef CONFIG_IEEE80211AX 758 if (iface->conf->ieee80211ax && 759 !ieee80211ax_supported_he_capab(iface)) 760 return -1; 761 #endif /* CONFIG_IEEE80211AX */ 762 #ifdef CONFIG_IEEE80211AC 763 if (iface->conf->ieee80211ac && 764 !ieee80211ac_supported_vht_capab(iface)) 765 return -1; 766 #endif /* CONFIG_IEEE80211AC */ 767 ret = ieee80211n_check_40mhz(iface); 768 if (ret) 769 return ret; 770 if (!ieee80211n_allowed_ht40_channel_pair(iface)) 771 return -1; 772 773 return 0; 774 } 775 776 hostapd_check_edmg_capab(struct hostapd_iface * iface)777 int hostapd_check_edmg_capab(struct hostapd_iface *iface) 778 { 779 struct hostapd_hw_modes *mode = iface->hw_features; 780 struct ieee80211_edmg_config edmg; 781 782 if (!iface->conf->enable_edmg) 783 return 0; 784 785 hostapd_encode_edmg_chan(iface->conf->enable_edmg, 786 iface->conf->edmg_channel, 787 iface->conf->channel, 788 &edmg); 789 790 if (mode->edmg.channels && ieee802_edmg_is_allowed(mode->edmg, edmg)) 791 return 0; 792 793 wpa_printf(MSG_WARNING, "Requested EDMG configuration is not valid"); 794 wpa_printf(MSG_INFO, "EDMG capab: channels 0x%x, bw_config %d", 795 mode->edmg.channels, mode->edmg.bw_config); 796 wpa_printf(MSG_INFO, 797 "Requested EDMG configuration: channels 0x%x, bw_config %d", 798 edmg.channels, edmg.bw_config); 799 return -1; 800 } 801 802 hostapd_check_he_6ghz_capab(struct hostapd_iface * iface)803 int hostapd_check_he_6ghz_capab(struct hostapd_iface *iface) 804 { 805 #ifdef CONFIG_IEEE80211AX 806 struct he_capabilities *he_cap; 807 u16 hw; 808 809 if (!iface->current_mode || !is_6ghz_freq(iface->freq)) 810 return 0; 811 812 he_cap = &iface->current_mode->he_capab[IEEE80211_MODE_AP]; 813 hw = he_cap->he_6ghz_capa; 814 if (iface->conf->he_6ghz_max_mpdu > 815 ((hw & HE_6GHZ_BAND_CAP_MAX_MPDU_LEN_MASK) >> 816 HE_6GHZ_BAND_CAP_MAX_MPDU_LEN_SHIFT)) { 817 wpa_printf(MSG_ERROR, 818 "The driver does not support the configured HE 6 GHz Max MPDU length"); 819 return -1; 820 } 821 822 if (iface->conf->he_6ghz_max_ampdu_len_exp > 823 ((hw & HE_6GHZ_BAND_CAP_MAX_AMPDU_LEN_EXP_MASK) >> 824 HE_6GHZ_BAND_CAP_MAX_AMPDU_LEN_EXP_SHIFT)) { 825 wpa_printf(MSG_ERROR, 826 "The driver does not support the configured HE 6 GHz Max AMPDU Length Exponent"); 827 return -1; 828 } 829 830 if (iface->conf->he_6ghz_rx_ant_pat && 831 !(hw & HE_6GHZ_BAND_CAP_RX_ANTPAT_CONS)) { 832 wpa_printf(MSG_ERROR, 833 "The driver does not support the configured HE 6 GHz Rx Antenna Pattern"); 834 return -1; 835 } 836 837 if (iface->conf->he_6ghz_tx_ant_pat && 838 !(hw & HE_6GHZ_BAND_CAP_TX_ANTPAT_CONS)) { 839 wpa_printf(MSG_ERROR, 840 "The driver does not support the configured HE 6 GHz Tx Antenna Pattern"); 841 return -1; 842 } 843 #endif /* CONFIG_IEEE80211AX */ 844 return 0; 845 } 846 847 848 /* Returns: 849 * 1 = usable 850 * 0 = not usable 851 * -1 = not currently usable due to 6 GHz NO-IR 852 */ hostapd_is_usable_chan(struct hostapd_iface * iface,int frequency,int primary)853 static int hostapd_is_usable_chan(struct hostapd_iface *iface, 854 int frequency, int primary) 855 { 856 struct hostapd_channel_data *chan; 857 858 if (!iface->current_mode) 859 return 0; 860 861 chan = hw_get_channel_freq(iface->current_mode->mode, frequency, NULL, 862 iface->hw_features, iface->num_hw_features); 863 if (!chan) 864 return 0; 865 866 if ((primary && chan_pri_allowed(chan)) || 867 (!primary && !(chan->flag & HOSTAPD_CHAN_DISABLED))) 868 return 1; 869 870 wpa_printf(MSG_INFO, 871 "Frequency %d (%s) not allowed for AP mode, flags: 0x%x%s%s", 872 frequency, primary ? "primary" : "secondary", 873 chan->flag, 874 chan->flag & HOSTAPD_CHAN_NO_IR ? " NO-IR" : "", 875 chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : ""); 876 877 if (is_6ghz_freq(chan->freq) && (chan->flag & HOSTAPD_CHAN_NO_IR)) 878 return -1; 879 880 return 0; 881 } 882 883 hostapd_is_usable_edmg(struct hostapd_iface * iface)884 static int hostapd_is_usable_edmg(struct hostapd_iface *iface) 885 { 886 int i, contiguous = 0; 887 int num_of_enabled = 0; 888 int max_contiguous = 0; 889 int err; 890 struct ieee80211_edmg_config edmg; 891 struct hostapd_channel_data *pri_chan; 892 893 if (!iface->conf->enable_edmg) 894 return 1; 895 896 if (!iface->current_mode) 897 return 0; 898 pri_chan = hw_get_channel_freq(iface->current_mode->mode, 899 iface->freq, NULL, 900 iface->hw_features, 901 iface->num_hw_features); 902 if (!pri_chan) 903 return 0; 904 hostapd_encode_edmg_chan(iface->conf->enable_edmg, 905 iface->conf->edmg_channel, 906 pri_chan->chan, 907 &edmg); 908 if (!(edmg.channels & BIT(pri_chan->chan - 1))) 909 return 0; 910 911 /* 60 GHz channels 1..6 */ 912 for (i = 0; i < 6; i++) { 913 int freq = 56160 + 2160 * (i + 1); 914 915 if (edmg.channels & BIT(i)) { 916 contiguous++; 917 num_of_enabled++; 918 } else { 919 contiguous = 0; 920 continue; 921 } 922 923 /* P802.11ay defines that the total number of subfields 924 * set to one does not exceed 4. 925 */ 926 if (num_of_enabled > 4) 927 return 0; 928 929 err = hostapd_is_usable_chan(iface, freq, 1); 930 if (err <= 0) 931 return err; 932 933 if (contiguous > max_contiguous) 934 max_contiguous = contiguous; 935 } 936 937 /* Check if the EDMG configuration is valid under the limitations 938 * of P802.11ay. 939 */ 940 /* check bw_config against contiguous EDMG channels */ 941 switch (edmg.bw_config) { 942 case EDMG_BW_CONFIG_4: 943 if (!max_contiguous) 944 return 0; 945 break; 946 case EDMG_BW_CONFIG_5: 947 if (max_contiguous < 2) 948 return 0; 949 break; 950 default: 951 return 0; 952 } 953 954 return 1; 955 } 956 957 hostapd_is_usable_punct_bitmap(struct hostapd_iface * iface)958 static bool hostapd_is_usable_punct_bitmap(struct hostapd_iface *iface) 959 { 960 #ifdef CONFIG_IEEE80211BE 961 struct hostapd_config *conf = iface->conf; 962 u16 bw; 963 u8 start_chan; 964 965 if (!conf->punct_bitmap) 966 return true; 967 968 if (!conf->ieee80211be) { 969 wpa_printf(MSG_ERROR, 970 "Currently RU puncturing is supported only if ieee80211be is enabled"); 971 return false; 972 } 973 974 if (iface->freq >= 2412 && iface->freq <= 2484) { 975 wpa_printf(MSG_ERROR, 976 "RU puncturing not supported in 2.4 GHz"); 977 return false; 978 } 979 980 /* 981 * In the 6 GHz band, eht_oper_chwidth is ignored. Use operating class 982 * to determine channel width. 983 */ 984 if (conf->op_class == 137) { 985 bw = 320; 986 start_chan = conf->eht_oper_centr_freq_seg0_idx - 30; 987 } else { 988 switch (conf->eht_oper_chwidth) { 989 case 0: 990 wpa_printf(MSG_ERROR, 991 "RU puncturing is supported only in 80 MHz and 160 MHz"); 992 return false; 993 case 1: 994 bw = 80; 995 start_chan = conf->eht_oper_centr_freq_seg0_idx - 6; 996 break; 997 case 2: 998 bw = 160; 999 start_chan = conf->eht_oper_centr_freq_seg0_idx - 14; 1000 break; 1001 default: 1002 return false; 1003 } 1004 } 1005 1006 if (!is_punct_bitmap_valid(bw, (conf->channel - start_chan) / 4, 1007 conf->punct_bitmap)) { 1008 wpa_printf(MSG_ERROR, "Invalid puncturing bitmap"); 1009 return false; 1010 } 1011 #endif /* CONFIG_IEEE80211BE */ 1012 1013 return true; 1014 } 1015 1016 1017 /* Returns: 1018 * 1 = usable 1019 * 0 = not usable 1020 * -1 = not currently usable due to 6 GHz NO-IR 1021 */ hostapd_is_usable_chans(struct hostapd_iface * iface)1022 static int hostapd_is_usable_chans(struct hostapd_iface *iface) 1023 { 1024 int secondary_freq; 1025 struct hostapd_channel_data *pri_chan; 1026 int err, err2; 1027 1028 if (!iface->current_mode) 1029 return 0; 1030 pri_chan = hw_get_channel_freq(iface->current_mode->mode, 1031 iface->freq, NULL, 1032 iface->hw_features, 1033 iface->num_hw_features); 1034 if (!pri_chan) { 1035 wpa_printf(MSG_ERROR, "Primary frequency not present"); 1036 return 0; 1037 } 1038 1039 err = hostapd_is_usable_chan(iface, pri_chan->freq, 1); 1040 if (err <= 0) { 1041 wpa_printf(MSG_ERROR, "Primary frequency not allowed"); 1042 return err; 1043 } 1044 err = hostapd_is_usable_edmg(iface); 1045 if (err <= 0) 1046 return err; 1047 1048 if (!hostapd_is_usable_punct_bitmap(iface)) 1049 return 0; 1050 1051 if (!iface->conf->secondary_channel) 1052 return 1; 1053 1054 err = hostapd_is_usable_chan(iface, iface->freq + 1055 iface->conf->secondary_channel * 20, 0); 1056 if (err > 0) { 1057 if (iface->conf->secondary_channel == 1 && 1058 (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)) 1059 return 1; 1060 if (iface->conf->secondary_channel == -1 && 1061 (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40M)) 1062 return 1; 1063 } 1064 if (!iface->conf->ht40_plus_minus_allowed) 1065 return err; 1066 1067 /* Both HT40+ and HT40- are set, pick a valid secondary channel */ 1068 secondary_freq = iface->freq + 20; 1069 err2 = hostapd_is_usable_chan(iface, secondary_freq, 0); 1070 if (err2 > 0 && (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)) { 1071 iface->conf->secondary_channel = 1; 1072 return 1; 1073 } 1074 1075 secondary_freq = iface->freq - 20; 1076 err2 = hostapd_is_usable_chan(iface, secondary_freq, 0); 1077 if (err2 > 0 && (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40M)) { 1078 iface->conf->secondary_channel = -1; 1079 return 1; 1080 } 1081 1082 return err; 1083 } 1084 1085 skip_mode(struct hostapd_iface * iface,struct hostapd_hw_modes * mode)1086 static bool skip_mode(struct hostapd_iface *iface, 1087 struct hostapd_hw_modes *mode) 1088 { 1089 int chan; 1090 1091 if (iface->freq > 0 && !hw_mode_get_channel(mode, iface->freq, &chan)) 1092 return true; 1093 1094 if (is_6ghz_op_class(iface->conf->op_class) && iface->freq == 0 && 1095 !mode->is_6ghz) 1096 return true; 1097 1098 return false; 1099 } 1100 1101 hostapd_determine_mode(struct hostapd_iface * iface)1102 int hostapd_determine_mode(struct hostapd_iface *iface) 1103 { 1104 int i; 1105 enum hostapd_hw_mode target_mode; 1106 1107 if (iface->current_mode || 1108 iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY) 1109 return 0; 1110 1111 if (iface->freq < 4000) 1112 target_mode = HOSTAPD_MODE_IEEE80211G; 1113 else if (iface->freq > 50000) 1114 target_mode = HOSTAPD_MODE_IEEE80211AD; 1115 else 1116 target_mode = HOSTAPD_MODE_IEEE80211A; 1117 1118 for (i = 0; i < iface->num_hw_features; i++) { 1119 struct hostapd_hw_modes *mode; 1120 1121 mode = &iface->hw_features[i]; 1122 if (mode->mode == target_mode) { 1123 if (skip_mode(iface, mode)) 1124 continue; 1125 1126 iface->current_mode = mode; 1127 iface->conf->hw_mode = mode->mode; 1128 break; 1129 } 1130 } 1131 1132 if (!iface->current_mode) { 1133 wpa_printf(MSG_ERROR, "ACS/CSA: Cannot decide mode"); 1134 return -1; 1135 } 1136 return 0; 1137 } 1138 1139 1140 static enum hostapd_chan_status hostapd_check_chans(struct hostapd_iface * iface)1141 hostapd_check_chans(struct hostapd_iface *iface) 1142 { 1143 if (iface->freq) { 1144 int err; 1145 1146 hostapd_determine_mode(iface); 1147 1148 err = hostapd_is_usable_chans(iface); 1149 if (err <= 0) { 1150 if (!err) 1151 return HOSTAPD_CHAN_INVALID; 1152 return HOSTAPD_CHAN_INVALID_NO_IR; 1153 } 1154 return HOSTAPD_CHAN_VALID; 1155 } 1156 1157 /* 1158 * The user set channel=0 or channel=acs_survey 1159 * which is used to trigger ACS. 1160 */ 1161 1162 switch (acs_init(iface)) { 1163 case HOSTAPD_CHAN_ACS: 1164 return HOSTAPD_CHAN_ACS; 1165 case HOSTAPD_CHAN_INVALID_NO_IR: 1166 return HOSTAPD_CHAN_INVALID_NO_IR; 1167 case HOSTAPD_CHAN_VALID: 1168 case HOSTAPD_CHAN_INVALID: 1169 default: 1170 return HOSTAPD_CHAN_INVALID; 1171 } 1172 } 1173 1174 hostapd_notify_bad_chans(struct hostapd_iface * iface)1175 static void hostapd_notify_bad_chans(struct hostapd_iface *iface) 1176 { 1177 if (!iface->current_mode) { 1178 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211, 1179 HOSTAPD_LEVEL_WARNING, 1180 "Hardware does not support configured mode"); 1181 return; 1182 } 1183 hostapd_logger(iface->bss[0], NULL, 1184 HOSTAPD_MODULE_IEEE80211, 1185 HOSTAPD_LEVEL_WARNING, 1186 "Configured channel (%d) or frequency (%d) (secondary_channel=%d) not found from the channel list of the current mode (%d) %s", 1187 iface->conf->channel, 1188 iface->freq, iface->conf->secondary_channel, 1189 iface->current_mode->mode, 1190 hostapd_hw_mode_txt(iface->current_mode->mode)); 1191 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211, 1192 HOSTAPD_LEVEL_WARNING, 1193 "Hardware does not support configured channel"); 1194 } 1195 1196 hostapd_acs_completed(struct hostapd_iface * iface,int err)1197 int hostapd_acs_completed(struct hostapd_iface *iface, int err) 1198 { 1199 int ret = -1; 1200 1201 if (err) 1202 goto out; 1203 1204 switch (hostapd_check_chans(iface)) { 1205 case HOSTAPD_CHAN_VALID: 1206 iface->is_no_ir = false; 1207 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, 1208 ACS_EVENT_COMPLETED "freq=%d channel=%d", 1209 iface->freq, iface->conf->channel); 1210 break; 1211 case HOSTAPD_CHAN_ACS: 1212 wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available"); 1213 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED); 1214 hostapd_notify_bad_chans(iface); 1215 goto out; 1216 case HOSTAPD_CHAN_INVALID_NO_IR: 1217 iface->is_no_ir = true; 1218 /* fall through */ 1219 case HOSTAPD_CHAN_INVALID: 1220 default: 1221 wpa_printf(MSG_ERROR, "ACS picked unusable channels"); 1222 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED); 1223 hostapd_notify_bad_chans(iface); 1224 goto out; 1225 } 1226 1227 ret = hostapd_check_ht_capab(iface); 1228 if (ret < 0) 1229 goto out; 1230 if (ret == 1) { 1231 wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback"); 1232 return 0; 1233 } 1234 1235 ret = 0; 1236 out: 1237 return hostapd_setup_interface_complete(iface, ret); 1238 } 1239 1240 1241 /** 1242 * hostapd_csa_update_hwmode - Update hardware mode 1243 * @iface: Pointer to interface data. 1244 * Returns: 0 on success, < 0 on failure 1245 * 1246 * Update hardware mode when the operating channel changed because of CSA. 1247 */ hostapd_csa_update_hwmode(struct hostapd_iface * iface)1248 int hostapd_csa_update_hwmode(struct hostapd_iface *iface) 1249 { 1250 if (!iface || !iface->conf) 1251 return -1; 1252 1253 iface->current_mode = NULL; 1254 iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211ANY; 1255 1256 return hostapd_determine_mode(iface); 1257 } 1258 1259 1260 /** 1261 * hostapd_select_hw_mode - Select the hardware mode 1262 * @iface: Pointer to interface data. 1263 * Returns: 0 on success, < 0 on failure 1264 * 1265 * Sets up the hardware mode, channel, rates, and passive scanning 1266 * based on the configuration. 1267 */ hostapd_select_hw_mode(struct hostapd_iface * iface)1268 int hostapd_select_hw_mode(struct hostapd_iface *iface) 1269 { 1270 int i; 1271 1272 if (iface->num_hw_features < 1) 1273 return -1; 1274 1275 if ((iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211G || 1276 iface->conf->ieee80211n || iface->conf->ieee80211ac || 1277 iface->conf->ieee80211ax || iface->conf->ieee80211be) && 1278 iface->conf->channel == 14) { 1279 wpa_printf(MSG_INFO, "Disable OFDM/HT/VHT/HE/EHT on channel 14"); 1280 iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211B; 1281 iface->conf->ieee80211n = 0; 1282 iface->conf->ieee80211ac = 0; 1283 iface->conf->ieee80211ax = 0; 1284 iface->conf->ieee80211be = 0; 1285 } 1286 1287 iface->current_mode = NULL; 1288 for (i = 0; i < iface->num_hw_features; i++) { 1289 struct hostapd_hw_modes *mode = &iface->hw_features[i]; 1290 1291 if (mode->mode == iface->conf->hw_mode) { 1292 if (skip_mode(iface, mode)) 1293 continue; 1294 1295 iface->current_mode = mode; 1296 break; 1297 } 1298 } 1299 1300 if (iface->current_mode == NULL) { 1301 if ((iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) && 1302 (iface->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY)) { 1303 wpa_printf(MSG_DEBUG, 1304 "Using offloaded hw_mode=any ACS"); 1305 } else if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) && 1306 iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211ANY) { 1307 wpa_printf(MSG_DEBUG, 1308 "Using internal ACS for hw_mode=any"); 1309 } else { 1310 wpa_printf(MSG_ERROR, 1311 "Hardware does not support configured mode"); 1312 hostapd_logger(iface->bss[0], NULL, 1313 HOSTAPD_MODULE_IEEE80211, 1314 HOSTAPD_LEVEL_WARNING, 1315 "Hardware does not support configured mode (%d) (hw_mode in hostapd.conf)", 1316 (int) iface->conf->hw_mode); 1317 return -2; 1318 } 1319 } 1320 1321 switch (hostapd_check_chans(iface)) { 1322 case HOSTAPD_CHAN_VALID: 1323 iface->is_no_ir = false; 1324 return 0; 1325 case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */ 1326 return 1; 1327 case HOSTAPD_CHAN_INVALID_NO_IR: 1328 iface->is_no_ir = true; 1329 /* fall through */ 1330 case HOSTAPD_CHAN_INVALID: 1331 default: 1332 hostapd_notify_bad_chans(iface); 1333 return -3; 1334 } 1335 } 1336 1337 hostapd_hw_mode_txt(int mode)1338 const char * hostapd_hw_mode_txt(int mode) 1339 { 1340 switch (mode) { 1341 case HOSTAPD_MODE_IEEE80211A: 1342 return "IEEE 802.11a"; 1343 case HOSTAPD_MODE_IEEE80211B: 1344 return "IEEE 802.11b"; 1345 case HOSTAPD_MODE_IEEE80211G: 1346 return "IEEE 802.11g"; 1347 case HOSTAPD_MODE_IEEE80211AD: 1348 return "IEEE 802.11ad"; 1349 default: 1350 return "UNKNOWN"; 1351 } 1352 } 1353 1354 hostapd_hw_get_freq(struct hostapd_data * hapd,int chan)1355 int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan) 1356 { 1357 return hw_get_freq(hapd->iface->current_mode, chan); 1358 } 1359 1360 hostapd_hw_get_channel(struct hostapd_data * hapd,int freq)1361 int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq) 1362 { 1363 int i, channel; 1364 struct hostapd_hw_modes *mode; 1365 1366 if (hapd->iface->current_mode) { 1367 channel = hw_get_chan(hapd->iface->current_mode->mode, freq, 1368 hapd->iface->hw_features, 1369 hapd->iface->num_hw_features); 1370 if (channel) 1371 return channel; 1372 } 1373 1374 /* Check other available modes since the channel list for the current 1375 * mode did not include the specified frequency. */ 1376 if (!hapd->iface->hw_features) 1377 return 0; 1378 for (i = 0; i < hapd->iface->num_hw_features; i++) { 1379 mode = &hapd->iface->hw_features[i]; 1380 channel = hw_get_chan(mode->mode, freq, 1381 hapd->iface->hw_features, 1382 hapd->iface->num_hw_features); 1383 if (channel) 1384 return channel; 1385 } 1386 return 0; 1387 } 1388 1389 hostapd_hw_skip_mode(struct hostapd_iface * iface,struct hostapd_hw_modes * mode)1390 int hostapd_hw_skip_mode(struct hostapd_iface *iface, 1391 struct hostapd_hw_modes *mode) 1392 { 1393 int i; 1394 1395 if (iface->current_mode) 1396 return mode != iface->current_mode; 1397 if (mode->mode != HOSTAPD_MODE_IEEE80211B) 1398 return 0; 1399 for (i = 0; i < iface->num_hw_features; i++) { 1400 if (iface->hw_features[i].mode == HOSTAPD_MODE_IEEE80211G) 1401 return 1; 1402 } 1403 return 0; 1404 } 1405 1406 hostapd_free_multi_hw_info(struct hostapd_multi_hw_info * multi_hw_info)1407 void hostapd_free_multi_hw_info(struct hostapd_multi_hw_info *multi_hw_info) 1408 { 1409 os_free(multi_hw_info); 1410 } 1411 1412 hostapd_set_current_hw_info(struct hostapd_iface * iface,int oper_freq)1413 int hostapd_set_current_hw_info(struct hostapd_iface *iface, int oper_freq) 1414 { 1415 struct hostapd_multi_hw_info *hw_info; 1416 unsigned int i; 1417 1418 if (!iface->num_multi_hws) 1419 return 0; 1420 1421 for (i = 0; i < iface->num_multi_hws; i++) { 1422 hw_info = &iface->multi_hw_info[i]; 1423 1424 if (hw_info->start_freq <= oper_freq && 1425 hw_info->end_freq >= oper_freq) { 1426 iface->current_hw_info = hw_info; 1427 wpa_printf(MSG_DEBUG, 1428 "Mode: Selected underlying hardware: hw_idx=%u", 1429 iface->current_hw_info->hw_idx); 1430 return 0; 1431 } 1432 } 1433 1434 return -1; 1435 } 1436