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