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>
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.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
17 #include "utils/includes.h"
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"
25 #include "ap_config.h"
26 #include "ap_drv_ops.h"
28 #include "hw_features.h"
31 void hostapd_free_hw_features(struct hostapd_hw_modes
*hw_features
,
32 size_t num_hw_features
)
36 if (hw_features
== NULL
)
39 for (i
= 0; i
< num_hw_features
; i
++) {
40 os_free(hw_features
[i
].channels
);
41 os_free(hw_features
[i
].rates
);
48 #ifndef CONFIG_NO_STDOUT_DEBUG
49 static char * dfs_info(struct hostapd_channel_data
*chan
)
51 static char info
[256];
54 switch (chan
->flag
& HOSTAPD_CHAN_DFS_MASK
) {
55 case HOSTAPD_CHAN_DFS_UNKNOWN
:
58 case HOSTAPD_CHAN_DFS_USABLE
:
61 case HOSTAPD_CHAN_DFS_UNAVAILABLE
:
62 state
= "unavailable";
64 case HOSTAPD_CHAN_DFS_AVAILABLE
:
70 os_snprintf(info
, sizeof(info
), " (DFS state = %s)", state
);
71 info
[sizeof(info
) - 1] = '\0';
75 #endif /* CONFIG_NO_STDOUT_DEBUG */
78 int hostapd_get_hw_features(struct hostapd_iface
*iface
)
80 struct hostapd_data
*hapd
= iface
->bss
[0];
83 struct hostapd_hw_modes
*modes
;
85 if (hostapd_drv_none(hapd
))
87 modes
= hostapd_get_hw_feature_data(hapd
, &num_modes
, &flags
);
89 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
91 "Fetching hardware channel/rate support not "
96 iface
->hw_flags
= flags
;
98 hostapd_free_hw_features(iface
->hw_features
, iface
->num_hw_features
);
99 iface
->hw_features
= modes
;
100 iface
->num_hw_features
= num_modes
;
102 for (i
= 0; i
< num_modes
; i
++) {
103 struct hostapd_hw_modes
*feature
= &modes
[i
];
104 int dfs_enabled
= hapd
->iconf
->ieee80211h
&&
105 (iface
->drv_flags
& WPA_DRIVER_FLAGS_RADAR
);
107 /* set flag for channels we can use in current regulatory
109 for (j
= 0; j
< feature
->num_channels
; j
++) {
113 * Disable all channels that are marked not to allow
114 * IBSS operation or active scanning.
115 * Use radar channels only if the driver supports DFS.
117 if ((feature
->channels
[j
].flag
&
118 HOSTAPD_CHAN_RADAR
) && dfs_enabled
) {
120 } else if (feature
->channels
[j
].flag
&
121 (HOSTAPD_CHAN_NO_IBSS
|
122 HOSTAPD_CHAN_PASSIVE_SCAN
|
123 HOSTAPD_CHAN_RADAR
)) {
124 feature
->channels
[j
].flag
|=
125 HOSTAPD_CHAN_DISABLED
;
128 if (feature
->channels
[j
].flag
& HOSTAPD_CHAN_DISABLED
)
131 wpa_printf(MSG_MSGDUMP
, "Allowed channel: mode=%d "
132 "chan=%d freq=%d MHz max_tx_power=%d dBm%s",
134 feature
->channels
[j
].chan
,
135 feature
->channels
[j
].freq
,
136 feature
->channels
[j
].max_tx_power
,
137 dfs
? dfs_info(&feature
->channels
[j
]) : "");
145 int hostapd_prepare_rates(struct hostapd_iface
*iface
,
146 struct hostapd_hw_modes
*mode
)
148 int i
, num_basic_rates
= 0;
149 int basic_rates_a
[] = { 60, 120, 240, -1 };
150 int basic_rates_b
[] = { 10, 20, -1 };
151 int basic_rates_g
[] = { 10, 20, 55, 110, -1 };
154 if (iface
->conf
->basic_rates
)
155 basic_rates
= iface
->conf
->basic_rates
;
156 else switch (mode
->mode
) {
157 case HOSTAPD_MODE_IEEE80211A
:
158 basic_rates
= basic_rates_a
;
160 case HOSTAPD_MODE_IEEE80211B
:
161 basic_rates
= basic_rates_b
;
163 case HOSTAPD_MODE_IEEE80211G
:
164 basic_rates
= basic_rates_g
;
166 case HOSTAPD_MODE_IEEE80211AD
:
167 return 0; /* No basic rates for 11ad */
173 while (basic_rates
[i
] >= 0)
176 i
++; /* -1 termination */
177 os_free(iface
->basic_rates
);
178 iface
->basic_rates
= os_malloc(i
* sizeof(int));
179 if (iface
->basic_rates
)
180 os_memcpy(iface
->basic_rates
, basic_rates
, i
* sizeof(int));
182 os_free(iface
->current_rates
);
183 iface
->num_rates
= 0;
185 iface
->current_rates
=
186 os_calloc(mode
->num_rates
, sizeof(struct hostapd_rate_data
));
187 if (!iface
->current_rates
) {
188 wpa_printf(MSG_ERROR
, "Failed to allocate memory for rate "
193 for (i
= 0; i
< mode
->num_rates
; i
++) {
194 struct hostapd_rate_data
*rate
;
196 if (iface
->conf
->supported_rates
&&
197 !hostapd_rate_found(iface
->conf
->supported_rates
,
201 rate
= &iface
->current_rates
[iface
->num_rates
];
202 rate
->rate
= mode
->rates
[i
];
203 if (hostapd_rate_found(basic_rates
, rate
->rate
)) {
204 rate
->flags
|= HOSTAPD_RATE_BASIC
;
207 wpa_printf(MSG_DEBUG
, "RATE[%d] rate=%d flags=0x%x",
208 iface
->num_rates
, rate
->rate
, rate
->flags
);
212 if ((iface
->num_rates
== 0 || num_basic_rates
== 0) &&
213 (!iface
->conf
->ieee80211n
|| !iface
->conf
->require_ht
)) {
214 wpa_printf(MSG_ERROR
, "No rates remaining in supported/basic "
215 "rate sets (%d,%d).",
216 iface
->num_rates
, num_basic_rates
);
224 #ifdef CONFIG_IEEE80211N
225 static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface
*iface
)
227 int sec_chan
, ok
, j
, first
;
228 int allowed
[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
232 if (!iface
->conf
->secondary_channel
)
233 return 1; /* HT40 not used */
235 sec_chan
= iface
->conf
->channel
+ iface
->conf
->secondary_channel
* 4;
236 wpa_printf(MSG_DEBUG
, "HT40: control channel: %d "
237 "secondary channel: %d",
238 iface
->conf
->channel
, sec_chan
);
240 /* Verify that HT40 secondary channel is an allowed 20 MHz
243 for (j
= 0; j
< iface
->current_mode
->num_channels
; j
++) {
244 struct hostapd_channel_data
*chan
=
245 &iface
->current_mode
->channels
[j
];
246 if (!(chan
->flag
& HOSTAPD_CHAN_DISABLED
) &&
247 chan
->chan
== sec_chan
) {
253 wpa_printf(MSG_ERROR
, "HT40 secondary channel %d not allowed",
259 * Verify that HT40 primary,secondary channel pair is allowed per
260 * IEEE 802.11n Annex J. This is only needed for 5 GHz band since
261 * 2.4 GHz rules allow all cases where the secondary channel fits into
262 * the list of allowed channels (already checked above).
264 if (iface
->current_mode
->mode
!= HOSTAPD_MODE_IEEE80211A
)
267 if (iface
->conf
->secondary_channel
> 0)
268 first
= iface
->conf
->channel
;
273 for (k
= 0; k
< ARRAY_SIZE(allowed
); k
++) {
274 if (first
== allowed
[k
]) {
280 wpa_printf(MSG_ERROR
, "HT40 channel pair (%d, %d) not allowed",
281 iface
->conf
->channel
,
282 iface
->conf
->secondary_channel
);
290 static void ieee80211n_switch_pri_sec(struct hostapd_iface
*iface
)
292 if (iface
->conf
->secondary_channel
> 0) {
293 iface
->conf
->channel
+= 4;
294 iface
->conf
->secondary_channel
= -1;
296 iface
->conf
->channel
-= 4;
297 iface
->conf
->secondary_channel
= 1;
302 static void ieee80211n_get_pri_sec_chan(struct wpa_scan_res
*bss
,
303 int *pri_chan
, int *sec_chan
)
305 struct ieee80211_ht_operation
*oper
;
306 struct ieee802_11_elems elems
;
308 *pri_chan
= *sec_chan
= 0;
310 ieee802_11_parse_elems((u8
*) (bss
+ 1), bss
->ie_len
, &elems
, 0);
311 if (elems
.ht_operation
&&
312 elems
.ht_operation_len
>= sizeof(*oper
)) {
313 oper
= (struct ieee80211_ht_operation
*) elems
.ht_operation
;
314 *pri_chan
= oper
->control_chan
;
315 if (oper
->ht_param
& HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH
) {
316 int sec
= oper
->ht_param
&
317 HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK
;
318 if (sec
== HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE
)
319 *sec_chan
= *pri_chan
+ 4;
320 else if (sec
== HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW
)
321 *sec_chan
= *pri_chan
- 4;
327 static int ieee80211n_check_40mhz_5g(struct hostapd_iface
*iface
,
328 struct wpa_scan_results
*scan_res
)
330 int pri_chan
, sec_chan
, pri_freq
, sec_freq
, pri_bss
, sec_bss
;
331 int bss_pri_chan
, bss_sec_chan
;
335 pri_chan
= iface
->conf
->channel
;
336 sec_chan
= iface
->conf
->secondary_channel
* 4;
337 pri_freq
= hostapd_hw_get_freq(iface
->bss
[0], pri_chan
);
338 if (iface
->conf
->secondary_channel
> 0)
339 sec_freq
= pri_freq
+ 20;
341 sec_freq
= pri_freq
- 20;
344 * Switch PRI/SEC channels if Beacons were detected on selected SEC
345 * channel, but not on selected PRI channel.
347 pri_bss
= sec_bss
= 0;
348 for (i
= 0; i
< scan_res
->num
; i
++) {
349 struct wpa_scan_res
*bss
= scan_res
->res
[i
];
350 if (bss
->freq
== pri_freq
)
352 else if (bss
->freq
== sec_freq
)
355 if (sec_bss
&& !pri_bss
) {
356 wpa_printf(MSG_INFO
, "Switch own primary and secondary "
357 "channel to get secondary channel with no Beacons "
359 ieee80211n_switch_pri_sec(iface
);
363 * Match PRI/SEC channel with any existing HT40 BSS on the same
364 * channels that we are about to use (if already mixed order in
365 * existing BSSes, use own preference).
368 for (i
= 0; i
< scan_res
->num
; i
++) {
369 struct wpa_scan_res
*bss
= scan_res
->res
[i
];
370 ieee80211n_get_pri_sec_chan(bss
, &bss_pri_chan
, &bss_sec_chan
);
371 if (pri_chan
== bss_pri_chan
&&
372 sec_chan
== bss_sec_chan
) {
378 for (i
= 0; i
< scan_res
->num
; i
++) {
379 struct wpa_scan_res
*bss
= scan_res
->res
[i
];
380 ieee80211n_get_pri_sec_chan(bss
, &bss_pri_chan
,
382 if (pri_chan
== bss_sec_chan
&&
383 sec_chan
== bss_pri_chan
) {
384 wpa_printf(MSG_INFO
, "Switch own primary and "
385 "secondary channel due to BSS "
386 "overlap with " MACSTR
,
387 MAC2STR(bss
->bssid
));
388 ieee80211n_switch_pri_sec(iface
);
398 static int ieee80211n_check_40mhz_2g4(struct hostapd_iface
*iface
,
399 struct wpa_scan_results
*scan_res
)
401 int pri_freq
, sec_freq
;
402 int affected_start
, affected_end
;
405 pri_freq
= hostapd_hw_get_freq(iface
->bss
[0], iface
->conf
->channel
);
406 if (iface
->conf
->secondary_channel
> 0)
407 sec_freq
= pri_freq
+ 20;
409 sec_freq
= pri_freq
- 20;
410 affected_start
= (pri_freq
+ sec_freq
) / 2 - 25;
411 affected_end
= (pri_freq
+ sec_freq
) / 2 + 25;
412 wpa_printf(MSG_DEBUG
, "40 MHz affected channel range: [%d,%d] MHz",
413 affected_start
, affected_end
);
414 for (i
= 0; i
< scan_res
->num
; i
++) {
415 struct wpa_scan_res
*bss
= scan_res
->res
[i
];
418 int sec_chan
, pri_chan
;
420 ieee80211n_get_pri_sec_chan(bss
, &pri_chan
, &sec_chan
);
423 if (sec_chan
< pri_chan
)
429 if ((pri
< affected_start
|| pri
> affected_end
) &&
430 (sec
< affected_start
|| sec
> affected_end
))
431 continue; /* not within affected channel range */
433 wpa_printf(MSG_DEBUG
, "Neighboring BSS: " MACSTR
434 " freq=%d pri=%d sec=%d",
435 MAC2STR(bss
->bssid
), bss
->freq
, pri_chan
, sec_chan
);
438 if (pri_freq
!= pri
|| sec_freq
!= sec
) {
439 wpa_printf(MSG_DEBUG
, "40 MHz pri/sec "
440 "mismatch with BSS " MACSTR
441 " <%d,%d> (chan=%d%c) vs. <%d,%d>",
444 sec
> pri
? '+' : '-',
450 /* TODO: 40 MHz intolerant */
457 static void ieee80211n_check_scan(struct hostapd_iface
*iface
)
459 struct wpa_scan_results
*scan_res
;
463 /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
464 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */
466 iface
->scan_cb
= NULL
;
468 scan_res
= hostapd_driver_get_scan_results(iface
->bss
[0]);
469 if (scan_res
== NULL
) {
470 hostapd_setup_interface_complete(iface
, 1);
474 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
)
475 oper40
= ieee80211n_check_40mhz_5g(iface
, scan_res
);
477 oper40
= ieee80211n_check_40mhz_2g4(iface
, scan_res
);
478 wpa_scan_results_free(scan_res
);
481 wpa_printf(MSG_INFO
, "20/40 MHz operation not permitted on "
482 "channel pri=%d sec=%d based on overlapping BSSes",
483 iface
->conf
->channel
,
484 iface
->conf
->channel
+
485 iface
->conf
->secondary_channel
* 4);
486 iface
->conf
->secondary_channel
= 0;
489 res
= ieee80211n_allowed_ht40_channel_pair(iface
);
490 hostapd_setup_interface_complete(iface
, !res
);
494 static void ieee80211n_scan_channels_2g4(struct hostapd_iface
*iface
,
495 struct wpa_driver_scan_params
*params
)
497 /* Scan only the affected frequency range */
498 int pri_freq
, sec_freq
;
499 int affected_start
, affected_end
;
501 struct hostapd_hw_modes
*mode
;
503 if (iface
->current_mode
== NULL
)
506 pri_freq
= hostapd_hw_get_freq(iface
->bss
[0], iface
->conf
->channel
);
507 if (iface
->conf
->secondary_channel
> 0)
508 sec_freq
= pri_freq
+ 20;
510 sec_freq
= pri_freq
- 20;
511 affected_start
= (pri_freq
+ sec_freq
) / 2 - 25;
512 affected_end
= (pri_freq
+ sec_freq
) / 2 + 25;
513 wpa_printf(MSG_DEBUG
, "40 MHz affected channel range: [%d,%d] MHz",
514 affected_start
, affected_end
);
516 mode
= iface
->current_mode
;
517 params
->freqs
= os_calloc(mode
->num_channels
+ 1, sizeof(int));
518 if (params
->freqs
== NULL
)
522 for (i
= 0; i
< mode
->num_channels
; i
++) {
523 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
524 if (chan
->flag
& HOSTAPD_CHAN_DISABLED
)
526 if (chan
->freq
< affected_start
||
527 chan
->freq
> affected_end
)
529 params
->freqs
[pos
++] = chan
->freq
;
534 static void ieee80211n_scan_channels_5g(struct hostapd_iface
*iface
,
535 struct wpa_driver_scan_params
*params
)
537 /* Scan only the affected frequency range */
539 int affected_start
, affected_end
;
541 struct hostapd_hw_modes
*mode
;
543 if (iface
->current_mode
== NULL
)
546 pri_freq
= hostapd_hw_get_freq(iface
->bss
[0], iface
->conf
->channel
);
547 if (iface
->conf
->secondary_channel
> 0) {
548 affected_start
= pri_freq
- 10;
549 affected_end
= pri_freq
+ 30;
551 affected_start
= pri_freq
- 30;
552 affected_end
= pri_freq
+ 10;
554 wpa_printf(MSG_DEBUG
, "40 MHz affected channel range: [%d,%d] MHz",
555 affected_start
, affected_end
);
557 mode
= iface
->current_mode
;
558 params
->freqs
= os_calloc(mode
->num_channels
+ 1, sizeof(int));
559 if (params
->freqs
== NULL
)
563 for (i
= 0; i
< mode
->num_channels
; i
++) {
564 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
565 if (chan
->flag
& HOSTAPD_CHAN_DISABLED
)
567 if (chan
->freq
< affected_start
||
568 chan
->freq
> affected_end
)
570 params
->freqs
[pos
++] = chan
->freq
;
575 static int ieee80211n_check_40mhz(struct hostapd_iface
*iface
)
577 struct wpa_driver_scan_params params
;
579 if (!iface
->conf
->secondary_channel
)
580 return 0; /* HT40 not used */
582 hostapd_set_state(iface
, HAPD_IFACE_HT_SCAN
);
583 wpa_printf(MSG_DEBUG
, "Scan for neighboring BSSes prior to enabling "
585 os_memset(¶ms
, 0, sizeof(params
));
586 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
587 ieee80211n_scan_channels_2g4(iface
, ¶ms
);
589 ieee80211n_scan_channels_5g(iface
, ¶ms
);
590 if (hostapd_driver_scan(iface
->bss
[0], ¶ms
) < 0) {
591 wpa_printf(MSG_ERROR
, "Failed to request a scan of "
592 "neighboring BSSes");
593 os_free(params
.freqs
);
596 os_free(params
.freqs
);
598 iface
->scan_cb
= ieee80211n_check_scan
;
603 static int ieee80211n_supported_ht_capab(struct hostapd_iface
*iface
)
605 u16 hw
= iface
->current_mode
->ht_capab
;
606 u16 conf
= iface
->conf
->ht_capab
;
608 if ((conf
& HT_CAP_INFO_LDPC_CODING_CAP
) &&
609 !(hw
& HT_CAP_INFO_LDPC_CODING_CAP
)) {
610 wpa_printf(MSG_ERROR
, "Driver does not support configured "
611 "HT capability [LDPC]");
615 if ((conf
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
) &&
616 !(hw
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
)) {
617 wpa_printf(MSG_ERROR
, "Driver does not support configured "
618 "HT capability [HT40*]");
622 if ((conf
& HT_CAP_INFO_SMPS_MASK
) != (hw
& HT_CAP_INFO_SMPS_MASK
) &&
623 (conf
& HT_CAP_INFO_SMPS_MASK
) != HT_CAP_INFO_SMPS_DISABLED
) {
624 wpa_printf(MSG_ERROR
, "Driver does not support configured "
625 "HT capability [SMPS-*]");
629 if ((conf
& HT_CAP_INFO_GREEN_FIELD
) &&
630 !(hw
& HT_CAP_INFO_GREEN_FIELD
)) {
631 wpa_printf(MSG_ERROR
, "Driver does not support configured "
632 "HT capability [GF]");
636 if ((conf
& HT_CAP_INFO_SHORT_GI20MHZ
) &&
637 !(hw
& HT_CAP_INFO_SHORT_GI20MHZ
)) {
638 wpa_printf(MSG_ERROR
, "Driver does not support configured "
639 "HT capability [SHORT-GI-20]");
643 if ((conf
& HT_CAP_INFO_SHORT_GI40MHZ
) &&
644 !(hw
& HT_CAP_INFO_SHORT_GI40MHZ
)) {
645 wpa_printf(MSG_ERROR
, "Driver does not support configured "
646 "HT capability [SHORT-GI-40]");
650 if ((conf
& HT_CAP_INFO_TX_STBC
) && !(hw
& HT_CAP_INFO_TX_STBC
)) {
651 wpa_printf(MSG_ERROR
, "Driver does not support configured "
652 "HT capability [TX-STBC]");
656 if ((conf
& HT_CAP_INFO_RX_STBC_MASK
) >
657 (hw
& HT_CAP_INFO_RX_STBC_MASK
)) {
658 wpa_printf(MSG_ERROR
, "Driver does not support configured "
659 "HT capability [RX-STBC*]");
663 if ((conf
& HT_CAP_INFO_DELAYED_BA
) &&
664 !(hw
& HT_CAP_INFO_DELAYED_BA
)) {
665 wpa_printf(MSG_ERROR
, "Driver does not support configured "
666 "HT capability [DELAYED-BA]");
670 if ((conf
& HT_CAP_INFO_MAX_AMSDU_SIZE
) &&
671 !(hw
& HT_CAP_INFO_MAX_AMSDU_SIZE
)) {
672 wpa_printf(MSG_ERROR
, "Driver does not support configured "
673 "HT capability [MAX-AMSDU-7935]");
677 if ((conf
& HT_CAP_INFO_DSSS_CCK40MHZ
) &&
678 !(hw
& HT_CAP_INFO_DSSS_CCK40MHZ
)) {
679 wpa_printf(MSG_ERROR
, "Driver does not support configured "
680 "HT capability [DSSS_CCK-40]");
684 if ((conf
& HT_CAP_INFO_PSMP_SUPP
) && !(hw
& HT_CAP_INFO_PSMP_SUPP
)) {
685 wpa_printf(MSG_ERROR
, "Driver does not support configured "
686 "HT capability [PSMP]");
690 if ((conf
& HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
) &&
691 !(hw
& HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
)) {
692 wpa_printf(MSG_ERROR
, "Driver does not support configured "
693 "HT capability [LSIG-TXOP-PROT]");
701 #ifdef CONFIG_IEEE80211AC
703 static int ieee80211ac_cap_check(u32 hw
, u32 conf
, u32 cap
, const char *name
)
705 u32 req_cap
= conf
& cap
;
708 * Make sure we support all requested capabilities.
709 * NOTE: We assume that 'cap' represents a capability mask,
710 * not a discrete value.
712 if ((hw
& req_cap
) != req_cap
) {
713 wpa_printf(MSG_ERROR
, "Driver does not support configured VHT capability [%s]",
721 static int ieee80211ac_cap_check_max(u32 hw
, u32 conf
, u32 cap
,
724 u32 hw_max
= hw
& cap
;
725 u32 conf_val
= conf
& cap
;
727 if (conf_val
> hw_max
) {
728 int offset
= find_first_bit(cap
);
729 wpa_printf(MSG_ERROR
, "Configured VHT capability [%s] exceeds max value supported by the driver (%d > %d)",
730 name
, conf_val
>> offset
, hw_max
>> offset
);
737 static int ieee80211ac_supported_vht_capab(struct hostapd_iface
*iface
)
739 u32 hw
= iface
->current_mode
->vht_capab
;
740 u32 conf
= iface
->conf
->vht_capab
;
742 wpa_printf(MSG_DEBUG
, "hw vht capab: 0x%x, conf vht capab: 0x%x",
745 #define VHT_CAP_CHECK(cap) \
747 if (!ieee80211ac_cap_check(hw, conf, cap, #cap)) \
751 #define VHT_CAP_CHECK_MAX(cap) \
753 if (!ieee80211ac_cap_check_max(hw, conf, cap, #cap)) \
757 VHT_CAP_CHECK_MAX(VHT_CAP_MAX_MPDU_LENGTH_MASK
);
758 VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160MHZ
);
759 VHT_CAP_CHECK(VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ
);
760 VHT_CAP_CHECK(VHT_CAP_RXLDPC
);
761 VHT_CAP_CHECK(VHT_CAP_SHORT_GI_80
);
762 VHT_CAP_CHECK(VHT_CAP_SHORT_GI_160
);
763 VHT_CAP_CHECK(VHT_CAP_TXSTBC
);
764 VHT_CAP_CHECK_MAX(VHT_CAP_RXSTBC_MASK
);
765 VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMER_CAPABLE
);
766 VHT_CAP_CHECK(VHT_CAP_SU_BEAMFORMEE_CAPABLE
);
767 VHT_CAP_CHECK_MAX(VHT_CAP_BEAMFORMEE_STS_MAX
);
768 VHT_CAP_CHECK_MAX(VHT_CAP_SOUNDING_DIMENSION_MAX
);
769 VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMER_CAPABLE
);
770 VHT_CAP_CHECK(VHT_CAP_MU_BEAMFORMEE_CAPABLE
);
771 VHT_CAP_CHECK(VHT_CAP_VHT_TXOP_PS
);
772 VHT_CAP_CHECK(VHT_CAP_HTC_VHT
);
773 VHT_CAP_CHECK_MAX(VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT
);
774 VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB
);
775 VHT_CAP_CHECK(VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB
);
776 VHT_CAP_CHECK(VHT_CAP_RX_ANTENNA_PATTERN
);
777 VHT_CAP_CHECK(VHT_CAP_TX_ANTENNA_PATTERN
);
780 #undef VHT_CAP_CHECK_MAX
784 #endif /* CONFIG_IEEE80211AC */
786 #endif /* CONFIG_IEEE80211N */
789 int hostapd_check_ht_capab(struct hostapd_iface
*iface
)
791 #ifdef CONFIG_IEEE80211N
793 if (!iface
->conf
->ieee80211n
)
795 if (!ieee80211n_supported_ht_capab(iface
))
797 #ifdef CONFIG_IEEE80211AC
798 if (!ieee80211ac_supported_vht_capab(iface
))
800 #endif /* CONFIG_IEEE80211AC */
801 ret
= ieee80211n_check_40mhz(iface
);
804 if (!ieee80211n_allowed_ht40_channel_pair(iface
))
806 #endif /* CONFIG_IEEE80211N */
812 static int hostapd_is_usable_chan(struct hostapd_iface
*iface
,
813 int channel
, int primary
)
816 struct hostapd_channel_data
*chan
;
818 for (i
= 0; i
< iface
->current_mode
->num_channels
; i
++) {
819 chan
= &iface
->current_mode
->channels
[i
];
820 if (chan
->chan
!= channel
)
823 if (!(chan
->flag
& HOSTAPD_CHAN_DISABLED
))
826 wpa_printf(MSG_DEBUG
,
827 "%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s%s",
828 primary
? "" : "Configured HT40 secondary ",
829 i
, chan
->chan
, chan
->flag
,
830 chan
->flag
& HOSTAPD_CHAN_NO_IBSS
? " NO-IBSS" : "",
831 chan
->flag
& HOSTAPD_CHAN_PASSIVE_SCAN
?
832 " PASSIVE-SCAN" : "",
833 chan
->flag
& HOSTAPD_CHAN_RADAR
? " RADAR" : "");
840 static int hostapd_is_usable_chans(struct hostapd_iface
*iface
)
842 if (!hostapd_is_usable_chan(iface
, iface
->conf
->channel
, 1))
845 if (!iface
->conf
->secondary_channel
)
848 return hostapd_is_usable_chan(iface
, iface
->conf
->channel
+
849 iface
->conf
->secondary_channel
* 4, 0);
853 static enum hostapd_chan_status
854 hostapd_check_chans(struct hostapd_iface
*iface
)
856 if (iface
->conf
->channel
) {
857 if (hostapd_is_usable_chans(iface
))
858 return HOSTAPD_CHAN_VALID
;
860 return HOSTAPD_CHAN_INVALID
;
864 * The user set channel=0 or channel=acs_survey
865 * which is used to trigger ACS.
868 switch (acs_init(iface
)) {
869 case HOSTAPD_CHAN_ACS
:
870 return HOSTAPD_CHAN_ACS
;
871 case HOSTAPD_CHAN_VALID
:
872 case HOSTAPD_CHAN_INVALID
:
874 return HOSTAPD_CHAN_INVALID
;
879 static void hostapd_notify_bad_chans(struct hostapd_iface
*iface
)
881 hostapd_logger(iface
->bss
[0], NULL
,
882 HOSTAPD_MODULE_IEEE80211
,
883 HOSTAPD_LEVEL_WARNING
,
884 "Configured channel (%d) not found from the "
885 "channel list of current mode (%d) %s",
886 iface
->conf
->channel
,
887 iface
->current_mode
->mode
,
888 hostapd_hw_mode_txt(iface
->current_mode
->mode
));
889 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
890 HOSTAPD_LEVEL_WARNING
,
891 "Hardware does not support configured channel");
895 int hostapd_acs_completed(struct hostapd_iface
*iface
, int err
)
902 switch (hostapd_check_chans(iface
)) {
903 case HOSTAPD_CHAN_VALID
:
904 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
,
905 ACS_EVENT_COMPLETED
"freq=%d channel=%d",
906 hostapd_hw_get_freq(iface
->bss
[0],
907 iface
->conf
->channel
),
908 iface
->conf
->channel
);
910 case HOSTAPD_CHAN_ACS
:
911 wpa_printf(MSG_ERROR
, "ACS error - reported complete, but no result available");
912 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
, ACS_EVENT_FAILED
);
913 hostapd_notify_bad_chans(iface
);
915 case HOSTAPD_CHAN_INVALID
:
917 wpa_printf(MSG_ERROR
, "ACS picked unusable channels");
918 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
, ACS_EVENT_FAILED
);
919 hostapd_notify_bad_chans(iface
);
923 ret
= hostapd_check_ht_capab(iface
);
927 wpa_printf(MSG_DEBUG
, "Interface initialization will be completed in a callback");
933 return hostapd_setup_interface_complete(iface
, ret
);
938 * hostapd_select_hw_mode - Select the hardware mode
939 * @iface: Pointer to interface data.
940 * Returns: 0 on success, < 0 on failure
942 * Sets up the hardware mode, channel, rates, and passive scanning
943 * based on the configuration.
945 int hostapd_select_hw_mode(struct hostapd_iface
*iface
)
949 if (iface
->num_hw_features
< 1)
952 iface
->current_mode
= NULL
;
953 for (i
= 0; i
< iface
->num_hw_features
; i
++) {
954 struct hostapd_hw_modes
*mode
= &iface
->hw_features
[i
];
955 if (mode
->mode
== iface
->conf
->hw_mode
) {
956 iface
->current_mode
= mode
;
961 if (iface
->current_mode
== NULL
) {
962 wpa_printf(MSG_ERROR
, "Hardware does not support configured "
964 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
965 HOSTAPD_LEVEL_WARNING
,
966 "Hardware does not support configured mode "
967 "(%d) (hw_mode in hostapd.conf)",
968 (int) iface
->conf
->hw_mode
);
972 switch (hostapd_check_chans(iface
)) {
973 case HOSTAPD_CHAN_VALID
:
975 case HOSTAPD_CHAN_ACS
: /* ACS will run and later complete */
977 case HOSTAPD_CHAN_INVALID
:
979 hostapd_notify_bad_chans(iface
);
987 const char * hostapd_hw_mode_txt(int mode
)
990 case HOSTAPD_MODE_IEEE80211A
:
991 return "IEEE 802.11a";
992 case HOSTAPD_MODE_IEEE80211B
:
993 return "IEEE 802.11b";
994 case HOSTAPD_MODE_IEEE80211G
:
995 return "IEEE 802.11g";
996 case HOSTAPD_MODE_IEEE80211AD
:
997 return "IEEE 802.11ad";
1004 int hostapd_hw_get_freq(struct hostapd_data
*hapd
, int chan
)
1008 if (!hapd
->iface
->current_mode
)
1011 for (i
= 0; i
< hapd
->iface
->current_mode
->num_channels
; i
++) {
1012 struct hostapd_channel_data
*ch
=
1013 &hapd
->iface
->current_mode
->channels
[i
];
1014 if (ch
->chan
== chan
)
1022 int hostapd_hw_get_channel(struct hostapd_data
*hapd
, int freq
)
1026 if (!hapd
->iface
->current_mode
)
1029 for (i
= 0; i
< hapd
->iface
->current_mode
->num_channels
; i
++) {
1030 struct hostapd_channel_data
*ch
=
1031 &hapd
->iface
->current_mode
->channels
[i
];
1032 if (ch
->freq
== freq
)