nl80211: Replace hostapd WEXT events with nl80211 events
[wpasupplicant] / hostapd / 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, Jouni Malinen <j@w1.fi>
6  *
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.
10  *
11  * Alternatively, this software may be distributed under the terms of BSD
12  * license.
13  *
14  * See README and COPYING for more details.
15  */
16
17 #include "includes.h"
18
19 #include "hostapd.h"
20 #include "ieee802_11_defs.h"
21 #include "hw_features.h"
22 #include "driver_i.h"
23 #include "config.h"
24
25
26 void hostapd_free_hw_features(struct hostapd_hw_modes *hw_features,
27                               size_t num_hw_features)
28 {
29         size_t i;
30
31         if (hw_features == NULL)
32                 return;
33
34         for (i = 0; i < num_hw_features; i++) {
35                 os_free(hw_features[i].channels);
36                 os_free(hw_features[i].rates);
37         }
38
39         os_free(hw_features);
40 }
41
42
43 int hostapd_get_hw_features(struct hostapd_iface *iface)
44 {
45         struct hostapd_data *hapd = iface->bss[0];
46         int ret = 0, i, j;
47         u16 num_modes, flags;
48         struct hostapd_hw_modes *modes;
49
50         if (hostapd_drv_none(hapd))
51                 return -1;
52         modes = hostapd_get_hw_feature_data(hapd, &num_modes, &flags);
53         if (modes == NULL) {
54                 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
55                                HOSTAPD_LEVEL_DEBUG,
56                                "Fetching hardware channel/rate support not "
57                                "supported.");
58                 return -1;
59         }
60
61         iface->hw_flags = flags;
62
63         hostapd_free_hw_features(iface->hw_features, iface->num_hw_features);
64         iface->hw_features = modes;
65         iface->num_hw_features = num_modes;
66
67         for (i = 0; i < num_modes; i++) {
68                 struct hostapd_hw_modes *feature = &modes[i];
69                 /* set flag for channels we can use in current regulatory
70                  * domain */
71                 for (j = 0; j < feature->num_channels; j++) {
72                         /*
73                          * Disable all channels that are marked not to allow
74                          * IBSS operation or active scanning. In addition,
75                          * disable all channels that require radar detection,
76                          * since that (in addition to full DFS) is not yet
77                          * supported.
78                          */
79                         if (feature->channels[j].flag &
80                             (HOSTAPD_CHAN_NO_IBSS |
81                              HOSTAPD_CHAN_PASSIVE_SCAN |
82                              HOSTAPD_CHAN_RADAR))
83                                 feature->channels[j].flag |=
84                                         HOSTAPD_CHAN_DISABLED;
85                         if (feature->channels[j].flag & HOSTAPD_CHAN_DISABLED)
86                                 continue;
87                         wpa_printf(MSG_MSGDUMP, "Allowed channel: mode=%d "
88                                    "chan=%d freq=%d MHz max_tx_power=%d dBm",
89                                    feature->mode,
90                                    feature->channels[j].chan,
91                                    feature->channels[j].freq,
92                                    feature->channels[j].max_tx_power);
93                 }
94         }
95
96         return ret;
97 }
98
99
100 static int hostapd_prepare_rates(struct hostapd_data *hapd,
101                                  struct hostapd_hw_modes *mode)
102 {
103         int i, num_basic_rates = 0;
104         int basic_rates_a[] = { 60, 120, 240, -1 };
105         int basic_rates_b[] = { 10, 20, -1 };
106         int basic_rates_g[] = { 10, 20, 55, 110, -1 };
107         int *basic_rates;
108
109         if (hapd->iconf->basic_rates)
110                 basic_rates = hapd->iconf->basic_rates;
111         else switch (mode->mode) {
112         case HOSTAPD_MODE_IEEE80211A:
113                 basic_rates = basic_rates_a;
114                 break;
115         case HOSTAPD_MODE_IEEE80211B:
116                 basic_rates = basic_rates_b;
117                 break;
118         case HOSTAPD_MODE_IEEE80211G:
119                 basic_rates = basic_rates_g;
120                 break;
121         default:
122                 return -1;
123         }
124
125         if (hostapd_set_rate_sets(hapd, hapd->iconf->supported_rates,
126                                   basic_rates, mode->mode)) {
127                 wpa_printf(MSG_ERROR, "Failed to update rate sets in kernel "
128                            "module");
129         }
130
131         os_free(hapd->iface->current_rates);
132         hapd->iface->num_rates = 0;
133
134         hapd->iface->current_rates =
135                 os_malloc(mode->num_rates * sizeof(struct hostapd_rate_data));
136         if (!hapd->iface->current_rates) {
137                 wpa_printf(MSG_ERROR, "Failed to allocate memory for rate "
138                            "table.");
139                 return -1;
140         }
141
142         for (i = 0; i < mode->num_rates; i++) {
143                 struct hostapd_rate_data *rate;
144
145                 if (hapd->iconf->supported_rates &&
146                     !hostapd_rate_found(hapd->iconf->supported_rates,
147                                         mode->rates[i].rate))
148                         continue;
149
150                 rate = &hapd->iface->current_rates[hapd->iface->num_rates];
151                 os_memcpy(rate, &mode->rates[i],
152                           sizeof(struct hostapd_rate_data));
153                 if (hostapd_rate_found(basic_rates, rate->rate)) {
154                         rate->flags |= HOSTAPD_RATE_BASIC;
155                         num_basic_rates++;
156                 } else
157                         rate->flags &= ~HOSTAPD_RATE_BASIC;
158                 wpa_printf(MSG_DEBUG, "RATE[%d] rate=%d flags=0x%x",
159                            hapd->iface->num_rates, rate->rate, rate->flags);
160                 hapd->iface->num_rates++;
161         }
162
163         if (hapd->iface->num_rates == 0 || num_basic_rates == 0) {
164                 wpa_printf(MSG_ERROR, "No rates remaining in supported/basic "
165                            "rate sets (%d,%d).",
166                            hapd->iface->num_rates, num_basic_rates);
167                 return -1;
168         }
169
170         return 0;
171 }
172
173
174 #ifdef CONFIG_IEEE80211N
175 static int ieee80211n_allowed_ht40_channel_pair(struct hostapd_iface *iface)
176 {
177         int sec_chan, ok, j, first;
178         int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
179                           184, 192 };
180         size_t k;
181
182         if (!iface->conf->secondary_channel)
183                 return 1; /* HT40 not used */
184
185         sec_chan = iface->conf->channel + iface->conf->secondary_channel * 4;
186         wpa_printf(MSG_DEBUG, "HT40: control channel: %d  "
187                    "secondary channel: %d",
188                    iface->conf->channel, sec_chan);
189
190         /* Verify that HT40 secondary channel is an allowed 20 MHz
191          * channel */
192         ok = 0;
193         for (j = 0; j < iface->current_mode->num_channels; j++) {
194                 struct hostapd_channel_data *chan =
195                         &iface->current_mode->channels[j];
196                 if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
197                     chan->chan == sec_chan) {
198                         ok = 1;
199                         break;
200                 }
201         }
202         if (!ok) {
203                 wpa_printf(MSG_ERROR, "HT40 secondary channel %d not allowed",
204                            sec_chan);
205                 return 0;
206         }
207
208         /*
209          * Verify that HT40 primary,secondary channel pair is allowed per
210          * IEEE 802.11n Annex J. This is only needed for 5 GHz band since
211          * 2.4 GHz rules allow all cases where the secondary channel fits into
212          * the list of allowed channels (already checked above).
213          */
214         if (iface->current_mode->mode != HOSTAPD_MODE_IEEE80211A)
215                 return 1;
216
217         if (iface->conf->secondary_channel > 0)
218                 first = iface->conf->channel;
219         else
220                 first = sec_chan;
221
222         ok = 0;
223         for (k = 0; k < sizeof(allowed) / sizeof(allowed[0]); k++) {
224                 if (first == allowed[k]) {
225                         ok = 1;
226                         break;
227                 }
228         }
229         if (!ok) {
230                 wpa_printf(MSG_ERROR, "HT40 channel pair (%d, %d) not allowed",
231                            iface->conf->channel,
232                            iface->conf->secondary_channel);
233                 return 0;
234         }
235
236         return 1;
237 }
238
239
240 static void ieee80211n_switch_pri_sec(struct hostapd_iface *iface)
241 {
242         if (iface->conf->secondary_channel > 0) {
243                 iface->conf->channel += 4;
244                 iface->conf->secondary_channel = -1;
245         } else {
246                 iface->conf->channel -= 4;
247                 iface->conf->secondary_channel = 1;
248         }
249 }
250
251
252 static int ieee80211n_check_40mhz_5g(struct hostapd_iface *iface)
253 {
254         int pri_chan, sec_chan, pri_freq, sec_freq, pri_bss, sec_bss;
255         const struct hostapd_neighbor_bss *n;
256         size_t i, num;
257         int match;
258
259         pri_chan = iface->conf->channel;
260         sec_chan = iface->conf->secondary_channel * 4;
261         pri_freq = hostapd_hw_get_freq(iface->bss[0], pri_chan);
262         if (iface->conf->secondary_channel > 0)
263                 sec_freq = pri_freq + 20;
264         else
265                 sec_freq = pri_freq - 20;
266
267         n = hostapd_driver_get_neighbor_bss(iface->bss[0], &num);
268
269         /*
270          * Switch PRI/SEC channels if Beacons were detected on selected SEC
271          * channel, but not on selected PRI channel.
272          */
273         pri_bss = sec_bss = 0;
274         for (i = 0; n && i < num; i++) {
275                 if (n[i].freq == pri_freq)
276                         pri_bss++;
277                 else if (n[i].freq == sec_freq)
278                         sec_bss++;
279         }
280         if (sec_bss && !pri_bss) {
281                 wpa_printf(MSG_INFO, "Switch own primary and secondary "
282                            "channel to get secondary channel with no Beacons "
283                            "from other BSSes");
284                 ieee80211n_switch_pri_sec(iface);
285         }
286
287         /*
288          * Match PRI/SEC channel with any existing HT40 BSS on the same
289          * channels that we are about to use (if already mixed order in
290          * existing BSSes, use own preference).
291          */
292         match = 0;
293         for (i = 0; n && i < num; i++) {
294                 if (pri_chan == n[i].pri_chan &&
295                     sec_chan == n[i].sec_chan) {
296                         match = 1;
297                         break;
298                 }
299         }
300         if (!match) {
301                 for (i = 0; n && i < num; i++) {
302                         if (pri_chan == n[i].sec_chan &&
303                             sec_chan == n[i].pri_chan) {
304                                 wpa_printf(MSG_INFO, "Switch own primary and "
305                                            "secondary channel due to BSS "
306                                            "overlap with " MACSTR,
307                                            MAC2STR(n[i].bssid));
308                                 ieee80211n_switch_pri_sec(iface);
309                                 break;
310                         }
311                 }
312         }
313
314         return 1;
315 }
316
317
318 static int ieee80211n_check_40mhz_2g4(struct hostapd_iface *iface)
319 {
320         int pri_freq, sec_freq;
321         int affected_start, affected_end;
322         const struct hostapd_neighbor_bss *n;
323         size_t i, num;
324
325         pri_freq = hostapd_hw_get_freq(iface->bss[0], iface->conf->channel);
326         if (iface->conf->secondary_channel > 0)
327                 sec_freq = pri_freq + 20;
328         else
329                 sec_freq = pri_freq - 20;
330         affected_start = (pri_freq + sec_freq) / 2 - 25;
331         affected_end = (pri_freq + sec_freq) / 2 + 25;
332         wpa_printf(MSG_DEBUG, "40 MHz affected channel range: [%d,%d] MHz",
333                    affected_start, affected_end);
334         n = hostapd_driver_get_neighbor_bss(iface->bss[0], &num);
335         for (i = 0; n && i < num; i++) {
336                 int pri = n[i].freq;
337                 int sec = pri;
338                 if (n[i].sec_chan) {
339                         if (n[i].sec_chan < n[i].pri_chan)
340                                 sec = pri - 20;
341                         else
342                                 sec = pri + 20;
343                 }
344
345                 if ((pri < affected_start || pri > affected_end) &&
346                     (sec < affected_start || sec > affected_end))
347                         continue; /* not within affected channel range */
348
349                 if (n[i].sec_chan) {
350                         if (pri_freq != pri || sec_freq != sec) {
351                                 wpa_printf(MSG_DEBUG, "40 MHz pri/sec "
352                                            "mismatch with BSS " MACSTR
353                                            " <%d,%d> (chan=%d%c) vs. <%d,%d>",
354                                            MAC2STR(n[i].bssid),
355                                            pri, sec, n[i].pri_chan,
356                                            sec > pri ? '+' : '-',
357                                            pri_freq, sec_freq);
358                                 return 0;
359                         }
360                 }
361
362                 /* TODO: 40 MHz intolerant */
363         }
364
365         return 1;
366 }
367
368
369 static void ieee80211n_check_40mhz(struct hostapd_iface *iface)
370 {
371         int oper40;
372
373         if (!iface->conf->secondary_channel)
374                 return; /* HT40 not used */
375
376         /* Check list of neighboring BSSes (from scan) to see whether 40 MHz is
377          * allowed per IEEE 802.11n/D7.0, 11.14.3.2 */
378
379         if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A)
380                 oper40 = ieee80211n_check_40mhz_5g(iface);
381         else
382                 oper40 = ieee80211n_check_40mhz_2g4(iface);
383
384         if (!oper40) {
385                 wpa_printf(MSG_INFO, "20/40 MHz operation not permitted on "
386                            "channel pri=%d sec=%d based on overlapping BSSes",
387                            iface->conf->channel,
388                            iface->conf->channel +
389                            iface->conf->secondary_channel * 4);
390                 iface->conf->secondary_channel = 0;
391                 iface->conf->ht_capab &= ~HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
392         }
393 }
394
395
396 static int ieee80211n_supported_ht_capab(struct hostapd_iface *iface)
397 {
398         u16 hw = iface->current_mode->ht_capab;
399         u16 conf = iface->conf->ht_capab;
400
401         if (!iface->conf->ieee80211n)
402                 return 1;
403
404         if ((conf & HT_CAP_INFO_LDPC_CODING_CAP) &&
405             !(hw & HT_CAP_INFO_LDPC_CODING_CAP)) {
406                 wpa_printf(MSG_ERROR, "Driver does not support configured "
407                            "HT capability [LDPC]");
408                 return 0;
409         }
410
411         if ((conf & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
412             !(hw & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
413                 wpa_printf(MSG_ERROR, "Driver does not support configured "
414                            "HT capability [HT40*]");
415                 return 0;
416         }
417
418         if ((conf & HT_CAP_INFO_SMPS_MASK) != (hw & HT_CAP_INFO_SMPS_MASK) &&
419             (conf & HT_CAP_INFO_SMPS_MASK) != HT_CAP_INFO_SMPS_DISABLED) {
420                 wpa_printf(MSG_ERROR, "Driver does not support configured "
421                            "HT capability [SMPS-*]");
422                 return 0;
423         }
424
425         if ((conf & HT_CAP_INFO_GREEN_FIELD) &&
426             !(hw & HT_CAP_INFO_GREEN_FIELD)) {
427                 wpa_printf(MSG_ERROR, "Driver does not support configured "
428                            "HT capability [GF]");
429                 return 0;
430         }
431
432         if ((conf & HT_CAP_INFO_SHORT_GI20MHZ) &&
433             !(hw & HT_CAP_INFO_SHORT_GI20MHZ)) {
434                 wpa_printf(MSG_ERROR, "Driver does not support configured "
435                            "HT capability [SHORT-GI-20]");
436                 return 0;
437         }
438
439         if ((conf & HT_CAP_INFO_SHORT_GI40MHZ) &&
440             !(hw & HT_CAP_INFO_SHORT_GI40MHZ)) {
441                 wpa_printf(MSG_ERROR, "Driver does not support configured "
442                            "HT capability [SHORT-GI-40]");
443                 return 0;
444         }
445
446         if ((conf & HT_CAP_INFO_TX_STBC) && !(hw & HT_CAP_INFO_TX_STBC)) {
447                 wpa_printf(MSG_ERROR, "Driver does not support configured "
448                            "HT capability [TX-STBC]");
449                 return 0;
450         }
451
452         if ((conf & HT_CAP_INFO_RX_STBC_MASK) >
453             (hw & HT_CAP_INFO_RX_STBC_MASK)) {
454                 wpa_printf(MSG_ERROR, "Driver does not support configured "
455                            "HT capability [RX-STBC*]");
456                 return 0;
457         }
458
459         if ((conf & HT_CAP_INFO_DELAYED_BA) &&
460             !(hw & HT_CAP_INFO_DELAYED_BA)) {
461                 wpa_printf(MSG_ERROR, "Driver does not support configured "
462                            "HT capability [DELAYED-BA]");
463                 return 0;
464         }
465
466         if ((conf & HT_CAP_INFO_MAX_AMSDU_SIZE) &&
467             !(hw & HT_CAP_INFO_MAX_AMSDU_SIZE)) {
468                 wpa_printf(MSG_ERROR, "Driver does not support configured "
469                            "HT capability [MAX-AMSDU-7935]");
470                 return 0;
471         }
472
473         if ((conf & HT_CAP_INFO_DSSS_CCK40MHZ) &&
474             !(hw & HT_CAP_INFO_DSSS_CCK40MHZ)) {
475                 wpa_printf(MSG_ERROR, "Driver does not support configured "
476                            "HT capability [DSSS_CCK-40]");
477                 return 0;
478         }
479
480         if ((conf & HT_CAP_INFO_PSMP_SUPP) && !(hw & HT_CAP_INFO_PSMP_SUPP)) {
481                 wpa_printf(MSG_ERROR, "Driver does not support configured "
482                            "HT capability [PSMP]");
483                 return 0;
484         }
485
486         if ((conf & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT) &&
487             !(hw & HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT)) {
488                 wpa_printf(MSG_ERROR, "Driver does not support configured "
489                            "HT capability [LSIG-TXOP-PROT]");
490                 return 0;
491         }
492
493         return 1;
494 }
495 #endif /* CONFIG_IEEE80211N */
496
497
498 /**
499  * hostapd_select_hw_mode - Select the hardware mode
500  * @iface: Pointer to interface data.
501  * Returns: 0 on success, -1 on failure
502  *
503  * Sets up the hardware mode, channel, rates, and passive scanning
504  * based on the configuration.
505  */
506 int hostapd_select_hw_mode(struct hostapd_iface *iface)
507 {
508         int i, j, ok, ret;
509
510         if (iface->num_hw_features < 1)
511                 return -1;
512
513         iface->current_mode = NULL;
514         for (i = 0; i < iface->num_hw_features; i++) {
515                 struct hostapd_hw_modes *mode = &iface->hw_features[i];
516                 if (mode->mode == iface->conf->hw_mode) {
517                         iface->current_mode = mode;
518                         break;
519                 }
520         }
521
522         if (iface->current_mode == NULL) {
523                 wpa_printf(MSG_ERROR, "Hardware does not support configured "
524                            "mode");
525                 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
526                                HOSTAPD_LEVEL_WARNING,
527                                "Hardware does not support configured mode "
528                                "(%d)", (int) iface->conf->hw_mode);
529                 return -1;
530         }
531
532         ok = 0;
533         for (j = 0; j < iface->current_mode->num_channels; j++) {
534                 struct hostapd_channel_data *chan =
535                         &iface->current_mode->channels[j];
536                 if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
537                     (chan->chan == iface->conf->channel)) {
538                         ok = 1;
539                         break;
540                 }
541         }
542         if (ok == 0 && iface->conf->channel != 0) {
543                 hostapd_logger(iface->bss[0], NULL,
544                                HOSTAPD_MODULE_IEEE80211,
545                                HOSTAPD_LEVEL_WARNING,
546                                "Configured channel (%d) not found from the "
547                                "channel list of current mode (%d) %s",
548                                iface->conf->channel,
549                                iface->current_mode->mode,
550                                hostapd_hw_mode_txt(iface->current_mode->mode));
551                 iface->current_mode = NULL;
552         }
553
554         if (iface->current_mode == NULL) {
555                 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
556                                HOSTAPD_LEVEL_WARNING,
557                                "Hardware does not support configured channel");
558                 return -1;
559         }
560
561 #ifdef CONFIG_IEEE80211N
562         ieee80211n_check_40mhz(iface);
563         if (!ieee80211n_allowed_ht40_channel_pair(iface))
564                 return -1;
565         if (!ieee80211n_supported_ht_capab(iface))
566                 return -1;
567 #endif /* CONFIG_IEEE80211N */
568
569         if (hostapd_prepare_rates(iface->bss[0], iface->current_mode)) {
570                 wpa_printf(MSG_ERROR, "Failed to prepare rates table.");
571                 hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
572                                            HOSTAPD_LEVEL_WARNING,
573                                            "Failed to prepare rates table.");
574                 return -1;
575         }
576
577         ret = hostapd_passive_scan(iface->bss[0], 0,
578                                    iface->conf->passive_scan_mode,
579                                    iface->conf->passive_scan_interval,
580                                    iface->conf->passive_scan_listen,
581                                    NULL, NULL);
582         if (ret) {
583                 if (ret == -1) {
584                         wpa_printf(MSG_DEBUG, "Passive scanning not "
585                                    "supported");
586                 } else {
587                         wpa_printf(MSG_ERROR, "Could not set passive "
588                                    "scanning: %s", strerror(ret));
589                 }
590                 ret = 0;
591         }
592
593         return ret;
594 }
595
596
597 const char * hostapd_hw_mode_txt(int mode)
598 {
599         switch (mode) {
600         case HOSTAPD_MODE_IEEE80211A:
601                 return "IEEE 802.11a";
602         case HOSTAPD_MODE_IEEE80211B:
603                 return "IEEE 802.11b";
604         case HOSTAPD_MODE_IEEE80211G:
605                 return "IEEE 802.11g";
606         default:
607                 return "UNKNOWN";
608         }
609 }
610
611
612 int hostapd_hw_get_freq(struct hostapd_data *hapd, int chan)
613 {
614         int i;
615
616         if (!hapd->iface->current_mode)
617                 return 0;
618
619         for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {
620                 struct hostapd_channel_data *ch =
621                         &hapd->iface->current_mode->channels[i];
622                 if (ch->chan == chan)
623                         return ch->freq;
624         }
625
626         return 0;
627 }
628
629
630 int hostapd_hw_get_channel(struct hostapd_data *hapd, int freq)
631 {
632         int i;
633
634         if (!hapd->iface->current_mode)
635                 return 0;
636
637         for (i = 0; i < hapd->iface->current_mode->num_channels; i++) {
638                 struct hostapd_channel_data *ch =
639                         &hapd->iface->current_mode->channels[i];
640                 if (ch->freq == freq)
641                         return ch->chan;
642         }
643
644         return 0;
645 }