]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/drivers/driver_nl80211_capa.c
mka: Send MKPDUs forever if mode is PSK
[thirdparty/hostap.git] / src / drivers / driver_nl80211_capa.c
CommitLineData
0fafeb54
JM
1/*
2 * Driver interaction with Linux nl80211/cfg80211 - Capabilities
399e6135 3 * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
0fafeb54
JM
4 * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
5 * Copyright (c) 2009-2010, Atheros Communications
6 *
7 * This software may be distributed under the terms of the BSD license.
8 * See README for more details.
9 */
10
11#include "includes.h"
12#include <netlink/genl/genl.h>
13
14#include "utils/common.h"
0fafeb54 15#include "common/ieee802_11_common.h"
a042e39a 16#include "common/wpa_common.h"
0fafeb54
JM
17#include "common/qca-vendor.h"
18#include "common/qca-vendor-attr.h"
19#include "driver_nl80211.h"
20
21
22static int protocol_feature_handler(struct nl_msg *msg, void *arg)
23{
24 u32 *feat = arg;
25 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
26 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
27
28 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
29 genlmsg_attrlen(gnlh, 0), NULL);
30
31 if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES])
32 *feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]);
33
34 return NL_SKIP;
35}
36
37
38static u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
39{
40 u32 feat = 0;
41 struct nl_msg *msg;
42
43 msg = nlmsg_alloc();
44 if (!msg)
9589a91e
JM
45 return 0;
46
47 if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES)) {
48 nlmsg_free(msg);
49 return 0;
50 }
0fafeb54 51
0fafeb54
JM
52 if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat) == 0)
53 return feat;
54
0fafeb54
JM
55 return 0;
56}
57
58
59struct wiphy_info_data {
60 struct wpa_driver_nl80211_data *drv;
61 struct wpa_driver_capa *capa;
62
63 unsigned int num_multichan_concurrent;
64
65 unsigned int error:1;
66 unsigned int device_ap_sme:1;
67 unsigned int poll_command_supported:1;
68 unsigned int data_tx_status:1;
0fafeb54
JM
69 unsigned int auth_supported:1;
70 unsigned int connect_supported:1;
71 unsigned int p2p_go_supported:1;
72 unsigned int p2p_client_supported:1;
abb8d08b 73 unsigned int p2p_go_ctwindow_supported:1;
0fafeb54
JM
74 unsigned int p2p_concurrent:1;
75 unsigned int channel_switch_supported:1;
76 unsigned int set_qos_map_supported:1;
77 unsigned int have_low_prio_scan:1;
dfa87878 78 unsigned int wmm_ac_supported:1;
86056fea
IP
79 unsigned int mac_addr_rand_scan_supported:1;
80 unsigned int mac_addr_rand_sched_scan_supported:1;
0fafeb54
JM
81};
82
83
84static unsigned int probe_resp_offload_support(int supp_protocols)
85{
86 unsigned int prot = 0;
87
88 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS)
89 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS;
90 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2)
91 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2;
92 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P)
93 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P;
94 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U)
95 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING;
96
97 return prot;
98}
99
100
101static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
102 struct nlattr *tb)
103{
104 struct nlattr *nl_mode;
105 int i;
106
107 if (tb == NULL)
108 return;
109
110 nla_for_each_nested(nl_mode, tb, i) {
111 switch (nla_type(nl_mode)) {
112 case NL80211_IFTYPE_AP:
113 info->capa->flags |= WPA_DRIVER_FLAGS_AP;
114 break;
115 case NL80211_IFTYPE_MESH_POINT:
116 info->capa->flags |= WPA_DRIVER_FLAGS_MESH;
117 break;
118 case NL80211_IFTYPE_ADHOC:
119 info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
120 break;
121 case NL80211_IFTYPE_P2P_DEVICE:
122 info->capa->flags |=
123 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
124 break;
125 case NL80211_IFTYPE_P2P_GO:
126 info->p2p_go_supported = 1;
127 break;
128 case NL80211_IFTYPE_P2P_CLIENT:
129 info->p2p_client_supported = 1;
130 break;
0fafeb54
JM
131 }
132 }
133}
134
135
136static int wiphy_info_iface_comb_process(struct wiphy_info_data *info,
137 struct nlattr *nl_combi)
138{
139 struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
140 struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
141 struct nlattr *nl_limit, *nl_mode;
142 int err, rem_limit, rem_mode;
143 int combination_has_p2p = 0, combination_has_mgd = 0;
144 static struct nla_policy
145 iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
146 [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
147 [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
148 [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
149 [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
150 [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
151 },
152 iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
153 [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
154 [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
155 };
156
157 err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
158 nl_combi, iface_combination_policy);
159 if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
160 !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
161 !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
162 return 0; /* broken combination */
163
164 if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS])
165 info->capa->flags |= WPA_DRIVER_FLAGS_RADAR;
166
167 nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
168 rem_limit) {
169 err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
170 nl_limit, iface_limit_policy);
171 if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES])
172 return 0; /* broken combination */
173
174 nla_for_each_nested(nl_mode,
175 tb_limit[NL80211_IFACE_LIMIT_TYPES],
176 rem_mode) {
177 int ift = nla_type(nl_mode);
178 if (ift == NL80211_IFTYPE_P2P_GO ||
179 ift == NL80211_IFTYPE_P2P_CLIENT)
180 combination_has_p2p = 1;
181 if (ift == NL80211_IFTYPE_STATION)
182 combination_has_mgd = 1;
183 }
184 if (combination_has_p2p && combination_has_mgd)
185 break;
186 }
187
188 if (combination_has_p2p && combination_has_mgd) {
189 unsigned int num_channels =
190 nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
191
192 info->p2p_concurrent = 1;
193 if (info->num_multichan_concurrent < num_channels)
194 info->num_multichan_concurrent = num_channels;
195 }
196
197 return 0;
198}
199
200
201static void wiphy_info_iface_comb(struct wiphy_info_data *info,
202 struct nlattr *tb)
203{
204 struct nlattr *nl_combi;
205 int rem_combi;
206
207 if (tb == NULL)
208 return;
209
210 nla_for_each_nested(nl_combi, tb, rem_combi) {
211 if (wiphy_info_iface_comb_process(info, nl_combi) > 0)
212 break;
213 }
214}
215
216
217static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
218 struct nlattr *tb)
219{
220 struct nlattr *nl_cmd;
221 int i;
222
223 if (tb == NULL)
224 return;
225
226 nla_for_each_nested(nl_cmd, tb, i) {
227 switch (nla_get_u32(nl_cmd)) {
228 case NL80211_CMD_AUTHENTICATE:
229 info->auth_supported = 1;
230 break;
231 case NL80211_CMD_CONNECT:
232 info->connect_supported = 1;
233 break;
234 case NL80211_CMD_START_SCHED_SCAN:
235 info->capa->sched_scan_supported = 1;
236 break;
237 case NL80211_CMD_PROBE_CLIENT:
238 info->poll_command_supported = 1;
239 break;
240 case NL80211_CMD_CHANNEL_SWITCH:
241 info->channel_switch_supported = 1;
242 break;
243 case NL80211_CMD_SET_QOS_MAP:
244 info->set_qos_map_supported = 1;
245 break;
246 }
247 }
248}
249
250
251static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
252 struct nlattr *tb)
253{
254 int i, num;
255 u32 *ciphers;
256
257 if (tb == NULL)
258 return;
259
260 num = nla_len(tb) / sizeof(u32);
261 ciphers = nla_data(tb);
262 for (i = 0; i < num; i++) {
263 u32 c = ciphers[i];
264
265 wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
266 c >> 24, (c >> 16) & 0xff,
267 (c >> 8) & 0xff, c & 0xff);
268 switch (c) {
a042e39a 269 case RSN_CIPHER_SUITE_CCMP_256:
0fafeb54
JM
270 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
271 break;
a042e39a 272 case RSN_CIPHER_SUITE_GCMP_256:
0fafeb54
JM
273 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
274 break;
a042e39a 275 case RSN_CIPHER_SUITE_CCMP:
0fafeb54
JM
276 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
277 break;
a042e39a 278 case RSN_CIPHER_SUITE_GCMP:
0fafeb54
JM
279 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
280 break;
a042e39a 281 case RSN_CIPHER_SUITE_TKIP:
0fafeb54
JM
282 info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
283 break;
a042e39a 284 case RSN_CIPHER_SUITE_WEP104:
0fafeb54
JM
285 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
286 break;
a042e39a 287 case RSN_CIPHER_SUITE_WEP40:
0fafeb54
JM
288 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
289 break;
a042e39a 290 case RSN_CIPHER_SUITE_AES_128_CMAC:
0fafeb54
JM
291 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
292 break;
a042e39a 293 case RSN_CIPHER_SUITE_BIP_GMAC_128:
0fafeb54
JM
294 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
295 break;
a042e39a 296 case RSN_CIPHER_SUITE_BIP_GMAC_256:
0fafeb54
JM
297 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
298 break;
a042e39a 299 case RSN_CIPHER_SUITE_BIP_CMAC_256:
0fafeb54
JM
300 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
301 break;
a042e39a 302 case RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED:
0fafeb54
JM
303 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GTK_NOT_USED;
304 break;
305 }
306 }
307}
308
309
310static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
311 struct nlattr *tb)
312{
313 if (tb)
314 capa->max_remain_on_chan = nla_get_u32(tb);
315}
316
317
318static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
319 struct nlattr *ext_setup)
320{
321 if (tdls == NULL)
322 return;
323
324 wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
325 capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
326
327 if (ext_setup) {
328 wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
329 capa->flags |= WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
330 }
331}
332
333
4acdc48a
JD
334static int ext_feature_isset(const u8 *ext_features, int ext_features_len,
335 enum nl80211_ext_feature_index ftidx)
336{
337 u8 ft_byte;
338
339 if ((int) ftidx / 8 >= ext_features_len)
340 return 0;
341
342 ft_byte = ext_features[ftidx / 8];
343 return (ft_byte & BIT(ftidx % 8)) != 0;
344}
345
346
347static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
348 struct nlattr *tb)
349{
350 struct wpa_driver_capa *capa = info->capa;
b5d172e5
BL
351 u8 *ext_features;
352 int len;
4acdc48a
JD
353
354 if (tb == NULL)
355 return;
356
b5d172e5
BL
357 ext_features = nla_data(tb);
358 len = nla_len(tb);
359
360 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_VHT_IBSS))
4acdc48a 361 capa->flags |= WPA_DRIVER_FLAGS_VHT_IBSS;
b5d172e5
BL
362
363 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_RRM))
364 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_RRM;
befdb2dc
JM
365
366 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_FILS_STA))
367 capa->flags |= WPA_DRIVER_FLAGS_SUPPORT_FILS;
d4f3003c
PK
368
369 if (ext_feature_isset(ext_features, len,
370 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
371 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_LEGACY;
372
373 if (ext_feature_isset(ext_features, len,
374 NL80211_EXT_FEATURE_BEACON_RATE_HT))
375 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_HT;
376
377 if (ext_feature_isset(ext_features, len,
378 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
379 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_VHT;
96a5f14e
AS
380
381 if (ext_feature_isset(ext_features, len,
382 NL80211_EXT_FEATURE_SET_SCAN_DWELL))
383 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL;
384
385 if (ext_feature_isset(ext_features, len,
386 NL80211_EXT_FEATURE_SCAN_START_TIME) &&
387 ext_feature_isset(ext_features, len,
388 NL80211_EXT_FEATURE_BSS_PARENT_TSF) &&
389 ext_feature_isset(ext_features, len,
390 NL80211_EXT_FEATURE_SET_SCAN_DWELL))
391 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT;
8331c9b3
VK
392 if (ext_feature_isset(ext_features, len,
393 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
394 capa->flags |= WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA;
395 if (ext_feature_isset(ext_features, len,
396 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
397 capa->flags |= WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED;
4acdc48a
JD
398}
399
400
0fafeb54
JM
401static void wiphy_info_feature_flags(struct wiphy_info_data *info,
402 struct nlattr *tb)
403{
404 u32 flags;
405 struct wpa_driver_capa *capa = info->capa;
406
407 if (tb == NULL)
408 return;
409
410 flags = nla_get_u32(tb);
411
412 if (flags & NL80211_FEATURE_SK_TX_STATUS)
413 info->data_tx_status = 1;
414
415 if (flags & NL80211_FEATURE_INACTIVITY_TIMER)
416 capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
417
418 if (flags & NL80211_FEATURE_SAE)
419 capa->flags |= WPA_DRIVER_FLAGS_SAE;
420
421 if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
422 capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
423
424 if (flags & NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)
425 capa->flags |= WPA_DRIVER_FLAGS_HT_2040_COEX;
426
4daa5729
AN
427 if (flags & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) {
428 wpa_printf(MSG_DEBUG, "nl80211: TDLS channel switch");
429 capa->flags |= WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH;
430 }
431
abb8d08b
EP
432 if (flags & NL80211_FEATURE_P2P_GO_CTWIN)
433 info->p2p_go_ctwindow_supported = 1;
434
0fafeb54
JM
435 if (flags & NL80211_FEATURE_LOW_PRIORITY_SCAN)
436 info->have_low_prio_scan = 1;
437
86056fea
IP
438 if (flags & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)
439 info->mac_addr_rand_scan_supported = 1;
440
441 if (flags & NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR)
442 info->mac_addr_rand_sched_scan_supported = 1;
443
0fafeb54
JM
444 if (flags & NL80211_FEATURE_STATIC_SMPS)
445 capa->smps_modes |= WPA_DRIVER_SMPS_MODE_STATIC;
446
447 if (flags & NL80211_FEATURE_DYNAMIC_SMPS)
448 capa->smps_modes |= WPA_DRIVER_SMPS_MODE_DYNAMIC;
dfa87878
MB
449
450 if (flags & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
451 info->wmm_ac_supported = 1;
58162adf
AK
452
453 if (flags & NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES)
454 capa->rrm_flags |= WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES;
455
456 if (flags & NL80211_FEATURE_WFA_TPC_IE_IN_PROBES)
457 capa->rrm_flags |= WPA_DRIVER_FLAGS_WFA_TPC_IE_IN_PROBES;
458
459 if (flags & NL80211_FEATURE_QUIET)
460 capa->rrm_flags |= WPA_DRIVER_FLAGS_QUIET;
461
462 if (flags & NL80211_FEATURE_TX_POWER_INSERTION)
463 capa->rrm_flags |= WPA_DRIVER_FLAGS_TX_POWER_INSERTION;
1830817e
JD
464
465 if (flags & NL80211_FEATURE_HT_IBSS)
466 capa->flags |= WPA_DRIVER_FLAGS_HT_IBSS;
dc55b6b6
AB
467
468 if (flags & NL80211_FEATURE_FULL_AP_CLIENT_STATE)
469 capa->flags |= WPA_DRIVER_FLAGS_FULL_AP_CLIENT_STATE;
0fafeb54
JM
470}
471
472
473static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
474 struct nlattr *tb)
475{
476 u32 protocols;
477
478 if (tb == NULL)
479 return;
480
481 protocols = nla_get_u32(tb);
482 wpa_printf(MSG_DEBUG, "nl80211: Supports Probe Response offload in AP "
483 "mode");
484 capa->flags |= WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD;
485 capa->probe_resp_offloads = probe_resp_offload_support(protocols);
486}
487
488
489static void wiphy_info_wowlan_triggers(struct wpa_driver_capa *capa,
490 struct nlattr *tb)
491{
492 struct nlattr *triggers[MAX_NL80211_WOWLAN_TRIG + 1];
493
494 if (tb == NULL)
495 return;
496
497 if (nla_parse_nested(triggers, MAX_NL80211_WOWLAN_TRIG,
498 tb, NULL))
499 return;
500
501 if (triggers[NL80211_WOWLAN_TRIG_ANY])
502 capa->wowlan_triggers.any = 1;
503 if (triggers[NL80211_WOWLAN_TRIG_DISCONNECT])
504 capa->wowlan_triggers.disconnect = 1;
505 if (triggers[NL80211_WOWLAN_TRIG_MAGIC_PKT])
506 capa->wowlan_triggers.magic_pkt = 1;
507 if (triggers[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
508 capa->wowlan_triggers.gtk_rekey_failure = 1;
509 if (triggers[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
510 capa->wowlan_triggers.eap_identity_req = 1;
511 if (triggers[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
512 capa->wowlan_triggers.four_way_handshake = 1;
513 if (triggers[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
514 capa->wowlan_triggers.rfkill_release = 1;
515}
516
517
cc9a2575
KV
518static void wiphy_info_extended_capab(struct wpa_driver_nl80211_data *drv,
519 struct nlattr *tb)
520{
521 int rem = 0, i;
522 struct nlattr *tb1[NL80211_ATTR_MAX + 1], *attr;
523
524 if (!tb || drv->num_iface_ext_capa == NL80211_IFTYPE_MAX)
525 return;
526
527 nla_for_each_nested(attr, tb, rem) {
528 unsigned int len;
529 struct drv_nl80211_ext_capa *capa;
530
531 nla_parse(tb1, NL80211_ATTR_MAX, nla_data(attr),
532 nla_len(attr), NULL);
533
534 if (!tb1[NL80211_ATTR_IFTYPE] ||
535 !tb1[NL80211_ATTR_EXT_CAPA] ||
536 !tb1[NL80211_ATTR_EXT_CAPA_MASK])
537 continue;
538
539 capa = &drv->iface_ext_capa[drv->num_iface_ext_capa];
540 capa->iftype = nla_get_u32(tb1[NL80211_ATTR_IFTYPE]);
541 wpa_printf(MSG_DEBUG,
542 "nl80211: Driver-advertised extended capabilities for interface type %s",
543 nl80211_iftype_str(capa->iftype));
544
545 len = nla_len(tb1[NL80211_ATTR_EXT_CAPA]);
546 capa->ext_capa = os_malloc(len);
547 if (!capa->ext_capa)
548 goto err;
549
550 os_memcpy(capa->ext_capa, nla_data(tb1[NL80211_ATTR_EXT_CAPA]),
551 len);
552 capa->ext_capa_len = len;
553 wpa_hexdump(MSG_DEBUG, "nl80211: Extended capabilities",
554 capa->ext_capa, capa->ext_capa_len);
555
556 len = nla_len(tb1[NL80211_ATTR_EXT_CAPA_MASK]);
557 capa->ext_capa_mask = os_malloc(len);
558 if (!capa->ext_capa_mask)
559 goto err;
560
561 os_memcpy(capa->ext_capa_mask,
562 nla_data(tb1[NL80211_ATTR_EXT_CAPA_MASK]), len);
563 wpa_hexdump(MSG_DEBUG, "nl80211: Extended capabilities mask",
564 capa->ext_capa_mask, capa->ext_capa_len);
565
566 drv->num_iface_ext_capa++;
567 if (drv->num_iface_ext_capa == NL80211_IFTYPE_MAX)
568 break;
569 }
570
571 return;
572
573err:
574 /* Cleanup allocated memory on error */
575 for (i = 0; i < NL80211_IFTYPE_MAX; i++) {
576 os_free(drv->iface_ext_capa[i].ext_capa);
577 drv->iface_ext_capa[i].ext_capa = NULL;
578 os_free(drv->iface_ext_capa[i].ext_capa_mask);
579 drv->iface_ext_capa[i].ext_capa_mask = NULL;
580 drv->iface_ext_capa[i].ext_capa_len = 0;
581 }
582 drv->num_iface_ext_capa = 0;
583}
584
585
0fafeb54
JM
586static int wiphy_info_handler(struct nl_msg *msg, void *arg)
587{
588 struct nlattr *tb[NL80211_ATTR_MAX + 1];
589 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
590 struct wiphy_info_data *info = arg;
591 struct wpa_driver_capa *capa = info->capa;
592 struct wpa_driver_nl80211_data *drv = info->drv;
593
594 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
595 genlmsg_attrlen(gnlh, 0), NULL);
596
0e92fb8f
JB
597 if (tb[NL80211_ATTR_WIPHY])
598 drv->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
599
0fafeb54
JM
600 if (tb[NL80211_ATTR_WIPHY_NAME])
601 os_strlcpy(drv->phyname,
602 nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]),
603 sizeof(drv->phyname));
604 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
605 capa->max_scan_ssids =
606 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
607
608 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
609 capa->max_sched_scan_ssids =
610 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
611
09ea4309
AS
612 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS] &&
613 tb[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL] &&
614 tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]) {
615 capa->max_sched_scan_plans =
616 nla_get_u32(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS]);
617
618 capa->max_sched_scan_plan_interval =
619 nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL]);
620
621 capa->max_sched_scan_plan_iterations =
622 nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]);
623 }
624
0fafeb54
JM
625 if (tb[NL80211_ATTR_MAX_MATCH_SETS])
626 capa->max_match_sets =
627 nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
628
629 if (tb[NL80211_ATTR_MAC_ACL_MAX])
630 capa->max_acl_mac_addrs =
631 nla_get_u8(tb[NL80211_ATTR_MAC_ACL_MAX]);
632
633 wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
634 wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
635 wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
636 wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
637
638 if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
639 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
640 "off-channel TX");
641 capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
642 }
643
644 if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
645 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
646 capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
647 }
648
649 wiphy_info_max_roc(capa,
650 tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
651
652 if (tb[NL80211_ATTR_SUPPORT_AP_UAPSD])
653 capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
654
655 wiphy_info_tdls(capa, tb[NL80211_ATTR_TDLS_SUPPORT],
656 tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]);
657
658 if (tb[NL80211_ATTR_DEVICE_AP_SME])
659 info->device_ap_sme = 1;
660
661 wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
4acdc48a 662 wiphy_info_ext_feature_flags(info, tb[NL80211_ATTR_EXT_FEATURES]);
0fafeb54
JM
663 wiphy_info_probe_resp_offload(capa,
664 tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
665
666 if (tb[NL80211_ATTR_EXT_CAPA] && tb[NL80211_ATTR_EXT_CAPA_MASK] &&
667 drv->extended_capa == NULL) {
668 drv->extended_capa =
669 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
670 if (drv->extended_capa) {
671 os_memcpy(drv->extended_capa,
672 nla_data(tb[NL80211_ATTR_EXT_CAPA]),
673 nla_len(tb[NL80211_ATTR_EXT_CAPA]));
674 drv->extended_capa_len =
675 nla_len(tb[NL80211_ATTR_EXT_CAPA]);
cc9a2575
KV
676 wpa_hexdump(MSG_DEBUG,
677 "nl80211: Driver-advertised extended capabilities (default)",
678 drv->extended_capa, drv->extended_capa_len);
0fafeb54
JM
679 }
680 drv->extended_capa_mask =
7b7b4449 681 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA_MASK]));
0fafeb54
JM
682 if (drv->extended_capa_mask) {
683 os_memcpy(drv->extended_capa_mask,
7b7b4449
LC
684 nla_data(tb[NL80211_ATTR_EXT_CAPA_MASK]),
685 nla_len(tb[NL80211_ATTR_EXT_CAPA_MASK]));
cc9a2575
KV
686 wpa_hexdump(MSG_DEBUG,
687 "nl80211: Driver-advertised extended capabilities mask (default)",
688 drv->extended_capa_mask,
689 drv->extended_capa_len);
0fafeb54
JM
690 } else {
691 os_free(drv->extended_capa);
692 drv->extended_capa = NULL;
693 drv->extended_capa_len = 0;
694 }
695 }
696
cc9a2575
KV
697 wiphy_info_extended_capab(drv, tb[NL80211_ATTR_IFTYPE_EXT_CAPA]);
698
0fafeb54
JM
699 if (tb[NL80211_ATTR_VENDOR_DATA]) {
700 struct nlattr *nl;
701 int rem;
702
703 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
704 struct nl80211_vendor_cmd_info *vinfo;
705 if (nla_len(nl) != sizeof(*vinfo)) {
706 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
707 continue;
708 }
709 vinfo = nla_data(nl);
5f9c92f8
ZK
710 if (vinfo->vendor_id == OUI_QCA) {
711 switch (vinfo->subcmd) {
712 case QCA_NL80211_VENDOR_SUBCMD_TEST:
713 drv->vendor_cmd_test_avail = 1;
714 break;
b658547d 715#ifdef CONFIG_DRIVER_NL80211_QCA
5f9c92f8
ZK
716 case QCA_NL80211_VENDOR_SUBCMD_ROAMING:
717 drv->roaming_vendor_cmd_avail = 1;
718 break;
719 case QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY:
720 drv->dfs_vendor_cmd_avail = 1;
721 break;
722 case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
723 drv->get_features_vendor_cmd_avail = 1;
724 break;
98342208
AK
725 case QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST:
726 drv->get_pref_freq_list = 1;
727 break;
7c813acf
AK
728 case QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL:
729 drv->set_prob_oper_freq = 1;
730 break;
5f9c92f8
ZK
731 case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
732 drv->capa.flags |=
733 WPA_DRIVER_FLAGS_ACS_OFFLOAD;
734 break;
844dfeb8
SD
735 case QCA_NL80211_VENDOR_SUBCMD_SETBAND:
736 drv->setband_vendor_cmd_avail = 1;
737 break;
f22a080c
KV
738 case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
739 drv->scan_vendor_cmd_avail = 1;
740 break;
cc9985d1 741 case QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION:
742 drv->set_wifi_conf_vendor_cmd_avail = 1;
743 break;
b658547d 744#endif /* CONFIG_DRIVER_NL80211_QCA */
5f9c92f8 745 }
0fafeb54
JM
746 }
747
748 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
749 vinfo->vendor_id, vinfo->subcmd);
750 }
751 }
752
753 if (tb[NL80211_ATTR_VENDOR_EVENTS]) {
754 struct nlattr *nl;
755 int rem;
756
757 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
758 struct nl80211_vendor_cmd_info *vinfo;
759 if (nla_len(nl) != sizeof(*vinfo)) {
760 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
761 continue;
762 }
763 vinfo = nla_data(nl);
0fafeb54
JM
764 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u",
765 vinfo->vendor_id, vinfo->subcmd);
766 }
767 }
768
769 wiphy_info_wowlan_triggers(capa,
770 tb[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]);
771
772 if (tb[NL80211_ATTR_MAX_AP_ASSOC_STA])
773 capa->max_stations =
774 nla_get_u32(tb[NL80211_ATTR_MAX_AP_ASSOC_STA]);
775
366179d2
AO
776 if (tb[NL80211_ATTR_MAX_CSA_COUNTERS])
777 capa->max_csa_counters =
778 nla_get_u8(tb[NL80211_ATTR_MAX_CSA_COUNTERS]);
779
0fafeb54
JM
780 return NL_SKIP;
781}
782
783
784static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
785 struct wiphy_info_data *info)
786{
787 u32 feat;
788 struct nl_msg *msg;
9589a91e 789 int flags = 0;
0fafeb54
JM
790
791 os_memset(info, 0, sizeof(*info));
792 info->capa = &drv->capa;
793 info->drv = drv;
794
0fafeb54
JM
795 feat = get_nl80211_protocol_features(drv);
796 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
9589a91e 797 flags = NLM_F_DUMP;
56f77852
JM
798 msg = nl80211_cmd_msg(drv->first_bss, flags, NL80211_CMD_GET_WIPHY);
799 if (!msg || nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
9589a91e
JM
800 nlmsg_free(msg);
801 return -1;
802 }
0fafeb54
JM
803
804 if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info))
805 return -1;
806
807 if (info->auth_supported)
808 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
809 else if (!info->connect_supported) {
810 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
811 "authentication/association or connect commands");
812 info->error = 1;
813 }
814
815 if (info->p2p_go_supported && info->p2p_client_supported)
816 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
817 if (info->p2p_concurrent) {
818 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
819 "interface (driver advertised support)");
820 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
821 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
822 }
823 if (info->num_multichan_concurrent > 1) {
824 wpa_printf(MSG_DEBUG, "nl80211: Enable multi-channel "
825 "concurrent (driver advertised support)");
826 drv->capa.num_multichan_concurrent =
827 info->num_multichan_concurrent;
828 }
829 if (drv->capa.flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
830 wpa_printf(MSG_DEBUG, "nl80211: use P2P_DEVICE support");
831
832 /* default to 5000 since early versions of mac80211 don't set it */
833 if (!drv->capa.max_remain_on_chan)
834 drv->capa.max_remain_on_chan = 5000;
835
dfa87878 836 drv->capa.wmm_ac_supported = info->wmm_ac_supported;
0fafeb54 837
86056fea
IP
838 drv->capa.mac_addr_rand_sched_scan_supported =
839 info->mac_addr_rand_sched_scan_supported;
840 drv->capa.mac_addr_rand_scan_supported =
841 info->mac_addr_rand_scan_supported;
842
366179d2
AO
843 if (info->channel_switch_supported) {
844 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_CSA;
845 if (!drv->capa.max_csa_counters)
846 drv->capa.max_csa_counters = 1;
847 }
848
09ea4309
AS
849 if (!drv->capa.max_sched_scan_plans) {
850 drv->capa.max_sched_scan_plans = 1;
851 drv->capa.max_sched_scan_plan_interval = UINT32_MAX;
852 drv->capa.max_sched_scan_plan_iterations = 0;
853 }
854
0fafeb54 855 return 0;
0fafeb54
JM
856}
857
858
b658547d
JM
859#ifdef CONFIG_DRIVER_NL80211_QCA
860
0fafeb54
JM
861static int dfs_info_handler(struct nl_msg *msg, void *arg)
862{
863 struct nlattr *tb[NL80211_ATTR_MAX + 1];
864 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
865 int *dfs_capability_ptr = arg;
866
867 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
868 genlmsg_attrlen(gnlh, 0), NULL);
869
870 if (tb[NL80211_ATTR_VENDOR_DATA]) {
871 struct nlattr *nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
872 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
873
874 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
875 nla_data(nl_vend), nla_len(nl_vend), NULL);
876
877 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]) {
878 u32 val;
879 val = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]);
880 wpa_printf(MSG_DEBUG, "nl80211: DFS offload capability: %u",
881 val);
882 *dfs_capability_ptr = val;
883 }
884 }
885
886 return NL_SKIP;
887}
888
889
890static void qca_nl80211_check_dfs_capa(struct wpa_driver_nl80211_data *drv)
891{
892 struct nl_msg *msg;
893 int dfs_capability = 0;
894 int ret;
895
896 if (!drv->dfs_vendor_cmd_avail)
897 return;
898
9725b784 899 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
9589a91e
JM
900 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
901 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
902 QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY)) {
903 nlmsg_free(msg);
904 return;
905 }
0fafeb54
JM
906
907 ret = send_and_recv_msgs(drv, msg, dfs_info_handler, &dfs_capability);
908 if (!ret && dfs_capability)
909 drv->capa.flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
0fafeb54
JM
910}
911
912
15badebd
CL
913struct features_info {
914 u8 *flags;
915 size_t flags_len;
079a28f7 916 struct wpa_driver_capa *capa;
15badebd
CL
917};
918
919
920static int features_info_handler(struct nl_msg *msg, void *arg)
921{
922 struct nlattr *tb[NL80211_ATTR_MAX + 1];
923 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
924 struct features_info *info = arg;
925 struct nlattr *nl_vend, *attr;
926
927 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
928 genlmsg_attrlen(gnlh, 0), NULL);
929
930 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
931 if (nl_vend) {
932 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
933
934 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
935 nla_data(nl_vend), nla_len(nl_vend), NULL);
936
937 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
938 if (attr) {
fdc1188a
PS
939 int len = nla_len(attr);
940 info->flags = os_malloc(len);
941 if (info->flags != NULL) {
942 os_memcpy(info->flags, nla_data(attr), len);
943 info->flags_len = len;
944 }
15badebd 945 }
079a28f7
AK
946 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA];
947 if (attr)
948 info->capa->conc_capab = nla_get_u32(attr);
949
950 attr = tb_vendor[
951 QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND];
952 if (attr)
953 info->capa->max_conc_chan_2_4 = nla_get_u32(attr);
954
955 attr = tb_vendor[
956 QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND];
957 if (attr)
958 info->capa->max_conc_chan_5_0 = nla_get_u32(attr);
15badebd
CL
959 }
960
961 return NL_SKIP;
962}
963
964
965static int check_feature(enum qca_wlan_vendor_features feature,
966 struct features_info *info)
967{
49e3eea8 968 size_t idx = feature / 8;
15badebd 969
49e3eea8
JM
970 return (idx < info->flags_len) &&
971 (info->flags[idx] & BIT(feature % 8));
15badebd
CL
972}
973
974
975static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
976{
977 struct nl_msg *msg;
978 struct features_info info;
979 int ret;
980
981 if (!drv->get_features_vendor_cmd_avail)
982 return;
983
984 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
985 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
986 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
987 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
988 nlmsg_free(msg);
989 return;
990 }
991
992 os_memset(&info, 0, sizeof(info));
079a28f7 993 info.capa = &drv->capa;
15badebd
CL
994 ret = send_and_recv_msgs(drv, msg, features_info_handler, &info);
995 if (ret || !info.flags)
996 return;
997
998 if (check_feature(QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD, &info))
999 drv->capa.flags |= WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD;
3784c058
PX
1000
1001 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY, &info))
1002 drv->capa.flags |= WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;
8e509745
KV
1003
1004 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS,
1005 &info))
1006 drv->capa.flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS;
a6f5b193
PX
1007 if (check_feature(QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD, &info))
1008 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_LISTEN_OFFLOAD;
fdc1188a 1009 os_free(info.flags);
15badebd
CL
1010}
1011
b658547d
JM
1012#endif /* CONFIG_DRIVER_NL80211_QCA */
1013
15badebd 1014
0fafeb54
JM
1015int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
1016{
1017 struct wiphy_info_data info;
1018 if (wpa_driver_nl80211_get_info(drv, &info))
1019 return -1;
1020
1021 if (info.error)
1022 return -1;
1023
1024 drv->has_capability = 1;
1025 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1026 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1027 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
399e6135
JM
1028 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
1029 WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B |
1030 WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
0fafeb54
JM
1031 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
1032 WPA_DRIVER_AUTH_SHARED |
1033 WPA_DRIVER_AUTH_LEAP;
1034
1035 drv->capa.flags |= WPA_DRIVER_FLAGS_SANE_ERROR_CODES;
1036 drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
1037 drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
1038
1039 /*
1040 * As all cfg80211 drivers must support cases where the AP interface is
1041 * removed without the knowledge of wpa_supplicant/hostapd, e.g., in
1042 * case that the user space daemon has crashed, they must be able to
1043 * cleanup all stations and key entries in the AP tear down flow. Thus,
1044 * this flag can/should always be set for cfg80211 drivers.
1045 */
1046 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT;
1047
1048 if (!info.device_ap_sme) {
1049 drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
1050
1051 /*
1052 * No AP SME is currently assumed to also indicate no AP MLME
1053 * in the driver/firmware.
1054 */
1055 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_MLME;
1056 }
1057
1058 drv->device_ap_sme = info.device_ap_sme;
1059 drv->poll_command_supported = info.poll_command_supported;
1060 drv->data_tx_status = info.data_tx_status;
abb8d08b 1061 drv->p2p_go_ctwindow_supported = info.p2p_go_ctwindow_supported;
0fafeb54
JM
1062 if (info.set_qos_map_supported)
1063 drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
1064 drv->have_low_prio_scan = info.have_low_prio_scan;
1065
1066 /*
1067 * If poll command and tx status are supported, mac80211 is new enough
1068 * to have everything we need to not need monitor interfaces.
1069 */
660103ec
SD
1070 drv->use_monitor = !info.device_ap_sme &&
1071 (!info.poll_command_supported || !info.data_tx_status);
0fafeb54
JM
1072
1073 /*
1074 * If we aren't going to use monitor interfaces, but the
1075 * driver doesn't support data TX status, we won't get TX
1076 * status for EAPOL frames.
1077 */
1078 if (!drv->use_monitor && !info.data_tx_status)
1079 drv->capa.flags &= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
1080
b658547d 1081#ifdef CONFIG_DRIVER_NL80211_QCA
0fafeb54 1082 qca_nl80211_check_dfs_capa(drv);
15badebd 1083 qca_nl80211_get_features(drv);
0fafeb54 1084
8e509745
KV
1085 /*
1086 * To enable offchannel simultaneous support in wpa_supplicant, the
1087 * underlying driver needs to support the same along with offchannel TX.
1088 * Offchannel TX support is needed since remain_on_channel and
1089 * action_tx use some common data structures and hence cannot be
1090 * scheduled simultaneously.
1091 */
1092 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX))
1093 drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS;
b658547d 1094#endif /* CONFIG_DRIVER_NL80211_QCA */
8e509745 1095
0fafeb54
JM
1096 return 0;
1097}
1098
1099
1100struct phy_info_arg {
1101 u16 *num_modes;
1102 struct hostapd_hw_modes *modes;
1103 int last_mode, last_chan_idx;
747ba106 1104 int failed;
0fafeb54
JM
1105};
1106
1107static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
1108 struct nlattr *ampdu_factor,
1109 struct nlattr *ampdu_density,
1110 struct nlattr *mcs_set)
1111{
1112 if (capa)
1113 mode->ht_capab = nla_get_u16(capa);
1114
1115 if (ampdu_factor)
1116 mode->a_mpdu_params |= nla_get_u8(ampdu_factor) & 0x03;
1117
1118 if (ampdu_density)
1119 mode->a_mpdu_params |= nla_get_u8(ampdu_density) << 2;
1120
1121 if (mcs_set && nla_len(mcs_set) >= 16) {
1122 u8 *mcs;
1123 mcs = nla_data(mcs_set);
1124 os_memcpy(mode->mcs_set, mcs, 16);
1125 }
1126}
1127
1128
1129static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
1130 struct nlattr *capa,
1131 struct nlattr *mcs_set)
1132{
1133 if (capa)
1134 mode->vht_capab = nla_get_u32(capa);
1135
1136 if (mcs_set && nla_len(mcs_set) >= 8) {
1137 u8 *mcs;
1138 mcs = nla_data(mcs_set);
1139 os_memcpy(mode->vht_mcs_set, mcs, 8);
1140 }
1141}
1142
1143
1144static void phy_info_freq(struct hostapd_hw_modes *mode,
1145 struct hostapd_channel_data *chan,
1146 struct nlattr *tb_freq[])
1147{
1148 u8 channel;
1149 chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
1150 chan->flag = 0;
1151 chan->dfs_cac_ms = 0;
1152 if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
1153 chan->chan = channel;
1154
1155 if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
1156 chan->flag |= HOSTAPD_CHAN_DISABLED;
1157 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
1158 chan->flag |= HOSTAPD_CHAN_NO_IR;
1159 if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
1160 chan->flag |= HOSTAPD_CHAN_RADAR;
1161 if (tb_freq[NL80211_FREQUENCY_ATTR_INDOOR_ONLY])
1162 chan->flag |= HOSTAPD_CHAN_INDOOR_ONLY;
1163 if (tb_freq[NL80211_FREQUENCY_ATTR_GO_CONCURRENT])
1164 chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;
1165
1166 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
1167 enum nl80211_dfs_state state =
1168 nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
1169
1170 switch (state) {
1171 case NL80211_DFS_USABLE:
1172 chan->flag |= HOSTAPD_CHAN_DFS_USABLE;
1173 break;
1174 case NL80211_DFS_AVAILABLE:
1175 chan->flag |= HOSTAPD_CHAN_DFS_AVAILABLE;
1176 break;
1177 case NL80211_DFS_UNAVAILABLE:
1178 chan->flag |= HOSTAPD_CHAN_DFS_UNAVAILABLE;
1179 break;
1180 }
1181 }
1182
1183 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) {
1184 chan->dfs_cac_ms = nla_get_u32(
1185 tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]);
1186 }
1187}
1188
1189
1190static int phy_info_freqs(struct phy_info_arg *phy_info,
1191 struct hostapd_hw_modes *mode, struct nlattr *tb)
1192{
1193 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
1194 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
1195 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
1196 [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
1197 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
1198 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
1199 [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
1200 };
1201 int new_channels = 0;
1202 struct hostapd_channel_data *channel;
1203 struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
1204 struct nlattr *nl_freq;
1205 int rem_freq, idx;
1206
1207 if (tb == NULL)
1208 return NL_OK;
1209
1210 nla_for_each_nested(nl_freq, tb, rem_freq) {
1211 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
1212 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
1213 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
1214 continue;
1215 new_channels++;
1216 }
1217
1218 channel = os_realloc_array(mode->channels,
1219 mode->num_channels + new_channels,
1220 sizeof(struct hostapd_channel_data));
1221 if (!channel)
747ba106 1222 return NL_STOP;
0fafeb54
JM
1223
1224 mode->channels = channel;
1225 mode->num_channels += new_channels;
1226
1227 idx = phy_info->last_chan_idx;
1228
1229 nla_for_each_nested(nl_freq, tb, rem_freq) {
1230 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
1231 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
1232 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
1233 continue;
1234 phy_info_freq(mode, &mode->channels[idx], tb_freq);
1235 idx++;
1236 }
1237 phy_info->last_chan_idx = idx;
1238
1239 return NL_OK;
1240}
1241
1242
1243static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
1244{
1245 static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
1246 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
1247 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =
1248 { .type = NLA_FLAG },
1249 };
1250 struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
1251 struct nlattr *nl_rate;
1252 int rem_rate, idx;
1253
1254 if (tb == NULL)
1255 return NL_OK;
1256
1257 nla_for_each_nested(nl_rate, tb, rem_rate) {
1258 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
1259 nla_data(nl_rate), nla_len(nl_rate),
1260 rate_policy);
1261 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
1262 continue;
1263 mode->num_rates++;
1264 }
1265
1266 mode->rates = os_calloc(mode->num_rates, sizeof(int));
1267 if (!mode->rates)
747ba106 1268 return NL_STOP;
0fafeb54
JM
1269
1270 idx = 0;
1271
1272 nla_for_each_nested(nl_rate, tb, rem_rate) {
1273 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
1274 nla_data(nl_rate), nla_len(nl_rate),
1275 rate_policy);
1276 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
1277 continue;
1278 mode->rates[idx] = nla_get_u32(
1279 tb_rate[NL80211_BITRATE_ATTR_RATE]);
1280 idx++;
1281 }
1282
1283 return NL_OK;
1284}
1285
1286
1287static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
1288{
1289 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
1290 struct hostapd_hw_modes *mode;
1291 int ret;
1292
1293 if (phy_info->last_mode != nl_band->nla_type) {
1294 mode = os_realloc_array(phy_info->modes,
1295 *phy_info->num_modes + 1,
1296 sizeof(*mode));
747ba106
JM
1297 if (!mode) {
1298 phy_info->failed = 1;
1299 return NL_STOP;
1300 }
0fafeb54
JM
1301 phy_info->modes = mode;
1302
1303 mode = &phy_info->modes[*(phy_info->num_modes)];
1304 os_memset(mode, 0, sizeof(*mode));
1305 mode->mode = NUM_HOSTAPD_MODES;
1306 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
1307 HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
1308
1309 /*
1310 * Unsupported VHT MCS stream is defined as value 3, so the VHT
1311 * MCS RX/TX map must be initialized with 0xffff to mark all 8
1312 * possible streams as unsupported. This will be overridden if
1313 * driver advertises VHT support.
1314 */
1315 mode->vht_mcs_set[0] = 0xff;
1316 mode->vht_mcs_set[1] = 0xff;
1317 mode->vht_mcs_set[4] = 0xff;
1318 mode->vht_mcs_set[5] = 0xff;
1319
1320 *(phy_info->num_modes) += 1;
1321 phy_info->last_mode = nl_band->nla_type;
1322 phy_info->last_chan_idx = 0;
1323 } else
1324 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
1325
1326 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
1327 nla_len(nl_band), NULL);
1328
1329 phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
1330 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
1331 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
1332 tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
1333 phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
1334 tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
1335 ret = phy_info_freqs(phy_info, mode, tb_band[NL80211_BAND_ATTR_FREQS]);
747ba106
JM
1336 if (ret == NL_OK)
1337 ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
1338 if (ret != NL_OK) {
1339 phy_info->failed = 1;
0fafeb54 1340 return ret;
747ba106 1341 }
0fafeb54
JM
1342
1343 return NL_OK;
1344}
1345
1346
1347static int phy_info_handler(struct nl_msg *msg, void *arg)
1348{
1349 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
1350 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1351 struct phy_info_arg *phy_info = arg;
1352 struct nlattr *nl_band;
1353 int rem_band;
1354
1355 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1356 genlmsg_attrlen(gnlh, 0), NULL);
1357
1358 if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
1359 return NL_SKIP;
1360
1361 nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
1362 {
1363 int res = phy_info_band(phy_info, nl_band);
1364 if (res != NL_OK)
1365 return res;
1366 }
1367
1368 return NL_SKIP;
1369}
1370
1371
1372static struct hostapd_hw_modes *
1373wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
1374 u16 *num_modes)
1375{
1376 u16 m;
1377 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
1378 int i, mode11g_idx = -1;
1379
1380 /* heuristic to set up modes */
1381 for (m = 0; m < *num_modes; m++) {
1382 if (!modes[m].num_channels)
1383 continue;
1384 if (modes[m].channels[0].freq < 4000) {
1385 modes[m].mode = HOSTAPD_MODE_IEEE80211B;
1386 for (i = 0; i < modes[m].num_rates; i++) {
1387 if (modes[m].rates[i] > 200) {
1388 modes[m].mode = HOSTAPD_MODE_IEEE80211G;
1389 break;
1390 }
1391 }
1392 } else if (modes[m].channels[0].freq > 50000)
1393 modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
1394 else
1395 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
1396 }
1397
1398 /* If only 802.11g mode is included, use it to construct matching
1399 * 802.11b mode data. */
1400
1401 for (m = 0; m < *num_modes; m++) {
1402 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
1403 return modes; /* 802.11b already included */
1404 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
1405 mode11g_idx = m;
1406 }
1407
1408 if (mode11g_idx < 0)
1409 return modes; /* 2.4 GHz band not supported at all */
1410
1411 nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
1412 if (nmodes == NULL)
1413 return modes; /* Could not add 802.11b mode */
1414
1415 mode = &nmodes[*num_modes];
1416 os_memset(mode, 0, sizeof(*mode));
1417 (*num_modes)++;
1418 modes = nmodes;
1419
1420 mode->mode = HOSTAPD_MODE_IEEE80211B;
1421
1422 mode11g = &modes[mode11g_idx];
1423 mode->num_channels = mode11g->num_channels;
1424 mode->channels = os_malloc(mode11g->num_channels *
1425 sizeof(struct hostapd_channel_data));
1426 if (mode->channels == NULL) {
1427 (*num_modes)--;
1428 return modes; /* Could not add 802.11b mode */
1429 }
1430 os_memcpy(mode->channels, mode11g->channels,
1431 mode11g->num_channels * sizeof(struct hostapd_channel_data));
1432
1433 mode->num_rates = 0;
1434 mode->rates = os_malloc(4 * sizeof(int));
1435 if (mode->rates == NULL) {
1436 os_free(mode->channels);
1437 (*num_modes)--;
1438 return modes; /* Could not add 802.11b mode */
1439 }
1440
1441 for (i = 0; i < mode11g->num_rates; i++) {
1442 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
1443 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
1444 continue;
1445 mode->rates[mode->num_rates] = mode11g->rates[i];
1446 mode->num_rates++;
1447 if (mode->num_rates == 4)
1448 break;
1449 }
1450
1451 if (mode->num_rates == 0) {
1452 os_free(mode->channels);
1453 os_free(mode->rates);
1454 (*num_modes)--;
1455 return modes; /* No 802.11b rates */
1456 }
1457
1458 wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
1459 "information");
1460
1461 return modes;
1462}
1463
1464
1465static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
1466 int end)
1467{
1468 int c;
1469
1470 for (c = 0; c < mode->num_channels; c++) {
1471 struct hostapd_channel_data *chan = &mode->channels[c];
1472 if (chan->freq - 10 >= start && chan->freq + 10 <= end)
1473 chan->flag |= HOSTAPD_CHAN_HT40;
1474 }
1475}
1476
1477
1478static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
1479 int end)
1480{
1481 int c;
1482
1483 for (c = 0; c < mode->num_channels; c++) {
1484 struct hostapd_channel_data *chan = &mode->channels[c];
1485 if (!(chan->flag & HOSTAPD_CHAN_HT40))
1486 continue;
1487 if (chan->freq - 30 >= start && chan->freq - 10 <= end)
1488 chan->flag |= HOSTAPD_CHAN_HT40MINUS;
1489 if (chan->freq + 10 >= start && chan->freq + 30 <= end)
1490 chan->flag |= HOSTAPD_CHAN_HT40PLUS;
1491 }
1492}
1493
1494
1495static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
1496 struct phy_info_arg *results)
1497{
1498 u16 m;
1499
1500 for (m = 0; m < *results->num_modes; m++) {
1501 int c;
1502 struct hostapd_hw_modes *mode = &results->modes[m];
1503
1504 for (c = 0; c < mode->num_channels; c++) {
1505 struct hostapd_channel_data *chan = &mode->channels[c];
1506 if ((u32) chan->freq - 10 >= start &&
1507 (u32) chan->freq + 10 <= end)
1508 chan->max_tx_power = max_eirp;
1509 }
1510 }
1511}
1512
1513
1514static void nl80211_reg_rule_ht40(u32 start, u32 end,
1515 struct phy_info_arg *results)
1516{
1517 u16 m;
1518
1519 for (m = 0; m < *results->num_modes; m++) {
1520 if (!(results->modes[m].ht_capab &
1521 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
1522 continue;
1523 nl80211_set_ht40_mode(&results->modes[m], start, end);
1524 }
1525}
1526
1527
1528static void nl80211_reg_rule_sec(struct nlattr *tb[],
1529 struct phy_info_arg *results)
1530{
1531 u32 start, end, max_bw;
1532 u16 m;
1533
1534 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
1535 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
1536 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
1537 return;
1538
1539 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
1540 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
1541 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
1542
1543 if (max_bw < 20)
1544 return;
1545
1546 for (m = 0; m < *results->num_modes; m++) {
1547 if (!(results->modes[m].ht_capab &
1548 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
1549 continue;
1550 nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
1551 }
1552}
1553
1554
1555static void nl80211_set_vht_mode(struct hostapd_hw_modes *mode, int start,
bee5d8e0 1556 int end, int max_bw)
0fafeb54
JM
1557{
1558 int c;
1559
1560 for (c = 0; c < mode->num_channels; c++) {
1561 struct hostapd_channel_data *chan = &mode->channels[c];
1562 if (chan->freq - 10 >= start && chan->freq + 70 <= end)
1563 chan->flag |= HOSTAPD_CHAN_VHT_10_70;
1564
1565 if (chan->freq - 30 >= start && chan->freq + 50 <= end)
1566 chan->flag |= HOSTAPD_CHAN_VHT_30_50;
1567
1568 if (chan->freq - 50 >= start && chan->freq + 30 <= end)
1569 chan->flag |= HOSTAPD_CHAN_VHT_50_30;
1570
1571 if (chan->freq - 70 >= start && chan->freq + 10 <= end)
1572 chan->flag |= HOSTAPD_CHAN_VHT_70_10;
bee5d8e0
AK
1573
1574 if (max_bw >= 160) {
1575 if (chan->freq - 10 >= start && chan->freq + 150 <= end)
1576 chan->flag |= HOSTAPD_CHAN_VHT_10_150;
1577
1578 if (chan->freq - 30 >= start && chan->freq + 130 <= end)
1579 chan->flag |= HOSTAPD_CHAN_VHT_30_130;
1580
1581 if (chan->freq - 50 >= start && chan->freq + 110 <= end)
1582 chan->flag |= HOSTAPD_CHAN_VHT_50_110;
1583
1584 if (chan->freq - 70 >= start && chan->freq + 90 <= end)
1585 chan->flag |= HOSTAPD_CHAN_VHT_70_90;
1586
1587 if (chan->freq - 90 >= start && chan->freq + 70 <= end)
1588 chan->flag |= HOSTAPD_CHAN_VHT_90_70;
1589
1590 if (chan->freq - 110 >= start && chan->freq + 50 <= end)
1591 chan->flag |= HOSTAPD_CHAN_VHT_110_50;
1592
1593 if (chan->freq - 130 >= start && chan->freq + 30 <= end)
1594 chan->flag |= HOSTAPD_CHAN_VHT_130_30;
1595
1596 if (chan->freq - 150 >= start && chan->freq + 10 <= end)
1597 chan->flag |= HOSTAPD_CHAN_VHT_150_10;
1598 }
0fafeb54
JM
1599 }
1600}
1601
1602
1603static void nl80211_reg_rule_vht(struct nlattr *tb[],
1604 struct phy_info_arg *results)
1605{
1606 u32 start, end, max_bw;
1607 u16 m;
1608
1609 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
1610 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
1611 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
1612 return;
1613
1614 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
1615 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
1616 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
1617
1618 if (max_bw < 80)
1619 return;
1620
1621 for (m = 0; m < *results->num_modes; m++) {
1622 if (!(results->modes[m].ht_capab &
1623 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
1624 continue;
1625 /* TODO: use a real VHT support indication */
1626 if (!results->modes[m].vht_capab)
1627 continue;
1628
bee5d8e0 1629 nl80211_set_vht_mode(&results->modes[m], start, end, max_bw);
0fafeb54
JM
1630 }
1631}
1632
1633
1634static const char * dfs_domain_name(enum nl80211_dfs_regions region)
1635{
1636 switch (region) {
1637 case NL80211_DFS_UNSET:
1638 return "DFS-UNSET";
1639 case NL80211_DFS_FCC:
1640 return "DFS-FCC";
1641 case NL80211_DFS_ETSI:
1642 return "DFS-ETSI";
1643 case NL80211_DFS_JP:
1644 return "DFS-JP";
1645 default:
1646 return "DFS-invalid";
1647 }
1648}
1649
1650
1651static int nl80211_get_reg(struct nl_msg *msg, void *arg)
1652{
1653 struct phy_info_arg *results = arg;
1654 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
1655 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1656 struct nlattr *nl_rule;
1657 struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
1658 int rem_rule;
1659 static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
1660 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
1661 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
1662 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
1663 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
1664 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
1665 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
1666 };
1667
1668 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1669 genlmsg_attrlen(gnlh, 0), NULL);
1670 if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
1671 !tb_msg[NL80211_ATTR_REG_RULES]) {
1672 wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
1673 "available");
1674 return NL_SKIP;
1675 }
1676
1677 if (tb_msg[NL80211_ATTR_DFS_REGION]) {
1678 enum nl80211_dfs_regions dfs_domain;
1679 dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
1680 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
1681 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
1682 dfs_domain_name(dfs_domain));
1683 } else {
1684 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
1685 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
1686 }
1687
1688 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
1689 {
1690 u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
1691 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
1692 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
1693 if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
1694 tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
1695 continue;
1696 start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
1697 end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
1698 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
1699 max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
1700 if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
1701 max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
1702 if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
1703 flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
1704
1705 wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
1706 start, end, max_bw, max_eirp,
1707 flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
1708 flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
1709 flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
1710 flags & NL80211_RRF_NO_OUTDOOR ? " (no outdoor)" :
1711 "",
1712 flags & NL80211_RRF_DFS ? " (DFS)" : "",
1713 flags & NL80211_RRF_PTP_ONLY ? " (PTP only)" : "",
1714 flags & NL80211_RRF_PTMP_ONLY ? " (PTMP only)" : "",
1715 flags & NL80211_RRF_NO_IR ? " (no IR)" : "");
1716 if (max_bw >= 40)
1717 nl80211_reg_rule_ht40(start, end, results);
1718 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
1719 nl80211_reg_rule_max_eirp(start, end, max_eirp,
1720 results);
1721 }
1722
1723 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
1724 {
1725 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
1726 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
1727 nl80211_reg_rule_sec(tb_rule, results);
1728 }
1729
1730 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
1731 {
1732 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
1733 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
1734 nl80211_reg_rule_vht(tb_rule, results);
1735 }
1736
1737 return NL_SKIP;
1738}
1739
1740
1741static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
1742 struct phy_info_arg *results)
1743{
1744 struct nl_msg *msg;
1745
1746 msg = nlmsg_alloc();
1747 if (!msg)
1748 return -ENOMEM;
1749
1750 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
1751 return send_and_recv_msgs(drv, msg, nl80211_get_reg, results);
1752}
1753
1754
1755struct hostapd_hw_modes *
1756nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
1757{
1758 u32 feat;
1759 struct i802_bss *bss = priv;
1760 struct wpa_driver_nl80211_data *drv = bss->drv;
9589a91e 1761 int nl_flags = 0;
0fafeb54
JM
1762 struct nl_msg *msg;
1763 struct phy_info_arg result = {
1764 .num_modes = num_modes,
1765 .modes = NULL,
1766 .last_mode = -1,
747ba106 1767 .failed = 0,
0fafeb54
JM
1768 };
1769
1770 *num_modes = 0;
1771 *flags = 0;
1772
0fafeb54
JM
1773 feat = get_nl80211_protocol_features(drv);
1774 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
9589a91e 1775 nl_flags = NLM_F_DUMP;
56f77852
JM
1776 if (!(msg = nl80211_cmd_msg(bss, nl_flags, NL80211_CMD_GET_WIPHY)) ||
1777 nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
9589a91e
JM
1778 nlmsg_free(msg);
1779 return NULL;
1780 }
0fafeb54
JM
1781
1782 if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
1783 nl80211_set_regulatory_flags(drv, &result);
747ba106
JM
1784 if (result.failed) {
1785 int i;
1786
1787 for (i = 0; result.modes && i < *num_modes; i++) {
1788 os_free(result.modes[i].channels);
1789 os_free(result.modes[i].rates);
1790 }
1791 os_free(result.modes);
517b5f92 1792 *num_modes = 0;
747ba106
JM
1793 return NULL;
1794 }
0fafeb54
JM
1795 return wpa_driver_nl80211_postprocess_modes(result.modes,
1796 num_modes);
1797 }
9589a91e 1798
0fafeb54
JM
1799 return NULL;
1800}