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