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 software may be distributed under the terms of the BSD license.
8 * See README for more details.
11 #include "utils/includes.h"
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"
20 #include "ap_config.h"
21 #include "ap_drv_ops.h"
23 #include "ieee802_11.h"
25 #include "hw_features.h"
28 void hostapd_free_hw_features(struct hostapd_hw_modes
*hw_features
,
29 size_t num_hw_features
)
33 if (hw_features
== NULL
)
36 for (i
= 0; i
< num_hw_features
; i
++) {
37 os_free(hw_features
[i
].channels
);
38 os_free(hw_features
[i
].rates
);
45 #ifndef CONFIG_NO_STDOUT_DEBUG
46 static char * dfs_info(struct hostapd_channel_data
*chan
)
48 static char info
[256];
51 switch (chan
->flag
& HOSTAPD_CHAN_DFS_MASK
) {
52 case HOSTAPD_CHAN_DFS_UNKNOWN
:
55 case HOSTAPD_CHAN_DFS_USABLE
:
58 case HOSTAPD_CHAN_DFS_UNAVAILABLE
:
59 state
= "unavailable";
61 case HOSTAPD_CHAN_DFS_AVAILABLE
:
67 os_snprintf(info
, sizeof(info
), " (DFS state = %s)", state
);
68 info
[sizeof(info
) - 1] = '\0';
72 #endif /* CONFIG_NO_STDOUT_DEBUG */
75 int hostapd_get_hw_features(struct hostapd_iface
*iface
)
77 struct hostapd_data
*hapd
= iface
->bss
[0];
80 struct hostapd_hw_modes
*modes
;
83 if (hostapd_drv_none(hapd
))
85 modes
= hostapd_get_hw_feature_data(hapd
, &num_modes
, &flags
,
88 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
90 "Fetching hardware channel/rate support not "
95 iface
->hw_flags
= flags
;
96 iface
->dfs_domain
= dfs_domain
;
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 * to initiate radiation (a.k.a. passive scan and no
116 * Use radar channels only if the driver supports DFS.
118 if ((feature
->channels
[j
].flag
&
119 HOSTAPD_CHAN_RADAR
) && dfs_enabled
) {
121 } else if (((feature
->channels
[j
].flag
&
122 HOSTAPD_CHAN_RADAR
) &&
124 WPA_DRIVER_FLAGS_DFS_OFFLOAD
)) ||
125 (feature
->channels
[j
].flag
&
126 HOSTAPD_CHAN_NO_IR
)) {
127 feature
->channels
[j
].flag
|=
128 HOSTAPD_CHAN_DISABLED
;
131 if (feature
->channels
[j
].flag
& HOSTAPD_CHAN_DISABLED
)
134 wpa_printf(MSG_MSGDUMP
, "Allowed channel: mode=%d "
135 "chan=%d freq=%d MHz max_tx_power=%d dBm%s",
137 feature
->channels
[j
].chan
,
138 feature
->channels
[j
].freq
,
139 feature
->channels
[j
].max_tx_power
,
140 dfs
? dfs_info(&feature
->channels
[j
]) : "");
148 int hostapd_prepare_rates(struct hostapd_iface
*iface
,
149 struct hostapd_hw_modes
*mode
)
151 int i
, num_basic_rates
= 0;
152 int basic_rates_a
[] = { 60, 120, 240, -1 };
153 int basic_rates_b
[] = { 10, 20, -1 };
154 int basic_rates_g
[] = { 10, 20, 55, 110, -1 };
157 if (iface
->conf
->basic_rates
)
158 basic_rates
= iface
->conf
->basic_rates
;
159 else switch (mode
->mode
) {
160 case HOSTAPD_MODE_IEEE80211A
:
161 basic_rates
= basic_rates_a
;
163 case HOSTAPD_MODE_IEEE80211B
:
164 basic_rates
= basic_rates_b
;
166 case HOSTAPD_MODE_IEEE80211G
:
167 basic_rates
= basic_rates_g
;
169 case HOSTAPD_MODE_IEEE80211AD
:
170 return 0; /* No basic rates for 11ad */
176 while (basic_rates
[i
] >= 0)
179 i
++; /* -1 termination */
180 os_free(iface
->basic_rates
);
181 iface
->basic_rates
= os_malloc(i
* sizeof(int));
182 if (iface
->basic_rates
)
183 os_memcpy(iface
->basic_rates
, basic_rates
, i
* sizeof(int));
185 os_free(iface
->current_rates
);
186 iface
->num_rates
= 0;
188 iface
->current_rates
=
189 os_calloc(mode
->num_rates
, sizeof(struct hostapd_rate_data
));
190 if (!iface
->current_rates
) {
191 wpa_printf(MSG_ERROR
, "Failed to allocate memory for rate "
196 for (i
= 0; i
< mode
->num_rates
; i
++) {
197 struct hostapd_rate_data
*rate
;
199 if (iface
->conf
->supported_rates
&&
200 !hostapd_rate_found(iface
->conf
->supported_rates
,
204 rate
= &iface
->current_rates
[iface
->num_rates
];
205 rate
->rate
= mode
->rates
[i
];
206 if (hostapd_rate_found(basic_rates
, rate
->rate
)) {
207 rate
->flags
|= HOSTAPD_RATE_BASIC
;
210 wpa_printf(MSG_DEBUG
, "RATE[%d] rate=%d flags=0x%x",
211 iface
->num_rates
, rate
->rate
, rate
->flags
);
215 if ((iface
->num_rates
== 0 || num_basic_rates
== 0) &&
216 (!iface
->conf
->ieee80211n
|| !iface
->conf
->require_ht
)) {
217 wpa_printf(MSG_ERROR
, "No rates remaining in supported/basic "
218 "rate sets (%d,%d).",
219 iface
->num_rates
, num_basic_rates
);
227 #ifdef CONFIG_IEEE80211N
228 static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface
*iface
)
230 int pri_freq
, sec_freq
;
231 struct hostapd_channel_data
*p_chan
, *s_chan
;
233 pri_freq
= iface
->freq
;
234 sec_freq
= pri_freq
+ iface
->conf
->secondary_channel
* 20;
236 if (!iface
->current_mode
)
239 p_chan
= hw_get_channel_freq(iface
->current_mode
->mode
, pri_freq
, NULL
,
241 iface
->num_hw_features
);
243 s_chan
= hw_get_channel_freq(iface
->current_mode
->mode
, sec_freq
, NULL
,
245 iface
->num_hw_features
);
247 return allowed_ht40_channel_pair(iface
->current_mode
->mode
,
252 static void ieee80211n_switch_pri_sec(struct hostapd_iface
*iface
)
254 if (iface
->conf
->secondary_channel
> 0) {
255 iface
->conf
->channel
+= 4;
257 iface
->conf
->secondary_channel
= -1;
259 iface
->conf
->channel
-= 4;
261 iface
->conf
->secondary_channel
= 1;
266 static int ieee80211n_check_40mhz_5g(struct hostapd_iface
*iface
,
267 struct wpa_scan_results
*scan_res
)
269 unsigned int pri_freq
, sec_freq
;
271 struct hostapd_channel_data
*pri_chan
, *sec_chan
;
273 pri_freq
= iface
->freq
;
274 sec_freq
= pri_freq
+ iface
->conf
->secondary_channel
* 20;
276 if (!iface
->current_mode
)
278 pri_chan
= hw_get_channel_freq(iface
->current_mode
->mode
, pri_freq
,
279 NULL
, iface
->hw_features
,
280 iface
->num_hw_features
);
281 sec_chan
= hw_get_channel_freq(iface
->current_mode
->mode
, sec_freq
,
282 NULL
, iface
->hw_features
,
283 iface
->num_hw_features
);
285 res
= check_40mhz_5g(scan_res
, pri_chan
, sec_chan
);
288 if (iface
->conf
->no_pri_sec_switch
) {
289 wpa_printf(MSG_DEBUG
,
290 "Cannot switch PRI/SEC channels due to local constraint");
292 ieee80211n_switch_pri_sec(iface
);
300 static int ieee80211n_check_40mhz_2g4(struct hostapd_iface
*iface
,
301 struct wpa_scan_results
*scan_res
)
303 int pri_chan
, sec_chan
;
305 pri_chan
= iface
->conf
->channel
;
306 sec_chan
= pri_chan
+ iface
->conf
->secondary_channel
* 4;
308 return check_40mhz_2g4(iface
->current_mode
, scan_res
, pri_chan
,
313 static void ieee80211n_check_scan(struct hostapd_iface
*iface
)
315 struct wpa_scan_results
*scan_res
;
319 /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
320 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */
322 iface
->scan_cb
= NULL
;
324 scan_res
= hostapd_driver_get_scan_results(iface
->bss
[0]);
325 if (scan_res
== NULL
) {
326 hostapd_setup_interface_complete(iface
, 1);
330 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
)
331 oper40
= ieee80211n_check_40mhz_5g(iface
, scan_res
);
333 oper40
= ieee80211n_check_40mhz_2g4(iface
, scan_res
);
334 wpa_scan_results_free(scan_res
);
336 iface
->secondary_ch
= iface
->conf
->secondary_channel
;
338 wpa_printf(MSG_INFO
, "20/40 MHz operation not permitted on "
339 "channel pri=%d sec=%d based on overlapping BSSes",
340 iface
->conf
->channel
,
341 iface
->conf
->channel
+
342 iface
->conf
->secondary_channel
* 4);
343 iface
->conf
->secondary_channel
= 0;
344 if (iface
->drv_flags
& WPA_DRIVER_FLAGS_HT_2040_COEX
) {
346 * TODO: Could consider scheduling another scan to check
347 * if channel width can be changed if no coex reports
348 * are received from associating stations.
353 res
= ieee80211n_allowed_ht40_channel_pair(iface
);
355 iface
->conf
->secondary_channel
= 0;
356 hostapd_set_oper_centr_freq_seg0_idx(iface
->conf
, 0);
357 hostapd_set_oper_centr_freq_seg1_idx(iface
->conf
, 0);
358 hostapd_set_oper_chwidth(iface
->conf
, CHANWIDTH_USE_HT
);
360 wpa_printf(MSG_INFO
, "Fallback to 20 MHz");
363 hostapd_setup_interface_complete(iface
, !res
);
367 static void ieee80211n_scan_channels_2g4(struct hostapd_iface
*iface
,
368 struct wpa_driver_scan_params
*params
)
370 /* Scan only the affected frequency range */
371 int pri_freq
, sec_freq
;
372 int affected_start
, affected_end
;
374 struct hostapd_hw_modes
*mode
;
376 if (iface
->current_mode
== NULL
)
379 pri_freq
= iface
->freq
;
380 if (iface
->conf
->secondary_channel
> 0)
381 sec_freq
= pri_freq
+ 20;
383 sec_freq
= pri_freq
- 20;
385 * Note: Need to find the PRI channel also in cases where the affected
386 * channel is the SEC channel of a 40 MHz BSS, so need to include the
387 * scanning coverage here to be 40 MHz from the center frequency.
389 affected_start
= (pri_freq
+ sec_freq
) / 2 - 40;
390 affected_end
= (pri_freq
+ sec_freq
) / 2 + 40;
391 wpa_printf(MSG_DEBUG
, "40 MHz affected channel range: [%d,%d] MHz",
392 affected_start
, affected_end
);
394 mode
= iface
->current_mode
;
395 params
->freqs
= os_calloc(mode
->num_channels
+ 1, sizeof(int));
396 if (params
->freqs
== NULL
)
400 for (i
= 0; i
< mode
->num_channels
; i
++) {
401 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
402 if (chan
->flag
& HOSTAPD_CHAN_DISABLED
)
404 if (chan
->freq
< affected_start
||
405 chan
->freq
> affected_end
)
407 params
->freqs
[pos
++] = chan
->freq
;
412 static void ieee80211n_scan_channels_5g(struct hostapd_iface
*iface
,
413 struct wpa_driver_scan_params
*params
)
415 /* Scan only the affected frequency range */
417 int affected_start
, affected_end
;
419 struct hostapd_hw_modes
*mode
;
421 if (iface
->current_mode
== NULL
)
424 pri_freq
= iface
->freq
;
425 if (iface
->conf
->secondary_channel
> 0) {
426 affected_start
= pri_freq
- 10;
427 affected_end
= pri_freq
+ 30;
429 affected_start
= pri_freq
- 30;
430 affected_end
= pri_freq
+ 10;
432 wpa_printf(MSG_DEBUG
, "40 MHz affected channel range: [%d,%d] MHz",
433 affected_start
, affected_end
);
435 mode
= iface
->current_mode
;
436 params
->freqs
= os_calloc(mode
->num_channels
+ 1, sizeof(int));
437 if (params
->freqs
== NULL
)
441 for (i
= 0; i
< mode
->num_channels
; i
++) {
442 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
443 if (chan
->flag
& HOSTAPD_CHAN_DISABLED
)
445 if (chan
->freq
< affected_start
||
446 chan
->freq
> affected_end
)
448 params
->freqs
[pos
++] = chan
->freq
;
453 static void ap_ht40_scan_retry(void *eloop_data
, void *user_data
)
455 #define HT2040_COEX_SCAN_RETRY 15
456 struct hostapd_iface
*iface
= eloop_data
;
457 struct wpa_driver_scan_params params
;
460 os_memset(¶ms
, 0, sizeof(params
));
461 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
462 ieee80211n_scan_channels_2g4(iface
, ¶ms
);
464 ieee80211n_scan_channels_5g(iface
, ¶ms
);
466 ret
= hostapd_driver_scan(iface
->bss
[0], ¶ms
);
467 iface
->num_ht40_scan_tries
++;
468 os_free(params
.freqs
);
471 iface
->num_ht40_scan_tries
< HT2040_COEX_SCAN_RETRY
) {
472 wpa_printf(MSG_ERROR
,
473 "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)",
474 ret
, strerror(-ret
), iface
->num_ht40_scan_tries
);
475 eloop_register_timeout(1, 0, ap_ht40_scan_retry
, iface
, NULL
);
480 iface
->scan_cb
= ieee80211n_check_scan
;
484 wpa_printf(MSG_DEBUG
,
485 "Failed to request a scan in device, bringing up in HT20 mode");
486 iface
->conf
->secondary_channel
= 0;
487 iface
->conf
->ht_capab
&= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
;
488 hostapd_setup_interface_complete(iface
, 0);
492 void hostapd_stop_setup_timers(struct hostapd_iface
*iface
)
494 eloop_cancel_timeout(ap_ht40_scan_retry
, iface
, NULL
);
498 static int ieee80211n_check_40mhz(struct hostapd_iface
*iface
)
500 struct wpa_driver_scan_params params
;
503 /* Check that HT40 is used and PRI / SEC switch is allowed */
504 if (!iface
->conf
->secondary_channel
|| iface
->conf
->no_pri_sec_switch
)
507 hostapd_set_state(iface
, HAPD_IFACE_HT_SCAN
);
508 wpa_printf(MSG_DEBUG
, "Scan for neighboring BSSes prior to enabling "
510 os_memset(¶ms
, 0, sizeof(params
));
511 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
512 ieee80211n_scan_channels_2g4(iface
, ¶ms
);
514 ieee80211n_scan_channels_5g(iface
, ¶ms
);
516 ret
= hostapd_driver_scan(iface
->bss
[0], ¶ms
);
517 os_free(params
.freqs
);
520 wpa_printf(MSG_ERROR
,
521 "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again",
522 ret
, strerror(-ret
));
523 iface
->num_ht40_scan_tries
= 1;
524 eloop_cancel_timeout(ap_ht40_scan_retry
, iface
, NULL
);
525 eloop_register_timeout(1, 0, ap_ht40_scan_retry
, iface
, NULL
);
530 wpa_printf(MSG_ERROR
,
531 "Failed to request a scan of neighboring BSSes ret=%d (%s)",
532 ret
, strerror(-ret
));
536 iface
->scan_cb
= ieee80211n_check_scan
;
541 static int ieee80211n_supported_ht_capab(struct hostapd_iface
*iface
)
543 u16 hw
= iface
->current_mode
->ht_capab
;
544 u16 conf
= iface
->conf
->ht_capab
;
546 if ((conf
& HT_CAP_INFO_LDPC_CODING_CAP
) &&
547 !(hw
& HT_CAP_INFO_LDPC_CODING_CAP
)) {
548 wpa_printf(MSG_ERROR
, "Driver does not support configured "
549 "HT capability [LDPC]");
554 * Driver ACS chosen channel may not be HT40 due to internal driver
557 if (!iface
->conf
->acs
&& (conf
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
) &&
558 !(hw
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
)) {
559 wpa_printf(MSG_ERROR
, "Driver does not support configured "
560 "HT capability [HT40*]");
564 switch (conf
& HT_CAP_INFO_SMPS_MASK
) {
565 case HT_CAP_INFO_SMPS_STATIC
:
566 if (!(iface
->smps_modes
& WPA_DRIVER_SMPS_MODE_STATIC
)) {
567 wpa_printf(MSG_ERROR
,
568 "Driver does not support configured HT capability [SMPS-STATIC]");
572 case HT_CAP_INFO_SMPS_DYNAMIC
:
573 if (!(iface
->smps_modes
& WPA_DRIVER_SMPS_MODE_DYNAMIC
)) {
574 wpa_printf(MSG_ERROR
,
575 "Driver does not support configured HT capability [SMPS-DYNAMIC]");
579 case HT_CAP_INFO_SMPS_DISABLED
:
584 if ((conf
& HT_CAP_INFO_GREEN_FIELD
) &&
585 !(hw
& HT_CAP_INFO_GREEN_FIELD
)) {
586 wpa_printf(MSG_ERROR
, "Driver does not support configured "
587 "HT capability [GF]");
591 if ((conf
& HT_CAP_INFO_SHORT_GI20MHZ
) &&
592 !(hw
& HT_CAP_INFO_SHORT_GI20MHZ
)) {
593 wpa_printf(MSG_ERROR
, "Driver does not support configured "
594 "HT capability [SHORT-GI-20]");
598 if ((conf
& HT_CAP_INFO_SHORT_GI40MHZ
) &&
599 !(hw
& HT_CAP_INFO_SHORT_GI40MHZ
)) {
600 wpa_printf(MSG_ERROR
, "Driver does not support configured "
601 "HT capability [SHORT-GI-40]");
605 if ((conf
& HT_CAP_INFO_TX_STBC
) && !(hw
& HT_CAP_INFO_TX_STBC
)) {
606 wpa_printf(MSG_ERROR
, "Driver does not support configured "
607 "HT capability [TX-STBC]");
611 if ((conf
& HT_CAP_INFO_RX_STBC_MASK
) >
612 (hw
& HT_CAP_INFO_RX_STBC_MASK
)) {
613 wpa_printf(MSG_ERROR
, "Driver does not support configured "
614 "HT capability [RX-STBC*]");
618 if ((conf
& HT_CAP_INFO_DELAYED_BA
) &&
619 !(hw
& HT_CAP_INFO_DELAYED_BA
)) {
620 wpa_printf(MSG_ERROR
, "Driver does not support configured "
621 "HT capability [DELAYED-BA]");
625 if ((conf
& HT_CAP_INFO_MAX_AMSDU_SIZE
) &&
626 !(hw
& HT_CAP_INFO_MAX_AMSDU_SIZE
)) {
627 wpa_printf(MSG_ERROR
, "Driver does not support configured "
628 "HT capability [MAX-AMSDU-7935]");
632 if ((conf
& HT_CAP_INFO_DSSS_CCK40MHZ
) &&
633 !(hw
& HT_CAP_INFO_DSSS_CCK40MHZ
)) {
634 wpa_printf(MSG_ERROR
, "Driver does not support configured "
635 "HT capability [DSSS_CCK-40]");
639 if ((conf
& HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
) &&
640 !(hw
& HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
)) {
641 wpa_printf(MSG_ERROR
, "Driver does not support configured "
642 "HT capability [LSIG-TXOP-PROT]");
650 #ifdef CONFIG_IEEE80211AC
651 static int ieee80211ac_supported_vht_capab(struct hostapd_iface
*iface
)
653 struct hostapd_hw_modes
*mode
= iface
->current_mode
;
654 u32 hw
= mode
->vht_capab
;
655 u32 conf
= iface
->conf
->vht_capab
;
657 wpa_printf(MSG_DEBUG
, "hw vht capab: 0x%x, conf vht capab: 0x%x",
660 if (mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
661 iface
->conf
->bss
[0]->vendor_vht
&&
662 mode
->vht_capab
== 0 && iface
->hw_features
) {
665 for (i
= 0; i
< iface
->num_hw_features
; i
++) {
666 if (iface
->hw_features
[i
].mode
==
667 HOSTAPD_MODE_IEEE80211A
) {
668 mode
= &iface
->hw_features
[i
];
669 hw
= mode
->vht_capab
;
670 wpa_printf(MSG_DEBUG
,
671 "update hw vht capab based on 5 GHz band: 0x%x",
678 return ieee80211ac_cap_check(hw
, conf
);
680 #endif /* CONFIG_IEEE80211AC */
683 #ifdef CONFIG_IEEE80211AX
684 static int ieee80211ax_supported_he_capab(struct hostapd_iface
*iface
)
688 #endif /* CONFIG_IEEE80211AX */
690 #endif /* CONFIG_IEEE80211N */
693 int hostapd_check_ht_capab(struct hostapd_iface
*iface
)
695 #ifdef CONFIG_IEEE80211N
698 if (is_6ghz_freq(iface
->freq
))
700 if (!iface
->conf
->ieee80211n
)
703 if (iface
->current_mode
->mode
!= HOSTAPD_MODE_IEEE80211B
&&
704 iface
->current_mode
->mode
!= HOSTAPD_MODE_IEEE80211G
&&
705 (iface
->conf
->ht_capab
& HT_CAP_INFO_DSSS_CCK40MHZ
)) {
706 wpa_printf(MSG_DEBUG
,
707 "Disable HT capability [DSSS_CCK-40] on 5 GHz band");
708 iface
->conf
->ht_capab
&= ~HT_CAP_INFO_DSSS_CCK40MHZ
;
711 if (!ieee80211n_supported_ht_capab(iface
))
713 #ifdef CONFIG_IEEE80211AX
714 if (iface
->conf
->ieee80211ax
&&
715 !ieee80211ax_supported_he_capab(iface
))
717 #endif /* CONFIG_IEEE80211AX */
718 #ifdef CONFIG_IEEE80211AC
719 if (iface
->conf
->ieee80211ac
&&
720 !ieee80211ac_supported_vht_capab(iface
))
722 #endif /* CONFIG_IEEE80211AC */
723 ret
= ieee80211n_check_40mhz(iface
);
726 if (!ieee80211n_allowed_ht40_channel_pair(iface
))
728 #endif /* CONFIG_IEEE80211N */
734 int hostapd_check_edmg_capab(struct hostapd_iface
*iface
)
736 struct hostapd_hw_modes
*mode
= iface
->hw_features
;
737 struct ieee80211_edmg_config edmg
;
739 if (!iface
->conf
->enable_edmg
)
742 hostapd_encode_edmg_chan(iface
->conf
->enable_edmg
,
743 iface
->conf
->edmg_channel
,
744 iface
->conf
->channel
,
747 if (mode
->edmg
.channels
&& ieee802_edmg_is_allowed(mode
->edmg
, edmg
))
750 wpa_printf(MSG_WARNING
, "Requested EDMG configuration is not valid");
751 wpa_printf(MSG_INFO
, "EDMG capab: channels 0x%x, bw_config %d",
752 mode
->edmg
.channels
, mode
->edmg
.bw_config
);
754 "Requested EDMG configuration: channels 0x%x, bw_config %d",
755 edmg
.channels
, edmg
.bw_config
);
760 static int hostapd_is_usable_chan(struct hostapd_iface
*iface
,
761 int frequency
, int primary
)
763 struct hostapd_channel_data
*chan
;
765 if (!iface
->current_mode
)
768 chan
= hw_get_channel_freq(iface
->current_mode
->mode
, frequency
, NULL
,
769 iface
->hw_features
, iface
->num_hw_features
);
773 if ((primary
&& chan_pri_allowed(chan
)) ||
774 (!primary
&& !(chan
->flag
& HOSTAPD_CHAN_DISABLED
)))
778 "Frequency %d (%s) not allowed for AP mode, flags: 0x%x%s%s",
779 frequency
, primary
? "primary" : "secondary",
781 chan
->flag
& HOSTAPD_CHAN_NO_IR
? " NO-IR" : "",
782 chan
->flag
& HOSTAPD_CHAN_RADAR
? " RADAR" : "");
787 static int hostapd_is_usable_edmg(struct hostapd_iface
*iface
)
789 int i
, contiguous
= 0;
790 int num_of_enabled
= 0;
791 int max_contiguous
= 0;
792 struct ieee80211_edmg_config edmg
;
793 struct hostapd_channel_data
*pri_chan
;
795 if (!iface
->conf
->enable_edmg
)
798 if (!iface
->current_mode
)
800 pri_chan
= hw_get_channel_freq(iface
->current_mode
->mode
,
803 iface
->num_hw_features
);
804 hostapd_encode_edmg_chan(iface
->conf
->enable_edmg
,
805 iface
->conf
->edmg_channel
,
808 if (!(edmg
.channels
& BIT(pri_chan
->chan
- 1)))
811 /* 60 GHz channels 1..6 */
812 for (i
= 0; i
< 6; i
++) {
813 int freq
= 56160 + 2160 * i
;
815 if (edmg
.channels
& BIT(i
)) {
823 /* P802.11ay defines that the total number of subfields
824 * set to one does not exceed 4.
826 if (num_of_enabled
> 4)
829 if (!hostapd_is_usable_chan(iface
, freq
, 1))
832 if (contiguous
> max_contiguous
)
833 max_contiguous
= contiguous
;
836 /* Check if the EDMG configuration is valid under the limitations
839 /* check bw_config against contiguous EDMG channels */
840 switch (edmg
.bw_config
) {
841 case EDMG_BW_CONFIG_4
:
845 case EDMG_BW_CONFIG_5
:
846 if (max_contiguous
< 2)
857 static int hostapd_is_usable_chans(struct hostapd_iface
*iface
)
860 struct hostapd_channel_data
*pri_chan
;
862 if (!iface
->current_mode
)
864 pri_chan
= hw_get_channel_freq(iface
->current_mode
->mode
,
867 iface
->num_hw_features
);
869 wpa_printf(MSG_ERROR
, "Primary frequency not present");
872 if (!hostapd_is_usable_chan(iface
, pri_chan
->freq
, 1)) {
873 wpa_printf(MSG_ERROR
, "Primary frequency not allowed");
876 if (!hostapd_is_usable_edmg(iface
))
879 if (!iface
->conf
->secondary_channel
)
882 if (hostapd_is_usable_chan(iface
, iface
->freq
+
883 iface
->conf
->secondary_channel
* 20, 0))
885 if (!iface
->conf
->ht40_plus_minus_allowed
)
888 /* Both HT40+ and HT40- are set, pick a valid secondary channel */
889 secondary_freq
= iface
->freq
+ 20;
890 if (hostapd_is_usable_chan(iface
, secondary_freq
, 0) &&
891 (pri_chan
->allowed_bw
& HOSTAPD_CHAN_WIDTH_40P
)) {
892 iface
->conf
->secondary_channel
= 1;
896 secondary_freq
= iface
->freq
- 20;
897 if (hostapd_is_usable_chan(iface
, secondary_freq
, 0) &&
898 (pri_chan
->allowed_bw
& HOSTAPD_CHAN_WIDTH_40M
)) {
899 iface
->conf
->secondary_channel
= -1;
907 static enum hostapd_chan_status
908 hostapd_check_chans(struct hostapd_iface
*iface
)
911 if (hostapd_is_usable_chans(iface
))
912 return HOSTAPD_CHAN_VALID
;
914 return HOSTAPD_CHAN_INVALID
;
918 * The user set channel=0 or channel=acs_survey
919 * which is used to trigger ACS.
922 switch (acs_init(iface
)) {
923 case HOSTAPD_CHAN_ACS
:
924 return HOSTAPD_CHAN_ACS
;
925 case HOSTAPD_CHAN_VALID
:
926 case HOSTAPD_CHAN_INVALID
:
928 return HOSTAPD_CHAN_INVALID
;
933 static void hostapd_notify_bad_chans(struct hostapd_iface
*iface
)
935 if (!iface
->current_mode
) {
936 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
937 HOSTAPD_LEVEL_WARNING
,
938 "Hardware does not support configured mode");
941 hostapd_logger(iface
->bss
[0], NULL
,
942 HOSTAPD_MODULE_IEEE80211
,
943 HOSTAPD_LEVEL_WARNING
,
944 "Configured channel (%d) or frequency (%d) not found from the channel list of the current mode (%d) %s",
945 iface
->conf
->channel
,
947 iface
->current_mode
->mode
,
948 hostapd_hw_mode_txt(iface
->current_mode
->mode
));
949 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
950 HOSTAPD_LEVEL_WARNING
,
951 "Hardware does not support configured channel");
955 int hostapd_acs_completed(struct hostapd_iface
*iface
, int err
)
962 switch (hostapd_check_chans(iface
)) {
963 case HOSTAPD_CHAN_VALID
:
964 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
,
965 ACS_EVENT_COMPLETED
"freq=%d channel=%d",
966 iface
->freq
, iface
->conf
->channel
);
968 case HOSTAPD_CHAN_ACS
:
969 wpa_printf(MSG_ERROR
, "ACS error - reported complete, but no result available");
970 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
, ACS_EVENT_FAILED
);
971 hostapd_notify_bad_chans(iface
);
973 case HOSTAPD_CHAN_INVALID
:
975 wpa_printf(MSG_ERROR
, "ACS picked unusable channels");
976 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
, ACS_EVENT_FAILED
);
977 hostapd_notify_bad_chans(iface
);
981 ret
= hostapd_check_ht_capab(iface
);
985 wpa_printf(MSG_DEBUG
, "Interface initialization will be completed in a callback");
991 return hostapd_setup_interface_complete(iface
, ret
);
996 * hostapd_select_hw_mode - Select the hardware mode
997 * @iface: Pointer to interface data.
998 * Returns: 0 on success, < 0 on failure
1000 * Sets up the hardware mode, channel, rates, and passive scanning
1001 * based on the configuration.
1003 int hostapd_select_hw_mode(struct hostapd_iface
*iface
)
1007 if (iface
->num_hw_features
< 1)
1010 if ((iface
->conf
->hw_mode
== HOSTAPD_MODE_IEEE80211G
||
1011 iface
->conf
->ieee80211n
|| iface
->conf
->ieee80211ac
||
1012 iface
->conf
->ieee80211ax
) &&
1013 iface
->conf
->channel
== 14) {
1014 wpa_printf(MSG_INFO
, "Disable OFDM/HT/VHT/HE on channel 14");
1015 iface
->conf
->hw_mode
= HOSTAPD_MODE_IEEE80211B
;
1016 iface
->conf
->ieee80211n
= 0;
1017 iface
->conf
->ieee80211ac
= 0;
1018 iface
->conf
->ieee80211ax
= 0;
1021 iface
->current_mode
= NULL
;
1022 for (i
= 0; i
< iface
->num_hw_features
; i
++) {
1023 struct hostapd_hw_modes
*mode
= &iface
->hw_features
[i
];
1024 if (mode
->mode
== iface
->conf
->hw_mode
) {
1025 if (iface
->freq
> 0 &&
1026 !hw_get_chan(mode
->mode
, iface
->freq
,
1028 iface
->num_hw_features
))
1030 iface
->current_mode
= mode
;
1035 if (iface
->current_mode
== NULL
) {
1036 if (!(iface
->drv_flags
& WPA_DRIVER_FLAGS_ACS_OFFLOAD
) ||
1037 !(iface
->drv_flags
& WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY
))
1039 wpa_printf(MSG_ERROR
,
1040 "Hardware does not support configured mode");
1041 hostapd_logger(iface
->bss
[0], NULL
,
1042 HOSTAPD_MODULE_IEEE80211
,
1043 HOSTAPD_LEVEL_WARNING
,
1044 "Hardware does not support configured mode (%d) (hw_mode in hostapd.conf)",
1045 (int) iface
->conf
->hw_mode
);
1050 switch (hostapd_check_chans(iface
)) {
1051 case HOSTAPD_CHAN_VALID
:
1053 case HOSTAPD_CHAN_ACS
: /* ACS will run and later complete */
1055 case HOSTAPD_CHAN_INVALID
:
1057 hostapd_notify_bad_chans(iface
);
1063 const char * hostapd_hw_mode_txt(int mode
)
1066 case HOSTAPD_MODE_IEEE80211A
:
1067 return "IEEE 802.11a";
1068 case HOSTAPD_MODE_IEEE80211B
:
1069 return "IEEE 802.11b";
1070 case HOSTAPD_MODE_IEEE80211G
:
1071 return "IEEE 802.11g";
1072 case HOSTAPD_MODE_IEEE80211AD
:
1073 return "IEEE 802.11ad";
1080 int hostapd_hw_get_freq(struct hostapd_data
*hapd
, int chan
)
1082 return hw_get_freq(hapd
->iface
->current_mode
, chan
);
1086 int hostapd_hw_get_channel(struct hostapd_data
*hapd
, int freq
)
1089 struct hostapd_hw_modes
*mode
;
1091 if (hapd
->iface
->current_mode
) {
1092 channel
= hw_get_chan(hapd
->iface
->current_mode
->mode
, freq
,
1093 hapd
->iface
->hw_features
,
1094 hapd
->iface
->num_hw_features
);
1099 /* Check other available modes since the channel list for the current
1100 * mode did not include the specified frequency. */
1101 if (!hapd
->iface
->hw_features
)
1103 for (i
= 0; i
< hapd
->iface
->num_hw_features
; i
++) {
1104 mode
= &hapd
->iface
->hw_features
[i
];
1105 channel
= hw_get_chan(mode
->mode
, freq
,
1106 hapd
->iface
->hw_features
,
1107 hapd
->iface
->num_hw_features
);