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