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-2009, 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 "drivers/driver.h"
25 #include "ap_config.h"
26 #include "ap_drv_ops.h"
27 #include "hw_features.h"
30 void hostapd_free_hw_features(struct hostapd_hw_modes
*hw_features
,
31 size_t num_hw_features
)
35 if (hw_features
== NULL
)
38 for (i
= 0; i
< num_hw_features
; i
++) {
39 os_free(hw_features
[i
].channels
);
40 os_free(hw_features
[i
].rates
);
47 int hostapd_get_hw_features(struct hostapd_iface
*iface
)
49 struct hostapd_data
*hapd
= iface
->bss
[0];
52 struct hostapd_hw_modes
*modes
;
54 if (hostapd_drv_none(hapd
))
56 modes
= hostapd_get_hw_feature_data(hapd
, &num_modes
, &flags
);
58 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
60 "Fetching hardware channel/rate support not "
65 iface
->hw_flags
= flags
;
67 hostapd_free_hw_features(iface
->hw_features
, iface
->num_hw_features
);
68 iface
->hw_features
= modes
;
69 iface
->num_hw_features
= num_modes
;
71 for (i
= 0; i
< num_modes
; i
++) {
72 struct hostapd_hw_modes
*feature
= &modes
[i
];
73 /* set flag for channels we can use in current regulatory
75 for (j
= 0; j
< feature
->num_channels
; j
++) {
77 * Disable all channels that are marked not to allow
78 * IBSS operation or active scanning. In addition,
79 * disable all channels that require radar detection,
80 * since that (in addition to full DFS) is not yet
83 if (feature
->channels
[j
].flag
&
84 (HOSTAPD_CHAN_NO_IBSS
|
85 HOSTAPD_CHAN_PASSIVE_SCAN
|
87 feature
->channels
[j
].flag
|=
88 HOSTAPD_CHAN_DISABLED
;
89 if (feature
->channels
[j
].flag
& HOSTAPD_CHAN_DISABLED
)
91 wpa_printf(MSG_MSGDUMP
, "Allowed channel: mode=%d "
92 "chan=%d freq=%d MHz max_tx_power=%d dBm",
94 feature
->channels
[j
].chan
,
95 feature
->channels
[j
].freq
,
96 feature
->channels
[j
].max_tx_power
);
104 static int hostapd_prepare_rates(struct hostapd_data
*hapd
,
105 struct hostapd_hw_modes
*mode
)
107 int i
, num_basic_rates
= 0;
108 int basic_rates_a
[] = { 60, 120, 240, -1 };
109 int basic_rates_b
[] = { 10, 20, -1 };
110 int basic_rates_g
[] = { 10, 20, 55, 110, -1 };
113 if (hapd
->iconf
->basic_rates
)
114 basic_rates
= hapd
->iconf
->basic_rates
;
115 else switch (mode
->mode
) {
116 case HOSTAPD_MODE_IEEE80211A
:
117 basic_rates
= basic_rates_a
;
119 case HOSTAPD_MODE_IEEE80211B
:
120 basic_rates
= basic_rates_b
;
122 case HOSTAPD_MODE_IEEE80211G
:
123 basic_rates
= basic_rates_g
;
129 if (hostapd_set_rate_sets(hapd
, hapd
->iconf
->supported_rates
,
130 basic_rates
, mode
->mode
)) {
131 wpa_printf(MSG_ERROR
, "Failed to update rate sets in kernel "
135 os_free(hapd
->iface
->current_rates
);
136 hapd
->iface
->num_rates
= 0;
138 hapd
->iface
->current_rates
=
139 os_zalloc(mode
->num_rates
* sizeof(struct hostapd_rate_data
));
140 if (!hapd
->iface
->current_rates
) {
141 wpa_printf(MSG_ERROR
, "Failed to allocate memory for rate "
146 for (i
= 0; i
< mode
->num_rates
; i
++) {
147 struct hostapd_rate_data
*rate
;
149 if (hapd
->iconf
->supported_rates
&&
150 !hostapd_rate_found(hapd
->iconf
->supported_rates
,
154 rate
= &hapd
->iface
->current_rates
[hapd
->iface
->num_rates
];
155 rate
->rate
= mode
->rates
[i
];
156 if (hostapd_rate_found(basic_rates
, rate
->rate
)) {
157 rate
->flags
|= HOSTAPD_RATE_BASIC
;
160 wpa_printf(MSG_DEBUG
, "RATE[%d] rate=%d flags=0x%x",
161 hapd
->iface
->num_rates
, rate
->rate
, rate
->flags
);
162 hapd
->iface
->num_rates
++;
165 if (hapd
->iface
->num_rates
== 0 || num_basic_rates
== 0) {
166 wpa_printf(MSG_ERROR
, "No rates remaining in supported/basic "
167 "rate sets (%d,%d).",
168 hapd
->iface
->num_rates
, num_basic_rates
);
176 #ifdef CONFIG_IEEE80211N
177 static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface
*iface
)
179 int sec_chan
, ok
, j
, first
;
180 int allowed
[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
184 if (!iface
->conf
->secondary_channel
)
185 return 1; /* HT40 not used */
187 sec_chan
= iface
->conf
->channel
+ iface
->conf
->secondary_channel
* 4;
188 wpa_printf(MSG_DEBUG
, "HT40: control channel: %d "
189 "secondary channel: %d",
190 iface
->conf
->channel
, sec_chan
);
192 /* Verify that HT40 secondary channel is an allowed 20 MHz
195 for (j
= 0; j
< iface
->current_mode
->num_channels
; j
++) {
196 struct hostapd_channel_data
*chan
=
197 &iface
->current_mode
->channels
[j
];
198 if (!(chan
->flag
& HOSTAPD_CHAN_DISABLED
) &&
199 chan
->chan
== sec_chan
) {
205 wpa_printf(MSG_ERROR
, "HT40 secondary channel %d not allowed",
211 * Verify that HT40 primary,secondary channel pair is allowed per
212 * IEEE 802.11n Annex J. This is only needed for 5 GHz band since
213 * 2.4 GHz rules allow all cases where the secondary channel fits into
214 * the list of allowed channels (already checked above).
216 if (iface
->current_mode
->mode
!= HOSTAPD_MODE_IEEE80211A
)
219 if (iface
->conf
->secondary_channel
> 0)
220 first
= iface
->conf
->channel
;
225 for (k
= 0; k
< sizeof(allowed
) / sizeof(allowed
[0]); k
++) {
226 if (first
== allowed
[k
]) {
232 wpa_printf(MSG_ERROR
, "HT40 channel pair (%d, %d) not allowed",
233 iface
->conf
->channel
,
234 iface
->conf
->secondary_channel
);
242 static void ieee80211n_switch_pri_sec(struct hostapd_iface
*iface
)
244 if (iface
->conf
->secondary_channel
> 0) {
245 iface
->conf
->channel
+= 4;
246 iface
->conf
->secondary_channel
= -1;
248 iface
->conf
->channel
-= 4;
249 iface
->conf
->secondary_channel
= 1;
254 static void ieee80211n_get_pri_sec_chan(struct wpa_scan_res
*bss
,
255 int *pri_chan
, int *sec_chan
)
257 struct ieee80211_ht_operation
*oper
;
258 struct ieee802_11_elems elems
;
260 *pri_chan
= *sec_chan
= 0;
262 ieee802_11_parse_elems((u8
*) (bss
+ 1), bss
->ie_len
, &elems
, 0);
263 if (elems
.ht_operation
&&
264 elems
.ht_operation_len
>= sizeof(*oper
)) {
265 oper
= (struct ieee80211_ht_operation
*) elems
.ht_operation
;
266 *pri_chan
= oper
->control_chan
;
267 if (oper
->ht_param
& HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH
) {
269 HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE
)
270 *sec_chan
= *pri_chan
+ 4;
271 else if (oper
->ht_param
&
272 HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW
)
273 *sec_chan
= *pri_chan
- 4;
279 static int ieee80211n_check_40mhz_5g(struct hostapd_iface
*iface
,
280 struct wpa_scan_results
*scan_res
)
282 int pri_chan
, sec_chan
, pri_freq
, sec_freq
, pri_bss
, sec_bss
;
283 int bss_pri_chan
, bss_sec_chan
;
287 pri_chan
= iface
->conf
->channel
;
288 sec_chan
= iface
->conf
->secondary_channel
* 4;
289 pri_freq
= hostapd_hw_get_freq(iface
->bss
[0], pri_chan
);
290 if (iface
->conf
->secondary_channel
> 0)
291 sec_freq
= pri_freq
+ 20;
293 sec_freq
= pri_freq
- 20;
296 * Switch PRI/SEC channels if Beacons were detected on selected SEC
297 * channel, but not on selected PRI channel.
299 pri_bss
= sec_bss
= 0;
300 for (i
= 0; i
< scan_res
->num
; i
++) {
301 struct wpa_scan_res
*bss
= scan_res
->res
[i
];
302 if (bss
->freq
== pri_freq
)
304 else if (bss
->freq
== sec_freq
)
307 if (sec_bss
&& !pri_bss
) {
308 wpa_printf(MSG_INFO
, "Switch own primary and secondary "
309 "channel to get secondary channel with no Beacons "
311 ieee80211n_switch_pri_sec(iface
);
315 * Match PRI/SEC channel with any existing HT40 BSS on the same
316 * channels that we are about to use (if already mixed order in
317 * existing BSSes, use own preference).
320 for (i
= 0; i
< scan_res
->num
; i
++) {
321 struct wpa_scan_res
*bss
= scan_res
->res
[i
];
322 ieee80211n_get_pri_sec_chan(bss
, &bss_pri_chan
, &bss_sec_chan
);
323 if (pri_chan
== bss_pri_chan
&&
324 sec_chan
== bss_sec_chan
) {
330 for (i
= 0; i
< scan_res
->num
; i
++) {
331 struct wpa_scan_res
*bss
= scan_res
->res
[i
];
332 ieee80211n_get_pri_sec_chan(bss
, &bss_pri_chan
,
334 if (pri_chan
== bss_sec_chan
&&
335 sec_chan
== bss_pri_chan
) {
336 wpa_printf(MSG_INFO
, "Switch own primary and "
337 "secondary channel due to BSS "
338 "overlap with " MACSTR
,
339 MAC2STR(bss
->bssid
));
340 ieee80211n_switch_pri_sec(iface
);
350 static int ieee80211n_check_40mhz_2g4(struct hostapd_iface
*iface
,
351 struct wpa_scan_results
*scan_res
)
353 int pri_freq
, sec_freq
;
354 int affected_start
, affected_end
;
357 pri_freq
= hostapd_hw_get_freq(iface
->bss
[0], iface
->conf
->channel
);
358 if (iface
->conf
->secondary_channel
> 0)
359 sec_freq
= pri_freq
+ 20;
361 sec_freq
= pri_freq
- 20;
362 affected_start
= (pri_freq
+ sec_freq
) / 2 - 25;
363 affected_end
= (pri_freq
+ sec_freq
) / 2 + 25;
364 wpa_printf(MSG_DEBUG
, "40 MHz affected channel range: [%d,%d] MHz",
365 affected_start
, affected_end
);
366 for (i
= 0; i
< scan_res
->num
; i
++) {
367 struct wpa_scan_res
*bss
= scan_res
->res
[i
];
370 int sec_chan
, pri_chan
;
372 ieee80211n_get_pri_sec_chan(bss
, &pri_chan
, &sec_chan
);
375 if (sec_chan
< pri_chan
)
381 if ((pri
< affected_start
|| pri
> affected_end
) &&
382 (sec
< affected_start
|| sec
> affected_end
))
383 continue; /* not within affected channel range */
385 wpa_printf(MSG_DEBUG
, "Neighboring BSS: " MACSTR
386 " freq=%d pri=%d sec=%d",
387 MAC2STR(bss
->bssid
), bss
->freq
, pri_chan
, sec_chan
);
390 if (pri_freq
!= pri
|| sec_freq
!= sec
) {
391 wpa_printf(MSG_DEBUG
, "40 MHz pri/sec "
392 "mismatch with BSS " MACSTR
393 " <%d,%d> (chan=%d%c) vs. <%d,%d>",
396 sec
> pri
? '+' : '-',
402 /* TODO: 40 MHz intolerant */
409 static void wpa_scan_results_free(struct wpa_scan_results
*res
)
416 for (i
= 0; i
< res
->num
; i
++)
417 os_free(res
->res
[i
]);
423 static void ieee80211n_check_scan(struct hostapd_iface
*iface
)
425 struct wpa_scan_results
*scan_res
;
428 /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
429 * allowed per IEEE 802.11n/D7.0, 11.14.3.2 */
431 iface
->scan_cb
= NULL
;
433 scan_res
= hostapd_driver_get_scan_results(iface
->bss
[0]);
434 if (scan_res
== NULL
) {
435 hostapd_setup_interface_complete(iface
, 1);
439 if (iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
)
440 oper40
= ieee80211n_check_40mhz_5g(iface
, scan_res
);
442 oper40
= ieee80211n_check_40mhz_2g4(iface
, scan_res
);
443 wpa_scan_results_free(scan_res
);
446 wpa_printf(MSG_INFO
, "20/40 MHz operation not permitted on "
447 "channel pri=%d sec=%d based on overlapping BSSes",
448 iface
->conf
->channel
,
449 iface
->conf
->channel
+
450 iface
->conf
->secondary_channel
* 4);
451 iface
->conf
->secondary_channel
= 0;
452 iface
->conf
->ht_capab
&= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
;
455 hostapd_setup_interface_complete(iface
, 0);
459 static int ieee80211n_check_40mhz(struct hostapd_iface
*iface
)
461 struct wpa_driver_scan_params params
;
463 if (!iface
->conf
->secondary_channel
)
464 return 0; /* HT40 not used */
466 wpa_printf(MSG_DEBUG
, "Scan for neighboring BSSes prior to enabling "
468 os_memset(¶ms
, 0, sizeof(params
));
469 /* TODO: scan only the needed frequency */
470 if (hostapd_driver_scan(iface
->bss
[0], ¶ms
) < 0) {
471 wpa_printf(MSG_ERROR
, "Failed to request a scan of "
472 "neighboring BSSes");
476 iface
->scan_cb
= ieee80211n_check_scan
;
481 static int ieee80211n_supported_ht_capab(struct hostapd_iface
*iface
)
483 u16 hw
= iface
->current_mode
->ht_capab
;
484 u16 conf
= iface
->conf
->ht_capab
;
486 if (!iface
->conf
->ieee80211n
)
489 if ((conf
& HT_CAP_INFO_LDPC_CODING_CAP
) &&
490 !(hw
& HT_CAP_INFO_LDPC_CODING_CAP
)) {
491 wpa_printf(MSG_ERROR
, "Driver does not support configured "
492 "HT capability [LDPC]");
496 if ((conf
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
) &&
497 !(hw
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
)) {
498 wpa_printf(MSG_ERROR
, "Driver does not support configured "
499 "HT capability [HT40*]");
503 if ((conf
& HT_CAP_INFO_SMPS_MASK
) != (hw
& HT_CAP_INFO_SMPS_MASK
) &&
504 (conf
& HT_CAP_INFO_SMPS_MASK
) != HT_CAP_INFO_SMPS_DISABLED
) {
505 wpa_printf(MSG_ERROR
, "Driver does not support configured "
506 "HT capability [SMPS-*]");
510 if ((conf
& HT_CAP_INFO_GREEN_FIELD
) &&
511 !(hw
& HT_CAP_INFO_GREEN_FIELD
)) {
512 wpa_printf(MSG_ERROR
, "Driver does not support configured "
513 "HT capability [GF]");
517 if ((conf
& HT_CAP_INFO_SHORT_GI20MHZ
) &&
518 !(hw
& HT_CAP_INFO_SHORT_GI20MHZ
)) {
519 wpa_printf(MSG_ERROR
, "Driver does not support configured "
520 "HT capability [SHORT-GI-20]");
524 if ((conf
& HT_CAP_INFO_SHORT_GI40MHZ
) &&
525 !(hw
& HT_CAP_INFO_SHORT_GI40MHZ
)) {
526 wpa_printf(MSG_ERROR
, "Driver does not support configured "
527 "HT capability [SHORT-GI-40]");
531 if ((conf
& HT_CAP_INFO_TX_STBC
) && !(hw
& HT_CAP_INFO_TX_STBC
)) {
532 wpa_printf(MSG_ERROR
, "Driver does not support configured "
533 "HT capability [TX-STBC]");
537 if ((conf
& HT_CAP_INFO_RX_STBC_MASK
) >
538 (hw
& HT_CAP_INFO_RX_STBC_MASK
)) {
539 wpa_printf(MSG_ERROR
, "Driver does not support configured "
540 "HT capability [RX-STBC*]");
544 if ((conf
& HT_CAP_INFO_DELAYED_BA
) &&
545 !(hw
& HT_CAP_INFO_DELAYED_BA
)) {
546 wpa_printf(MSG_ERROR
, "Driver does not support configured "
547 "HT capability [DELAYED-BA]");
551 if ((conf
& HT_CAP_INFO_MAX_AMSDU_SIZE
) &&
552 !(hw
& HT_CAP_INFO_MAX_AMSDU_SIZE
)) {
553 wpa_printf(MSG_ERROR
, "Driver does not support configured "
554 "HT capability [MAX-AMSDU-7935]");
558 if ((conf
& HT_CAP_INFO_DSSS_CCK40MHZ
) &&
559 !(hw
& HT_CAP_INFO_DSSS_CCK40MHZ
)) {
560 wpa_printf(MSG_ERROR
, "Driver does not support configured "
561 "HT capability [DSSS_CCK-40]");
565 if ((conf
& HT_CAP_INFO_PSMP_SUPP
) && !(hw
& HT_CAP_INFO_PSMP_SUPP
)) {
566 wpa_printf(MSG_ERROR
, "Driver does not support configured "
567 "HT capability [PSMP]");
571 if ((conf
& HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
) &&
572 !(hw
& HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT
)) {
573 wpa_printf(MSG_ERROR
, "Driver does not support configured "
574 "HT capability [LSIG-TXOP-PROT]");
581 #endif /* CONFIG_IEEE80211N */
584 int hostapd_check_ht_capab(struct hostapd_iface
*iface
)
586 #ifdef CONFIG_IEEE80211N
588 ret
= ieee80211n_check_40mhz(iface
);
591 if (!ieee80211n_allowed_ht40_channel_pair(iface
))
593 if (!ieee80211n_supported_ht_capab(iface
))
595 #endif /* CONFIG_IEEE80211N */
602 * hostapd_select_hw_mode - Select the hardware mode
603 * @iface: Pointer to interface data.
604 * Returns: 0 on success, -1 on failure
606 * Sets up the hardware mode, channel, rates, and passive scanning
607 * based on the configuration.
609 int hostapd_select_hw_mode(struct hostapd_iface
*iface
)
613 if (iface
->num_hw_features
< 1)
616 iface
->current_mode
= NULL
;
617 for (i
= 0; i
< iface
->num_hw_features
; i
++) {
618 struct hostapd_hw_modes
*mode
= &iface
->hw_features
[i
];
619 if (mode
->mode
== iface
->conf
->hw_mode
) {
620 iface
->current_mode
= mode
;
625 if (iface
->current_mode
== NULL
) {
626 wpa_printf(MSG_ERROR
, "Hardware does not support configured "
628 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
629 HOSTAPD_LEVEL_WARNING
,
630 "Hardware does not support configured mode "
631 "(%d)", (int) iface
->conf
->hw_mode
);
636 for (j
= 0; j
< iface
->current_mode
->num_channels
; j
++) {
637 struct hostapd_channel_data
*chan
=
638 &iface
->current_mode
->channels
[j
];
639 if (!(chan
->flag
& HOSTAPD_CHAN_DISABLED
) &&
640 (chan
->chan
== iface
->conf
->channel
)) {
645 if (iface
->conf
->channel
== 0) {
646 /* TODO: could request a scan of neighboring BSSes and select
647 * the channel automatically */
648 wpa_printf(MSG_ERROR
, "Channel not configured "
649 "(hw_mode/channel in hostapd.conf)");
652 if (ok
== 0 && iface
->conf
->channel
!= 0) {
653 hostapd_logger(iface
->bss
[0], NULL
,
654 HOSTAPD_MODULE_IEEE80211
,
655 HOSTAPD_LEVEL_WARNING
,
656 "Configured channel (%d) not found from the "
657 "channel list of current mode (%d) %s",
658 iface
->conf
->channel
,
659 iface
->current_mode
->mode
,
660 hostapd_hw_mode_txt(iface
->current_mode
->mode
));
661 iface
->current_mode
= NULL
;
664 if (iface
->current_mode
== NULL
) {
665 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
666 HOSTAPD_LEVEL_WARNING
,
667 "Hardware does not support configured channel");
671 if (hostapd_prepare_rates(iface
->bss
[0], iface
->current_mode
)) {
672 wpa_printf(MSG_ERROR
, "Failed to prepare rates table.");
673 hostapd_logger(iface
->bss
[0], NULL
, HOSTAPD_MODULE_IEEE80211
,
674 HOSTAPD_LEVEL_WARNING
,
675 "Failed to prepare rates table.");
683 const char * hostapd_hw_mode_txt(int mode
)
686 case HOSTAPD_MODE_IEEE80211A
:
687 return "IEEE 802.11a";
688 case HOSTAPD_MODE_IEEE80211B
:
689 return "IEEE 802.11b";
690 case HOSTAPD_MODE_IEEE80211G
:
691 return "IEEE 802.11g";
698 int hostapd_hw_get_freq(struct hostapd_data
*hapd
, int chan
)
702 if (!hapd
->iface
->current_mode
)
705 for (i
= 0; i
< hapd
->iface
->current_mode
->num_channels
; i
++) {
706 struct hostapd_channel_data
*ch
=
707 &hapd
->iface
->current_mode
->channels
[i
];
708 if (ch
->chan
== chan
)
716 int hostapd_hw_get_channel(struct hostapd_data
*hapd
, int freq
)
720 if (!hapd
->iface
->current_mode
)
723 for (i
= 0; i
< hapd
->iface
->current_mode
->num_channels
; i
++) {
724 struct hostapd_channel_data
*ch
=
725 &hapd
->iface
->current_mode
->channels
[i
];
726 if (ch
->freq
== freq
)