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 static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface
*iface
)
229 int pri_freq
, sec_freq
;
230 struct hostapd_channel_data
*p_chan
, *s_chan
;
232 pri_freq
= iface
->freq
;
233 sec_freq
= pri_freq
+ iface
->conf
->secondary_channel
* 20;
235 if (!iface
->current_mode
)
238 p_chan
= hw_get_channel_freq(iface
->current_mode
->mode
, pri_freq
, NULL
,
240 iface
->num_hw_features
);
242 s_chan
= hw_get_channel_freq(iface
->current_mode
->mode
, sec_freq
, NULL
,
244 iface
->num_hw_features
);
246 return allowed_ht40_channel_pair(iface
->current_mode
->mode
,
251 static void ieee80211n_switch_pri_sec(struct hostapd_iface
*iface
)
253 if (iface
->conf
->secondary_channel
> 0) {
254 iface
->conf
->channel
+= 4;
256 iface
->conf
->secondary_channel
= -1;
258 iface
->conf
->channel
-= 4;
260 iface
->conf
->secondary_channel
= 1;
265 static int ieee80211n_check_40mhz_5g(struct hostapd_iface
*iface
,
266 struct wpa_scan_results
*scan_res
)
268 unsigned int pri_freq
, sec_freq
;
270 struct hostapd_channel_data
*pri_chan
, *sec_chan
;
272 pri_freq
= iface
->freq
;
273 sec_freq
= pri_freq
+ iface
->conf
->secondary_channel
* 20;
275 if (!iface
->current_mode
)
277 pri_chan
= hw_get_channel_freq(iface
->current_mode
->mode
, pri_freq
,
278 NULL
, iface
->hw_features
,
279 iface
->num_hw_features
);
280 sec_chan
= hw_get_channel_freq(iface
->current_mode
->mode
, sec_freq
,
281 NULL
, iface
->hw_features
,
282 iface
->num_hw_features
);
284 res
= check_40mhz_5g(scan_res
, pri_chan
, sec_chan
);
287 if (iface
->conf
->no_pri_sec_switch
) {
288 wpa_printf(MSG_DEBUG
,
289 "Cannot switch PRI/SEC channels due to local constraint");
291 ieee80211n_switch_pri_sec(iface
);
299 static int ieee80211n_check_40mhz_2g4(struct hostapd_iface
*iface
,
300 struct wpa_scan_results
*scan_res
)
302 int pri_chan
, sec_chan
;
304 pri_chan
= iface
->conf
->channel
;
305 sec_chan
= pri_chan
+ iface
->conf
->secondary_channel
* 4;
307 return check_40mhz_2g4(iface
->current_mode
, scan_res
, pri_chan
,
312 static void ieee80211n_check_scan(struct hostapd_iface
*iface
)
314 struct wpa_scan_results
*scan_res
;
318 /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
319 * allowed per IEEE Std 802.11-2012, 10.15.3.2 */
321 iface
->scan_cb
= NULL
;
323 scan_res
= hostapd_driver_get_scan_results(iface
->bss
[0]);
324 if (scan_res
== NULL
) {
325 hostapd_setup_interface_complete(iface
, 1);
329 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
)
330 oper40
= ieee80211n_check_40mhz_5g(iface
, scan_res
);
332 oper40
= ieee80211n_check_40mhz_2g4(iface
, scan_res
);
333 wpa_scan_results_free(scan_res
);
335 iface
->secondary_ch
= iface
->conf
->secondary_channel
;
337 wpa_printf(MSG_INFO
, "20/40 MHz operation not permitted on "
338 "channel pri=%d sec=%d based on overlapping BSSes",
339 iface
->conf
->channel
,
340 iface
->conf
->channel
+
341 iface
->conf
->secondary_channel
* 4);
342 iface
->conf
->secondary_channel
= 0;
343 if (iface
->drv_flags
& WPA_DRIVER_FLAGS_HT_2040_COEX
) {
345 * TODO: Could consider scheduling another scan to check
346 * if channel width can be changed if no coex reports
347 * are received from associating stations.
352 res
= ieee80211n_allowed_ht40_channel_pair(iface
);
354 iface
->conf
->secondary_channel
= 0;
355 hostapd_set_oper_centr_freq_seg0_idx(iface
->conf
, 0);
356 hostapd_set_oper_centr_freq_seg1_idx(iface
->conf
, 0);
357 hostapd_set_oper_chwidth(iface
->conf
, CHANWIDTH_USE_HT
);
359 wpa_printf(MSG_INFO
, "Fallback to 20 MHz");
362 hostapd_setup_interface_complete(iface
, !res
);
366 static void ieee80211n_scan_channels_2g4(struct hostapd_iface
*iface
,
367 struct wpa_driver_scan_params
*params
)
369 /* Scan only the affected frequency range */
370 int pri_freq
, sec_freq
;
371 int affected_start
, affected_end
;
373 struct hostapd_hw_modes
*mode
;
375 if (iface
->current_mode
== NULL
)
378 pri_freq
= iface
->freq
;
379 if (iface
->conf
->secondary_channel
> 0)
380 sec_freq
= pri_freq
+ 20;
382 sec_freq
= pri_freq
- 20;
384 * Note: Need to find the PRI channel also in cases where the affected
385 * channel is the SEC channel of a 40 MHz BSS, so need to include the
386 * scanning coverage here to be 40 MHz from the center frequency.
388 affected_start
= (pri_freq
+ sec_freq
) / 2 - 40;
389 affected_end
= (pri_freq
+ sec_freq
) / 2 + 40;
390 wpa_printf(MSG_DEBUG
, "40 MHz affected channel range: [%d,%d] MHz",
391 affected_start
, affected_end
);
393 mode
= iface
->current_mode
;
394 params
->freqs
= os_calloc(mode
->num_channels
+ 1, sizeof(int));
395 if (params
->freqs
== NULL
)
399 for (i
= 0; i
< mode
->num_channels
; i
++) {
400 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
401 if (chan
->flag
& HOSTAPD_CHAN_DISABLED
)
403 if (chan
->freq
< affected_start
||
404 chan
->freq
> affected_end
)
406 params
->freqs
[pos
++] = chan
->freq
;
411 static void ieee80211n_scan_channels_5g(struct hostapd_iface
*iface
,
412 struct wpa_driver_scan_params
*params
)
414 /* Scan only the affected frequency range */
416 int affected_start
, affected_end
;
418 struct hostapd_hw_modes
*mode
;
420 if (iface
->current_mode
== NULL
)
423 pri_freq
= iface
->freq
;
424 if (iface
->conf
->secondary_channel
> 0) {
425 affected_start
= pri_freq
- 10;
426 affected_end
= pri_freq
+ 30;
428 affected_start
= pri_freq
- 30;
429 affected_end
= pri_freq
+ 10;
431 wpa_printf(MSG_DEBUG
, "40 MHz affected channel range: [%d,%d] MHz",
432 affected_start
, affected_end
);
434 mode
= iface
->current_mode
;
435 params
->freqs
= os_calloc(mode
->num_channels
+ 1, sizeof(int));
436 if (params
->freqs
== NULL
)
440 for (i
= 0; i
< mode
->num_channels
; i
++) {
441 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
442 if (chan
->flag
& HOSTAPD_CHAN_DISABLED
)
444 if (chan
->freq
< affected_start
||
445 chan
->freq
> affected_end
)
447 params
->freqs
[pos
++] = chan
->freq
;
452 static void ap_ht40_scan_retry(void *eloop_data
, void *user_data
)
454 #define HT2040_COEX_SCAN_RETRY 15
455 struct hostapd_iface
*iface
= eloop_data
;
456 struct wpa_driver_scan_params params
;
459 os_memset(¶ms
, 0, sizeof(params
));
460 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
461 ieee80211n_scan_channels_2g4(iface
, ¶ms
);
463 ieee80211n_scan_channels_5g(iface
, ¶ms
);
465 ret
= hostapd_driver_scan(iface
->bss
[0], ¶ms
);
466 iface
->num_ht40_scan_tries
++;
467 os_free(params
.freqs
);
470 iface
->num_ht40_scan_tries
< HT2040_COEX_SCAN_RETRY
) {
471 wpa_printf(MSG_ERROR
,
472 "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again (attempt %d)",
473 ret
, strerror(-ret
), iface
->num_ht40_scan_tries
);
474 eloop_register_timeout(1, 0, ap_ht40_scan_retry
, iface
, NULL
);
479 iface
->scan_cb
= ieee80211n_check_scan
;
483 wpa_printf(MSG_DEBUG
,
484 "Failed to request a scan in device, bringing up in HT20 mode");
485 iface
->conf
->secondary_channel
= 0;
486 iface
->conf
->ht_capab
&= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
;
487 hostapd_setup_interface_complete(iface
, 0);
491 void hostapd_stop_setup_timers(struct hostapd_iface
*iface
)
493 eloop_cancel_timeout(ap_ht40_scan_retry
, iface
, NULL
);
497 static int ieee80211n_check_40mhz(struct hostapd_iface
*iface
)
499 struct wpa_driver_scan_params params
;
502 /* Check that HT40 is used and PRI / SEC switch is allowed */
503 if (!iface
->conf
->secondary_channel
|| iface
->conf
->no_pri_sec_switch
)
506 hostapd_set_state(iface
, HAPD_IFACE_HT_SCAN
);
507 wpa_printf(MSG_DEBUG
, "Scan for neighboring BSSes prior to enabling "
509 os_memset(¶ms
, 0, sizeof(params
));
510 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
511 ieee80211n_scan_channels_2g4(iface
, ¶ms
);
513 ieee80211n_scan_channels_5g(iface
, ¶ms
);
515 ret
= hostapd_driver_scan(iface
->bss
[0], ¶ms
);
516 os_free(params
.freqs
);
519 wpa_printf(MSG_ERROR
,
520 "Failed to request a scan of neighboring BSSes ret=%d (%s) - try to scan again",
521 ret
, strerror(-ret
));
522 iface
->num_ht40_scan_tries
= 1;
523 eloop_cancel_timeout(ap_ht40_scan_retry
, iface
, NULL
);
524 eloop_register_timeout(1, 0, ap_ht40_scan_retry
, iface
, NULL
);
529 wpa_printf(MSG_ERROR
,
530 "Failed to request a scan of neighboring BSSes ret=%d (%s)",
531 ret
, strerror(-ret
));
535 iface
->scan_cb
= ieee80211n_check_scan
;
540 static int ieee80211n_supported_ht_capab(struct hostapd_iface
*iface
)
542 u16 hw
= iface
->current_mode
->ht_capab
;
543 u16 conf
= iface
->conf
->ht_capab
;
545 if ((conf
& HT_CAP_INFO_LDPC_CODING_CAP
) &&
546 !(hw
& HT_CAP_INFO_LDPC_CODING_CAP
)) {
547 wpa_printf(MSG_ERROR
, "Driver does not support configured "
548 "HT capability [LDPC]");
553 * Driver ACS chosen channel may not be HT40 due to internal driver
556 if (!iface
->conf
->acs
&& (conf
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
) &&
557 !(hw
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
)) {
558 wpa_printf(MSG_ERROR
, "Driver does not support configured "
559 "HT capability [HT40*]");
563 if ((conf
& HT_CAP_INFO_GREEN_FIELD
) &&
564 !(hw
& HT_CAP_INFO_GREEN_FIELD
)) {
565 wpa_printf(MSG_ERROR
, "Driver does not support configured "
566 "HT capability [GF]");
570 if ((conf
& HT_CAP_INFO_SHORT_GI20MHZ
) &&
571 !(hw
& HT_CAP_INFO_SHORT_GI20MHZ
)) {
572 wpa_printf(MSG_ERROR
, "Driver does not support configured "
573 "HT capability [SHORT-GI-20]");
577 if ((conf
& HT_CAP_INFO_SHORT_GI40MHZ
) &&
578 !(hw
& HT_CAP_INFO_SHORT_GI40MHZ
)) {
579 wpa_printf(MSG_ERROR
, "Driver does not support configured "
580 "HT capability [SHORT-GI-40]");
584 if ((conf
& HT_CAP_INFO_TX_STBC
) && !(hw
& HT_CAP_INFO_TX_STBC
)) {
585 wpa_printf(MSG_ERROR
, "Driver does not support configured "
586 "HT capability [TX-STBC]");
590 if ((conf
& HT_CAP_INFO_RX_STBC_MASK
) >
591 (hw
& HT_CAP_INFO_RX_STBC_MASK
)) {
592 wpa_printf(MSG_ERROR
, "Driver does not support configured "
593 "HT capability [RX-STBC*]");
597 if ((conf
& HT_CAP_INFO_DELAYED_BA
) &&
598 !(hw
& HT_CAP_INFO_DELAYED_BA
)) {
599 wpa_printf(MSG_ERROR
, "Driver does not support configured "
600 "HT capability [DELAYED-BA]");
604 if ((conf
& HT_CAP_INFO_MAX_AMSDU_SIZE
) &&
605 !(hw
& HT_CAP_INFO_MAX_AMSDU_SIZE
)) {
606 wpa_printf(MSG_ERROR
, "Driver does not support configured "
607 "HT capability [MAX-AMSDU-7935]");
611 if ((conf
& HT_CAP_INFO_DSSS_CCK40MHZ
) &&
612 !(hw
& HT_CAP_INFO_DSSS_CCK40MHZ
)) {
613 wpa_printf(MSG_ERROR
, "Driver does not support configured "
614 "HT capability [DSSS_CCK-40]");
618 if ((conf
& HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
) &&
619 !(hw
& HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
)) {
620 wpa_printf(MSG_ERROR
, "Driver does not support configured "
621 "HT capability [LSIG-TXOP-PROT]");
629 #ifdef CONFIG_IEEE80211AC
630 static int ieee80211ac_supported_vht_capab(struct hostapd_iface
*iface
)
632 struct hostapd_hw_modes
*mode
= iface
->current_mode
;
633 u32 hw
= mode
->vht_capab
;
634 u32 conf
= iface
->conf
->vht_capab
;
636 wpa_printf(MSG_DEBUG
, "hw vht capab: 0x%x, conf vht capab: 0x%x",
639 if (mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
640 iface
->conf
->bss
[0]->vendor_vht
&&
641 mode
->vht_capab
== 0 && iface
->hw_features
) {
644 for (i
= 0; i
< iface
->num_hw_features
; i
++) {
645 if (iface
->hw_features
[i
].mode
==
646 HOSTAPD_MODE_IEEE80211A
) {
647 mode
= &iface
->hw_features
[i
];
648 hw
= mode
->vht_capab
;
649 wpa_printf(MSG_DEBUG
,
650 "update hw vht capab based on 5 GHz band: 0x%x",
657 return ieee80211ac_cap_check(hw
, conf
);
659 #endif /* CONFIG_IEEE80211AC */
662 #ifdef CONFIG_IEEE80211AX
663 static int ieee80211ax_supported_he_capab(struct hostapd_iface
*iface
)
667 #endif /* CONFIG_IEEE80211AX */
670 int hostapd_check_ht_capab(struct hostapd_iface
*iface
)
674 if (is_6ghz_freq(iface
->freq
))
676 if (!iface
->conf
->ieee80211n
)
679 if (iface
->current_mode
->mode
!= HOSTAPD_MODE_IEEE80211B
&&
680 iface
->current_mode
->mode
!= HOSTAPD_MODE_IEEE80211G
&&
681 (iface
->conf
->ht_capab
& HT_CAP_INFO_DSSS_CCK40MHZ
)) {
682 wpa_printf(MSG_DEBUG
,
683 "Disable HT capability [DSSS_CCK-40] on 5 GHz band");
684 iface
->conf
->ht_capab
&= ~HT_CAP_INFO_DSSS_CCK40MHZ
;
687 if (!ieee80211n_supported_ht_capab(iface
))
689 #ifdef CONFIG_IEEE80211AX
690 if (iface
->conf
->ieee80211ax
&&
691 !ieee80211ax_supported_he_capab(iface
))
693 #endif /* CONFIG_IEEE80211AX */
694 #ifdef CONFIG_IEEE80211AC
695 if (iface
->conf
->ieee80211ac
&&
696 !ieee80211ac_supported_vht_capab(iface
))
698 #endif /* CONFIG_IEEE80211AC */
699 ret
= ieee80211n_check_40mhz(iface
);
702 if (!ieee80211n_allowed_ht40_channel_pair(iface
))
709 int hostapd_check_edmg_capab(struct hostapd_iface
*iface
)
711 struct hostapd_hw_modes
*mode
= iface
->hw_features
;
712 struct ieee80211_edmg_config edmg
;
714 if (!iface
->conf
->enable_edmg
)
717 hostapd_encode_edmg_chan(iface
->conf
->enable_edmg
,
718 iface
->conf
->edmg_channel
,
719 iface
->conf
->channel
,
722 if (mode
->edmg
.channels
&& ieee802_edmg_is_allowed(mode
->edmg
, edmg
))
725 wpa_printf(MSG_WARNING
, "Requested EDMG configuration is not valid");
726 wpa_printf(MSG_INFO
, "EDMG capab: channels 0x%x, bw_config %d",
727 mode
->edmg
.channels
, mode
->edmg
.bw_config
);
729 "Requested EDMG configuration: channels 0x%x, bw_config %d",
730 edmg
.channels
, edmg
.bw_config
);
735 static int hostapd_is_usable_chan(struct hostapd_iface
*iface
,
736 int frequency
, int primary
)
738 struct hostapd_channel_data
*chan
;
740 if (!iface
->current_mode
)
743 chan
= hw_get_channel_freq(iface
->current_mode
->mode
, frequency
, NULL
,
744 iface
->hw_features
, iface
->num_hw_features
);
748 if ((primary
&& chan_pri_allowed(chan
)) ||
749 (!primary
&& !(chan
->flag
& HOSTAPD_CHAN_DISABLED
)))
753 "Frequency %d (%s) not allowed for AP mode, flags: 0x%x%s%s",
754 frequency
, primary
? "primary" : "secondary",
756 chan
->flag
& HOSTAPD_CHAN_NO_IR
? " NO-IR" : "",
757 chan
->flag
& HOSTAPD_CHAN_RADAR
? " RADAR" : "");
762 static int hostapd_is_usable_edmg(struct hostapd_iface
*iface
)
764 int i
, contiguous
= 0;
765 int num_of_enabled
= 0;
766 int max_contiguous
= 0;
767 struct ieee80211_edmg_config edmg
;
768 struct hostapd_channel_data
*pri_chan
;
770 if (!iface
->conf
->enable_edmg
)
773 if (!iface
->current_mode
)
775 pri_chan
= hw_get_channel_freq(iface
->current_mode
->mode
,
778 iface
->num_hw_features
);
779 hostapd_encode_edmg_chan(iface
->conf
->enable_edmg
,
780 iface
->conf
->edmg_channel
,
783 if (!(edmg
.channels
& BIT(pri_chan
->chan
- 1)))
786 /* 60 GHz channels 1..6 */
787 for (i
= 0; i
< 6; i
++) {
788 int freq
= 56160 + 2160 * (i
+ 1);
790 if (edmg
.channels
& BIT(i
)) {
798 /* P802.11ay defines that the total number of subfields
799 * set to one does not exceed 4.
801 if (num_of_enabled
> 4)
804 if (!hostapd_is_usable_chan(iface
, freq
, 1))
807 if (contiguous
> max_contiguous
)
808 max_contiguous
= contiguous
;
811 /* Check if the EDMG configuration is valid under the limitations
814 /* check bw_config against contiguous EDMG channels */
815 switch (edmg
.bw_config
) {
816 case EDMG_BW_CONFIG_4
:
820 case EDMG_BW_CONFIG_5
:
821 if (max_contiguous
< 2)
832 static int hostapd_is_usable_chans(struct hostapd_iface
*iface
)
835 struct hostapd_channel_data
*pri_chan
;
837 if (!iface
->current_mode
)
839 pri_chan
= hw_get_channel_freq(iface
->current_mode
->mode
,
842 iface
->num_hw_features
);
844 wpa_printf(MSG_ERROR
, "Primary frequency not present");
847 if (!hostapd_is_usable_chan(iface
, pri_chan
->freq
, 1)) {
848 wpa_printf(MSG_ERROR
, "Primary frequency not allowed");
851 if (!hostapd_is_usable_edmg(iface
))
854 if (!iface
->conf
->secondary_channel
)
857 if (hostapd_is_usable_chan(iface
, iface
->freq
+
858 iface
->conf
->secondary_channel
* 20, 0))
860 if (!iface
->conf
->ht40_plus_minus_allowed
)
863 /* Both HT40+ and HT40- are set, pick a valid secondary channel */
864 secondary_freq
= iface
->freq
+ 20;
865 if (hostapd_is_usable_chan(iface
, secondary_freq
, 0) &&
866 (pri_chan
->allowed_bw
& HOSTAPD_CHAN_WIDTH_40P
)) {
867 iface
->conf
->secondary_channel
= 1;
871 secondary_freq
= iface
->freq
- 20;
872 if (hostapd_is_usable_chan(iface
, secondary_freq
, 0) &&
873 (pri_chan
->allowed_bw
& HOSTAPD_CHAN_WIDTH_40M
)) {
874 iface
->conf
->secondary_channel
= -1;
882 static void hostapd_determine_mode(struct hostapd_iface
*iface
)
885 enum hostapd_hw_mode target_mode
;
887 if (iface
->current_mode
||
888 iface
->conf
->hw_mode
!= HOSTAPD_MODE_IEEE80211ANY
)
891 if (iface
->freq
< 4000)
892 target_mode
= HOSTAPD_MODE_IEEE80211G
;
893 else if (iface
->freq
> 50000)
894 target_mode
= HOSTAPD_MODE_IEEE80211AD
;
896 target_mode
= HOSTAPD_MODE_IEEE80211A
;
898 for (i
= 0; i
< iface
->num_hw_features
; i
++) {
899 struct hostapd_hw_modes
*mode
;
901 mode
= &iface
->hw_features
[i
];
902 if (mode
->mode
== target_mode
) {
903 iface
->current_mode
= mode
;
904 iface
->conf
->hw_mode
= mode
->mode
;
909 if (!iface
->current_mode
)
910 wpa_printf(MSG_ERROR
, "ACS: Cannot decide mode");
914 static enum hostapd_chan_status
915 hostapd_check_chans(struct hostapd_iface
*iface
)
918 hostapd_determine_mode(iface
);
919 if (hostapd_is_usable_chans(iface
))
920 return HOSTAPD_CHAN_VALID
;
922 return HOSTAPD_CHAN_INVALID
;
926 * The user set channel=0 or channel=acs_survey
927 * which is used to trigger ACS.
930 switch (acs_init(iface
)) {
931 case HOSTAPD_CHAN_ACS
:
932 return HOSTAPD_CHAN_ACS
;
933 case HOSTAPD_CHAN_VALID
:
934 case HOSTAPD_CHAN_INVALID
:
936 return HOSTAPD_CHAN_INVALID
;
941 static void hostapd_notify_bad_chans(struct hostapd_iface
*iface
)
943 if (!iface
->current_mode
) {
944 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
945 HOSTAPD_LEVEL_WARNING
,
946 "Hardware does not support configured mode");
949 hostapd_logger(iface
->bss
[0], NULL
,
950 HOSTAPD_MODULE_IEEE80211
,
951 HOSTAPD_LEVEL_WARNING
,
952 "Configured channel (%d) or frequency (%d) not found from the channel list of the current mode (%d) %s",
953 iface
->conf
->channel
,
955 iface
->current_mode
->mode
,
956 hostapd_hw_mode_txt(iface
->current_mode
->mode
));
957 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
958 HOSTAPD_LEVEL_WARNING
,
959 "Hardware does not support configured channel");
963 int hostapd_acs_completed(struct hostapd_iface
*iface
, int err
)
970 switch (hostapd_check_chans(iface
)) {
971 case HOSTAPD_CHAN_VALID
:
972 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
,
973 ACS_EVENT_COMPLETED
"freq=%d channel=%d",
974 iface
->freq
, iface
->conf
->channel
);
976 case HOSTAPD_CHAN_ACS
:
977 wpa_printf(MSG_ERROR
, "ACS error - reported complete, but no result available");
978 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
, ACS_EVENT_FAILED
);
979 hostapd_notify_bad_chans(iface
);
981 case HOSTAPD_CHAN_INVALID
:
983 wpa_printf(MSG_ERROR
, "ACS picked unusable channels");
984 wpa_msg(iface
->bss
[0]->msg_ctx
, MSG_INFO
, ACS_EVENT_FAILED
);
985 hostapd_notify_bad_chans(iface
);
989 ret
= hostapd_check_ht_capab(iface
);
993 wpa_printf(MSG_DEBUG
, "Interface initialization will be completed in a callback");
999 return hostapd_setup_interface_complete(iface
, ret
);
1004 * hostapd_select_hw_mode - Select the hardware mode
1005 * @iface: Pointer to interface data.
1006 * Returns: 0 on success, < 0 on failure
1008 * Sets up the hardware mode, channel, rates, and passive scanning
1009 * based on the configuration.
1011 int hostapd_select_hw_mode(struct hostapd_iface
*iface
)
1015 if (iface
->num_hw_features
< 1)
1018 if ((iface
->conf
->hw_mode
== HOSTAPD_MODE_IEEE80211G
||
1019 iface
->conf
->ieee80211n
|| iface
->conf
->ieee80211ac
||
1020 iface
->conf
->ieee80211ax
) &&
1021 iface
->conf
->channel
== 14) {
1022 wpa_printf(MSG_INFO
, "Disable OFDM/HT/VHT/HE on channel 14");
1023 iface
->conf
->hw_mode
= HOSTAPD_MODE_IEEE80211B
;
1024 iface
->conf
->ieee80211n
= 0;
1025 iface
->conf
->ieee80211ac
= 0;
1026 iface
->conf
->ieee80211ax
= 0;
1029 iface
->current_mode
= NULL
;
1030 for (i
= 0; i
< iface
->num_hw_features
; i
++) {
1031 struct hostapd_hw_modes
*mode
= &iface
->hw_features
[i
];
1032 if (mode
->mode
== iface
->conf
->hw_mode
) {
1033 if (iface
->freq
> 0 &&
1034 !hw_get_chan(mode
->mode
, iface
->freq
,
1036 iface
->num_hw_features
))
1038 iface
->current_mode
= mode
;
1043 if (iface
->current_mode
== NULL
) {
1044 if ((iface
->drv_flags
& WPA_DRIVER_FLAGS_ACS_OFFLOAD
) &&
1045 (iface
->drv_flags
& WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY
)) {
1046 wpa_printf(MSG_DEBUG
,
1047 "Using offloaded hw_mode=any ACS");
1048 } else if (!(iface
->drv_flags
& WPA_DRIVER_FLAGS_ACS_OFFLOAD
) &&
1049 iface
->conf
->hw_mode
== HOSTAPD_MODE_IEEE80211ANY
) {
1050 wpa_printf(MSG_DEBUG
,
1051 "Using internal ACS for hw_mode=any");
1053 wpa_printf(MSG_ERROR
,
1054 "Hardware does not support configured mode");
1055 hostapd_logger(iface
->bss
[0], NULL
,
1056 HOSTAPD_MODULE_IEEE80211
,
1057 HOSTAPD_LEVEL_WARNING
,
1058 "Hardware does not support configured mode (%d) (hw_mode in hostapd.conf)",
1059 (int) iface
->conf
->hw_mode
);
1064 switch (hostapd_check_chans(iface
)) {
1065 case HOSTAPD_CHAN_VALID
:
1067 case HOSTAPD_CHAN_ACS
: /* ACS will run and later complete */
1069 case HOSTAPD_CHAN_INVALID
:
1071 hostapd_notify_bad_chans(iface
);
1077 const char * hostapd_hw_mode_txt(int mode
)
1080 case HOSTAPD_MODE_IEEE80211A
:
1081 return "IEEE 802.11a";
1082 case HOSTAPD_MODE_IEEE80211B
:
1083 return "IEEE 802.11b";
1084 case HOSTAPD_MODE_IEEE80211G
:
1085 return "IEEE 802.11g";
1086 case HOSTAPD_MODE_IEEE80211AD
:
1087 return "IEEE 802.11ad";
1094 int hostapd_hw_get_freq(struct hostapd_data
*hapd
, int chan
)
1096 return hw_get_freq(hapd
->iface
->current_mode
, chan
);
1100 int hostapd_hw_get_channel(struct hostapd_data
*hapd
, int freq
)
1103 struct hostapd_hw_modes
*mode
;
1105 if (hapd
->iface
->current_mode
) {
1106 channel
= hw_get_chan(hapd
->iface
->current_mode
->mode
, freq
,
1107 hapd
->iface
->hw_features
,
1108 hapd
->iface
->num_hw_features
);
1113 /* Check other available modes since the channel list for the current
1114 * mode did not include the specified frequency. */
1115 if (!hapd
->iface
->hw_features
)
1117 for (i
= 0; i
< hapd
->iface
->num_hw_features
; i
++) {
1118 mode
= &hapd
->iface
->hw_features
[i
];
1119 channel
= hw_get_chan(mode
->mode
, freq
,
1120 hapd
->iface
->hw_features
,
1121 hapd
->iface
->num_hw_features
);
1129 int hostapd_hw_skip_mode(struct hostapd_iface
*iface
,
1130 struct hostapd_hw_modes
*mode
)
1134 if (iface
->current_mode
)
1135 return mode
!= iface
->current_mode
;
1136 if (mode
->mode
!= HOSTAPD_MODE_IEEE80211B
)
1138 for (i
= 0; i
< iface
->num_hw_features
; i
++) {
1139 if (iface
->hw_features
[i
].mode
== HOSTAPD_MODE_IEEE80211G
)