Home | History | Annotate | Download | only in ap
      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 (at) w1.fi>
      6  *
      7  * This program is free software; you can redistribute it and/or modify
      8  * it under the terms of the GNU General Public License version 2 as
      9  * published by the Free Software Foundation.
     10  *
     11  * Alternatively, this software may be distributed under the terms of BSD
     12  * license.
     13  *
     14  * See README and COPYING for more details.
     15  */
     16 
     17 #include "utils/includes.h"
     18 
     19 #include "utils/common.h"
     20 #include "utils/eloop.h"
     21 #include "common/ieee802_11_defs.h"
     22 #include "common/ieee802_11_common.h"
     23 #include "drivers/driver.h"
     24 #include "hostapd.h"
     25 #include "ap_config.h"
     26 #include "ap_drv_ops.h"
     27 #include "acs.h"
     28 #include "hw_features.h"
     29 
     30 
     31 void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
     32 			      size_t num_hw_features)
     33 {
     34 	size_t i;
     35 
     36 	if (hw_features == NULL)
     37 		return;
     38 
     39 	for (i = 0; i < num_hw_features; i++) {
     40 		os_free(hw_features[i].channels);
     41 		os_free(hw_features[i].rates);
     42 	}
     43 
     44 	os_free(hw_features);
     45 }
     46 
     47 
     48 int hostapd_get_hw_features(struct hostapd_iface *iface)
     49 {
     50 	struct hostapd_data *hapd = iface->bss[0];
     51 	int ret = 0, i, j;
     52 	u16 num_modes, flags;
     53 	struct hostapd_hw_modes *modes;
     54 
     55 	if (hostapd_drv_none(hapd))
     56 		return -1;
     57 	modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags);
     58 	if (modes == NULL) {
     59 		hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
     60 			       HOSTAPD_LEVEL_DEBUG,
     61 			       "Fetching hardware channel/rate support not "
     62 			       "supported.");
     63 		return -1;
     64 	}
     65 
     66 	iface->hw_flags = flags;
     67 
     68 	hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
     69 	iface->hw_features = modes;
     70 	iface->num_hw_features = num_modes;
     71 
     72 	for (i = 0; i < num_modes; i++) {
     73 		struct hostapd_hw_modes *feature = &modes[i];
     74 		/* set flag for channels we can use in current regulatory
     75 		 * domain */
     76 		for (j = 0; j < feature->num_channels; j++) {
     77 			/*
     78 			 * Disable all channels that are marked not to allow
     79 			 * IBSS operation or active scanning. In addition,
     80 			 * disable all channels that require radar detection,
     81 			 * since that (in addition to full DFS) is not yet
     82 			 * supported.
     83 			 */
     84 			if (feature->channels[j].flag &
     85 			    (HOSTAPD_CHAN_NO_IBSS |
     86 			     HOSTAPD_CHAN_PASSIVE_SCAN |
     87 			     HOSTAPD_CHAN_RADAR))
     88 				feature->channels[j].flag |=
     89 					HOSTAPD_CHAN_DISABLED;
     90 			if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED)
     91 				continue;
     92 			wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d "
     93 				   "chan=%d freq=%d MHz max_tx_power=%d dBm",
     94 				   feature->mode,
     95 				   feature->channels[j].chan,
     96 				   feature->channels[j].freq,
     97 				   feature->channels[j].max_tx_power);
     98 		}
     99 	}
    100 
    101 	return ret;
    102 }
    103 
    104 
    105 int hostapd_prepare_rates(struct hostapd_iface *iface,
    106 			  struct hostapd_hw_modes *mode)
    107 {
    108 	int i, num_basic_rates = 0;
    109 	int basic_rates_a[] = { 60, 120, 240, -1 };
    110 	int basic_rates_b[] = { 10, 20, -1 };
    111 	int basic_rates_g[] = { 10, 20, 55, 110, -1 };
    112 	int *basic_rates;
    113 
    114 	if (iface->conf->basic_rates)
    115 		basic_rates = iface->conf->basic_rates;
    116 	else switch (mode->mode) {
    117 	case HOSTAPD_MODE_IEEE80211A:
    118 		basic_rates = basic_rates_a;
    119 		break;
    120 	case HOSTAPD_MODE_IEEE80211B:
    121 		basic_rates = basic_rates_b;
    122 		break;
    123 	case HOSTAPD_MODE_IEEE80211G:
    124 		basic_rates = basic_rates_g;
    125 		break;
    126 	case HOSTAPD_MODE_IEEE80211AD:
    127 		return 0; /* No basic rates for 11ad */
    128 	default:
    129 		return -1;
    130 	}
    131 
    132 	i = 0;
    133 	while (basic_rates[i] >= 0)
    134 		i++;
    135 	if (i)
    136 		i++; /* -1 termination */
    137 	os_free(iface->basic_rates);
    138 	iface->basic_rates = os_malloc(i * sizeof(int));
    139 	if (iface->basic_rates)
    140 		os_memcpy(iface->basic_rates, basic_rates, i * sizeof(int));
    141 
    142 	os_free(iface->current_rates);
    143 	iface->num_rates = 0;
    144 
    145 	iface->current_rates =
    146 		os_calloc(mode->num_rates, sizeof(struct hostapd_rate_data));
    147 	if (!iface->current_rates) {
    148 		wpa_printf(MSG_ERROR, "Failed to allocate memory for rate "
    149 			   "table.");
    150 		return -1;
    151 	}
    152 
    153 	for (i = 0; i < mode->num_rates; i++) {
    154 		struct hostapd_rate_data *rate;
    155 
    156 		if (iface->conf->supported_rates &&
    157 		    !hostapd_rate_found(iface->conf->supported_rates,
    158 					mode->rates[i]))
    159 			continue;
    160 
    161 		rate = &iface->current_rates[iface->num_rates];
    162 		rate->rate = mode->rates[i];
    163 		if (hostapd_rate_found(basic_rates, rate->rate)) {
    164 			rate->flags |= HOSTAPD_RATE_BASIC;
    165 			num_basic_rates++;
    166 		}
    167 		wpa_printf(MSG_DEBUG, "RATE[%d] rate=%d flags=0x%x",
    168 			   iface->num_rates, rate->rate, rate->flags);
    169 		iface->num_rates++;
    170 	}
    171 
    172 	if ((iface->num_rates == 0 || num_basic_rates == 0) &&
    173 	    (!iface->conf->ieee80211n || !iface->conf->require_ht)) {
    174 		wpa_printf(MSG_ERROR, "No rates remaining in supported/basic "
    175 			   "rate sets (%d,%d).",
    176 			   iface->num_rates, num_basic_rates);
    177 		return -1;
    178 	}
    179 
    180 	return 0;
    181 }
    182 
    183 
    184 #ifdef CONFIG_IEEE80211N
    185 static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
    186 {
    187 	int sec_chan, ok, j, first;
    188 	int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
    189 			  184, 192 };
    190 	size_t k;
    191 
    192 	if (!iface->conf->secondary_channel)
    193 		return 1; /* HT40 not used */
    194 
    195 	sec_chan = iface->conf->channel + iface->conf->secondary_channel * 4;
    196 	wpa_printf(MSG_DEBUG, "HT40: control channel: %d  "
    197 		   "secondary channel: %d",
    198 		   iface->conf->channel, sec_chan);
    199 
    200 	/* Verify that HT40 secondary channel is an allowed 20 MHz
    201 	 * channel */
    202 	ok = 0;
    203 	for (j = 0; j < iface->current_mode->num_channels; j++) {
    204 		struct hostapd_channel_data *chan =
    205 			&iface->current_mode->channels[j];
    206 		if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
    207 		    chan->chan == sec_chan) {
    208 			ok = 1;
    209 			break;
    210 		}
    211 	}
    212 	if (!ok) {
    213 		wpa_printf(MSG_ERROR, "HT40 secondary channel %d not allowed",
    214 			   sec_chan);
    215 		return 0;
    216 	}
    217 
    218 	/*
    219 	 * Verify that HT40 primary,secondary channel pair is allowed per
    220 	 * IEEE 802.11n Annex J. This is only needed for 5 GHz band since
    221 	 * 2.4 GHz rules allow all cases where the secondary channel fits into
    222 	 * the list of allowed channels (already checked above).
    223 	 */
    224 	if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
    225 		return 1;
    226 
    227 	if (iface->conf->secondary_channel > 0)
    228 		first = iface->conf->channel;
    229 	else
    230 		first = sec_chan;
    231 
    232 	ok = 0;
    233 	for (k = 0; k < sizeof(allowed) / sizeof(allowed[0]); k++) {
    234 		if (first == allowed[k]) {
    235 			ok = 1;
    236 			break;
    237 		}
    238 	}
    239 	if (!ok) {
    240 		wpa_printf(MSG_ERROR, "HT40 channel pair (%d, %d) not allowed",
    241 			   iface->conf->channel,
    242 			   iface->conf->secondary_channel);
    243 		return 0;
    244 	}
    245 
    246 	return 1;
    247 }
    248 
    249 
    250 static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface)
    251 {
    252 	if (iface->conf->secondary_channel > 0) {
    253 		iface->conf->channel += 4;
    254 		iface->conf->secondary_channel = -1;
    255 	} else {
    256 		iface->conf->channel -= 4;
    257 		iface->conf->secondary_channel = 1;
    258 	}
    259 }
    260 
    261 
    262 static void ieee80211n_get_pri_sec_chan(struct wpa_scan_res *bss,
    263 					int *pri_chan, int *sec_chan)
    264 {
    265 	struct ieee80211_ht_operation *oper;
    266 	struct ieee802_11_elems elems;
    267 
    268 	*pri_chan = *sec_chan = 0;
    269 
    270 	ieee802_11_parse_elems((u8 *) (bss + 1), bss->ie_len, &elems, 0);
    271 	if (elems.ht_operation &&
    272 	    elems.ht_operation_len >= sizeof(*oper)) {
    273 		oper = (struct ieee80211_ht_operation *) elems.ht_operation;
    274 		*pri_chan = oper->control_chan;
    275 		if (oper->ht_param & HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH) {
    276 			int sec = oper->ht_param &
    277 				HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
    278 			if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
    279 				*sec_chan = *pri_chan + 4;
    280 			else if (sec == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
    281 				*sec_chan = *pri_chan - 4;
    282 		}
    283 	}
    284 }
    285 
    286 
    287 static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface,
    288 				     struct wpa_scan_results *scan_res)
    289 {
    290 	int pri_chan, sec_chan, pri_freq, sec_freq, pri_bss, sec_bss;
    291 	int bss_pri_chan, bss_sec_chan;
    292 	size_t i;
    293 	int match;
    294 
    295 	pri_chan = iface->conf->channel;
    296 	sec_chan = iface->conf->secondary_channel * 4;
    297 	pri_freq = hostapd_hw_get_freq(iface->bss[0], pri_chan);
    298 	if (iface->conf->secondary_channel > 0)
    299 		sec_freq = pri_freq + 20;
    300 	else
    301 		sec_freq = pri_freq - 20;
    302 
    303 	/*
    304 	 * Switch PRI/SEC channels if Beacons were detected on selected SEC
    305 	 * channel, but not on selected PRI channel.
    306 	 */
    307 	pri_bss = sec_bss = 0;
    308 	for (i = 0; i < scan_res->num; i++) {
    309 		struct wpa_scan_res *bss = scan_res->res[i];
    310 		if (bss->freq == pri_freq)
    311 			pri_bss++;
    312 		else if (bss->freq == sec_freq)
    313 			sec_bss++;
    314 	}
    315 	if (sec_bss && !pri_bss) {
    316 		wpa_printf(MSG_INFO, "Switch own primary and secondary "
    317 			   "channel to get secondary channel with no Beacons "
    318 			   "from other BSSes");
    319 		ieee80211n_switch_pri_sec(iface);
    320 	}
    321 
    322 	/*
    323 	 * Match PRI/SEC channel with any existing HT40 BSS on the same
    324 	 * channels that we are about to use (if already mixed order in
    325 	 * existing BSSes, use own preference).
    326 	 */
    327 	match = 0;
    328 	for (i = 0; i < scan_res->num; i++) {
    329 		struct wpa_scan_res *bss = scan_res->res[i];
    330 		ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan, &bss_sec_chan);
    331 		if (pri_chan == bss_pri_chan &&
    332 		    sec_chan == bss_sec_chan) {
    333 			match = 1;
    334 			break;
    335 		}
    336 	}
    337 	if (!match) {
    338 		for (i = 0; i < scan_res->num; i++) {
    339 			struct wpa_scan_res *bss = scan_res->res[i];
    340 			ieee80211n_get_pri_sec_chan(bss, &bss_pri_chan,
    341 						    &bss_sec_chan);
    342 			if (pri_chan == bss_sec_chan &&
    343 			    sec_chan == bss_pri_chan) {
    344 				wpa_printf(MSG_INFO, "Switch own primary and "
    345 					   "secondary channel due to BSS "
    346 					   "overlap with " MACSTR,
    347 					   MAC2STR(bss->bssid));
    348 				ieee80211n_switch_pri_sec(iface);
    349 				break;
    350 			}
    351 		}
    352 	}
    353 
    354 	return 1;
    355 }
    356 
    357 
    358 static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface,
    359 				      struct wpa_scan_results *scan_res)
    360 {
    361 	int pri_freq, sec_freq;
    362 	int affected_start, affected_end;
    363 	size_t i;
    364 
    365 	pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
    366 	if (iface->conf->secondary_channel > 0)
    367 		sec_freq = pri_freq + 20;
    368 	else
    369 		sec_freq = pri_freq - 20;
    370 	affected_start = (pri_freq + sec_freq) / 2 - 25;
    371 	affected_end = (pri_freq + sec_freq) / 2 + 25;
    372 	wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
    373 		   affected_start, affected_end);
    374 	for (i = 0; i < scan_res->num; i++) {
    375 		struct wpa_scan_res *bss = scan_res->res[i];
    376 		int pri = bss->freq;
    377 		int sec = pri;
    378 		int sec_chan, pri_chan;
    379 
    380 		ieee80211n_get_pri_sec_chan(bss, &pri_chan, &sec_chan);
    381 
    382 		if (sec_chan) {
    383 			if (sec_chan < pri_chan)
    384 				sec = pri - 20;
    385 			else
    386 				sec = pri + 20;
    387 		}
    388 
    389 		if ((pri < affected_start || pri > affected_end) &&
    390 		    (sec < affected_start || sec > affected_end))
    391 			continue; /* not within affected channel range */
    392 
    393 		wpa_printf(MSG_DEBUG, "Neighboring BSS: " MACSTR
    394 			   " freq=%d pri=%d sec=%d",
    395 			   MAC2STR(bss->bssid), bss->freq, pri_chan, sec_chan);
    396 
    397 		if (sec_chan) {
    398 			if (pri_freq != pri || sec_freq != sec) {
    399 				wpa_printf(MSG_DEBUG, "40 MHz pri/sec "
    400 					   "mismatch with BSS " MACSTR
    401 					   " <%d,%d> (chan=%d%c) vs. <%d,%d>",
    402 					   MAC2STR(bss->bssid),
    403 					   pri, sec, pri_chan,
    404 					   sec > pri ? '+' : '-',
    405 					   pri_freq, sec_freq);
    406 				return 0;
    407 			}
    408 		}
    409 
    410 		/* TODO: 40 MHz intolerant */
    411 	}
    412 
    413 	return 1;
    414 }
    415 
    416 
    417 static void ieee80211n_check_scan(struct hostapd_iface *iface)
    418 {
    419 	struct wpa_scan_results *scan_res;
    420 	int oper40;
    421 	int res;
    422 
    423 	/* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
    424 	 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */
    425 
    426 	iface->scan_cb = NULL;
    427 
    428 	scan_res = hostapd_driver_get_scan_results(iface->bss[0]);
    429 	if (scan_res == NULL) {
    430 		hostapd_setup_interface_complete(iface, 1);
    431 		return;
    432 	}
    433 
    434 	if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A)
    435 		oper40 = ieee80211n_check_40mhz_5g(iface, scan_res);
    436 	else
    437 		oper40 = ieee80211n_check_40mhz_2g4(iface, scan_res);
    438 	wpa_scan_results_free(scan_res);
    439 
    440 	if (!oper40) {
    441 		wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on "
    442 			   "channel pri=%d sec=%d based on overlapping BSSes",
    443 			   iface->conf->channel,
    444 			   iface->conf->channel +
    445 			   iface->conf->secondary_channel * 4);
    446 		iface->conf->secondary_channel = 0;
    447 	}
    448 
    449 	res = ieee80211n_allowed_ht40_channel_pair(iface);
    450 	hostapd_setup_interface_complete(iface, !res);
    451 }
    452 
    453 
    454 static void ieee80211n_scan_channels_2g4(struct hostapd_iface *iface,
    455 					 struct wpa_driver_scan_params *params)
    456 {
    457 	/* Scan only the affected frequency range */
    458 	int pri_freq, sec_freq;
    459 	int affected_start, affected_end;
    460 	int i, pos;
    461 	struct hostapd_hw_modes *mode;
    462 
    463 	if (iface->current_mode == NULL)
    464 		return;
    465 
    466 	pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
    467 	if (iface->conf->secondary_channel > 0)
    468 		sec_freq = pri_freq + 20;
    469 	else
    470 		sec_freq = pri_freq - 20;
    471 	affected_start = (pri_freq + sec_freq) / 2 - 25;
    472 	affected_end = (pri_freq + sec_freq) / 2 + 25;
    473 	wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
    474 		   affected_start, affected_end);
    475 
    476 	mode = iface->current_mode;
    477 	params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
    478 	if (params->freqs == NULL)
    479 		return;
    480 	pos = 0;
    481 
    482 	for (i = 0; i < mode->num_channels; i++) {
    483 		struct hostapd_channel_data *chan = &mode->channels[i];
    484 		if (chan->flag & HOSTAPD_CHAN_DISABLED)
    485 			continue;
    486 		if (chan->freq < affected_start ||
    487 		    chan->freq > affected_end)
    488 			continue;
    489 		params->freqs[pos++] = chan->freq;
    490 	}
    491 }
    492 
    493 
    494 static int ieee80211n_check_40mhz(struct hostapd_iface *iface)
    495 {
    496 	struct wpa_driver_scan_params params;
    497 
    498 	if (!iface->conf->secondary_channel)
    499 		return 0; /* HT40 not used */
    500 
    501 	wpa_printf(MSG_DEBUG, "Scan for neighboring BSSes prior to enabling "
    502 		   "40 MHz channel");
    503 	os_memset(&params, 0, sizeof(params));
    504 	if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
    505 		ieee80211n_scan_channels_2g4(iface, &params);
    506 	if (hostapd_driver_scan(iface->bss[0], &params) < 0) {
    507 		wpa_printf(MSG_ERROR, "Failed to request a scan of "
    508 			   "neighboring BSSes");
    509 		os_free(params.freqs);
    510 		return -1;
    511 	}
    512 	os_free(params.freqs);
    513 
    514 	iface->scan_cb = ieee80211n_check_scan;
    515 	return 1;
    516 }
    517 
    518 
    519 static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
    520 {
    521 	u16 hw = iface->current_mode->ht_capab;
    522 	u16 conf = iface->conf->ht_capab;
    523 
    524 	if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) &&
    525 	    !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) {
    526 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    527 			   "HT capability [LDPC]");
    528 		return 0;
    529 	}
    530 
    531 	if ((conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
    532 	    !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
    533 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    534 			   "HT capability [HT40*]");
    535 		return 0;
    536 	}
    537 
    538 	if ((conf & HT_CAP_INFO_SMPS_MASK) != (hw & HT_CAP_INFO_SMPS_MASK) &&
    539 	    (conf & HT_CAP_INFO_SMPS_MASK) != HT_CAP_INFO_SMPS_DISABLED) {
    540 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    541 			   "HT capability [SMPS-*]");
    542 		return 0;
    543 	}
    544 
    545 	if ((conf & HT_CAP_INFO_GREEN_FIELD) &&
    546 	    !(hw & HT_CAP_INFO_GREEN_FIELD)) {
    547 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    548 			   "HT capability [GF]");
    549 		return 0;
    550 	}
    551 
    552 	if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) &&
    553 	    !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) {
    554 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    555 			   "HT capability [SHORT-GI-20]");
    556 		return 0;
    557 	}
    558 
    559 	if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) &&
    560 	    !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) {
    561 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    562 			   "HT capability [SHORT-GI-40]");
    563 		return 0;
    564 	}
    565 
    566 	if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) {
    567 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    568 			   "HT capability [TX-STBC]");
    569 		return 0;
    570 	}
    571 
    572 	if ((conf & HT_CAP_INFO_RX_STBC_MASK) >
    573 	    (hw & HT_CAP_INFO_RX_STBC_MASK)) {
    574 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    575 			   "HT capability [RX-STBC*]");
    576 		return 0;
    577 	}
    578 
    579 	if ((conf & HT_CAP_INFO_DELAYED_BA) &&
    580 	    !(hw & HT_CAP_INFO_DELAYED_BA)) {
    581 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    582 			   "HT capability [DELAYED-BA]");
    583 		return 0;
    584 	}
    585 
    586 	if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) &&
    587 	    !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) {
    588 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    589 			   "HT capability [MAX-AMSDU-7935]");
    590 		return 0;
    591 	}
    592 
    593 	if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) &&
    594 	    !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) {
    595 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    596 			   "HT capability [DSSS_CCK-40]");
    597 		return 0;
    598 	}
    599 
    600 	if ((conf & HT_CAP_INFO_PSMP_SUPP) && !(hw & HT_CAP_INFO_PSMP_SUPP)) {
    601 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    602 			   "HT capability [PSMP]");
    603 		return 0;
    604 	}
    605 
    606 	if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) &&
    607 	    !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) {
    608 		wpa_printf(MSG_ERROR, "Driver does not support configured "
    609 			   "HT capability [LSIG-TXOP-PROT]");
    610 		return 0;
    611 	}
    612 
    613 	return 1;
    614 }
    615 
    616 #endif /* CONFIG_IEEE80211N */
    617 
    618 
    619 int hostapd_check_ht_capab(struct hostapd_iface *iface)
    620 {
    621 #ifdef CONFIG_IEEE80211N
    622 	int ret;
    623 	if (!iface->conf->ieee80211n)
    624 		return 0;
    625 	if (!ieee80211n_supported_ht_capab(iface))
    626 		return -1;
    627 	ret = ieee80211n_check_40mhz(iface);
    628 	if (ret)
    629 		return ret;
    630 	if (!ieee80211n_allowed_ht40_channel_pair(iface))
    631 		return -1;
    632 #endif /* CONFIG_IEEE80211N */
    633 
    634 	return 0;
    635 }
    636 
    637 
    638 static int hostapd_is_usable_chan(struct hostapd_iface *iface,
    639 				  int channel, int primary)
    640 {
    641 	int i;
    642 	struct hostapd_channel_data *chan;
    643 
    644 	for (i = 0; i < iface->current_mode->num_channels; i++) {
    645 		chan = &iface->current_mode->channels[i];
    646 		if (chan->chan != channel)
    647 			continue;
    648 
    649 		if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
    650 			return 1;
    651 
    652 		wpa_printf(MSG_DEBUG,
    653 			   "%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s%s",
    654 			   primary ? "" : "Configured HT40 secondary ",
    655 			   i, chan->chan, chan->flag,
    656 			   chan->flag & HOSTAPD_CHAN_NO_IBSS ? " NO-IBSS" : "",
    657 			   chan->flag & HOSTAPD_CHAN_PASSIVE_SCAN ?
    658 			   " PASSIVE-SCAN" : "",
    659 			   chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");
    660 	}
    661 
    662 	return 0;
    663 }
    664 
    665 
    666 static int hostapd_is_usable_chans(struct hostapd_iface *iface)
    667 {
    668 	if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1))
    669 		return 0;
    670 
    671 	if (!iface->conf->secondary_channel)
    672 		return 1;
    673 
    674 	return hostapd_is_usable_chan(iface, iface->conf->channel +
    675 				      iface->conf->secondary_channel * 4, 0);
    676 }
    677 
    678 
    679 static enum hostapd_chan_status
    680 hostapd_check_chans(struct hostapd_iface *iface)
    681 {
    682 	if (iface->conf->channel) {
    683 		if (hostapd_is_usable_chans(iface))
    684 			return HOSTAPD_CHAN_VALID;
    685 		else
    686 			return HOSTAPD_CHAN_INVALID;
    687 	}
    688 
    689 	/*
    690 	 * The user set channel=0 or channel=acs_survey
    691 	 * which is used to trigger ACS.
    692 	 */
    693 
    694 	switch (acs_init(iface)) {
    695 	case HOSTAPD_CHAN_ACS:
    696 		return HOSTAPD_CHAN_ACS;
    697 	case HOSTAPD_CHAN_VALID:
    698 	case HOSTAPD_CHAN_INVALID:
    699 	default:
    700 		return HOSTAPD_CHAN_INVALID;
    701 	}
    702 }
    703 
    704 
    705 static void hostapd_notify_bad_chans(struct hostapd_iface *iface)
    706 {
    707 	hostapd_logger(iface->bss[0], NULL,
    708 		       HOSTAPD_MODULE_IEEE80211,
    709 		       HOSTAPD_LEVEL_WARNING,
    710 		       "Configured channel (%d) not found from the "
    711 		       "channel list of current mode (%d) %s",
    712 		       iface->conf->channel,
    713 		       iface->current_mode->mode,
    714 		       hostapd_hw_mode_txt(iface->current_mode->mode));
    715 	hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
    716 		       HOSTAPD_LEVEL_WARNING,
    717 		       "Hardware does not support configured channel");
    718 }
    719 
    720 
    721 int hostapd_acs_completed(struct hostapd_iface *iface)
    722 {
    723 	int ret;
    724 
    725 	switch (hostapd_check_chans(iface)) {
    726 	case HOSTAPD_CHAN_VALID:
    727 		break;
    728 	case HOSTAPD_CHAN_ACS:
    729 		wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available");
    730 		hostapd_notify_bad_chans(iface);
    731 		return -1;
    732 	case HOSTAPD_CHAN_INVALID:
    733 	default:
    734 		wpa_printf(MSG_ERROR, "ACS picked unusable channels");
    735 		hostapd_notify_bad_chans(iface);
    736 		return -1;
    737 	}
    738 
    739 	ret = hostapd_check_ht_capab(iface);
    740 	if (ret < 0)
    741 		return -1;
    742 	if (ret == 1) {
    743 		wpa_printf(MSG_DEBUG, "Interface initialization will be completed in a callback");
    744 		return 0;
    745 	}
    746 
    747 	return hostapd_setup_interface_complete(iface, 0);
    748 }
    749 
    750 
    751 /**
    752  * hostapd_select_hw_mode - Select the hardware mode
    753  * @iface: Pointer to interface data.
    754  * Returns: 0 on success, < 0 on failure
    755  *
    756  * Sets up the hardware mode, channel, rates, and passive scanning
    757  * based on the configuration.
    758  */
    759 int hostapd_select_hw_mode(struct hostapd_iface *iface)
    760 {
    761 	int i;
    762 
    763 	if (iface->num_hw_features < 1)
    764 		return -1;
    765 
    766 	iface->current_mode = NULL;
    767 	for (i = 0; i < iface->num_hw_features; i++) {
    768 		struct hostapd_hw_modes *mode = &iface->hw_features[i];
    769 		if (mode->mode == iface->conf->hw_mode) {
    770 			iface->current_mode = mode;
    771 			break;
    772 		}
    773 	}
    774 
    775 	if (iface->current_mode == NULL) {
    776 		wpa_printf(MSG_ERROR, "Hardware does not support configured "
    777 			   "mode");
    778 		hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
    779 			       HOSTAPD_LEVEL_WARNING,
    780 			       "Hardware does not support configured mode "
    781 			       "(%d) (hw_mode in hostapd.conf)",
    782 			       (int) iface->conf->hw_mode);
    783 		return -2;
    784 	}
    785 
    786 	switch (hostapd_check_chans(iface)) {
    787 	case HOSTAPD_CHAN_VALID:
    788 		return 0;
    789 	case HOSTAPD_CHAN_ACS: /* ACS will run and later complete */
    790 		return 1;
    791 	case HOSTAPD_CHAN_INVALID:
    792 	default:
    793 		hostapd_notify_bad_chans(iface);
    794 		return -3;
    795 	}
    796 
    797 	return 0;
    798 }
    799 
    800 
    801 const char * hostapd_hw_mode_txt(int mode)
    802 {
    803 	switch (mode) {
    804 	case HOSTAPD_MODE_IEEE80211A:
    805 		return "IEEE 802.11a";
    806 	case HOSTAPD_MODE_IEEE80211B:
    807 		return "IEEE 802.11b";
    808 	case HOSTAPD_MODE_IEEE80211G:
    809 		return "IEEE 802.11g";
    810 	case HOSTAPD_MODE_IEEE80211AD:
    811 		return "IEEE 802.11ad";
    812 	default:
    813 		return "UNKNOWN";
    814 	}
    815 }
    816 
    817 
    818 int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
    819 {
    820 	int i;
    821 
    822 	if (!hapd->iface->current_mode)
    823 		return 0;
    824 
    825 	for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {
    826 		struct hostapd_channel_data *ch =
    827 			&hapd->iface->current_mode->channels[i];
    828 		if (ch->chan == chan)
    829 			return ch->freq;
    830 	}
    831 
    832 	return 0;
    833 }
    834 
    835 
    836 int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
    837 {
    838 	int i;
    839 
    840 	if (!hapd->iface->current_mode)
    841 		return 0;
    842 
    843 	for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {
    844 		struct hostapd_channel_data *ch =
    845 			&hapd->iface->current_mode->channels[i];
    846 		if (ch->freq == freq)
    847 			return ch->chan;
    848 	}
    849 
    850 	return 0;
    851 }
    852