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 28void 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 46static 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 75int hostapd_get_hw_features(struct hostapd_iface *iface) 76{ 77 struct hostapd_data *hapd = iface->bss[0]; 78 int i, j; 79 u16 num_modes, flags; 80 struct hostapd_hw_modes *modes; 81 u8 dfs_domain; 82 83 if (hostapd_drv_none(hapd)) 84 return -1; 85 modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags, 86 &dfs_domain); 87 if (modes == NULL) { 88 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 89 HOSTAPD_LEVEL_DEBUG, 90 "Fetching hardware channel/rate support not " 91 "supported."); 92 return -1; 93 } 94 95 iface->hw_flags = flags; 96 iface->dfs_domain = dfs_domain; 97 98 hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); 99 iface->hw_features = modes; 100 iface->num_hw_features = num_modes; 101 102 for (i = 0; i < num_modes; i++) { 103 struct hostapd_hw_modes *feature = &modes[i]; 104 int dfs_enabled = hapd->iconf->ieee80211h && 105 (iface->drv_flags & WPA_DRIVER_FLAGS_RADAR); 106 107 /* set flag for channels we can use in current regulatory 108 * domain */ 109 for (j = 0; j < feature->num_channels; j++) { 110 int dfs = 0; 111 112 /* 113 * Disable all channels that are marked not to allow 114 * to initiate radiation (a.k.a. passive scan and no 115 * IBSS). 116 * Use radar channels only if the driver supports DFS. 117 */ 118 if ((feature->channels[j].flag & 119 HOSTAPD_CHAN_RADAR) && dfs_enabled) { 120 dfs = 1; 121 } else if (((feature->channels[j].flag & 122 HOSTAPD_CHAN_RADAR) && 123 !(iface->drv_flags & 124 WPA_DRIVER_FLAGS_DFS_OFFLOAD)) || 125 (feature->channels[j].flag & 126 HOSTAPD_CHAN_NO_IR)) { 127 feature->channels[j].flag |= 128 HOSTAPD_CHAN_DISABLED; 129 } 130 131 if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED) 132 continue; 133 134 wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d " 135 "chan=%d freq=%d MHz max_tx_power=%d dBm%s", 136 feature->mode, 137 feature->channels[j].chan, 138 feature->channels[j].freq, 139 feature->channels[j].max_tx_power, 140 dfs ? dfs_info(&feature->channels[j]) : ""); 141 } 142 } 143 144 return 0; 145} 146 147 148int hostapd_prepare_rates(struct hostapd_iface *iface, 149 struct hostapd_hw_modes *mode) 150{ 151 int i, num_basic_rates = 0; 152 int basic_rates_a[] = { 60, 120, 240, -1 }; 153 int basic_rates_b[] = { 10, 20, -1 }; 154 int basic_rates_g[] = { 10, 20, 55, 110, -1 }; 155 int *basic_rates; 156 157 if (iface->conf->basic_rates) 158 basic_rates = iface->conf->basic_rates; 159 else switch (mode->mode) { 160 case HOSTAPD_MODE_IEEE80211A: 161 basic_rates = basic_rates_a; 162 break; 163 case HOSTAPD_MODE_IEEE80211B: 164 basic_rates = basic_rates_b; 165 break; 166 case HOSTAPD_MODE_IEEE80211G: 167 basic_rates = basic_rates_g; 168 break; 169 case HOSTAPD_MODE_IEEE80211AD: 170 return 0; /* No basic rates for 11ad */ 171 default: 172 return -1; 173 } 174 175 i = 0; 176 while (basic_rates[i] >= 0) 177 i++; 178 if (i) 179 i++; /* -1 termination */ 180 os_free(iface->basic_rates); 181 iface->basic_rates = os_malloc(i * sizeof(int)); 182 if (iface->basic_rates) 183 os_memcpy(iface->basic_rates, basic_rates, i * sizeof(int)); 184 185 os_free(iface->current_rates); 186 iface->num_rates = 0; 187 188 iface->current_rates = 189 os_calloc(mode->num_rates, sizeof(struct hostapd_rate_data)); 190 if (!iface->current_rates) { 191 wpa_printf(MSG_ERROR, "Failed to allocate memory for rate " 192 "table."); 193 return -1; 194 } 195 196 for (i = 0; i < mode->num_rates; i++) { 197 struct hostapd_rate_data *rate; 198 199 if (iface->conf->supported_rates && 200 !hostapd_rate_found(iface->conf->supported_rates, 201 mode->rates[i])) 202 continue; 203 204 rate = &iface->current_rates[iface->num_rates]; 205 rate->rate = mode->rates[i]; 206 if (hostapd_rate_found(basic_rates, rate->rate)) { 207 rate->flags |= HOSTAPD_RATE_BASIC; 208 num_basic_rates++; 209 } 210 wpa_printf(MSG_DEBUG, "RATE[%d] rate=%d flags=0x%x", 211 iface->num_rates, rate->rate, rate->flags); 212 iface->num_rates++; 213 } 214 215 if ((iface->num_rates == 0 || num_basic_rates == 0) && 216 (!iface->conf->ieee80211n || !iface->conf->require_ht)) { 217 wpa_printf(MSG_ERROR, "No rates remaining in supported/basic " 218 "rate sets (%d,%d).", 219 iface->num_rates, num_basic_rates); 220 return -1; 221 } 222 223 return 0; 224} 225 226 227#ifdef CONFIG_IEEE80211N 228static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface) 229{ 230 int pri_chan, sec_chan; 231 232#ifdef CONFIG_OHOS_P2P 233 if (!iface->conf->secondary_channel) { 234 return 1; // HT40 not used. 235 } 236#endif 237 238 pri_chan = iface->conf->channel; 239 sec_chan = pri_chan + iface->conf->secondary_channel * 4; 240 241 return allowed_ht40_channel_pair(iface->current_mode, pri_chan, 242 sec_chan); 243} 244 245 246static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface) 247{ 248 if (iface->conf->secondary_channel > 0) { 249 iface->conf->channel += 4; 250 iface->conf->secondary_channel = -1; 251 } else { 252 iface->conf->channel -= 4; 253 iface->conf->secondary_channel = 1; 254 } 255} 256 257 258static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface, 259 struct wpa_scan_results *scan_res) 260{ 261 int pri_chan, sec_chan; 262 int res; 263 264 pri_chan = iface->conf->channel; 265 sec_chan = pri_chan + iface->conf->secondary_channel * 4; 266 267 res = check_40mhz_5g(iface->current_mode, scan_res, pri_chan, sec_chan); 268 269 if (res == 2) { 270 if (iface->conf->no_pri_sec_switch) { 271 wpa_printf(MSG_DEBUG, 272 "Cannot switch PRI/SEC channels due to local constraint"); 273 } else { 274 ieee80211n_switch_pri_sec(iface); 275 } 276 } 277 278 return !!res; 279} 280 281 282static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface, 283 struct wpa_scan_results *scan_res) 284{ 285 int pri_chan, sec_chan; 286 287 pri_chan = iface->conf->channel; 288 sec_chan = pri_chan + iface->conf->secondary_channel * 4; 289 290 return check_40mhz_2g4(iface->current_mode, scan_res, pri_chan, 291 sec_chan); 292} 293 294 295static void ieee80211n_check_scan(struct hostapd_iface *iface) 296{ 297 struct wpa_scan_results *scan_res; 298 int oper40; 299 int res; 300 301 /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is 302 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */ 303 304 iface->scan_cb = NULL; 305 306 scan_res = hostapd_driver_get_scan_results(iface->bss[0]); 307 if (scan_res == NULL) { 308 hostapd_setup_interface_complete(iface, 1); 309 return; 310 } 311 312 if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A) 313 oper40 = ieee80211n_check_40mhz_5g(iface, scan_res); 314 else 315 oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res); 316 wpa_scan_results_free(scan_res); 317 318 iface->secondary_ch = iface->conf->secondary_channel; 319 if (!oper40) { 320 wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on " 321 "channel pri=%d sec=%d based on overlapping BSSes", 322 iface->conf->channel, 323 iface->conf->channel + 324 iface->conf->secondary_channel * 4); 325 iface->conf->secondary_channel = 0; 326 if (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX) { 327 /* 328 * TODO: Could consider scheduling another scan to check 329 * if channel width can be changed if no coex reports 330 * are received from associating stations. 331 */ 332 } 333 } 334 335 res = ieee80211n_allowed_ht40_channel_pair(iface); 336 if (!res) { 337 iface->conf->secondary_channel = 0; 338 hostapd_set_oper_centr_freq_seg0_idx(iface->conf, 0); 339 hostapd_set_oper_centr_freq_seg1_idx(iface->conf, 0); 340 hostapd_set_oper_chwidth(iface->conf, CHANWIDTH_USE_HT); 341 res = 1; 342 wpa_printf(MSG_INFO, "Fallback to 20 MHz"); 343 } 344 345 hostapd_setup_interface_complete(iface, !res); 346} 347 348 349static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface, 350 struct wpa_driver_scan_params *params) 351{ 352 /* Scan only the affected frequency range */ 353 int pri_freq, sec_freq; 354 int affected_start, affected_end; 355 int i, pos; 356 struct hostapd_hw_modes *mode; 357 358 if (iface->current_mode == NULL) 359 return; 360 361 pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel); 362 if (iface->conf->secondary_channel > 0) 363 sec_freq = pri_freq + 20; 364 else 365 sec_freq = pri_freq - 20; 366 /* 367 * Note: Need to find the PRI channel also in cases where the affected 368 * channel is the SEC channel of a 40 MHz BSS, so need to include the 369 * scanning coverage here to be 40 MHz from the center frequency. 370 */ 371 affected_start = (pri_freq + sec_freq) / 2 - 40; 372 affected_end = (pri_freq + sec_freq) / 2 + 40; 373 wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz", 374 affected_start, affected_end); 375 376 mode = iface->current_mode; 377 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 378 if (params->freqs == NULL) 379 return; 380 pos = 0; 381 382 for (i = 0; i < mode->num_channels; i++) { 383 struct hostapd_channel_data *chan = &mode->channels[i]; 384 if (chan->flag & HOSTAPD_CHAN_DISABLED) 385 continue; 386 if (chan->freq < affected_start || 387 chan->freq > affected_end) 388 continue; 389 params->freqs[pos++] = chan->freq; 390 } 391} 392 393 394static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface, 395 struct wpa_driver_scan_params *params) 396{ 397 /* Scan only the affected frequency range */ 398 int pri_freq; 399 int affected_start, affected_end; 400 int i, pos; 401 struct hostapd_hw_modes *mode; 402 403 if (iface->current_mode == NULL) 404 return; 405 406 pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel); 407 if (iface->conf->secondary_channel > 0) { 408 affected_start = pri_freq - 10; 409 affected_end = pri_freq + 30; 410 } else { 411 affected_start = pri_freq - 30; 412 affected_end = pri_freq + 10; 413 } 414 wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz", 415 affected_start, affected_end); 416 417 mode = iface->current_mode; 418 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 419 if (params->freqs == NULL) 420 return; 421 pos = 0; 422 423 for (i = 0; i < mode->num_channels; i++) { 424 struct hostapd_channel_data *chan = &mode->channels[i]; 425 if (chan->flag & HOSTAPD_CHAN_DISABLED) 426 continue; 427 if (chan->freq < affected_start || 428 chan->freq > affected_end) 429 continue; 430 params->freqs[pos++] = chan->freq; 431 } 432} 433 434 435static void ap_ht40_scan_retry(void *eloop_data, void *user_data) 436{ 437#define HT2040_COEX_SCAN_RETRY 15 438 struct hostapd_iface *iface = eloop_data; 439 struct wpa_driver_scan_params params; 440 int ret; 441 442 os_memset(¶ms, 0, sizeof(params)); 443 if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 444 ieee80211n_scan_channels_2g4(iface, ¶ms); 445 else 446 ieee80211n_scan_channels_5g(iface, ¶ms); 447 448 ret = hostapd_driver_scan(iface->bss[0], ¶ms); 449 iface->num_ht40_scan_tries++; 450 os_free(params.freqs); 451 452 if (ret == -EBUSY && 453 iface->num_ht40_scan_tries < HT2040_COEX_SCAN_RETRY) { 454 wpa_printf(MSG_ERROR, 455 "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)", 456 ret, strerror(-ret), iface->num_ht40_scan_tries); 457 eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL); 458 return; 459 } 460 461 if (ret == 0) { 462 iface->scan_cb = ieee80211n_check_scan; 463 return; 464 } 465 466 wpa_printf(MSG_DEBUG, 467 "Failed to request a scan in device, bringing up in HT20 mode"); 468 iface->conf->secondary_channel = 0; 469 iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; 470 hostapd_setup_interface_complete(iface, 0); 471} 472 473 474void hostapd_stop_setup_timers(struct hostapd_iface *iface) 475{ 476 eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL); 477} 478 479 480static int ieee80211n_check_40mhz(struct hostapd_iface *iface) 481{ 482 struct wpa_driver_scan_params params; 483 int ret; 484 485 /* Check that HT40 is used and PRI / SEC switch is allowed */ 486 if (!iface->conf->secondary_channel || iface->conf->no_pri_sec_switch) 487 return 0; 488 489 hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); 490 wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling " 491 "40 MHz channel"); 492 os_memset(¶ms, 0, sizeof(params)); 493 if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 494 ieee80211n_scan_channels_2g4(iface, ¶ms); 495 else 496 ieee80211n_scan_channels_5g(iface, ¶ms); 497 498 ret = hostapd_driver_scan(iface->bss[0], ¶ms); 499 os_free(params.freqs); 500 501 if (ret == -EBUSY) { 502 wpa_printf(MSG_ERROR, 503 "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again", 504 ret, strerror(-ret)); 505 iface->num_ht40_scan_tries = 1; 506 eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL); 507 eloop_register_timeout(1, 0, ap_ht40_scan_retry, iface, NULL); 508 return 1; 509 } 510 511 if (ret < 0) { 512 wpa_printf(MSG_ERROR, 513 "Failed to request a scan of neighboring BSSes ret=%d (%s)", 514 ret, strerror(-ret)); 515 return -1; 516 } 517 518 iface->scan_cb = ieee80211n_check_scan; 519 return 1; 520} 521 522 523static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface) 524{ 525 u16 hw = iface->current_mode->ht_capab; 526 u16 conf = iface->conf->ht_capab; 527 528 if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) && 529 !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) { 530 wpa_printf(MSG_ERROR, "Driver does not support configured " 531 "HT capability [LDPC]"); 532 return 0; 533 } 534 535 /* 536 * Driver ACS chosen channel may not be HT40 due to internal driver 537 * restrictions. 538 */ 539 if (!iface->conf->acs && (conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) && 540 !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) { 541 wpa_printf(MSG_ERROR, "Driver does not support configured " 542 "HT capability [HT40*]"); 543 return 0; 544 } 545 546 switch (conf & HT_CAP_INFO_SMPS_MASK) { 547 case HT_CAP_INFO_SMPS_STATIC: 548 if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_STATIC)) { 549 wpa_printf(MSG_ERROR, 550 "Driver does not support configured HT capability [SMPS-STATIC]"); 551 return 0; 552 } 553 break; 554 case HT_CAP_INFO_SMPS_DYNAMIC: 555 if (!(iface->smps_modes & WPA_DRIVER_SMPS_MODE_DYNAMIC)) { 556 wpa_printf(MSG_ERROR, 557 "Driver does not support configured HT capability [SMPS-DYNAMIC]"); 558 return 0; 559 } 560 break; 561 case HT_CAP_INFO_SMPS_DISABLED: 562 default: 563 break; 564 } 565 566 if ((conf & HT_CAP_INFO_GREEN_FIELD) && 567 !(hw & HT_CAP_INFO_GREEN_FIELD)) { 568 wpa_printf(MSG_ERROR, "Driver does not support configured " 569 "HT capability [GF]"); 570 return 0; 571 } 572 573 if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) && 574 !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) { 575 wpa_printf(MSG_ERROR, "Driver does not support configured " 576 "HT capability [SHORT-GI-20]"); 577 return 0; 578 } 579 580 if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) && 581 !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) { 582 wpa_printf(MSG_ERROR, "Driver does not support configured " 583 "HT capability [SHORT-GI-40]"); 584 return 0; 585 } 586 587 if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) { 588 wpa_printf(MSG_ERROR, "Driver does not support configured " 589 "HT capability [TX-STBC]"); 590 return 0; 591 } 592 593 if ((conf & HT_CAP_INFO_RX_STBC_MASK) > 594 (hw & HT_CAP_INFO_RX_STBC_MASK)) { 595 wpa_printf(MSG_ERROR, "Driver does not support configured " 596 "HT capability [RX-STBC*]"); 597 return 0; 598 } 599 600 if ((conf & HT_CAP_INFO_DELAYED_BA) && 601 !(hw & HT_CAP_INFO_DELAYED_BA)) { 602 wpa_printf(MSG_ERROR, "Driver does not support configured " 603 "HT capability [DELAYED-BA]"); 604 return 0; 605 } 606 607 if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) && 608 !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) { 609 wpa_printf(MSG_ERROR, "Driver does not support configured " 610 "HT capability [MAX-AMSDU-7935]"); 611 return 0; 612 } 613 614 if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) && 615 !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) { 616 wpa_printf(MSG_ERROR, "Driver does not support configured " 617 "HT capability [DSSS_CCK-40]"); 618 return 0; 619 } 620 621 if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) && 622 !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) { 623 wpa_printf(MSG_ERROR, "Driver does not support configured " 624 "HT capability [LSIG-TXOP-PROT]"); 625 return 0; 626 } 627 628 return 1; 629} 630 631 632#ifdef CONFIG_IEEE80211AC 633static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface) 634{ 635 struct hostapd_hw_modes *mode = iface->current_mode; 636 u32 hw = mode->vht_capab; 637 u32 conf = iface->conf->vht_capab; 638 639 wpa_printf(MSG_DEBUG, "hw vht capab: 0x%x, conf vht capab: 0x%x", 640 hw, conf); 641 642 if (mode->mode == HOSTAPD_MODE_IEEE80211G && 643 iface->conf->bss[0]->vendor_vht && 644 mode->vht_capab == 0 && iface->hw_features) { 645 int i; 646 647 for (i = 0; i < iface->num_hw_features; i++) { 648 if (iface->hw_features[i].mode == 649 HOSTAPD_MODE_IEEE80211A) { 650 mode = &iface->hw_features[i]; 651 hw = mode->vht_capab; 652 wpa_printf(MSG_DEBUG, 653 "update hw vht capab based on 5 GHz band: 0x%x", 654 hw); 655 break; 656 } 657 } 658 } 659 660 return ieee80211ac_cap_check(hw, conf); 661} 662#endif /* CONFIG_IEEE80211AC */ 663 664 665#ifdef CONFIG_IEEE80211AX 666static int ieee80211ax_supported_he_capab(struct hostapd_iface *iface) 667{ 668 return 1; 669} 670#endif /* CONFIG_IEEE80211AX */ 671 672#endif /* CONFIG_IEEE80211N */ 673 674 675int hostapd_check_ht_capab(struct hostapd_iface *iface) 676{ 677#ifdef CONFIG_IEEE80211N 678 int ret; 679 if (!iface->conf->ieee80211n) 680 return 0; 681 682 if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211B && 683 iface->current_mode->mode != HOSTAPD_MODE_IEEE80211G && 684 (iface->conf->ht_capab & HT_CAP_INFO_DSSS_CCK40MHZ)) { 685 wpa_printf(MSG_DEBUG, 686 "Disable HT capability [DSSS_CCK-40] on 5 GHz band"); 687 iface->conf->ht_capab &= ~HT_CAP_INFO_DSSS_CCK40MHZ; 688 } 689 690 if (!ieee80211n_supported_ht_capab(iface)) 691 return -1; 692#ifdef CONFIG_IEEE80211AX 693 if (iface->conf->ieee80211ax && 694 !ieee80211ax_supported_he_capab(iface)) 695 return -1; 696#endif /* CONFIG_IEEE80211AX */ 697#ifdef CONFIG_IEEE80211AC 698 if (iface->conf->ieee80211ac && 699 !ieee80211ac_supported_vht_capab(iface)) 700 return -1; 701#endif /* CONFIG_IEEE80211AC */ 702 ret = ieee80211n_check_40mhz(iface); 703 if (ret) 704 return ret; 705 if (!ieee80211n_allowed_ht40_channel_pair(iface)) 706 return -1; 707#endif /* CONFIG_IEEE80211N */ 708 709 return 0; 710} 711 712 713static int hostapd_is_usable_chan(struct hostapd_iface *iface, 714 int channel, int primary) 715{ 716 struct hostapd_channel_data *chan; 717 718 if (!iface->current_mode) 719 return 0; 720 721 chan = hw_get_channel_chan(iface->current_mode, channel, NULL); 722 if (!chan) 723 return 0; 724 725 if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) 726 return 1; 727 728 wpa_printf(MSG_INFO, 729 "Channel %d (%s) not allowed for AP mode, flags: 0x%x%s%s", 730 channel, primary ? "primary" : "secondary", 731 chan->flag, 732 chan->flag & HOSTAPD_CHAN_NO_IR ? " NO-IR" : "", 733 chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : ""); 734 return 0; 735} 736 737 738static int hostapd_is_usable_chans(struct hostapd_iface *iface) 739{ 740 int secondary_chan; 741 struct hostapd_channel_data *pri_chan; 742 743 pri_chan = hw_get_channel_chan(iface->current_mode, 744 iface->conf->channel, NULL); 745 if (!pri_chan) 746 return 0; 747 748 if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1)) 749 return 0; 750 751 if (!iface->conf->secondary_channel) 752 return 1; 753 754 if (!iface->conf->ht40_plus_minus_allowed) 755 return hostapd_is_usable_chan( 756 iface, iface->conf->channel + 757 iface->conf->secondary_channel * 4, 0); 758 759 /* Both HT40+ and HT40- are set, pick a valid secondary channel */ 760 secondary_chan = iface->conf->channel + 4; 761 if (hostapd_is_usable_chan(iface, secondary_chan, 0) && 762 (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)) { 763 iface->conf->secondary_channel = 1; 764 return 1; 765 } 766 767 secondary_chan = iface->conf->channel - 4; 768 if (hostapd_is_usable_chan(iface, secondary_chan, 0) && 769 (pri_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40M)) { 770 iface->conf->secondary_channel = -1; 771 return 1; 772 } 773 774 return 0; 775} 776 777 778static enum hostapd_chan_status 779hostapd_check_chans(struct hostapd_iface *iface) 780{ 781 if (iface->conf->channel) { 782 if (hostapd_is_usable_chans(iface)) 783 return HOSTAPD_CHAN_VALID; 784 else 785 return HOSTAPD_CHAN_INVALID; 786 } 787 788 /* 789 * The user set channel=0 or channel=acs_survey 790 * which is used to trigger ACS. 791 */ 792 793 switch (acs_init(iface)) { 794 case HOSTAPD_CHAN_ACS: 795 return HOSTAPD_CHAN_ACS; 796 case HOSTAPD_CHAN_VALID: 797 case HOSTAPD_CHAN_INVALID: 798 default: 799 return HOSTAPD_CHAN_INVALID; 800 } 801} 802 803 804static void hostapd_notify_bad_chans(struct hostapd_iface *iface) 805{ 806 if (!iface->current_mode) { 807 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211, 808 HOSTAPD_LEVEL_WARNING, 809 "Hardware does not support configured mode"); 810 return; 811 } 812 hostapd_logger(iface->bss[0], NULL, 813 HOSTAPD_MODULE_IEEE80211, 814 HOSTAPD_LEVEL_WARNING, 815 "Configured channel (%d) not found from the " 816 "channel list of current mode (%d) %s", 817 iface->conf->channel, 818 iface->current_mode->mode, 819 hostapd_hw_mode_txt(iface->current_mode->mode)); 820 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211, 821 HOSTAPD_LEVEL_WARNING, 822 "Hardware does not support configured channel"); 823} 824 825 826int hostapd_acs_completed(struct hostapd_iface *iface, int err) 827{ 828 int ret = -1; 829 830 if (err) 831 goto out; 832 833 switch (hostapd_check_chans(iface)) { 834 case HOSTAPD_CHAN_VALID: 835 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, 836 ACS_EVENT_COMPLETED "freq=%d channel=%d", 837 hostapd_hw_get_freq(iface->bss[0], 838 iface->conf->channel), 839 iface->conf->channel); 840 break; 841 case HOSTAPD_CHAN_ACS: 842 wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available"); 843 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED); 844 hostapd_notify_bad_chans(iface); 845 goto out; 846 case HOSTAPD_CHAN_INVALID: 847 default: 848 wpa_printf(MSG_ERROR, "ACS picked unusable channels"); 849 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED); 850 hostapd_notify_bad_chans(iface); 851 goto out; 852 } 853 854 ret = hostapd_check_ht_capab(iface); 855 if (ret < 0) 856 goto out; 857 if (ret == 1) { 858 wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback"); 859 return 0; 860 } 861 862 ret = 0; 863out: 864 return hostapd_setup_interface_complete(iface, ret); 865} 866 867 868/** 869 * hostapd_select_hw_mode - Select the hardware mode 870 * @iface: Pointer to interface data. 871 * Returns: 0 on success, < 0 on failure 872 * 873 * Sets up the hardware mode, channel, rates, and passive scanning 874 * based on the configuration. 875 */ 876int hostapd_select_hw_mode(struct hostapd_iface *iface) 877{ 878 int i; 879 880 if (iface->num_hw_features < 1) 881 return -1; 882 883 if ((iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211G || 884 iface->conf->ieee80211n || iface->conf->ieee80211ac || 885 iface->conf->ieee80211ax) && 886 iface->conf->channel == 14) { 887 wpa_printf(MSG_INFO, "Disable OFDM/HT/VHT/HE on channel 14"); 888 iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211B; 889 iface->conf->ieee80211n = 0; 890 iface->conf->ieee80211ac = 0; 891 iface->conf->ieee80211ax = 0; 892 } 893 894 iface->current_mode = NULL; 895 for (i = 0; i < iface->num_hw_features; i++) { 896 struct hostapd_hw_modes *mode = &iface->hw_features[i]; 897 if (mode->mode == iface->conf->hw_mode) { 898 iface->current_mode = mode; 899 break; 900 } 901 } 902 903 if (iface->current_mode == NULL) { 904 if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) || 905 !(iface->drv_flags & WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY)) 906 { 907 wpa_printf(MSG_ERROR, 908 "Hardware does not support configured mode"); 909 hostapd_logger(iface->bss[0], NULL, 910 HOSTAPD_MODULE_IEEE80211, 911 HOSTAPD_LEVEL_WARNING, 912 "Hardware does not support configured mode (%d) (hw_mode in hostapd.conf)", 913 (int) iface->conf->hw_mode); 914 return -2; 915 } 916 } 917 918 switch (hostapd_check_chans(iface)) { 919 case HOSTAPD_CHAN_VALID: 920 return 0; 921 case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */ 922 return 1; 923 case HOSTAPD_CHAN_INVALID: 924 default: 925 hostapd_notify_bad_chans(iface); 926 return -3; 927 } 928} 929 930 931const char * hostapd_hw_mode_txt(int mode) 932{ 933 switch (mode) { 934 case HOSTAPD_MODE_IEEE80211A: 935 return "IEEE 802.11a"; 936 case HOSTAPD_MODE_IEEE80211B: 937 return "IEEE 802.11b"; 938 case HOSTAPD_MODE_IEEE80211G: 939 return "IEEE 802.11g"; 940 case HOSTAPD_MODE_IEEE80211AD: 941 return "IEEE 802.11ad"; 942 default: 943 return "UNKNOWN"; 944 } 945} 946 947 948int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan) 949{ 950 return hw_get_freq(hapd->iface->current_mode, chan); 951} 952 953 954int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq) 955{ 956 int i, channel; 957 struct hostapd_hw_modes *mode; 958 959 if (hapd->iface->current_mode) { 960 channel = hw_get_chan(hapd->iface->current_mode, freq); 961 if (channel) 962 return channel; 963 } 964 965 /* Check other available modes since the channel list for the current 966 * mode did not include the specified frequency. */ 967 if (!hapd->iface->hw_features) 968 return 0; 969 for (i = 0; i < hapd->iface->num_hw_features; i++) { 970 mode = &hapd->iface->hw_features[i]; 971 channel = hw_get_chan(mode, freq); 972 if (channel) 973 return channel; 974 } 975 return 0; 976} 977