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