1 /*
2 * Driver interaction with Linux nl80211/cfg80211 - Capabilities
3 * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
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"
15 #include "common/ieee802_11_common.h"
16 #include "common/wpa_common.h"
17 #include "common/qca-vendor.h"
18 #include "common/qca-vendor-attr.h"
19 #include "common/brcm_vendor.h"
20 #include "driver_nl80211.h"
21
protocol_feature_handler(struct nl_msg * msg,void * arg)22 static 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
get_nl80211_protocol_features(struct wpa_driver_nl80211_data * drv)38 static 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)
45 return 0;
46
47 if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES)) {
48 nlmsg_free(msg);
49 return 0;
50 }
51
52 if (send_and_recv_msgs(drv, msg, protocol_feature_handler, &feat,
53 NULL, NULL) == 0)
54 return feat;
55
56 return 0;
57 }
58
59
60 struct wiphy_info_data {
61 struct wpa_driver_nl80211_data *drv;
62 struct wpa_driver_capa *capa;
63
64 unsigned int num_multichan_concurrent;
65
66 unsigned int error:1;
67 unsigned int device_ap_sme:1;
68 unsigned int poll_command_supported:1;
69 unsigned int data_tx_status:1;
70 unsigned int auth_supported:1;
71 unsigned int connect_supported:1;
72 unsigned int p2p_go_supported:1;
73 unsigned int p2p_client_supported:1;
74 unsigned int p2p_go_ctwindow_supported:1;
75 unsigned int p2p_concurrent:1;
76 unsigned int channel_switch_supported:1;
77 unsigned int set_qos_map_supported:1;
78 unsigned int have_low_prio_scan:1;
79 unsigned int wmm_ac_supported:1;
80 unsigned int mac_addr_rand_scan_supported:1;
81 unsigned int mac_addr_rand_sched_scan_supported:1;
82 unsigned int update_ft_ies_supported:1;
83 unsigned int has_key_mgmt:1;
84 unsigned int has_key_mgmt_iftype:1;
85 };
86
87
probe_resp_offload_support(int supp_protocols)88 static unsigned int probe_resp_offload_support(int supp_protocols)
89 {
90 unsigned int prot = 0;
91
92 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS)
93 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS;
94 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2)
95 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2;
96 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P)
97 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P;
98 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U)
99 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING;
100
101 return prot;
102 }
103
104
wiphy_info_supported_iftypes(struct wiphy_info_data * info,struct nlattr * tb)105 static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
106 struct nlattr *tb)
107 {
108 struct nlattr *nl_mode;
109 int i;
110
111 if (tb == NULL)
112 return;
113
114 nla_for_each_nested(nl_mode, tb, i) {
115 switch (nla_type(nl_mode)) {
116 case NL80211_IFTYPE_AP:
117 info->capa->flags |= WPA_DRIVER_FLAGS_AP;
118 break;
119 case NL80211_IFTYPE_MESH_POINT:
120 info->capa->flags |= WPA_DRIVER_FLAGS_MESH;
121 break;
122 case NL80211_IFTYPE_ADHOC:
123 info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
124 break;
125 case NL80211_IFTYPE_P2P_DEVICE:
126 info->capa->flags |=
127 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
128 break;
129 case NL80211_IFTYPE_P2P_GO:
130 info->p2p_go_supported = 1;
131 break;
132 case NL80211_IFTYPE_P2P_CLIENT:
133 info->p2p_client_supported = 1;
134 break;
135 }
136 }
137 }
138
139
wiphy_info_iface_comb_process(struct wiphy_info_data * info,struct nlattr * nl_combi)140 static int wiphy_info_iface_comb_process(struct wiphy_info_data *info,
141 struct nlattr *nl_combi)
142 {
143 struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
144 struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
145 struct nlattr *nl_limit, *nl_mode;
146 int err, rem_limit, rem_mode;
147 int combination_has_p2p = 0, combination_has_mgd = 0;
148 static struct nla_policy
149 iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
150 [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
151 [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
152 [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
153 [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
154 [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
155 },
156 iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
157 [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
158 [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
159 };
160
161 err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
162 nl_combi, iface_combination_policy);
163 if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
164 !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
165 !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
166 return 0; /* broken combination */
167
168 if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS])
169 info->capa->flags |= WPA_DRIVER_FLAGS_RADAR;
170
171 nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
172 rem_limit) {
173 err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
174 nl_limit, iface_limit_policy);
175 if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES])
176 return 0; /* broken combination */
177
178 nla_for_each_nested(nl_mode,
179 tb_limit[NL80211_IFACE_LIMIT_TYPES],
180 rem_mode) {
181 int ift = nla_type(nl_mode);
182 if (ift == NL80211_IFTYPE_P2P_GO ||
183 ift == NL80211_IFTYPE_P2P_CLIENT)
184 combination_has_p2p = 1;
185 if (ift == NL80211_IFTYPE_STATION)
186 combination_has_mgd = 1;
187 }
188 if (combination_has_p2p && combination_has_mgd)
189 break;
190 }
191
192 if (combination_has_p2p && combination_has_mgd) {
193 unsigned int num_channels =
194 nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
195
196 info->p2p_concurrent = 1;
197 if (info->num_multichan_concurrent < num_channels)
198 info->num_multichan_concurrent = num_channels;
199 }
200
201 return 0;
202 }
203
204
wiphy_info_iface_comb(struct wiphy_info_data * info,struct nlattr * tb)205 static void wiphy_info_iface_comb(struct wiphy_info_data *info,
206 struct nlattr *tb)
207 {
208 struct nlattr *nl_combi;
209 int rem_combi;
210
211 if (tb == NULL)
212 return;
213
214 nla_for_each_nested(nl_combi, tb, rem_combi) {
215 if (wiphy_info_iface_comb_process(info, nl_combi) > 0)
216 break;
217 }
218 }
219
220
wiphy_info_supp_cmds(struct wiphy_info_data * info,struct nlattr * tb)221 static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
222 struct nlattr *tb)
223 {
224 struct nlattr *nl_cmd;
225 int i;
226
227 if (tb == NULL)
228 return;
229
230 nla_for_each_nested(nl_cmd, tb, i) {
231 switch (nla_get_u32(nl_cmd)) {
232 case NL80211_CMD_AUTHENTICATE:
233 info->auth_supported = 1;
234 break;
235 case NL80211_CMD_CONNECT:
236 info->connect_supported = 1;
237 break;
238 case NL80211_CMD_START_SCHED_SCAN:
239 info->capa->sched_scan_supported = 1;
240 break;
241 case NL80211_CMD_PROBE_CLIENT:
242 info->poll_command_supported = 1;
243 break;
244 case NL80211_CMD_CHANNEL_SWITCH:
245 info->channel_switch_supported = 1;
246 break;
247 case NL80211_CMD_SET_QOS_MAP:
248 info->set_qos_map_supported = 1;
249 break;
250 case NL80211_CMD_UPDATE_FT_IES:
251 info->update_ft_ies_supported = 1;
252 break;
253 }
254 }
255 }
256
257
get_akm_suites_info(struct nlattr * tb)258 static unsigned int get_akm_suites_info(struct nlattr *tb)
259 {
260 int i, num;
261 unsigned int key_mgmt = 0;
262 u32 *akms;
263
264 if (!tb)
265 return 0;
266
267 num = nla_len(tb) / sizeof(u32);
268 akms = nla_data(tb);
269 for (i = 0; i < num; i++) {
270 switch (akms[i]) {
271 case RSN_AUTH_KEY_MGMT_UNSPEC_802_1X:
272 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
273 WPA_DRIVER_CAPA_KEY_MGMT_WPA2;
274 break;
275 case RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X:
276 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
277 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
278 break;
279 case RSN_AUTH_KEY_MGMT_FT_802_1X:
280 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT;
281 break;
282 case RSN_AUTH_KEY_MGMT_FT_PSK:
283 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
284 break;
285 case RSN_AUTH_KEY_MGMT_802_1X_SHA256:
286 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_802_1X_SHA256;
287 break;
288 case RSN_AUTH_KEY_MGMT_PSK_SHA256:
289 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256;
290 break;
291 case RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE:
292 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_TPK_HANDSHAKE;
293 break;
294 case RSN_AUTH_KEY_MGMT_FT_SAE:
295 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE;
296 break;
297 case RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384:
298 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_802_1X_SHA384;
299 break;
300 case RSN_AUTH_KEY_MGMT_CCKM:
301 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_CCKM;
302 break;
303 case RSN_AUTH_KEY_MGMT_OSEN:
304 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_OSEN;
305 break;
306 case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B:
307 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B;
308 break;
309 case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192:
310 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
311 break;
312 case RSN_AUTH_KEY_MGMT_OWE:
313 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_OWE;
314 break;
315 case RSN_AUTH_KEY_MGMT_DPP:
316 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_DPP;
317 break;
318 case RSN_AUTH_KEY_MGMT_FILS_SHA256:
319 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256;
320 break;
321 case RSN_AUTH_KEY_MGMT_FILS_SHA384:
322 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384;
323 break;
324 case RSN_AUTH_KEY_MGMT_FT_FILS_SHA256:
325 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256;
326 break;
327 case RSN_AUTH_KEY_MGMT_FT_FILS_SHA384:
328 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384;
329 break;
330 case RSN_AUTH_KEY_MGMT_SAE:
331 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SAE;
332 break;
333 }
334 }
335
336 return key_mgmt;
337 }
338
339
get_iface_akm_suites_info(struct wiphy_info_data * info,struct nlattr * nl_akms)340 static void get_iface_akm_suites_info(struct wiphy_info_data *info,
341 struct nlattr *nl_akms)
342 {
343 struct nlattr *tb[NL80211_IFTYPE_AKM_ATTR_MAX + 1];
344 struct nlattr *nl_iftype;
345 unsigned int key_mgmt;
346 int i;
347
348 if (!nl_akms)
349 return;
350
351 nla_parse(tb, NL80211_IFTYPE_AKM_ATTR_MAX,
352 nla_data(nl_akms), nla_len(nl_akms), NULL);
353
354 if (!tb[NL80211_IFTYPE_AKM_ATTR_IFTYPES] ||
355 !tb[NL80211_IFTYPE_AKM_ATTR_SUITES])
356 return;
357
358 info->has_key_mgmt_iftype = 1;
359 key_mgmt = get_akm_suites_info(tb[NL80211_IFTYPE_AKM_ATTR_SUITES]);
360
361 nla_for_each_nested(nl_iftype, tb[NL80211_IFTYPE_AKM_ATTR_IFTYPES], i) {
362 switch (nla_type(nl_iftype)) {
363 case NL80211_IFTYPE_ADHOC:
364 info->drv->capa.key_mgmt_iftype[WPA_IF_IBSS] = key_mgmt;
365 break;
366 case NL80211_IFTYPE_STATION:
367 info->drv->capa.key_mgmt_iftype[WPA_IF_STATION] =
368 key_mgmt;
369 break;
370 case NL80211_IFTYPE_AP:
371 info->drv->capa.key_mgmt_iftype[WPA_IF_AP_BSS] =
372 key_mgmt;
373 break;
374 case NL80211_IFTYPE_AP_VLAN:
375 info->drv->capa.key_mgmt_iftype[WPA_IF_AP_VLAN] =
376 key_mgmt;
377 break;
378 case NL80211_IFTYPE_MESH_POINT:
379 info->drv->capa.key_mgmt_iftype[WPA_IF_MESH] = key_mgmt;
380 break;
381 case NL80211_IFTYPE_P2P_CLIENT:
382 info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_CLIENT] =
383 key_mgmt;
384 break;
385 case NL80211_IFTYPE_P2P_GO:
386 info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_GO] =
387 key_mgmt;
388 break;
389 case NL80211_IFTYPE_P2P_DEVICE:
390 info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_DEVICE] =
391 key_mgmt;
392 break;
393 case NL80211_IFTYPE_NAN:
394 info->drv->capa.key_mgmt_iftype[WPA_IF_NAN] = key_mgmt;
395 break;
396 }
397 wpa_printf(MSG_DEBUG, "nl80211: %s supported key_mgmt 0x%x",
398 nl80211_iftype_str(nla_type(nl_iftype)),
399 key_mgmt);
400 }
401 }
402
403
wiphy_info_iftype_akm_suites(struct wiphy_info_data * info,struct nlattr * tb)404 static void wiphy_info_iftype_akm_suites(struct wiphy_info_data *info,
405 struct nlattr *tb)
406 {
407 struct nlattr *nl_if;
408 int rem_if;
409
410 if (!tb)
411 return;
412
413 nla_for_each_nested(nl_if, tb, rem_if)
414 get_iface_akm_suites_info(info, nl_if);
415 }
416
417
wiphy_info_akm_suites(struct wiphy_info_data * info,struct nlattr * tb)418 static void wiphy_info_akm_suites(struct wiphy_info_data *info,
419 struct nlattr *tb)
420 {
421 if (!tb)
422 return;
423
424 info->has_key_mgmt = 1;
425 info->capa->key_mgmt = get_akm_suites_info(tb);
426 wpa_printf(MSG_DEBUG, "nl80211: wiphy supported key_mgmt 0x%x",
427 info->capa->key_mgmt);
428 }
429
430
wiphy_info_cipher_suites(struct wiphy_info_data * info,struct nlattr * tb)431 static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
432 struct nlattr *tb)
433 {
434 int i, num;
435 u32 *ciphers;
436
437 if (tb == NULL)
438 return;
439
440 num = nla_len(tb) / sizeof(u32);
441 ciphers = nla_data(tb);
442 for (i = 0; i < num; i++) {
443 u32 c = ciphers[i];
444
445 wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
446 c >> 24, (c >> 16) & 0xff,
447 (c >> 8) & 0xff, c & 0xff);
448 switch (c) {
449 case RSN_CIPHER_SUITE_CCMP_256:
450 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
451 break;
452 case RSN_CIPHER_SUITE_GCMP_256:
453 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
454 break;
455 case RSN_CIPHER_SUITE_CCMP:
456 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
457 break;
458 case RSN_CIPHER_SUITE_GCMP:
459 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
460 break;
461 case RSN_CIPHER_SUITE_TKIP:
462 info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
463 break;
464 case RSN_CIPHER_SUITE_WEP104:
465 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
466 break;
467 case RSN_CIPHER_SUITE_WEP40:
468 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
469 break;
470 case RSN_CIPHER_SUITE_AES_128_CMAC:
471 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
472 break;
473 case RSN_CIPHER_SUITE_BIP_GMAC_128:
474 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
475 break;
476 case RSN_CIPHER_SUITE_BIP_GMAC_256:
477 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
478 break;
479 case RSN_CIPHER_SUITE_BIP_CMAC_256:
480 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
481 break;
482 case RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED:
483 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GTK_NOT_USED;
484 break;
485 }
486 }
487 }
488
489
wiphy_info_max_roc(struct wpa_driver_capa * capa,struct nlattr * tb)490 static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
491 struct nlattr *tb)
492 {
493 if (tb)
494 capa->max_remain_on_chan = nla_get_u32(tb);
495 }
496
497
wiphy_info_tdls(struct wpa_driver_capa * capa,struct nlattr * tdls,struct nlattr * ext_setup)498 static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
499 struct nlattr *ext_setup)
500 {
501 if (tdls == NULL)
502 return;
503
504 wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
505 capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
506
507 if (ext_setup) {
508 wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
509 capa->flags |= WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
510 }
511 }
512
513
ext_feature_isset(const u8 * ext_features,int ext_features_len,enum nl80211_ext_feature_index ftidx)514 static int ext_feature_isset(const u8 *ext_features, int ext_features_len,
515 enum nl80211_ext_feature_index ftidx)
516 {
517 u8 ft_byte;
518
519 if ((int) ftidx / 8 >= ext_features_len)
520 return 0;
521
522 ft_byte = ext_features[ftidx / 8];
523 return (ft_byte & BIT(ftidx % 8)) != 0;
524 }
525
526
wiphy_info_ext_feature_flags(struct wiphy_info_data * info,struct nlattr * tb)527 static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
528 struct nlattr *tb)
529 {
530 struct wpa_driver_capa *capa = info->capa;
531 u8 *ext_features;
532 int len;
533
534 if (tb == NULL)
535 return;
536
537 ext_features = nla_data(tb);
538 len = nla_len(tb);
539
540 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_VHT_IBSS))
541 capa->flags |= WPA_DRIVER_FLAGS_VHT_IBSS;
542
543 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_RRM))
544 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_RRM;
545
546 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_FILS_STA))
547 capa->flags |= WPA_DRIVER_FLAGS_SUPPORT_FILS;
548
549 if (ext_feature_isset(ext_features, len,
550 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
551 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_LEGACY;
552
553 if (ext_feature_isset(ext_features, len,
554 NL80211_EXT_FEATURE_BEACON_RATE_HT))
555 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_HT;
556
557 if (ext_feature_isset(ext_features, len,
558 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
559 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_VHT;
560
561 if (ext_feature_isset(ext_features, len,
562 NL80211_EXT_FEATURE_BEACON_RATE_HE))
563 capa->flags2 |= WPA_DRIVER_FLAGS2_BEACON_RATE_HE;
564
565 if (ext_feature_isset(ext_features, len,
566 NL80211_EXT_FEATURE_SET_SCAN_DWELL))
567 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL;
568
569 if (ext_feature_isset(ext_features, len,
570 NL80211_EXT_FEATURE_SCAN_START_TIME) &&
571 ext_feature_isset(ext_features, len,
572 NL80211_EXT_FEATURE_BSS_PARENT_TSF) &&
573 ext_feature_isset(ext_features, len,
574 NL80211_EXT_FEATURE_SET_SCAN_DWELL))
575 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT;
576 if (ext_feature_isset(ext_features, len,
577 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
578 capa->flags |= WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA;
579 if (ext_feature_isset(ext_features, len,
580 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
581 capa->flags |= WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED;
582 if (ext_feature_isset(ext_features, len,
583 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI))
584 capa->flags |= WPA_DRIVER_FLAGS_SCHED_SCAN_RELATIVE_RSSI;
585 if (ext_feature_isset(ext_features, len,
586 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD))
587 capa->flags |= WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD;
588
589 if (ext_feature_isset(ext_features, len,
590 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
591 capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK;
592 if (ext_feature_isset(ext_features, len,
593 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
594 capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
595
596 if (ext_feature_isset(ext_features, len,
597 NL80211_EXT_FEATURE_MFP_OPTIONAL))
598 capa->flags |= WPA_DRIVER_FLAGS_MFP_OPTIONAL;
599
600 if (ext_feature_isset(ext_features, len,
601 NL80211_EXT_FEATURE_DFS_OFFLOAD))
602 capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
603
604 #ifdef CONFIG_MBO
605 if (ext_feature_isset(ext_features, len,
606 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) &&
607 ext_feature_isset(ext_features, len,
608 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) &&
609 ext_feature_isset(ext_features, len,
610 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) &&
611 ext_feature_isset(
612 ext_features, len,
613 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION))
614 capa->flags |= WPA_DRIVER_FLAGS_OCE_STA;
615 #endif /* CONFIG_MBO */
616
617 if (ext_feature_isset(ext_features, len,
618 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
619 capa->flags |= WPA_DRIVER_FLAGS_FTM_RESPONDER;
620
621 if (ext_feature_isset(ext_features, len,
622 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
623 capa->flags |= WPA_DRIVER_FLAGS_CONTROL_PORT;
624 if (ext_feature_isset(ext_features, len,
625 NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH))
626 capa->flags2 |= WPA_DRIVER_FLAGS2_CONTROL_PORT_RX;
627 if (ext_feature_isset(
628 ext_features, len,
629 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS))
630 capa->flags2 |= WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS;
631
632 if (ext_feature_isset(ext_features, len,
633 NL80211_EXT_FEATURE_VLAN_OFFLOAD))
634 capa->flags |= WPA_DRIVER_FLAGS_VLAN_OFFLOAD;
635
636 if (ext_feature_isset(ext_features, len,
637 NL80211_EXT_FEATURE_CAN_REPLACE_PTK0))
638 capa->flags |= WPA_DRIVER_FLAGS_SAFE_PTK0_REKEYS;
639
640 if (ext_feature_isset(ext_features, len,
641 NL80211_EXT_FEATURE_BEACON_PROTECTION))
642 capa->flags |= WPA_DRIVER_FLAGS_BEACON_PROTECTION;
643
644 if (ext_feature_isset(ext_features, len,
645 NL80211_EXT_FEATURE_EXT_KEY_ID))
646 capa->flags |= WPA_DRIVER_FLAGS_EXTENDED_KEY_ID;
647
648 if (ext_feature_isset(ext_features, len,
649 NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS))
650 info->drv->multicast_registrations = 1;
651
652 if (ext_feature_isset(ext_features, len,
653 NL80211_EXT_FEATURE_FILS_DISCOVERY))
654 info->drv->fils_discovery = 1;
655
656 if (ext_feature_isset(ext_features, len,
657 NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP))
658 info->drv->unsol_bcast_probe_resp = 1;
659
660 if (ext_feature_isset(ext_features, len,
661 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
662 capa->flags2 |= WPA_DRIVER_FLAGS2_BEACON_PROTECTION_CLIENT;
663
664 if (ext_feature_isset(ext_features, len,
665 NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION))
666 capa->flags2 |= WPA_DRIVER_FLAGS2_OCV;
667
668 if (ext_feature_isset(ext_features, len,
669 NL80211_EXT_FEATURE_RADAR_BACKGROUND))
670 capa->flags2 |= WPA_DRIVER_RADAR_BACKGROUND;
671 }
672
673
wiphy_info_feature_flags(struct wiphy_info_data * info,struct nlattr * tb)674 static void wiphy_info_feature_flags(struct wiphy_info_data *info,
675 struct nlattr *tb)
676 {
677 u32 flags;
678 struct wpa_driver_capa *capa = info->capa;
679
680 if (tb == NULL)
681 return;
682
683 flags = nla_get_u32(tb);
684
685 if (flags & NL80211_FEATURE_SK_TX_STATUS)
686 info->data_tx_status = 1;
687
688 if (flags & NL80211_FEATURE_INACTIVITY_TIMER)
689 capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
690
691 if (flags & NL80211_FEATURE_SAE)
692 capa->flags |= WPA_DRIVER_FLAGS_SAE;
693
694 if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
695 capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
696
697 if (flags & NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)
698 capa->flags |= WPA_DRIVER_FLAGS_HT_2040_COEX;
699
700 if (flags & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) {
701 wpa_printf(MSG_DEBUG, "nl80211: TDLS channel switch");
702 capa->flags |= WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH;
703 }
704
705 if (flags & NL80211_FEATURE_P2P_GO_CTWIN)
706 info->p2p_go_ctwindow_supported = 1;
707
708 if (flags & NL80211_FEATURE_LOW_PRIORITY_SCAN)
709 info->have_low_prio_scan = 1;
710
711 if (flags & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)
712 info->mac_addr_rand_scan_supported = 1;
713
714 if (flags & NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR)
715 info->mac_addr_rand_sched_scan_supported = 1;
716
717 if (flags & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
718 info->wmm_ac_supported = 1;
719
720 if (flags & NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES)
721 capa->rrm_flags |= WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES;
722
723 if (flags & NL80211_FEATURE_WFA_TPC_IE_IN_PROBES)
724 capa->rrm_flags |= WPA_DRIVER_FLAGS_WFA_TPC_IE_IN_PROBES;
725
726 if (flags & NL80211_FEATURE_QUIET)
727 capa->rrm_flags |= WPA_DRIVER_FLAGS_QUIET;
728
729 if (flags & NL80211_FEATURE_TX_POWER_INSERTION)
730 capa->rrm_flags |= WPA_DRIVER_FLAGS_TX_POWER_INSERTION;
731
732 if (flags & NL80211_FEATURE_HT_IBSS)
733 capa->flags |= WPA_DRIVER_FLAGS_HT_IBSS;
734
735 if (flags & NL80211_FEATURE_FULL_AP_CLIENT_STATE)
736 capa->flags |= WPA_DRIVER_FLAGS_FULL_AP_CLIENT_STATE;
737 }
738
739
wiphy_info_probe_resp_offload(struct wpa_driver_capa * capa,struct nlattr * tb)740 static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
741 struct nlattr *tb)
742 {
743 u32 protocols;
744
745 if (tb == NULL)
746 return;
747
748 protocols = nla_get_u32(tb);
749 wpa_printf(MSG_DEBUG, "nl80211: Supports Probe Response offload in AP "
750 "mode");
751 capa->flags |= WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD;
752 capa->probe_resp_offloads = probe_resp_offload_support(protocols);
753 }
754
755
wiphy_info_wowlan_triggers(struct wpa_driver_capa * capa,struct nlattr * tb)756 static void wiphy_info_wowlan_triggers(struct wpa_driver_capa *capa,
757 struct nlattr *tb)
758 {
759 struct nlattr *triggers[MAX_NL80211_WOWLAN_TRIG + 1];
760
761 if (tb == NULL)
762 return;
763
764 if (nla_parse_nested(triggers, MAX_NL80211_WOWLAN_TRIG,
765 tb, NULL))
766 return;
767
768 if (triggers[NL80211_WOWLAN_TRIG_ANY])
769 capa->wowlan_triggers.any = 1;
770 if (triggers[NL80211_WOWLAN_TRIG_DISCONNECT])
771 capa->wowlan_triggers.disconnect = 1;
772 if (triggers[NL80211_WOWLAN_TRIG_MAGIC_PKT])
773 capa->wowlan_triggers.magic_pkt = 1;
774 if (triggers[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
775 capa->wowlan_triggers.gtk_rekey_failure = 1;
776 if (triggers[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
777 capa->wowlan_triggers.eap_identity_req = 1;
778 if (triggers[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
779 capa->wowlan_triggers.four_way_handshake = 1;
780 if (triggers[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
781 capa->wowlan_triggers.rfkill_release = 1;
782 }
783
784
wiphy_info_extended_capab(struct wpa_driver_nl80211_data * drv,struct nlattr * tb)785 static void wiphy_info_extended_capab(struct wpa_driver_nl80211_data *drv,
786 struct nlattr *tb)
787 {
788 int rem = 0, i;
789 struct nlattr *tb1[NL80211_ATTR_MAX + 1], *attr;
790
791 if (!tb || drv->num_iface_ext_capa == NL80211_IFTYPE_MAX)
792 return;
793
794 nla_for_each_nested(attr, tb, rem) {
795 unsigned int len;
796 struct drv_nl80211_ext_capa *capa;
797
798 nla_parse(tb1, NL80211_ATTR_MAX, nla_data(attr),
799 nla_len(attr), NULL);
800
801 if (!tb1[NL80211_ATTR_IFTYPE] ||
802 !tb1[NL80211_ATTR_EXT_CAPA] ||
803 !tb1[NL80211_ATTR_EXT_CAPA_MASK])
804 continue;
805
806 capa = &drv->iface_ext_capa[drv->num_iface_ext_capa];
807 capa->iftype = nla_get_u32(tb1[NL80211_ATTR_IFTYPE]);
808 wpa_printf(MSG_DEBUG,
809 "nl80211: Driver-advertised extended capabilities for interface type %s",
810 nl80211_iftype_str(capa->iftype));
811
812 len = nla_len(tb1[NL80211_ATTR_EXT_CAPA]);
813 capa->ext_capa = os_memdup(nla_data(tb1[NL80211_ATTR_EXT_CAPA]),
814 len);
815 if (!capa->ext_capa)
816 goto err;
817
818 capa->ext_capa_len = len;
819 wpa_hexdump(MSG_DEBUG, "nl80211: Extended capabilities",
820 capa->ext_capa, capa->ext_capa_len);
821
822 len = nla_len(tb1[NL80211_ATTR_EXT_CAPA_MASK]);
823 capa->ext_capa_mask =
824 os_memdup(nla_data(tb1[NL80211_ATTR_EXT_CAPA_MASK]),
825 len);
826 if (!capa->ext_capa_mask)
827 goto err;
828
829 wpa_hexdump(MSG_DEBUG, "nl80211: Extended capabilities mask",
830 capa->ext_capa_mask, capa->ext_capa_len);
831
832 drv->num_iface_ext_capa++;
833 if (drv->num_iface_ext_capa == NL80211_IFTYPE_MAX)
834 break;
835 }
836
837 return;
838
839 err:
840 /* Cleanup allocated memory on error */
841 for (i = 0; i < NL80211_IFTYPE_MAX; i++) {
842 os_free(drv->iface_ext_capa[i].ext_capa);
843 drv->iface_ext_capa[i].ext_capa = NULL;
844 os_free(drv->iface_ext_capa[i].ext_capa_mask);
845 drv->iface_ext_capa[i].ext_capa_mask = NULL;
846 drv->iface_ext_capa[i].ext_capa_len = 0;
847 }
848 drv->num_iface_ext_capa = 0;
849 }
850
851
wiphy_info_handler(struct nl_msg * msg,void * arg)852 static int wiphy_info_handler(struct nl_msg *msg, void *arg)
853 {
854 struct nlattr *tb[NL80211_ATTR_MAX + 1];
855 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
856 struct wiphy_info_data *info = arg;
857 struct wpa_driver_capa *capa = info->capa;
858 struct wpa_driver_nl80211_data *drv = info->drv;
859
860 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
861 genlmsg_attrlen(gnlh, 0), NULL);
862
863 if (tb[NL80211_ATTR_WIPHY])
864 drv->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
865
866 if (tb[NL80211_ATTR_WIPHY_NAME])
867 os_strlcpy(drv->phyname,
868 nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]),
869 sizeof(drv->phyname));
870 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
871 capa->max_scan_ssids =
872 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
873
874 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
875 capa->max_sched_scan_ssids =
876 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
877
878 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS] &&
879 tb[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL] &&
880 tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]) {
881 capa->max_sched_scan_plans =
882 nla_get_u32(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS]);
883
884 capa->max_sched_scan_plan_interval =
885 nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL]);
886
887 capa->max_sched_scan_plan_iterations =
888 nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]);
889 }
890
891 if (tb[NL80211_ATTR_MAX_MATCH_SETS])
892 capa->max_match_sets =
893 nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
894
895 if (tb[NL80211_ATTR_MAC_ACL_MAX])
896 capa->max_acl_mac_addrs =
897 nla_get_u32(tb[NL80211_ATTR_MAC_ACL_MAX]);
898
899 wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
900 wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
901 wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
902 wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
903 wiphy_info_akm_suites(info, tb[NL80211_ATTR_AKM_SUITES]);
904 wiphy_info_iftype_akm_suites(info, tb[NL80211_ATTR_IFTYPE_AKM_SUITES]);
905
906 if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
907 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
908 "off-channel TX");
909 capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
910 }
911
912 if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
913 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
914 capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
915 }
916
917 wiphy_info_max_roc(capa,
918 tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
919
920 if (tb[NL80211_ATTR_SUPPORT_AP_UAPSD])
921 capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
922
923 wiphy_info_tdls(capa, tb[NL80211_ATTR_TDLS_SUPPORT],
924 tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]);
925
926 if (tb[NL80211_ATTR_DEVICE_AP_SME]) {
927 u32 ap_sme_features_flags =
928 nla_get_u32(tb[NL80211_ATTR_DEVICE_AP_SME]);
929
930 if (ap_sme_features_flags & NL80211_AP_SME_SA_QUERY_OFFLOAD)
931 capa->flags2 |= WPA_DRIVER_FLAGS2_SA_QUERY_OFFLOAD_AP;
932
933 info->device_ap_sme = 1;
934 }
935
936 wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
937 wiphy_info_ext_feature_flags(info, tb[NL80211_ATTR_EXT_FEATURES]);
938 wiphy_info_probe_resp_offload(capa,
939 tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
940
941 if (tb[NL80211_ATTR_EXT_CAPA] && tb[NL80211_ATTR_EXT_CAPA_MASK] &&
942 drv->extended_capa == NULL) {
943 drv->extended_capa =
944 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
945 if (drv->extended_capa) {
946 os_memcpy(drv->extended_capa,
947 nla_data(tb[NL80211_ATTR_EXT_CAPA]),
948 nla_len(tb[NL80211_ATTR_EXT_CAPA]));
949 drv->extended_capa_len =
950 nla_len(tb[NL80211_ATTR_EXT_CAPA]);
951 wpa_hexdump(MSG_DEBUG,
952 "nl80211: Driver-advertised extended capabilities (default)",
953 drv->extended_capa, drv->extended_capa_len);
954 }
955 drv->extended_capa_mask =
956 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA_MASK]));
957 if (drv->extended_capa_mask) {
958 os_memcpy(drv->extended_capa_mask,
959 nla_data(tb[NL80211_ATTR_EXT_CAPA_MASK]),
960 nla_len(tb[NL80211_ATTR_EXT_CAPA_MASK]));
961 wpa_hexdump(MSG_DEBUG,
962 "nl80211: Driver-advertised extended capabilities mask (default)",
963 drv->extended_capa_mask,
964 drv->extended_capa_len);
965 } else {
966 os_free(drv->extended_capa);
967 drv->extended_capa = NULL;
968 drv->extended_capa_len = 0;
969 }
970 }
971
972 wiphy_info_extended_capab(drv, tb[NL80211_ATTR_IFTYPE_EXT_CAPA]);
973
974 if (tb[NL80211_ATTR_VENDOR_DATA]) {
975 struct nlattr *nl;
976 int rem;
977
978 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
979 struct nl80211_vendor_cmd_info *vinfo;
980 if (nla_len(nl) != sizeof(*vinfo)) {
981 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
982 continue;
983 }
984 vinfo = nla_data(nl);
985 if (vinfo->vendor_id == OUI_QCA) {
986 switch (vinfo->subcmd) {
987 case QCA_NL80211_VENDOR_SUBCMD_TEST:
988 drv->vendor_cmd_test_avail = 1;
989 break;
990 #ifdef CONFIG_DRIVER_NL80211_QCA
991 case QCA_NL80211_VENDOR_SUBCMD_ROAMING:
992 drv->roaming_vendor_cmd_avail = 1;
993 break;
994 case QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY:
995 drv->dfs_vendor_cmd_avail = 1;
996 break;
997 case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
998 drv->get_features_vendor_cmd_avail = 1;
999 break;
1000 case QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST:
1001 drv->get_pref_freq_list = 1;
1002 break;
1003 case QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL:
1004 drv->set_prob_oper_freq = 1;
1005 break;
1006 case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
1007 drv->capa.flags |=
1008 WPA_DRIVER_FLAGS_ACS_OFFLOAD;
1009 drv->qca_do_acs = 1;
1010 break;
1011 case QCA_NL80211_VENDOR_SUBCMD_SETBAND:
1012 drv->setband_vendor_cmd_avail = 1;
1013 break;
1014 case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
1015 drv->scan_vendor_cmd_avail = 1;
1016 break;
1017 case QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION:
1018 drv->set_wifi_conf_vendor_cmd_avail = 1;
1019 break;
1020 case QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS:
1021 drv->fetch_bss_trans_status = 1;
1022 break;
1023 case QCA_NL80211_VENDOR_SUBCMD_ROAM:
1024 drv->roam_vendor_cmd_avail = 1;
1025 break;
1026 case QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE:
1027 drv->add_sta_node_vendor_cmd_avail = 1;
1028 break;
1029 case QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO:
1030 drv->get_sta_info_vendor_cmd_avail = 1;
1031 break;
1032 #endif /* CONFIG_DRIVER_NL80211_QCA */
1033 }
1034 #if defined(CONFIG_DRIVER_NL80211_BRCM) || defined(CONFIG_DRIVER_NL80211_SYNA)
1035 } else if (vinfo->vendor_id == OUI_BRCM) {
1036 switch (vinfo->subcmd) {
1037 case BRCM_VENDOR_SCMD_ACS:
1038 drv->capa.flags |=
1039 WPA_DRIVER_FLAGS_ACS_OFFLOAD;
1040 drv->capa.flags |=
1041 WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;
1042 wpa_printf(MSG_DEBUG,
1043 "Enabled BRCM ACS");
1044 drv->brcm_do_acs = 1;
1045 break;
1046 case BRCM_VENDOR_SCMD_SET_PMK:
1047 drv->vendor_set_pmk = 1;
1048 break;
1049 default:
1050 break;
1051 }
1052 #endif /* CONFIG_DRIVER_NL80211_BRCM || CONFIG_DRIVER_NL80211_SYNA */
1053 }
1054 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
1055 vinfo->vendor_id, vinfo->subcmd);
1056 }
1057 }
1058
1059 if (tb[NL80211_ATTR_VENDOR_EVENTS]) {
1060 struct nlattr *nl;
1061 int rem;
1062
1063 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
1064 struct nl80211_vendor_cmd_info *vinfo;
1065 if (nla_len(nl) != sizeof(*vinfo)) {
1066 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
1067 continue;
1068 }
1069 vinfo = nla_data(nl);
1070 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u",
1071 vinfo->vendor_id, vinfo->subcmd);
1072 }
1073 }
1074
1075 wiphy_info_wowlan_triggers(capa,
1076 tb[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]);
1077
1078 if (tb[NL80211_ATTR_MAX_AP_ASSOC_STA])
1079 capa->max_stations =
1080 nla_get_u32(tb[NL80211_ATTR_MAX_AP_ASSOC_STA]);
1081
1082 if (tb[NL80211_ATTR_MAX_CSA_COUNTERS])
1083 capa->max_csa_counters =
1084 nla_get_u8(tb[NL80211_ATTR_MAX_CSA_COUNTERS]);
1085
1086 if (tb[NL80211_ATTR_WIPHY_SELF_MANAGED_REG])
1087 capa->flags |= WPA_DRIVER_FLAGS_SELF_MANAGED_REGULATORY;
1088
1089 return NL_SKIP;
1090 }
1091
1092
wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data * drv,struct wiphy_info_data * info)1093 static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
1094 struct wiphy_info_data *info)
1095 {
1096 u32 feat;
1097 struct nl_msg *msg;
1098 int flags = 0;
1099
1100 os_memset(info, 0, sizeof(*info));
1101 info->capa = &drv->capa;
1102 info->drv = drv;
1103
1104 feat = get_nl80211_protocol_features(drv);
1105 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
1106 flags = NLM_F_DUMP;
1107 msg = nl80211_cmd_msg(drv->first_bss, flags, NL80211_CMD_GET_WIPHY);
1108 if (!msg || nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
1109 nlmsg_free(msg);
1110 return -1;
1111 }
1112
1113 if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info, NULL, NULL))
1114 return -1;
1115
1116 if (info->auth_supported)
1117 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
1118 else if (!info->connect_supported) {
1119 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
1120 "authentication/association or connect commands");
1121 info->error = 1;
1122 }
1123
1124 if (info->p2p_go_supported && info->p2p_client_supported)
1125 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
1126 if (info->p2p_concurrent) {
1127 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
1128 "interface (driver advertised support)");
1129 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
1130 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
1131 }
1132 if (info->num_multichan_concurrent > 1) {
1133 wpa_printf(MSG_DEBUG, "nl80211: Enable multi-channel "
1134 "concurrent (driver advertised support)");
1135 drv->capa.num_multichan_concurrent =
1136 info->num_multichan_concurrent;
1137 }
1138 if (drv->capa.flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
1139 wpa_printf(MSG_DEBUG, "nl80211: use P2P_DEVICE support");
1140
1141 /* default to 5000 since early versions of mac80211 don't set it */
1142 if (!drv->capa.max_remain_on_chan)
1143 drv->capa.max_remain_on_chan = 5000;
1144
1145 drv->capa.wmm_ac_supported = info->wmm_ac_supported;
1146
1147 drv->capa.mac_addr_rand_sched_scan_supported =
1148 info->mac_addr_rand_sched_scan_supported;
1149 drv->capa.mac_addr_rand_scan_supported =
1150 info->mac_addr_rand_scan_supported;
1151
1152 if (info->channel_switch_supported) {
1153 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_CSA;
1154 if (!drv->capa.max_csa_counters)
1155 drv->capa.max_csa_counters = 1;
1156 }
1157
1158 if (!drv->capa.max_sched_scan_plans) {
1159 drv->capa.max_sched_scan_plans = 1;
1160 drv->capa.max_sched_scan_plan_interval = UINT32_MAX;
1161 drv->capa.max_sched_scan_plan_iterations = 0;
1162 }
1163
1164 if (info->update_ft_ies_supported)
1165 drv->capa.flags |= WPA_DRIVER_FLAGS_UPDATE_FT_IES;
1166
1167 return 0;
1168 }
1169
1170
1171 #ifdef CONFIG_DRIVER_NL80211_QCA
1172
dfs_info_handler(struct nl_msg * msg,void * arg)1173 static int dfs_info_handler(struct nl_msg *msg, void *arg)
1174 {
1175 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1176 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1177 int *dfs_capability_ptr = arg;
1178
1179 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1180 genlmsg_attrlen(gnlh, 0), NULL);
1181
1182 if (tb[NL80211_ATTR_VENDOR_DATA]) {
1183 struct nlattr *nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
1184 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
1185
1186 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
1187 nla_data(nl_vend), nla_len(nl_vend), NULL);
1188
1189 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]) {
1190 u32 val;
1191 val = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]);
1192 wpa_printf(MSG_DEBUG, "nl80211: DFS offload capability: %u",
1193 val);
1194 *dfs_capability_ptr = val;
1195 }
1196 }
1197
1198 return NL_SKIP;
1199 }
1200
1201
qca_nl80211_check_dfs_capa(struct wpa_driver_nl80211_data * drv)1202 static void qca_nl80211_check_dfs_capa(struct wpa_driver_nl80211_data *drv)
1203 {
1204 struct nl_msg *msg;
1205 int dfs_capability = 0;
1206 int ret;
1207
1208 if (!drv->dfs_vendor_cmd_avail)
1209 return;
1210
1211 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
1212 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
1213 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
1214 QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY)) {
1215 nlmsg_free(msg);
1216 return;
1217 }
1218
1219 ret = send_and_recv_msgs(drv, msg, dfs_info_handler, &dfs_capability,
1220 NULL, NULL);
1221 if (!ret && dfs_capability)
1222 drv->capa.flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
1223 }
1224
1225
1226 struct features_info {
1227 u8 *flags;
1228 size_t flags_len;
1229 struct wpa_driver_capa *capa;
1230 };
1231
1232
features_info_handler(struct nl_msg * msg,void * arg)1233 static int features_info_handler(struct nl_msg *msg, void *arg)
1234 {
1235 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1236 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1237 struct features_info *info = arg;
1238 struct nlattr *nl_vend, *attr;
1239
1240 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1241 genlmsg_attrlen(gnlh, 0), NULL);
1242
1243 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
1244 if (nl_vend) {
1245 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
1246
1247 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
1248 nla_data(nl_vend), nla_len(nl_vend), NULL);
1249
1250 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
1251 if (attr) {
1252 int len = nla_len(attr);
1253 info->flags = os_malloc(len);
1254 if (info->flags != NULL) {
1255 os_memcpy(info->flags, nla_data(attr), len);
1256 info->flags_len = len;
1257 }
1258 }
1259 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA];
1260 if (attr)
1261 info->capa->conc_capab = nla_get_u32(attr);
1262
1263 attr = tb_vendor[
1264 QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND];
1265 if (attr)
1266 info->capa->max_conc_chan_2_4 = nla_get_u32(attr);
1267
1268 attr = tb_vendor[
1269 QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND];
1270 if (attr)
1271 info->capa->max_conc_chan_5_0 = nla_get_u32(attr);
1272 }
1273
1274 return NL_SKIP;
1275 }
1276
1277
check_feature(enum qca_wlan_vendor_features feature,struct features_info * info)1278 static int check_feature(enum qca_wlan_vendor_features feature,
1279 struct features_info *info)
1280 {
1281 size_t idx = feature / 8;
1282
1283 return (idx < info->flags_len) &&
1284 (info->flags[idx] & BIT(feature % 8));
1285 }
1286
1287
qca_nl80211_get_features(struct wpa_driver_nl80211_data * drv)1288 static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
1289 {
1290 struct nl_msg *msg;
1291 struct features_info info;
1292 int ret;
1293
1294 if (!drv->get_features_vendor_cmd_avail)
1295 return;
1296
1297 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
1298 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
1299 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
1300 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
1301 nlmsg_free(msg);
1302 return;
1303 }
1304
1305 os_memset(&info, 0, sizeof(info));
1306 info.capa = &drv->capa;
1307 ret = send_and_recv_msgs(drv, msg, features_info_handler, &info,
1308 NULL, NULL);
1309 if (ret || !info.flags)
1310 return;
1311
1312 if (check_feature(QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD, &info))
1313 drv->capa.flags |= WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD;
1314
1315 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY, &info))
1316 drv->capa.flags |= WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;
1317
1318 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS,
1319 &info))
1320 drv->capa.flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS;
1321 if (check_feature(QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD, &info))
1322 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_LISTEN_OFFLOAD;
1323 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OCE_STA, &info))
1324 drv->capa.flags |= WPA_DRIVER_FLAGS_OCE_STA;
1325 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OCE_AP, &info))
1326 drv->capa.flags |= WPA_DRIVER_FLAGS_OCE_AP;
1327 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON, &info))
1328 drv->capa.flags |= WPA_DRIVER_FLAGS_OCE_STA_CFON;
1329 os_free(info.flags);
1330 }
1331
1332 #endif /* CONFIG_DRIVER_NL80211_QCA */
1333
1334
wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data * drv)1335 int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
1336 {
1337 struct wiphy_info_data info;
1338 int i;
1339
1340 if (wpa_driver_nl80211_get_info(drv, &info))
1341 return -1;
1342
1343 if (info.error)
1344 return -1;
1345
1346 drv->has_capability = 1;
1347 drv->has_driver_key_mgmt = info.has_key_mgmt | info.has_key_mgmt_iftype;
1348
1349 /* Fallback to hardcoded defaults if the driver does not advertise any
1350 * AKM capabilities. */
1351 if (!drv->has_driver_key_mgmt) {
1352 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1353 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1354 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1355 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
1356 WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B |
1357 WPA_DRIVER_CAPA_KEY_MGMT_OWE |
1358 WPA_DRIVER_CAPA_KEY_MGMT_DPP;
1359
1360 if (drv->capa.enc & (WPA_DRIVER_CAPA_ENC_CCMP_256 |
1361 WPA_DRIVER_CAPA_ENC_GCMP_256))
1362 drv->capa.key_mgmt |=
1363 WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
1364
1365 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME)
1366 drv->capa.key_mgmt |=
1367 WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256 |
1368 WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384 |
1369 WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256 |
1370 WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384 |
1371 WPA_DRIVER_CAPA_KEY_MGMT_SAE;
1372 else if (drv->capa.flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)
1373 drv->capa.key_mgmt |=
1374 WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256 |
1375 WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384;
1376 }
1377
1378 if (!info.has_key_mgmt_iftype) {
1379 /* If the driver does not advertize per interface AKM
1380 * capabilities, consider all interfaces to support default AKMs
1381 * in key_mgmt. */
1382 for (i = 0; i < WPA_IF_MAX; i++)
1383 drv->capa.key_mgmt_iftype[i] = drv->capa.key_mgmt;
1384 } else if (info.has_key_mgmt_iftype && !info.has_key_mgmt) {
1385 /* If the driver advertizes only per interface supported AKMs
1386 * but does not advertize per wiphy AKM capabilities, consider
1387 * the default key_mgmt as a mask of per interface supported
1388 * AKMs. */
1389 drv->capa.key_mgmt = 0;
1390 for (i = 0; i < WPA_IF_MAX; i++)
1391 drv->capa.key_mgmt |= drv->capa.key_mgmt_iftype[i];
1392 } else if (info.has_key_mgmt_iftype && info.has_key_mgmt) {
1393 /* If the driver advertizes AKM capabilities both per wiphy and
1394 * per interface, consider the interfaces for which per
1395 * interface AKM capabilities were not received to support the
1396 * default key_mgmt capabilities.
1397 */
1398 for (i = 0; i < WPA_IF_MAX; i++)
1399 if (!drv->capa.key_mgmt_iftype[i])
1400 drv->capa.key_mgmt_iftype[i] =
1401 drv->capa.key_mgmt;
1402 }
1403
1404 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
1405 WPA_DRIVER_AUTH_SHARED |
1406 WPA_DRIVER_AUTH_LEAP;
1407
1408 drv->capa.flags |= WPA_DRIVER_FLAGS_VALID_ERROR_CODES;
1409 drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
1410 drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
1411
1412 /*
1413 * As all cfg80211 drivers must support cases where the AP interface is
1414 * removed without the knowledge of wpa_supplicant/hostapd, e.g., in
1415 * case that the user space daemon has crashed, they must be able to
1416 * cleanup all stations and key entries in the AP tear down flow. Thus,
1417 * this flag can/should always be set for cfg80211 drivers.
1418 */
1419 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT;
1420
1421 if (!info.device_ap_sme) {
1422 drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
1423 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_AP_SME;
1424
1425 /*
1426 * No AP SME is currently assumed to also indicate no AP MLME
1427 * in the driver/firmware.
1428 */
1429 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_MLME;
1430 }
1431
1432 drv->device_ap_sme = info.device_ap_sme;
1433 drv->poll_command_supported = info.poll_command_supported;
1434 drv->data_tx_status = info.data_tx_status;
1435 drv->p2p_go_ctwindow_supported = info.p2p_go_ctwindow_supported;
1436 if (info.set_qos_map_supported)
1437 drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
1438 drv->have_low_prio_scan = info.have_low_prio_scan;
1439
1440 /*
1441 * If poll command and tx status are supported, mac80211 is new enough
1442 * to have everything we need to not need monitor interfaces.
1443 */
1444 drv->use_monitor = !info.device_ap_sme &&
1445 (!info.poll_command_supported || !info.data_tx_status);
1446
1447 /*
1448 * If we aren't going to use monitor interfaces, but the
1449 * driver doesn't support data TX status, we won't get TX
1450 * status for EAPOL frames.
1451 */
1452 if (!drv->use_monitor && !info.data_tx_status)
1453 drv->capa.flags &= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
1454
1455 #ifdef CONFIG_DRIVER_NL80211_QCA
1456 if (!(info.capa->flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD))
1457 qca_nl80211_check_dfs_capa(drv);
1458 qca_nl80211_get_features(drv);
1459
1460 /*
1461 * To enable offchannel simultaneous support in wpa_supplicant, the
1462 * underlying driver needs to support the same along with offchannel TX.
1463 * Offchannel TX support is needed since remain_on_channel and
1464 * action_tx use some common data structures and hence cannot be
1465 * scheduled simultaneously.
1466 */
1467 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX))
1468 drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS;
1469 #endif /* CONFIG_DRIVER_NL80211_QCA */
1470
1471 wpa_printf(MSG_DEBUG,
1472 "nl80211: key_mgmt=0x%x enc=0x%x auth=0x%x flags=0x%llx rrm_flags=0x%x probe_resp_offloads=0x%x max_stations=%u max_remain_on_chan=%u max_scan_ssids=%d",
1473 drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth,
1474 (unsigned long long) drv->capa.flags, drv->capa.rrm_flags,
1475 drv->capa.probe_resp_offloads, drv->capa.max_stations,
1476 drv->capa.max_remain_on_chan, drv->capa.max_scan_ssids);
1477 return 0;
1478 }
1479
1480
1481 struct phy_info_arg {
1482 u16 *num_modes;
1483 struct hostapd_hw_modes *modes;
1484 int last_mode, last_chan_idx;
1485 int failed;
1486 u8 dfs_domain;
1487 };
1488
phy_info_ht_capa(struct hostapd_hw_modes * mode,struct nlattr * capa,struct nlattr * ampdu_factor,struct nlattr * ampdu_density,struct nlattr * mcs_set)1489 static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
1490 struct nlattr *ampdu_factor,
1491 struct nlattr *ampdu_density,
1492 struct nlattr *mcs_set)
1493 {
1494 if (capa)
1495 mode->ht_capab = nla_get_u16(capa);
1496
1497 if (ampdu_factor)
1498 mode->a_mpdu_params |= nla_get_u8(ampdu_factor) & 0x03;
1499
1500 if (ampdu_density)
1501 mode->a_mpdu_params |= nla_get_u8(ampdu_density) << 2;
1502
1503 if (mcs_set && nla_len(mcs_set) >= 16) {
1504 u8 *mcs;
1505 mcs = nla_data(mcs_set);
1506 os_memcpy(mode->mcs_set, mcs, 16);
1507 }
1508 }
1509
1510
phy_info_vht_capa(struct hostapd_hw_modes * mode,struct nlattr * capa,struct nlattr * mcs_set)1511 static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
1512 struct nlattr *capa,
1513 struct nlattr *mcs_set)
1514 {
1515 if (capa)
1516 mode->vht_capab = nla_get_u32(capa);
1517
1518 if (mcs_set && nla_len(mcs_set) >= 8) {
1519 u8 *mcs;
1520 mcs = nla_data(mcs_set);
1521 os_memcpy(mode->vht_mcs_set, mcs, 8);
1522 }
1523 }
1524
1525
phy_info_edmg_capa(struct hostapd_hw_modes * mode,struct nlattr * bw_config,struct nlattr * channels)1526 static int phy_info_edmg_capa(struct hostapd_hw_modes *mode,
1527 struct nlattr *bw_config,
1528 struct nlattr *channels)
1529 {
1530 if (!bw_config || !channels)
1531 return NL_OK;
1532
1533 mode->edmg.bw_config = nla_get_u8(bw_config);
1534 mode->edmg.channels = nla_get_u8(channels);
1535
1536 if (!mode->edmg.channels || !mode->edmg.bw_config)
1537 return NL_STOP;
1538
1539 return NL_OK;
1540 }
1541
1542
cw2ecw(unsigned int cw)1543 static int cw2ecw(unsigned int cw)
1544 {
1545 int bit;
1546
1547 if (cw == 0)
1548 return 0;
1549
1550 for (bit = 1; cw != 1; bit++)
1551 cw >>= 1;
1552
1553 return bit;
1554 }
1555
1556
phy_info_freq(struct hostapd_hw_modes * mode,struct hostapd_channel_data * chan,struct nlattr * tb_freq[])1557 static void phy_info_freq(struct hostapd_hw_modes *mode,
1558 struct hostapd_channel_data *chan,
1559 struct nlattr *tb_freq[])
1560 {
1561 u8 channel;
1562
1563 os_memset(chan, 0, sizeof(*chan));
1564 chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
1565 chan->flag = 0;
1566 chan->allowed_bw = ~0;
1567 chan->dfs_cac_ms = 0;
1568 if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
1569 chan->chan = channel;
1570 else
1571 wpa_printf(MSG_DEBUG,
1572 "nl80211: No channel number found for frequency %u MHz",
1573 chan->freq);
1574
1575 if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
1576 chan->flag |= HOSTAPD_CHAN_DISABLED;
1577 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
1578 chan->flag |= HOSTAPD_CHAN_NO_IR;
1579 if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
1580 chan->flag |= HOSTAPD_CHAN_RADAR;
1581 if (tb_freq[NL80211_FREQUENCY_ATTR_INDOOR_ONLY])
1582 chan->flag |= HOSTAPD_CHAN_INDOOR_ONLY;
1583 if (tb_freq[NL80211_FREQUENCY_ATTR_GO_CONCURRENT])
1584 chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;
1585
1586 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_10MHZ])
1587 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_10;
1588 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_20MHZ])
1589 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_20;
1590 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS])
1591 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40P;
1592 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS])
1593 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40M;
1594 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_80MHZ])
1595 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80;
1596 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ])
1597 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160;
1598
1599 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
1600 enum nl80211_dfs_state state =
1601 nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
1602
1603 switch (state) {
1604 case NL80211_DFS_USABLE:
1605 chan->flag |= HOSTAPD_CHAN_DFS_USABLE;
1606 break;
1607 case NL80211_DFS_AVAILABLE:
1608 chan->flag |= HOSTAPD_CHAN_DFS_AVAILABLE;
1609 break;
1610 case NL80211_DFS_UNAVAILABLE:
1611 chan->flag |= HOSTAPD_CHAN_DFS_UNAVAILABLE;
1612 break;
1613 }
1614 }
1615
1616 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) {
1617 chan->dfs_cac_ms = nla_get_u32(
1618 tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]);
1619 }
1620
1621 chan->wmm_rules_valid = 0;
1622 if (tb_freq[NL80211_FREQUENCY_ATTR_WMM]) {
1623 static struct nla_policy wmm_policy[NL80211_WMMR_MAX + 1] = {
1624 [NL80211_WMMR_CW_MIN] = { .type = NLA_U16 },
1625 [NL80211_WMMR_CW_MAX] = { .type = NLA_U16 },
1626 [NL80211_WMMR_AIFSN] = { .type = NLA_U8 },
1627 [NL80211_WMMR_TXOP] = { .type = NLA_U16 },
1628 };
1629 static const u8 wmm_map[4] = {
1630 [NL80211_AC_BE] = WMM_AC_BE,
1631 [NL80211_AC_BK] = WMM_AC_BK,
1632 [NL80211_AC_VI] = WMM_AC_VI,
1633 [NL80211_AC_VO] = WMM_AC_VO,
1634 };
1635 struct nlattr *nl_wmm;
1636 struct nlattr *tb_wmm[NL80211_WMMR_MAX + 1];
1637 int rem_wmm, ac, count = 0;
1638
1639 nla_for_each_nested(nl_wmm, tb_freq[NL80211_FREQUENCY_ATTR_WMM],
1640 rem_wmm) {
1641 if (nla_parse_nested(tb_wmm, NL80211_WMMR_MAX, nl_wmm,
1642 wmm_policy)) {
1643 wpa_printf(MSG_DEBUG,
1644 "nl80211: Failed to parse WMM rules attribute");
1645 return;
1646 }
1647 if (!tb_wmm[NL80211_WMMR_CW_MIN] ||
1648 !tb_wmm[NL80211_WMMR_CW_MAX] ||
1649 !tb_wmm[NL80211_WMMR_AIFSN] ||
1650 !tb_wmm[NL80211_WMMR_TXOP]) {
1651 wpa_printf(MSG_DEBUG,
1652 "nl80211: Channel is missing WMM rule attribute");
1653 return;
1654 }
1655 ac = nl_wmm->nla_type;
1656 if ((unsigned int) ac >= ARRAY_SIZE(wmm_map)) {
1657 wpa_printf(MSG_DEBUG,
1658 "nl80211: Invalid AC value %d", ac);
1659 return;
1660 }
1661
1662 ac = wmm_map[ac];
1663 chan->wmm_rules[ac].min_cwmin =
1664 cw2ecw(nla_get_u16(
1665 tb_wmm[NL80211_WMMR_CW_MIN]));
1666 chan->wmm_rules[ac].min_cwmax =
1667 cw2ecw(nla_get_u16(
1668 tb_wmm[NL80211_WMMR_CW_MAX]));
1669 chan->wmm_rules[ac].min_aifs =
1670 nla_get_u8(tb_wmm[NL80211_WMMR_AIFSN]);
1671 chan->wmm_rules[ac].max_txop =
1672 nla_get_u16(tb_wmm[NL80211_WMMR_TXOP]) / 32;
1673 count++;
1674 }
1675
1676 /* Set valid flag if all the AC rules are present */
1677 if (count == WMM_AC_NUM)
1678 chan->wmm_rules_valid = 1;
1679 }
1680 }
1681
1682
phy_info_freqs(struct phy_info_arg * phy_info,struct hostapd_hw_modes * mode,struct nlattr * tb)1683 static int phy_info_freqs(struct phy_info_arg *phy_info,
1684 struct hostapd_hw_modes *mode, struct nlattr *tb)
1685 {
1686 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
1687 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
1688 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
1689 [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
1690 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
1691 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
1692 [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
1693 [NL80211_FREQUENCY_ATTR_NO_10MHZ] = { .type = NLA_FLAG },
1694 [NL80211_FREQUENCY_ATTR_NO_20MHZ] = { .type = NLA_FLAG },
1695 [NL80211_FREQUENCY_ATTR_NO_HT40_PLUS] = { .type = NLA_FLAG },
1696 [NL80211_FREQUENCY_ATTR_NO_HT40_MINUS] = { .type = NLA_FLAG },
1697 [NL80211_FREQUENCY_ATTR_NO_80MHZ] = { .type = NLA_FLAG },
1698 [NL80211_FREQUENCY_ATTR_NO_160MHZ] = { .type = NLA_FLAG },
1699 };
1700 int new_channels = 0;
1701 struct hostapd_channel_data *channel;
1702 struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
1703 struct nlattr *nl_freq;
1704 int rem_freq, idx;
1705
1706 if (tb == NULL)
1707 return NL_OK;
1708
1709 nla_for_each_nested(nl_freq, tb, rem_freq) {
1710 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
1711 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
1712 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
1713 continue;
1714 new_channels++;
1715 }
1716
1717 channel = os_realloc_array(mode->channels,
1718 mode->num_channels + new_channels,
1719 sizeof(struct hostapd_channel_data));
1720 if (!channel)
1721 return NL_STOP;
1722
1723 mode->channels = channel;
1724 mode->num_channels += new_channels;
1725
1726 idx = phy_info->last_chan_idx;
1727
1728 nla_for_each_nested(nl_freq, tb, rem_freq) {
1729 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
1730 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
1731 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
1732 continue;
1733 phy_info_freq(mode, &mode->channels[idx], tb_freq);
1734 idx++;
1735 }
1736 phy_info->last_chan_idx = idx;
1737
1738 return NL_OK;
1739 }
1740
1741
phy_info_rates(struct hostapd_hw_modes * mode,struct nlattr * tb)1742 static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
1743 {
1744 static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
1745 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
1746 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =
1747 { .type = NLA_FLAG },
1748 };
1749 struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
1750 struct nlattr *nl_rate;
1751 int rem_rate, idx;
1752
1753 if (tb == NULL)
1754 return NL_OK;
1755
1756 nla_for_each_nested(nl_rate, tb, rem_rate) {
1757 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
1758 nla_data(nl_rate), nla_len(nl_rate),
1759 rate_policy);
1760 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
1761 continue;
1762 mode->num_rates++;
1763 }
1764
1765 mode->rates = os_calloc(mode->num_rates, sizeof(int));
1766 if (!mode->rates)
1767 return NL_STOP;
1768
1769 idx = 0;
1770
1771 nla_for_each_nested(nl_rate, tb, rem_rate) {
1772 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
1773 nla_data(nl_rate), nla_len(nl_rate),
1774 rate_policy);
1775 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
1776 continue;
1777 mode->rates[idx] = nla_get_u32(
1778 tb_rate[NL80211_BITRATE_ATTR_RATE]);
1779 idx++;
1780 }
1781
1782 return NL_OK;
1783 }
1784
1785
phy_info_iftype_copy(struct hostapd_hw_modes * mode,enum ieee80211_op_mode opmode,struct nlattr ** tb,struct nlattr ** tb_flags)1786 static void phy_info_iftype_copy(struct hostapd_hw_modes *mode,
1787 enum ieee80211_op_mode opmode,
1788 struct nlattr **tb, struct nlattr **tb_flags)
1789 {
1790 enum nl80211_iftype iftype;
1791 size_t len;
1792 struct he_capabilities *he_capab = &mode->he_capab[opmode];
1793 struct eht_capabilities *eht_capab = &mode->eht_capab[opmode];
1794
1795 switch (opmode) {
1796 case IEEE80211_MODE_INFRA:
1797 iftype = NL80211_IFTYPE_STATION;
1798 break;
1799 case IEEE80211_MODE_IBSS:
1800 iftype = NL80211_IFTYPE_ADHOC;
1801 break;
1802 case IEEE80211_MODE_AP:
1803 iftype = NL80211_IFTYPE_AP;
1804 break;
1805 case IEEE80211_MODE_MESH:
1806 iftype = NL80211_IFTYPE_MESH_POINT;
1807 break;
1808 default:
1809 return;
1810 }
1811
1812 if (!nla_get_flag(tb_flags[iftype]))
1813 return;
1814
1815 he_capab->he_supported = 1;
1816
1817 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
1818 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
1819
1820 if (len > sizeof(he_capab->phy_cap))
1821 len = sizeof(he_capab->phy_cap);
1822 os_memcpy(he_capab->phy_cap,
1823 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
1824 len);
1825 }
1826
1827 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]) {
1828 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]);
1829
1830 if (len > sizeof(he_capab->mac_cap))
1831 len = sizeof(he_capab->mac_cap);
1832 os_memcpy(he_capab->mac_cap,
1833 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]),
1834 len);
1835 }
1836
1837 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]) {
1838 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]);
1839
1840 if (len > sizeof(he_capab->mcs))
1841 len = sizeof(he_capab->mcs);
1842 os_memcpy(he_capab->mcs,
1843 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]),
1844 len);
1845 }
1846
1847 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]) {
1848 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]);
1849
1850 if (len > sizeof(he_capab->ppet))
1851 len = sizeof(he_capab->ppet);
1852 os_memcpy(&he_capab->ppet,
1853 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]),
1854 len);
1855 }
1856
1857 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA]) {
1858 u16 capa;
1859
1860 capa = nla_get_u16(tb[NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA]);
1861 he_capab->he_6ghz_capa = le_to_host16(capa);
1862 }
1863
1864 if (!tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC] ||
1865 !tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY])
1866 return;
1867
1868 eht_capab->eht_supported = true;
1869
1870 if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC] &&
1871 nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]) >= 2) {
1872 const u8 *pos;
1873
1874 pos = nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]);
1875 eht_capab->mac_cap = WPA_GET_LE16(pos);
1876 }
1877
1878 if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) {
1879 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]);
1880 if (len > sizeof(eht_capab->phy_cap))
1881 len = sizeof(eht_capab->phy_cap);
1882 os_memcpy(eht_capab->phy_cap,
1883 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]),
1884 len);
1885 }
1886
1887 if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]) {
1888 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]);
1889 if (len > sizeof(eht_capab->mcs))
1890 len = sizeof(eht_capab->mcs);
1891 os_memcpy(eht_capab->mcs,
1892 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]),
1893 len);
1894 }
1895
1896 if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]) {
1897 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]);
1898 if (len > sizeof(eht_capab->ppet))
1899 len = sizeof(eht_capab->ppet);
1900 os_memcpy(&eht_capab->ppet,
1901 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]),
1902 len);
1903 }
1904 }
1905
1906
phy_info_iftype(struct hostapd_hw_modes * mode,struct nlattr * nl_iftype)1907 static int phy_info_iftype(struct hostapd_hw_modes *mode,
1908 struct nlattr *nl_iftype)
1909 {
1910 struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
1911 struct nlattr *tb_flags[NL80211_IFTYPE_MAX + 1];
1912 unsigned int i;
1913
1914 nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
1915 nla_data(nl_iftype), nla_len(nl_iftype), NULL);
1916
1917 if (!tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES])
1918 return NL_STOP;
1919
1920 if (nla_parse_nested(tb_flags, NL80211_IFTYPE_MAX,
1921 tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES], NULL))
1922 return NL_STOP;
1923
1924 for (i = 0; i < IEEE80211_MODE_NUM; i++)
1925 phy_info_iftype_copy(mode, i, tb, tb_flags);
1926
1927 return NL_OK;
1928 }
1929
1930
phy_info_band(struct phy_info_arg * phy_info,struct nlattr * nl_band)1931 static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
1932 {
1933 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
1934 struct hostapd_hw_modes *mode;
1935 int ret;
1936
1937 if (phy_info->last_mode != nl_band->nla_type) {
1938 mode = os_realloc_array(phy_info->modes,
1939 *phy_info->num_modes + 1,
1940 sizeof(*mode));
1941 if (!mode) {
1942 phy_info->failed = 1;
1943 return NL_STOP;
1944 }
1945 phy_info->modes = mode;
1946
1947 mode = &phy_info->modes[*(phy_info->num_modes)];
1948 os_memset(mode, 0, sizeof(*mode));
1949 mode->mode = NUM_HOSTAPD_MODES;
1950 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
1951 HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN;
1952
1953 /*
1954 * Unsupported VHT MCS stream is defined as value 3, so the VHT
1955 * MCS RX/TX map must be initialized with 0xffff to mark all 8
1956 * possible streams as unsupported. This will be overridden if
1957 * driver advertises VHT support.
1958 */
1959 mode->vht_mcs_set[0] = 0xff;
1960 mode->vht_mcs_set[1] = 0xff;
1961 mode->vht_mcs_set[4] = 0xff;
1962 mode->vht_mcs_set[5] = 0xff;
1963
1964 *(phy_info->num_modes) += 1;
1965 phy_info->last_mode = nl_band->nla_type;
1966 phy_info->last_chan_idx = 0;
1967 } else
1968 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
1969
1970 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
1971 nla_len(nl_band), NULL);
1972
1973 phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
1974 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
1975 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
1976 tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
1977 phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
1978 tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
1979 ret = phy_info_edmg_capa(mode,
1980 tb_band[NL80211_BAND_ATTR_EDMG_BW_CONFIG],
1981 tb_band[NL80211_BAND_ATTR_EDMG_CHANNELS]);
1982 if (ret == NL_OK)
1983 ret = phy_info_freqs(phy_info, mode,
1984 tb_band[NL80211_BAND_ATTR_FREQS]);
1985 if (ret == NL_OK)
1986 ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
1987 if (ret != NL_OK) {
1988 phy_info->failed = 1;
1989 return ret;
1990 }
1991
1992 if (tb_band[NL80211_BAND_ATTR_IFTYPE_DATA]) {
1993 struct nlattr *nl_iftype;
1994 int rem_band;
1995
1996 nla_for_each_nested(nl_iftype,
1997 tb_band[NL80211_BAND_ATTR_IFTYPE_DATA],
1998 rem_band) {
1999 ret = phy_info_iftype(mode, nl_iftype);
2000 if (ret != NL_OK)
2001 return ret;
2002 }
2003 }
2004
2005 return NL_OK;
2006 }
2007
2008
phy_info_handler(struct nl_msg * msg,void * arg)2009 static int phy_info_handler(struct nl_msg *msg, void *arg)
2010 {
2011 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
2012 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2013 struct phy_info_arg *phy_info = arg;
2014 struct nlattr *nl_band;
2015 int rem_band;
2016
2017 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2018 genlmsg_attrlen(gnlh, 0), NULL);
2019
2020 if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
2021 return NL_SKIP;
2022
2023 nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
2024 {
2025 int res = phy_info_band(phy_info, nl_band);
2026 if (res != NL_OK)
2027 return res;
2028 }
2029
2030 return NL_SKIP;
2031 }
2032
2033
2034 static struct hostapd_hw_modes *
wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes * modes,u16 * num_modes)2035 wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
2036 u16 *num_modes)
2037 {
2038 u16 m;
2039 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
2040 int i, mode11g_idx = -1;
2041
2042 /* heuristic to set up modes */
2043 for (m = 0; m < *num_modes; m++) {
2044 if (!modes[m].num_channels)
2045 continue;
2046 if (modes[m].channels[0].freq < 2000) {
2047 modes[m].num_channels = 0;
2048 continue;
2049 } else if (modes[m].channels[0].freq < 4000) {
2050 modes[m].mode = HOSTAPD_MODE_IEEE80211B;
2051 for (i = 0; i < modes[m].num_rates; i++) {
2052 if (modes[m].rates[i] > 200) {
2053 modes[m].mode = HOSTAPD_MODE_IEEE80211G;
2054 break;
2055 }
2056 }
2057 } else if (modes[m].channels[0].freq > 50000)
2058 modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
2059 else
2060 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
2061 }
2062
2063 /* Remove unsupported bands */
2064 m = 0;
2065 while (m < *num_modes) {
2066 if (modes[m].mode == NUM_HOSTAPD_MODES) {
2067 wpa_printf(MSG_DEBUG,
2068 "nl80211: Remove unsupported mode");
2069 os_free(modes[m].channels);
2070 os_free(modes[m].rates);
2071 if (m + 1 < *num_modes)
2072 os_memmove(&modes[m], &modes[m + 1],
2073 sizeof(struct hostapd_hw_modes) *
2074 (*num_modes - (m + 1)));
2075 (*num_modes)--;
2076 continue;
2077 }
2078 m++;
2079 }
2080
2081 /* If only 802.11g mode is included, use it to construct matching
2082 * 802.11b mode data. */
2083
2084 for (m = 0; m < *num_modes; m++) {
2085 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
2086 return modes; /* 802.11b already included */
2087 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
2088 mode11g_idx = m;
2089 }
2090
2091 if (mode11g_idx < 0)
2092 return modes; /* 2.4 GHz band not supported at all */
2093
2094 nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
2095 if (nmodes == NULL)
2096 return modes; /* Could not add 802.11b mode */
2097
2098 mode = &nmodes[*num_modes];
2099 os_memset(mode, 0, sizeof(*mode));
2100 (*num_modes)++;
2101 modes = nmodes;
2102
2103 mode->mode = HOSTAPD_MODE_IEEE80211B;
2104
2105 mode11g = &modes[mode11g_idx];
2106 mode->num_channels = mode11g->num_channels;
2107 mode->channels = os_memdup(mode11g->channels,
2108 mode11g->num_channels *
2109 sizeof(struct hostapd_channel_data));
2110 if (mode->channels == NULL) {
2111 (*num_modes)--;
2112 return modes; /* Could not add 802.11b mode */
2113 }
2114
2115 mode->num_rates = 0;
2116 mode->rates = os_malloc(4 * sizeof(int));
2117 if (mode->rates == NULL) {
2118 os_free(mode->channels);
2119 (*num_modes)--;
2120 return modes; /* Could not add 802.11b mode */
2121 }
2122
2123 for (i = 0; i < mode11g->num_rates; i++) {
2124 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
2125 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
2126 continue;
2127 mode->rates[mode->num_rates] = mode11g->rates[i];
2128 mode->num_rates++;
2129 if (mode->num_rates == 4)
2130 break;
2131 }
2132
2133 if (mode->num_rates == 0) {
2134 os_free(mode->channels);
2135 os_free(mode->rates);
2136 (*num_modes)--;
2137 return modes; /* No 802.11b rates */
2138 }
2139
2140 wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
2141 "information");
2142
2143 return modes;
2144 }
2145
2146
nl80211_set_ht40_mode(struct hostapd_hw_modes * mode,int start,int end)2147 static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
2148 int end)
2149 {
2150 int c;
2151
2152 for (c = 0; c < mode->num_channels; c++) {
2153 struct hostapd_channel_data *chan = &mode->channels[c];
2154 if (chan->freq - 10 >= start && chan->freq + 10 <= end)
2155 chan->flag |= HOSTAPD_CHAN_HT40;
2156 }
2157 }
2158
2159
nl80211_set_ht40_mode_sec(struct hostapd_hw_modes * mode,int start,int end)2160 static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
2161 int end)
2162 {
2163 int c;
2164
2165 for (c = 0; c < mode->num_channels; c++) {
2166 struct hostapd_channel_data *chan = &mode->channels[c];
2167 if (!(chan->flag & HOSTAPD_CHAN_HT40))
2168 continue;
2169 if (chan->freq - 30 >= start && chan->freq - 10 <= end)
2170 chan->flag |= HOSTAPD_CHAN_HT40MINUS;
2171 if (chan->freq + 10 >= start && chan->freq + 30 <= end)
2172 chan->flag |= HOSTAPD_CHAN_HT40PLUS;
2173 }
2174 }
2175
2176
nl80211_reg_rule_max_eirp(u32 start,u32 end,u32 max_eirp,struct phy_info_arg * results)2177 static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
2178 struct phy_info_arg *results)
2179 {
2180 u16 m;
2181
2182 for (m = 0; m < *results->num_modes; m++) {
2183 int c;
2184 struct hostapd_hw_modes *mode = &results->modes[m];
2185
2186 for (c = 0; c < mode->num_channels; c++) {
2187 struct hostapd_channel_data *chan = &mode->channels[c];
2188 if ((u32) chan->freq - 10 >= start &&
2189 (u32) chan->freq + 10 <= end)
2190 chan->max_tx_power = max_eirp;
2191 }
2192 }
2193 }
2194
2195
nl80211_reg_rule_ht40(u32 start,u32 end,struct phy_info_arg * results)2196 static void nl80211_reg_rule_ht40(u32 start, u32 end,
2197 struct phy_info_arg *results)
2198 {
2199 u16 m;
2200
2201 for (m = 0; m < *results->num_modes; m++) {
2202 if (!(results->modes[m].ht_capab &
2203 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
2204 continue;
2205 nl80211_set_ht40_mode(&results->modes[m], start, end);
2206 }
2207 }
2208
2209
nl80211_reg_rule_sec(struct nlattr * tb[],struct phy_info_arg * results)2210 static void nl80211_reg_rule_sec(struct nlattr *tb[],
2211 struct phy_info_arg *results)
2212 {
2213 u32 start, end, max_bw;
2214 u16 m;
2215
2216 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
2217 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
2218 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
2219 return;
2220
2221 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
2222 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
2223 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
2224
2225 if (max_bw < 20)
2226 return;
2227
2228 for (m = 0; m < *results->num_modes; m++) {
2229 if (!(results->modes[m].ht_capab &
2230 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
2231 continue;
2232 nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
2233 }
2234 }
2235
2236
nl80211_set_vht_mode(struct hostapd_hw_modes * mode,int start,int end,int max_bw)2237 static void nl80211_set_vht_mode(struct hostapd_hw_modes *mode, int start,
2238 int end, int max_bw)
2239 {
2240 int c;
2241
2242 for (c = 0; c < mode->num_channels; c++) {
2243 struct hostapd_channel_data *chan = &mode->channels[c];
2244 if (chan->freq - 10 >= start && chan->freq + 70 <= end)
2245 chan->flag |= HOSTAPD_CHAN_VHT_10_70;
2246
2247 if (chan->freq - 30 >= start && chan->freq + 50 <= end)
2248 chan->flag |= HOSTAPD_CHAN_VHT_30_50;
2249
2250 if (chan->freq - 50 >= start && chan->freq + 30 <= end)
2251 chan->flag |= HOSTAPD_CHAN_VHT_50_30;
2252
2253 if (chan->freq - 70 >= start && chan->freq + 10 <= end)
2254 chan->flag |= HOSTAPD_CHAN_VHT_70_10;
2255
2256 if (max_bw >= 160) {
2257 if (chan->freq - 10 >= start && chan->freq + 150 <= end)
2258 chan->flag |= HOSTAPD_CHAN_VHT_10_150;
2259
2260 if (chan->freq - 30 >= start && chan->freq + 130 <= end)
2261 chan->flag |= HOSTAPD_CHAN_VHT_30_130;
2262
2263 if (chan->freq - 50 >= start && chan->freq + 110 <= end)
2264 chan->flag |= HOSTAPD_CHAN_VHT_50_110;
2265
2266 if (chan->freq - 70 >= start && chan->freq + 90 <= end)
2267 chan->flag |= HOSTAPD_CHAN_VHT_70_90;
2268
2269 if (chan->freq - 90 >= start && chan->freq + 70 <= end)
2270 chan->flag |= HOSTAPD_CHAN_VHT_90_70;
2271
2272 if (chan->freq - 110 >= start && chan->freq + 50 <= end)
2273 chan->flag |= HOSTAPD_CHAN_VHT_110_50;
2274
2275 if (chan->freq - 130 >= start && chan->freq + 30 <= end)
2276 chan->flag |= HOSTAPD_CHAN_VHT_130_30;
2277
2278 if (chan->freq - 150 >= start && chan->freq + 10 <= end)
2279 chan->flag |= HOSTAPD_CHAN_VHT_150_10;
2280 }
2281 }
2282 }
2283
2284
nl80211_reg_rule_vht(struct nlattr * tb[],struct phy_info_arg * results)2285 static void nl80211_reg_rule_vht(struct nlattr *tb[],
2286 struct phy_info_arg *results)
2287 {
2288 u32 start, end, max_bw;
2289 u16 m;
2290
2291 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
2292 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
2293 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
2294 return;
2295
2296 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
2297 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
2298 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
2299
2300 if (max_bw < 80)
2301 return;
2302
2303 for (m = 0; m < *results->num_modes; m++) {
2304 if (!(results->modes[m].ht_capab &
2305 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
2306 continue;
2307 /* TODO: use a real VHT support indication */
2308 if (!results->modes[m].vht_capab)
2309 continue;
2310
2311 nl80211_set_vht_mode(&results->modes[m], start, end, max_bw);
2312 }
2313 }
2314
2315
nl80211_set_dfs_domain(enum nl80211_dfs_regions region,u8 * dfs_domain)2316 static void nl80211_set_dfs_domain(enum nl80211_dfs_regions region,
2317 u8 *dfs_domain)
2318 {
2319 if (region == NL80211_DFS_FCC)
2320 *dfs_domain = HOSTAPD_DFS_REGION_FCC;
2321 else if (region == NL80211_DFS_ETSI)
2322 *dfs_domain = HOSTAPD_DFS_REGION_ETSI;
2323 else if (region == NL80211_DFS_JP)
2324 *dfs_domain = HOSTAPD_DFS_REGION_JP;
2325 else
2326 *dfs_domain = 0;
2327 }
2328
2329
dfs_domain_name(enum nl80211_dfs_regions region)2330 static const char * dfs_domain_name(enum nl80211_dfs_regions region)
2331 {
2332 switch (region) {
2333 case NL80211_DFS_UNSET:
2334 return "DFS-UNSET";
2335 case NL80211_DFS_FCC:
2336 return "DFS-FCC";
2337 case NL80211_DFS_ETSI:
2338 return "DFS-ETSI";
2339 case NL80211_DFS_JP:
2340 return "DFS-JP";
2341 default:
2342 return "DFS-invalid";
2343 }
2344 }
2345
2346
nl80211_get_reg(struct nl_msg * msg,void * arg)2347 static int nl80211_get_reg(struct nl_msg *msg, void *arg)
2348 {
2349 struct phy_info_arg *results = arg;
2350 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
2351 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2352 struct nlattr *nl_rule;
2353 struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
2354 int rem_rule;
2355 static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
2356 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
2357 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
2358 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
2359 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
2360 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
2361 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
2362 };
2363
2364 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2365 genlmsg_attrlen(gnlh, 0), NULL);
2366 if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
2367 !tb_msg[NL80211_ATTR_REG_RULES]) {
2368 wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
2369 "available");
2370 return NL_SKIP;
2371 }
2372
2373 if (tb_msg[NL80211_ATTR_DFS_REGION]) {
2374 enum nl80211_dfs_regions dfs_domain;
2375 dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
2376 nl80211_set_dfs_domain(dfs_domain, &results->dfs_domain);
2377 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
2378 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
2379 dfs_domain_name(dfs_domain));
2380 } else {
2381 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
2382 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
2383 }
2384
2385 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
2386 {
2387 u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
2388 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
2389 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
2390 if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
2391 tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
2392 continue;
2393 start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
2394 end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
2395 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
2396 max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
2397 if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
2398 max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
2399 if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
2400 flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
2401
2402 wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
2403 start, end, max_bw, max_eirp,
2404 flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
2405 flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
2406 flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
2407 flags & NL80211_RRF_NO_OUTDOOR ? " (no outdoor)" :
2408 "",
2409 flags & NL80211_RRF_DFS ? " (DFS)" : "",
2410 flags & NL80211_RRF_PTP_ONLY ? " (PTP only)" : "",
2411 flags & NL80211_RRF_PTMP_ONLY ? " (PTMP only)" : "",
2412 flags & NL80211_RRF_NO_IR ? " (no IR)" : "");
2413 if (max_bw >= 40)
2414 nl80211_reg_rule_ht40(start, end, results);
2415 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
2416 nl80211_reg_rule_max_eirp(start, end, max_eirp,
2417 results);
2418 }
2419
2420 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
2421 {
2422 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
2423 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
2424 nl80211_reg_rule_sec(tb_rule, results);
2425 }
2426
2427 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
2428 {
2429 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
2430 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
2431 nl80211_reg_rule_vht(tb_rule, results);
2432 }
2433
2434 return NL_SKIP;
2435 }
2436
2437
nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data * drv,struct phy_info_arg * results)2438 static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
2439 struct phy_info_arg *results)
2440 {
2441 struct nl_msg *msg;
2442
2443 msg = nlmsg_alloc();
2444 if (!msg)
2445 return -ENOMEM;
2446
2447 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
2448 if (drv->capa.flags & WPA_DRIVER_FLAGS_SELF_MANAGED_REGULATORY) {
2449 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, drv->wiphy_idx)) {
2450 nlmsg_free(msg);
2451 return -1;
2452 }
2453 }
2454
2455 return send_and_recv_msgs(drv, msg, nl80211_get_reg, results,
2456 NULL, NULL);
2457 }
2458
2459
modestr(enum hostapd_hw_mode mode)2460 static const char * modestr(enum hostapd_hw_mode mode)
2461 {
2462 switch (mode) {
2463 case HOSTAPD_MODE_IEEE80211B:
2464 return "802.11b";
2465 case HOSTAPD_MODE_IEEE80211G:
2466 return "802.11g";
2467 case HOSTAPD_MODE_IEEE80211A:
2468 return "802.11a";
2469 case HOSTAPD_MODE_IEEE80211AD:
2470 return "802.11ad";
2471 default:
2472 return "?";
2473 }
2474 }
2475
2476
nl80211_dump_chan_list(struct hostapd_hw_modes * modes,u16 num_modes)2477 static void nl80211_dump_chan_list(struct hostapd_hw_modes *modes,
2478 u16 num_modes)
2479 {
2480 int i;
2481
2482 if (!modes)
2483 return;
2484
2485 for (i = 0; i < num_modes; i++) {
2486 struct hostapd_hw_modes *mode = &modes[i];
2487 char str[1000];
2488 char *pos = str;
2489 char *end = pos + sizeof(str);
2490 int j, res;
2491
2492 for (j = 0; j < mode->num_channels; j++) {
2493 struct hostapd_channel_data *chan = &mode->channels[j];
2494
2495 res = os_snprintf(pos, end - pos, " %d%s%s%s",
2496 chan->freq,
2497 (chan->flag & HOSTAPD_CHAN_DISABLED) ?
2498 "[DISABLED]" : "",
2499 (chan->flag & HOSTAPD_CHAN_NO_IR) ?
2500 "[NO_IR]" : "",
2501 (chan->flag & HOSTAPD_CHAN_RADAR) ?
2502 "[RADAR]" : "");
2503 if (os_snprintf_error(end - pos, res))
2504 break;
2505 pos += res;
2506 }
2507
2508 *pos = '\0';
2509 wpa_printf(MSG_DEBUG, "nl80211: Mode IEEE %s:%s",
2510 modestr(mode->mode), str);
2511 }
2512 }
2513
2514
2515 struct hostapd_hw_modes *
nl80211_get_hw_feature_data(void * priv,u16 * num_modes,u16 * flags,u8 * dfs_domain)2516 nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
2517 u8 *dfs_domain)
2518 {
2519 u32 feat;
2520 struct i802_bss *bss = priv;
2521 struct wpa_driver_nl80211_data *drv = bss->drv;
2522 int nl_flags = 0;
2523 struct nl_msg *msg;
2524 struct phy_info_arg result = {
2525 .num_modes = num_modes,
2526 .modes = NULL,
2527 .last_mode = -1,
2528 .failed = 0,
2529 .dfs_domain = 0,
2530 };
2531
2532 *num_modes = 0;
2533 *flags = 0;
2534 *dfs_domain = 0;
2535
2536 feat = get_nl80211_protocol_features(drv);
2537 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
2538 nl_flags = NLM_F_DUMP;
2539 if (!(msg = nl80211_cmd_msg(bss, nl_flags, NL80211_CMD_GET_WIPHY)) ||
2540 nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
2541 nlmsg_free(msg);
2542 return NULL;
2543 }
2544
2545 if (send_and_recv_msgs(drv, msg, phy_info_handler, &result,
2546 NULL, NULL) == 0) {
2547 struct hostapd_hw_modes *modes;
2548
2549 nl80211_set_regulatory_flags(drv, &result);
2550 if (result.failed) {
2551 int i;
2552
2553 for (i = 0; result.modes && i < *num_modes; i++) {
2554 os_free(result.modes[i].channels);
2555 os_free(result.modes[i].rates);
2556 }
2557 os_free(result.modes);
2558 *num_modes = 0;
2559 return NULL;
2560 }
2561
2562 *dfs_domain = result.dfs_domain;
2563
2564 modes = wpa_driver_nl80211_postprocess_modes(result.modes,
2565 num_modes);
2566 nl80211_dump_chan_list(modes, *num_modes);
2567 return modes;
2568 }
2569
2570 return NULL;
2571 }
2572