hw_features.c revision f940fbdc849eba19de7b63a74ced85e550bf4572
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 "hostapd.h" 19#include "ap_config.h" 20#include "ap_drv_ops.h" 21#include "acs.h" 22#include "hw_features.h" 23 24 25void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features, 26 size_t num_hw_features) 27{ 28 size_t i; 29 30 if (hw_features == NULL) 31 return; 32 33 for (i = 0; i < num_hw_features; i++) { 34 os_free(hw_features[i].channels); 35 os_free(hw_features[i].rates); 36 } 37 38 os_free(hw_features); 39} 40 41 42#ifndef CONFIG_NO_STDOUT_DEBUG 43static char * dfs_info(struct hostapd_channel_data *chan) 44{ 45 static char info[256]; 46 char *state; 47 48 switch (chan->flag & HOSTAPD_CHAN_DFS_MASK) { 49 case HOSTAPD_CHAN_DFS_UNKNOWN: 50 state = "unknown"; 51 break; 52 case HOSTAPD_CHAN_DFS_USABLE: 53 state = "usable"; 54 break; 55 case HOSTAPD_CHAN_DFS_UNAVAILABLE: 56 state = "unavailable"; 57 break; 58 case HOSTAPD_CHAN_DFS_AVAILABLE: 59 state = "available"; 60 break; 61 default: 62 return ""; 63 } 64 os_snprintf(info, sizeof(info), " (DFS state = %s)", state); 65 info[sizeof(info) - 1] = '\0'; 66 67 return info; 68} 69#endif /* CONFIG_NO_STDOUT_DEBUG */ 70 71 72int hostapd_get_hw_features(struct hostapd_iface *iface) 73{ 74 struct hostapd_data *hapd = iface->bss[0]; 75 int ret = 0, i, j; 76 u16 num_modes, flags; 77 struct hostapd_hw_modes *modes; 78 79 if (hostapd_drv_none(hapd)) 80 return -1; 81 modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags); 82 if (modes == NULL) { 83 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211, 84 HOSTAPD_LEVEL_DEBUG, 85 "Fetching hardware channel/rate support not " 86 "supported."); 87 return -1; 88 } 89 90 iface->hw_flags = flags; 91 92 hostapd_free_hw_features(iface->hw_features, iface->num_hw_features); 93 iface->hw_features = modes; 94 iface->num_hw_features = num_modes; 95 96 for (i = 0; i < num_modes; i++) { 97 struct hostapd_hw_modes *feature = &modes[i]; 98 int dfs_enabled = hapd->iconf->ieee80211h && 99 (iface->drv_flags & WPA_DRIVER_FLAGS_RADAR); 100 101 /* set flag for channels we can use in current regulatory 102 * domain */ 103 for (j = 0; j < feature->num_channels; j++) { 104 int dfs = 0; 105 106 /* 107 * Disable all channels that are marked not to allow 108 * IBSS operation or active scanning. 109 * Use radar channels only if the driver supports DFS. 110 */ 111 if ((feature->channels[j].flag & 112 HOSTAPD_CHAN_RADAR) && dfs_enabled) { 113 dfs = 1; 114 } else if (((feature->channels[j].flag & 115 HOSTAPD_CHAN_RADAR) && 116 !(iface->drv_flags & 117 WPA_DRIVER_FLAGS_DFS_OFFLOAD)) || 118 (feature->channels[j].flag & 119 (HOSTAPD_CHAN_NO_IBSS | 120 HOSTAPD_CHAN_PASSIVE_SCAN))) { 121 feature->channels[j].flag |= 122 HOSTAPD_CHAN_DISABLED; 123 } 124 125 if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED) 126 continue; 127 128 wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d " 129 "chan=%d freq=%d MHz max_tx_power=%d dBm%s", 130 feature->mode, 131 feature->channels[j].chan, 132 feature->channels[j].freq, 133 feature->channels[j].max_tx_power, 134 dfs ? dfs_info(&feature->channels[j]) : ""); 135 } 136 } 137 138 return ret; 139} 140 141 142int hostapd_prepare_rates(struct hostapd_iface *iface, 143 struct hostapd_hw_modes *mode) 144{ 145 int i, num_basic_rates = 0; 146 int basic_rates_a[] = { 60, 120, 240, -1 }; 147 int basic_rates_b[] = { 10, 20, -1 }; 148 int basic_rates_g[] = { 10, 20, 55, 110, -1 }; 149 int *basic_rates; 150 151 if (iface->conf->basic_rates) 152 basic_rates = iface->conf->basic_rates; 153 else switch (mode->mode) { 154 case HOSTAPD_MODE_IEEE80211A: 155 basic_rates = basic_rates_a; 156 break; 157 case HOSTAPD_MODE_IEEE80211B: 158 basic_rates = basic_rates_b; 159 break; 160 case HOSTAPD_MODE_IEEE80211G: 161 basic_rates = basic_rates_g; 162 break; 163 case HOSTAPD_MODE_IEEE80211AD: 164 return 0; /* No basic rates for 11ad */ 165 default: 166 return -1; 167 } 168 169 i = 0; 170 while (basic_rates[i] >= 0) 171 i++; 172 if (i) 173 i++; /* -1 termination */ 174 os_free(iface->basic_rates); 175 iface->basic_rates = os_malloc(i * sizeof(int)); 176 if (iface->basic_rates) 177 os_memcpy(iface->basic_rates, basic_rates, i * sizeof(int)); 178 179 os_free(iface->current_rates); 180 iface->num_rates = 0; 181 182 iface->current_rates = 183 os_calloc(mode->num_rates, sizeof(struct hostapd_rate_data)); 184 if (!iface->current_rates) { 185 wpa_printf(MSG_ERROR, "Failed to allocate memory for rate " 186 "table."); 187 return -1; 188 } 189 190 for (i = 0; i < mode->num_rates; i++) { 191 struct hostapd_rate_data *rate; 192 193 if (iface->conf->supported_rates && 194 !hostapd_rate_found(iface->conf->supported_rates, 195 mode->rates[i])) 196 continue; 197 198 rate = &iface->current_rates[iface->num_rates]; 199 rate->rate = mode->rates[i]; 200 if (hostapd_rate_found(basic_rates, rate->rate)) { 201 rate->flags |= HOSTAPD_RATE_BASIC; 202 num_basic_rates++; 203 } 204 wpa_printf(MSG_DEBUG, "RATE[%d] rate=%d flags=0x%x", 205 iface->num_rates, rate->rate, rate->flags); 206 iface->num_rates++; 207 } 208 209 if ((iface->num_rates == 0 || num_basic_rates == 0) && 210 (!iface->conf->ieee80211n || !iface->conf->require_ht)) { 211 wpa_printf(MSG_ERROR, "No rates remaining in supported/basic " 212 "rate sets (%d,%d).", 213 iface->num_rates, num_basic_rates); 214 return -1; 215 } 216 217 return 0; 218} 219 220 221#ifdef CONFIG_IEEE80211N 222static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface) 223{ 224 int sec_chan, ok, j, first; 225 int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157, 226 184, 192 }; 227 size_t k; 228 229 if (!iface->conf->secondary_channel) 230 return 1; /* HT40 not used */ 231 232 sec_chan = iface->conf->channel + iface->conf->secondary_channel * 4; 233 wpa_printf(MSG_DEBUG, "HT40: control channel: %d " 234 "secondary channel: %d", 235 iface->conf->channel, sec_chan); 236 237 /* Verify that HT40 secondary channel is an allowed 20 MHz 238 * channel */ 239 ok = 0; 240 for (j = 0; j < iface->current_mode->num_channels; j++) { 241 struct hostapd_channel_data *chan = 242 &iface->current_mode->channels[j]; 243 if (!(chan->flag & HOSTAPD_CHAN_DISABLED) && 244 chan->chan == sec_chan) { 245 ok = 1; 246 break; 247 } 248 } 249 if (!ok) { 250 wpa_printf(MSG_ERROR, "HT40 secondary channel %d not allowed", 251 sec_chan); 252 return 0; 253 } 254 255 /* 256 * Verify that HT40 primary,secondary channel pair is allowed per 257 * IEEE 802.11n Annex J. This is only needed for 5 GHz band since 258 * 2.4 GHz rules allow all cases where the secondary channel fits into 259 * the list of allowed channels (already checked above). 260 */ 261 if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A) 262 return 1; 263 264 if (iface->conf->secondary_channel > 0) 265 first = iface->conf->channel; 266 else 267 first = sec_chan; 268 269 ok = 0; 270 for (k = 0; k < ARRAY_SIZE(allowed); k++) { 271 if (first == allowed[k]) { 272 ok = 1; 273 break; 274 } 275 } 276 if (!ok) { 277 wpa_printf(MSG_ERROR, "HT40 channel pair (%d, %d) not allowed", 278 iface->conf->channel, 279 iface->conf->secondary_channel); 280 return 0; 281 } 282 283 return 1; 284} 285 286 287static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface) 288{ 289 if (iface->conf->secondary_channel > 0) { 290 iface->conf->channel += 4; 291 iface->conf->secondary_channel = -1; 292 } else { 293 iface->conf->channel -= 4; 294 iface->conf->secondary_channel = 1; 295 } 296} 297 298 299static void ieee80211n_get_pri_sec_chan(struct wpa_scan_res *bss, 300 int *pri_chan, int *sec_chan) 301{ 302 struct ieee80211_ht_operation *oper; 303 struct ieee802_11_elems elems; 304 305 *pri_chan = *sec_chan = 0; 306 307 ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0); 308 if (elems.ht_operation && 309 elems.ht_operation_len >= sizeof(*oper)) { 310 oper = (struct ieee80211_ht_operation *) elems.ht_operation; 311 *pri_chan = oper->primary_chan; 312 if (oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) { 313 int sec = oper->ht_param & 314 HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK; 315 if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE) 316 *sec_chan = *pri_chan + 4; 317 else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW) 318 *sec_chan = *pri_chan - 4; 319 } 320 } 321} 322 323 324static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface, 325 struct wpa_scan_results *scan_res) 326{ 327 int pri_chan, sec_chan, pri_freq, sec_freq, pri_bss, sec_bss; 328 int bss_pri_chan, bss_sec_chan; 329 size_t i; 330 int match; 331 332 pri_chan = iface->conf->channel; 333 sec_chan = pri_chan + iface->conf->secondary_channel * 4; 334 pri_freq = hostapd_hw_get_freq(iface->bss[0], pri_chan); 335 if (iface->conf->secondary_channel > 0) 336 sec_freq = pri_freq + 20; 337 else 338 sec_freq = pri_freq - 20; 339 340 /* 341 * Switch PRI/SEC channels if Beacons were detected on selected SEC 342 * channel, but not on selected PRI channel. 343 */ 344 pri_bss = sec_bss = 0; 345 for (i = 0; i < scan_res->num; i++) { 346 struct wpa_scan_res *bss = scan_res->res[i]; 347 if (bss->freq == pri_freq) 348 pri_bss++; 349 else if (bss->freq == sec_freq) 350 sec_bss++; 351 } 352 if (sec_bss && !pri_bss) { 353 wpa_printf(MSG_INFO, "Switch own primary and secondary " 354 "channel to get secondary channel with no Beacons " 355 "from other BSSes"); 356 ieee80211n_switch_pri_sec(iface); 357 return 1; 358 } 359 360 /* 361 * Match PRI/SEC channel with any existing HT40 BSS on the same 362 * channels that we are about to use (if already mixed order in 363 * existing BSSes, use own preference). 364 */ 365 match = 0; 366 for (i = 0; i < scan_res->num; i++) { 367 struct wpa_scan_res *bss = scan_res->res[i]; 368 ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan); 369 if (pri_chan == bss_pri_chan && 370 sec_chan == bss_sec_chan) { 371 match = 1; 372 break; 373 } 374 } 375 if (!match) { 376 for (i = 0; i < scan_res->num; i++) { 377 struct wpa_scan_res *bss = scan_res->res[i]; 378 ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan, 379 &bss_sec_chan); 380 if (pri_chan == bss_sec_chan && 381 sec_chan == bss_pri_chan) { 382 wpa_printf(MSG_INFO, "Switch own primary and " 383 "secondary channel due to BSS " 384 "overlap with " MACSTR, 385 MAC2STR(bss->bssid)); 386 ieee80211n_switch_pri_sec(iface); 387 break; 388 } 389 } 390 } 391 392 return 1; 393} 394 395 396static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface, 397 struct wpa_scan_results *scan_res) 398{ 399 int pri_freq, sec_freq; 400 int affected_start, affected_end; 401 size_t i; 402 403 pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel); 404 if (iface->conf->secondary_channel > 0) 405 sec_freq = pri_freq + 20; 406 else 407 sec_freq = pri_freq - 20; 408 affected_start = (pri_freq + sec_freq) / 2 - 25; 409 affected_end = (pri_freq + sec_freq) / 2 + 25; 410 wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz", 411 affected_start, affected_end); 412 for (i = 0; i < scan_res->num; i++) { 413 struct wpa_scan_res *bss = scan_res->res[i]; 414 int pri = bss->freq; 415 int sec = pri; 416 int sec_chan, pri_chan; 417 418 ieee80211n_get_pri_sec_chan(bss, &pri_chan, &sec_chan); 419 420 if (sec_chan) { 421 if (sec_chan < pri_chan) 422 sec = pri - 20; 423 else 424 sec = pri + 20; 425 } 426 427 if ((pri < affected_start || pri > affected_end) && 428 (sec < affected_start || sec > affected_end)) 429 continue; /* not within affected channel range */ 430 431 wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR 432 " freq=%d pri=%d sec=%d", 433 MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan); 434 435 if (sec_chan) { 436 if (pri_freq != pri || sec_freq != sec) { 437 wpa_printf(MSG_DEBUG, "40 MHz pri/sec " 438 "mismatch with BSS " MACSTR 439 " <%d,%d> (chan=%d%c) vs. <%d,%d>", 440 MAC2STR(bss->bssid), 441 pri, sec, pri_chan, 442 sec > pri ? '+' : '-', 443 pri_freq, sec_freq); 444 return 0; 445 } 446 } 447 448 /* TODO: 40 MHz intolerant */ 449 } 450 451 return 1; 452} 453 454 455static void ieee80211n_check_scan(struct hostapd_iface *iface) 456{ 457 struct wpa_scan_results *scan_res; 458 int oper40; 459 int res; 460 461 /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is 462 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */ 463 464 iface->scan_cb = NULL; 465 466 scan_res = hostapd_driver_get_scan_results(iface->bss[0]); 467 if (scan_res == NULL) { 468 hostapd_setup_interface_complete(iface, 1); 469 return; 470 } 471 472 if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A) 473 oper40 = ieee80211n_check_40mhz_5g(iface, scan_res); 474 else 475 oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res); 476 wpa_scan_results_free(scan_res); 477 478 if (!oper40) { 479 wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on " 480 "channel pri=%d sec=%d based on overlapping BSSes", 481 iface->conf->channel, 482 iface->conf->channel + 483 iface->conf->secondary_channel * 4); 484 iface->conf->secondary_channel = 0; 485 } 486 487 res = ieee80211n_allowed_ht40_channel_pair(iface); 488 hostapd_setup_interface_complete(iface, !res); 489} 490 491 492static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface, 493 struct wpa_driver_scan_params *params) 494{ 495 /* Scan only the affected frequency range */ 496 int pri_freq, sec_freq; 497 int affected_start, affected_end; 498 int i, pos; 499 struct hostapd_hw_modes *mode; 500 501 if (iface->current_mode == NULL) 502 return; 503 504 pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel); 505 if (iface->conf->secondary_channel > 0) 506 sec_freq = pri_freq + 20; 507 else 508 sec_freq = pri_freq - 20; 509 affected_start = (pri_freq + sec_freq) / 2 - 25; 510 affected_end = (pri_freq + sec_freq) / 2 + 25; 511 wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz", 512 affected_start, affected_end); 513 514 mode = iface->current_mode; 515 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 516 if (params->freqs == NULL) 517 return; 518 pos = 0; 519 520 for (i = 0; i < mode->num_channels; i++) { 521 struct hostapd_channel_data *chan = &mode->channels[i]; 522 if (chan->flag & HOSTAPD_CHAN_DISABLED) 523 continue; 524 if (chan->freq < affected_start || 525 chan->freq > affected_end) 526 continue; 527 params->freqs[pos++] = chan->freq; 528 } 529} 530 531 532static void ieee80211n_scan_channels_5g(struct hostapd_iface *iface, 533 struct wpa_driver_scan_params *params) 534{ 535 /* Scan only the affected frequency range */ 536 int pri_freq; 537 int affected_start, affected_end; 538 int i, pos; 539 struct hostapd_hw_modes *mode; 540 541 if (iface->current_mode == NULL) 542 return; 543 544 pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel); 545 if (iface->conf->secondary_channel > 0) { 546 affected_start = pri_freq - 10; 547 affected_end = pri_freq + 30; 548 } else { 549 affected_start = pri_freq - 30; 550 affected_end = pri_freq + 10; 551 } 552 wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz", 553 affected_start, affected_end); 554 555 mode = iface->current_mode; 556 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 557 if (params->freqs == NULL) 558 return; 559 pos = 0; 560 561 for (i = 0; i < mode->num_channels; i++) { 562 struct hostapd_channel_data *chan = &mode->channels[i]; 563 if (chan->flag & HOSTAPD_CHAN_DISABLED) 564 continue; 565 if (chan->freq < affected_start || 566 chan->freq > affected_end) 567 continue; 568 params->freqs[pos++] = chan->freq; 569 } 570} 571 572 573static int ieee80211n_check_40mhz(struct hostapd_iface *iface) 574{ 575 struct wpa_driver_scan_params params; 576 577 if (!iface->conf->secondary_channel) 578 return 0; /* HT40 not used */ 579 580 hostapd_set_state(iface, HAPD_IFACE_HT_SCAN); 581 wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling " 582 "40 MHz channel"); 583 os_memset(¶ms, 0, sizeof(params)); 584 if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) 585 ieee80211n_scan_channels_2g4(iface, ¶ms); 586 else 587 ieee80211n_scan_channels_5g(iface, ¶ms); 588 if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) { 589 wpa_printf(MSG_ERROR, "Failed to request a scan of " 590 "neighboring BSSes"); 591 os_free(params.freqs); 592 return -1; 593 } 594 os_free(params.freqs); 595 596 iface->scan_cb = ieee80211n_check_scan; 597 return 1; 598} 599 600 601static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface) 602{ 603 u16 hw = iface->current_mode->ht_capab; 604 u16 conf = iface->conf->ht_capab; 605 606 if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) && 607 !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) { 608 wpa_printf(MSG_ERROR, "Driver does not support configured " 609 "HT capability [LDPC]"); 610 return 0; 611 } 612 613 if ((conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) && 614 !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) { 615 wpa_printf(MSG_ERROR, "Driver does not support configured " 616 "HT capability [HT40*]"); 617 return 0; 618 } 619 620 if ((conf & HT_CAP_INFO_SMPS_MASK) != (hw & HT_CAP_INFO_SMPS_MASK) && 621 (conf & HT_CAP_INFO_SMPS_MASK) != HT_CAP_INFO_SMPS_DISABLED) { 622 wpa_printf(MSG_ERROR, "Driver does not support configured " 623 "HT capability [SMPS-*]"); 624 return 0; 625 } 626 627 if ((conf & HT_CAP_INFO_GREEN_FIELD) && 628 !(hw & HT_CAP_INFO_GREEN_FIELD)) { 629 wpa_printf(MSG_ERROR, "Driver does not support configured " 630 "HT capability [GF]"); 631 return 0; 632 } 633 634 if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) && 635 !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) { 636 wpa_printf(MSG_ERROR, "Driver does not support configured " 637 "HT capability [SHORT-GI-20]"); 638 return 0; 639 } 640 641 if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) && 642 !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) { 643 wpa_printf(MSG_ERROR, "Driver does not support configured " 644 "HT capability [SHORT-GI-40]"); 645 return 0; 646 } 647 648 if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) { 649 wpa_printf(MSG_ERROR, "Driver does not support configured " 650 "HT capability [TX-STBC]"); 651 return 0; 652 } 653 654 if ((conf & HT_CAP_INFO_RX_STBC_MASK) > 655 (hw & HT_CAP_INFO_RX_STBC_MASK)) { 656 wpa_printf(MSG_ERROR, "Driver does not support configured " 657 "HT capability [RX-STBC*]"); 658 return 0; 659 } 660 661 if ((conf & HT_CAP_INFO_DELAYED_BA) && 662 !(hw & HT_CAP_INFO_DELAYED_BA)) { 663 wpa_printf(MSG_ERROR, "Driver does not support configured " 664 "HT capability [DELAYED-BA]"); 665 return 0; 666 } 667 668 if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) && 669 !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) { 670 wpa_printf(MSG_ERROR, "Driver does not support configured " 671 "HT capability [MAX-AMSDU-7935]"); 672 return 0; 673 } 674 675 if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) && 676 !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) { 677 wpa_printf(MSG_ERROR, "Driver does not support configured " 678 "HT capability [DSSS_CCK-40]"); 679 return 0; 680 } 681 682 if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) && 683 !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) { 684 wpa_printf(MSG_ERROR, "Driver does not support configured " 685 "HT capability [LSIG-TXOP-PROT]"); 686 return 0; 687 } 688 689 return 1; 690} 691 692 693#ifdef CONFIG_IEEE80211AC 694 695static int ieee80211ac_cap_check(u32 hw, u32 conf, u32 cap, const char *name) 696{ 697 u32 req_cap = conf & cap; 698 699 /* 700 * Make sure we support all requested capabilities. 701 * NOTE: We assume that 'cap' represents a capability mask, 702 * not a discrete value. 703 */ 704 if ((hw & req_cap) != req_cap) { 705 wpa_printf(MSG_ERROR, "Driver does not support configured VHT capability [%s]", 706 name); 707 return 0; 708 } 709 return 1; 710} 711 712 713static int ieee80211ac_cap_check_max(u32 hw, u32 conf, u32 cap, 714 const char *name) 715{ 716 u32 hw_max = hw & cap; 717 u32 conf_val = conf & cap; 718 719 if (conf_val > hw_max) { 720 int offset = find_first_bit(cap); 721 wpa_printf(MSG_ERROR, "Configured VHT capability [%s] exceeds max value supported by the driver (%d > %d)", 722 name, conf_val >> offset, hw_max >> offset); 723 return 0; 724 } 725 return 1; 726} 727 728 729static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface) 730{ 731 u32 hw = iface->current_mode->vht_capab; 732 u32 conf = iface->conf->vht_capab; 733 734 wpa_printf(MSG_DEBUG, "hw vht capab: 0x%x, conf vht capab: 0x%x", 735 hw, conf); 736 737#define VHT_CAP_CHECK(cap) \ 738 do { \ 739 if (!ieee80211ac_cap_check(hw, conf, cap, #cap)) \ 740 return 0; \ 741 } while (0) 742 743#define VHT_CAP_CHECK_MAX(cap) \ 744 do { \ 745 if (!ieee80211ac_cap_check_max(hw, conf, cap, #cap)) \ 746 return 0; \ 747 } while (0) 748 749 VHT_CAP_CHECK_MAX(VHT_CAP_MAX_MPDU_LENGTH_MASK); 750 VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ); 751 VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ); 752 VHT_CAP_CHECK(VHT_CAP_RXLDPC); 753 VHT_CAP_CHECK(VHT_CAP_SHORT_GI_80); 754 VHT_CAP_CHECK(VHT_CAP_SHORT_GI_160); 755 VHT_CAP_CHECK(VHT_CAP_TXSTBC); 756 VHT_CAP_CHECK_MAX(VHT_CAP_RXSTBC_MASK); 757 VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMER_CAPABLE); 758 VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMEE_CAPABLE); 759 VHT_CAP_CHECK_MAX(VHT_CAP_BEAMFORMEE_STS_MAX); 760 VHT_CAP_CHECK_MAX(VHT_CAP_SOUNDING_DIMENSION_MAX); 761 VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMER_CAPABLE); 762 VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMEE_CAPABLE); 763 VHT_CAP_CHECK(VHT_CAP_VHT_TXOP_PS); 764 VHT_CAP_CHECK(VHT_CAP_HTC_VHT); 765 VHT_CAP_CHECK_MAX(VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX); 766 VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB); 767 VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB); 768 VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN); 769 VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN); 770 771#undef VHT_CAP_CHECK 772#undef VHT_CAP_CHECK_MAX 773 774 return 1; 775} 776#endif /* CONFIG_IEEE80211AC */ 777 778#endif /* CONFIG_IEEE80211N */ 779 780 781int hostapd_check_ht_capab(struct hostapd_iface *iface) 782{ 783#ifdef CONFIG_IEEE80211N 784 int ret; 785 if (!iface->conf->ieee80211n) 786 return 0; 787 if (!ieee80211n_supported_ht_capab(iface)) 788 return -1; 789#ifdef CONFIG_IEEE80211AC 790 if (!ieee80211ac_supported_vht_capab(iface)) 791 return -1; 792#endif /* CONFIG_IEEE80211AC */ 793 ret = ieee80211n_check_40mhz(iface); 794 if (ret) 795 return ret; 796 if (!ieee80211n_allowed_ht40_channel_pair(iface)) 797 return -1; 798#endif /* CONFIG_IEEE80211N */ 799 800 return 0; 801} 802 803 804static int hostapd_is_usable_chan(struct hostapd_iface *iface, 805 int channel, int primary) 806{ 807 int i; 808 struct hostapd_channel_data *chan; 809 810 for (i = 0; i < iface->current_mode->num_channels; i++) { 811 chan = &iface->current_mode->channels[i]; 812 if (chan->chan != channel) 813 continue; 814 815 if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) 816 return 1; 817 818 wpa_printf(MSG_DEBUG, 819 "%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s%s", 820 primary ? "" : "Configured HT40 secondary ", 821 i, chan->chan, chan->flag, 822 chan->flag & HOSTAPD_CHAN_NO_IBSS ? " NO-IBSS" : "", 823 chan->flag & HOSTAPD_CHAN_PASSIVE_SCAN ? 824 " PASSIVE-SCAN" : "", 825 chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : ""); 826 } 827 828 return 0; 829} 830 831 832static int hostapd_is_usable_chans(struct hostapd_iface *iface) 833{ 834 if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1)) 835 return 0; 836 837 if (!iface->conf->secondary_channel) 838 return 1; 839 840 return hostapd_is_usable_chan(iface, iface->conf->channel + 841 iface->conf->secondary_channel * 4, 0); 842} 843 844 845static enum hostapd_chan_status 846hostapd_check_chans(struct hostapd_iface *iface) 847{ 848 if (iface->conf->channel) { 849 if (hostapd_is_usable_chans(iface)) 850 return HOSTAPD_CHAN_VALID; 851 else 852 return HOSTAPD_CHAN_INVALID; 853 } 854 855 /* 856 * The user set channel=0 or channel=acs_survey 857 * which is used to trigger ACS. 858 */ 859 860 switch (acs_init(iface)) { 861 case HOSTAPD_CHAN_ACS: 862 return HOSTAPD_CHAN_ACS; 863 case HOSTAPD_CHAN_VALID: 864 case HOSTAPD_CHAN_INVALID: 865 default: 866 return HOSTAPD_CHAN_INVALID; 867 } 868} 869 870 871static void hostapd_notify_bad_chans(struct hostapd_iface *iface) 872{ 873 hostapd_logger(iface->bss[0], NULL, 874 HOSTAPD_MODULE_IEEE80211, 875 HOSTAPD_LEVEL_WARNING, 876 "Configured channel (%d) not found from the " 877 "channel list of current mode (%d) %s", 878 iface->conf->channel, 879 iface->current_mode->mode, 880 hostapd_hw_mode_txt(iface->current_mode->mode)); 881 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211, 882 HOSTAPD_LEVEL_WARNING, 883 "Hardware does not support configured channel"); 884} 885 886 887int hostapd_acs_completed(struct hostapd_iface *iface, int err) 888{ 889 int ret = -1; 890 891 if (err) 892 goto out; 893 894 switch (hostapd_check_chans(iface)) { 895 case HOSTAPD_CHAN_VALID: 896 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, 897 ACS_EVENT_COMPLETED "freq=%d channel=%d", 898 hostapd_hw_get_freq(iface->bss[0], 899 iface->conf->channel), 900 iface->conf->channel); 901 break; 902 case HOSTAPD_CHAN_ACS: 903 wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available"); 904 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED); 905 hostapd_notify_bad_chans(iface); 906 goto out; 907 case HOSTAPD_CHAN_INVALID: 908 default: 909 wpa_printf(MSG_ERROR, "ACS picked unusable channels"); 910 wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO, ACS_EVENT_FAILED); 911 hostapd_notify_bad_chans(iface); 912 goto out; 913 } 914 915 ret = hostapd_check_ht_capab(iface); 916 if (ret < 0) 917 goto out; 918 if (ret == 1) { 919 wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback"); 920 return 0; 921 } 922 923 ret = 0; 924out: 925 return hostapd_setup_interface_complete(iface, ret); 926} 927 928 929/** 930 * hostapd_select_hw_mode - Select the hardware mode 931 * @iface: Pointer to interface data. 932 * Returns: 0 on success, < 0 on failure 933 * 934 * Sets up the hardware mode, channel, rates, and passive scanning 935 * based on the configuration. 936 */ 937int hostapd_select_hw_mode(struct hostapd_iface *iface) 938{ 939 int i; 940 941 if (iface->num_hw_features < 1) 942 return -1; 943 944 if ((iface->conf->hw_mode == HOSTAPD_MODE_IEEE80211G || 945 iface->conf->ieee80211n || iface->conf->ieee80211ac) && 946 iface->conf->channel == 14) { 947 wpa_printf(MSG_INFO, "Disable OFDM/HT/VHT on channel 14"); 948 iface->conf->hw_mode = HOSTAPD_MODE_IEEE80211B; 949 iface->conf->ieee80211n = 0; 950 iface->conf->ieee80211ac = 0; 951 } 952 953 iface->current_mode = NULL; 954 for (i = 0; i < iface->num_hw_features; i++) { 955 struct hostapd_hw_modes *mode = &iface->hw_features[i]; 956 if (mode->mode == iface->conf->hw_mode) { 957 iface->current_mode = mode; 958 break; 959 } 960 } 961 962 if (iface->current_mode == NULL) { 963 wpa_printf(MSG_ERROR, "Hardware does not support configured " 964 "mode"); 965 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211, 966 HOSTAPD_LEVEL_WARNING, 967 "Hardware does not support configured mode " 968 "(%d) (hw_mode in hostapd.conf)", 969 (int) iface->conf->hw_mode); 970 return -2; 971 } 972 973 switch (hostapd_check_chans(iface)) { 974 case HOSTAPD_CHAN_VALID: 975 return 0; 976 case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */ 977 return 1; 978 case HOSTAPD_CHAN_INVALID: 979 default: 980 hostapd_notify_bad_chans(iface); 981 return -3; 982 } 983} 984 985 986const char * hostapd_hw_mode_txt(int mode) 987{ 988 switch (mode) { 989 case HOSTAPD_MODE_IEEE80211A: 990 return "IEEE 802.11a"; 991 case HOSTAPD_MODE_IEEE80211B: 992 return "IEEE 802.11b"; 993 case HOSTAPD_MODE_IEEE80211G: 994 return "IEEE 802.11g"; 995 case HOSTAPD_MODE_IEEE80211AD: 996 return "IEEE 802.11ad"; 997 default: 998 return "UNKNOWN"; 999 } 1000} 1001 1002 1003int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan) 1004{ 1005 int i; 1006 1007 if (!hapd->iface->current_mode) 1008 return 0; 1009 1010 for (i = 0; i < hapd->iface->current_mode->num_channels; i++) { 1011 struct hostapd_channel_data *ch = 1012 &hapd->iface->current_mode->channels[i]; 1013 if (ch->chan == chan) 1014 return ch->freq; 1015 } 1016 1017 return 0; 1018} 1019 1020 1021int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq) 1022{ 1023 int i; 1024 1025 if (!hapd->iface->current_mode) 1026 return 0; 1027 1028 for (i = 0; i < hapd->iface->current_mode->num_channels; i++) { 1029 struct hostapd_channel_data *ch = 1030 &hapd->iface->current_mode->channels[i]; 1031 if (ch->freq == freq) 1032 return ch->chan; 1033 } 1034 1035 return 0; 1036} 1037