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/proximity_ranging.h"
18 #include "common/qca-vendor.h"
19 #include "common/qca-vendor-attr.h"
20 #include "common/brcm_vendor.h"
21 #include "driver_nl80211.h"
22
23
protocol_feature_handler(struct nl_msg * msg,void * arg)24 static int protocol_feature_handler(struct nl_msg *msg, void *arg)
25 {
26 u32 *feat = arg;
27 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
28 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
29
30 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
31 genlmsg_attrlen(gnlh, 0), NULL);
32
33 if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES])
34 *feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]);
35
36 return NL_SKIP;
37 }
38
39
get_nl80211_protocol_features(struct wpa_driver_nl80211_data * drv)40 u32 get_nl80211_protocol_features(struct wpa_driver_nl80211_data *drv)
41 {
42 u32 feat = 0;
43 struct nl_msg *msg;
44
45 msg = nlmsg_alloc();
46 if (!msg)
47 return 0;
48
49 if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES)) {
50 nlmsg_free(msg);
51 return 0;
52 }
53
54 if (send_and_recv_resp(drv, msg, protocol_feature_handler, &feat) == 0)
55 return feat;
56
57 return 0;
58 }
59
60
61 struct wiphy_info_data {
62 struct wpa_driver_nl80211_data *drv;
63 struct wpa_driver_capa *capa;
64
65 unsigned int num_multichan_concurrent;
66 unsigned int num_multichan_concurrent_nan;
67
68 unsigned int error:1;
69 unsigned int device_ap_sme:1;
70 unsigned int poll_command_supported:1;
71 unsigned int data_tx_status:1;
72 unsigned int auth_supported:1;
73 unsigned int connect_supported:1;
74 unsigned int p2p_go_supported:1;
75 unsigned int p2p_client_supported:1;
76 unsigned int p2p_go_ctwindow_supported:1;
77 unsigned int p2p_concurrent:1;
78 unsigned int channel_switch_supported:1;
79 unsigned int set_qos_map_supported:1;
80 unsigned int have_low_prio_scan:1;
81 unsigned int wmm_ac_supported:1;
82 unsigned int mac_addr_rand_scan_supported:1;
83 unsigned int mac_addr_rand_sched_scan_supported:1;
84 unsigned int update_ft_ies_supported:1;
85 unsigned int has_key_mgmt:1;
86 unsigned int has_key_mgmt_iftype:1;
87 unsigned int support_ap_scan:1;
88
89 unsigned int nan_supported:1;
90 unsigned int nan_ndp_supported:1;
91 unsigned int nan_phy_capabilities_valid:1;
92 };
93
94
probe_resp_offload_support(int supp_protocols)95 static unsigned int probe_resp_offload_support(int supp_protocols)
96 {
97 unsigned int prot = 0;
98
99 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS)
100 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS;
101 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2)
102 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_WPS2;
103 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P)
104 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_P2P;
105 if (supp_protocols & NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U)
106 prot |= WPA_DRIVER_PROBE_RESP_OFFLOAD_INTERWORKING;
107
108 return prot;
109 }
110
111
wiphy_info_supported_iftypes(struct wiphy_info_data * info,struct nlattr * tb)112 static void wiphy_info_supported_iftypes(struct wiphy_info_data *info,
113 struct nlattr *tb)
114 {
115 struct nlattr *nl_mode;
116 int i;
117
118 if (tb == NULL)
119 return;
120
121 nla_for_each_nested(nl_mode, tb, i) {
122 switch (nla_type(nl_mode)) {
123 case NL80211_IFTYPE_AP:
124 info->capa->flags |= WPA_DRIVER_FLAGS_AP;
125 break;
126 case NL80211_IFTYPE_MESH_POINT:
127 info->capa->flags |= WPA_DRIVER_FLAGS_MESH;
128 break;
129 case NL80211_IFTYPE_ADHOC:
130 info->capa->flags |= WPA_DRIVER_FLAGS_IBSS;
131 break;
132 case NL80211_IFTYPE_P2P_DEVICE:
133 info->capa->flags |=
134 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE;
135 break;
136 case NL80211_IFTYPE_P2P_GO:
137 info->p2p_go_supported = 1;
138 break;
139 case NL80211_IFTYPE_P2P_CLIENT:
140 info->p2p_client_supported = 1;
141 break;
142 case NL80211_IFTYPE_NAN:
143 info->capa->flags2 |= WPA_DRIVER_FLAGS2_SUPPORT_NAN;
144 break;
145 }
146 }
147 }
148
149
wiphy_info_iface_comb_process(struct wiphy_info_data * info,struct nlattr * nl_combi)150 static int wiphy_info_iface_comb_process(struct wiphy_info_data *info,
151 struct nlattr *nl_combi)
152 {
153 struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
154 struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
155 struct nlattr *nl_limit, *nl_mode;
156 int err, rem_limit, rem_mode;
157 int combination_has_p2p = 0, combination_has_mgd = 0;
158 static struct nla_policy
159 iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
160 [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED },
161 [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 },
162 [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
163 [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
164 [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
165 },
166 iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
167 [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED },
168 [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 },
169 };
170 bool combination_has_nan = false, combination_has_nan_ndp = false;
171 unsigned int num_channels;
172
173 err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB,
174 nl_combi, iface_combination_policy);
175 if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] ||
176 !tb_comb[NL80211_IFACE_COMB_MAXNUM] ||
177 !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS])
178 return 0; /* broken combination */
179
180 if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS])
181 info->capa->flags |= WPA_DRIVER_FLAGS_RADAR;
182
183 nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS],
184 rem_limit) {
185 err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
186 nl_limit, iface_limit_policy);
187 if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES])
188 return 0; /* broken combination */
189
190 nla_for_each_nested(nl_mode,
191 tb_limit[NL80211_IFACE_LIMIT_TYPES],
192 rem_mode) {
193 int ift = nla_type(nl_mode);
194 if (ift == NL80211_IFTYPE_P2P_GO ||
195 ift == NL80211_IFTYPE_P2P_CLIENT)
196 combination_has_p2p = 1;
197 if (ift == NL80211_IFTYPE_STATION)
198 combination_has_mgd = 1;
199 if (ift == NL80211_IFTYPE_NAN)
200 combination_has_nan = true;
201 if (ift == NL80211_IFTYPE_NAN_DATA)
202 combination_has_nan_ndp = true;
203 }
204 }
205
206 num_channels = nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]);
207 if (combination_has_p2p && combination_has_mgd) {
208
209 info->p2p_concurrent = 1;
210 if (info->num_multichan_concurrent < num_channels)
211 info->num_multichan_concurrent = num_channels;
212 }
213
214 if (combination_has_nan) {
215 info->nan_supported = 1;
216 info->nan_ndp_supported = combination_has_nan_ndp;
217
218 if (info->num_multichan_concurrent_nan < num_channels)
219 info->num_multichan_concurrent_nan = num_channels;
220 }
221
222 return 0;
223 }
224
225
wiphy_info_iface_comb(struct wiphy_info_data * info,struct nlattr * tb)226 static void wiphy_info_iface_comb(struct wiphy_info_data *info,
227 struct nlattr *tb)
228 {
229 struct nlattr *nl_combi;
230 int rem_combi;
231
232 if (tb == NULL)
233 return;
234
235 nla_for_each_nested(nl_combi, tb, rem_combi) {
236 if (wiphy_info_iface_comb_process(info, nl_combi) > 0)
237 break;
238 }
239 }
240
241
wiphy_info_supp_cmds(struct wiphy_info_data * info,struct nlattr * tb)242 static void wiphy_info_supp_cmds(struct wiphy_info_data *info,
243 struct nlattr *tb)
244 {
245 struct nlattr *nl_cmd;
246 int i;
247
248 if (tb == NULL)
249 return;
250
251 nla_for_each_nested(nl_cmd, tb, i) {
252 switch (nla_get_u32(nl_cmd)) {
253 case NL80211_CMD_AUTHENTICATE:
254 info->auth_supported = 1;
255 break;
256 case NL80211_CMD_CONNECT:
257 info->connect_supported = 1;
258 break;
259 case NL80211_CMD_START_SCHED_SCAN:
260 info->capa->sched_scan_supported = 1;
261 break;
262 case NL80211_CMD_PROBE_CLIENT:
263 info->poll_command_supported = 1;
264 break;
265 case NL80211_CMD_CHANNEL_SWITCH:
266 info->channel_switch_supported = 1;
267 break;
268 case NL80211_CMD_SET_QOS_MAP:
269 info->set_qos_map_supported = 1;
270 break;
271 case NL80211_CMD_UPDATE_FT_IES:
272 info->update_ft_ies_supported = 1;
273 break;
274 }
275 }
276 }
277
278
get_akm_suites_info(struct nlattr * tb)279 static unsigned int get_akm_suites_info(struct nlattr *tb)
280 {
281 int i, num;
282 unsigned int key_mgmt = 0;
283 u32 *akms;
284
285 if (!tb)
286 return 0;
287
288 num = nla_len(tb) / sizeof(u32);
289 akms = nla_data(tb);
290 for (i = 0; i < num; i++) {
291 switch (akms[i]) {
292 case RSN_AUTH_KEY_MGMT_UNSPEC_802_1X:
293 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA |
294 WPA_DRIVER_CAPA_KEY_MGMT_WPA2;
295 break;
296 case RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X:
297 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
298 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK;
299 break;
300 case RSN_AUTH_KEY_MGMT_FT_802_1X:
301 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT;
302 break;
303 case RSN_AUTH_KEY_MGMT_FT_PSK:
304 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_PSK;
305 break;
306 case RSN_AUTH_KEY_MGMT_802_1X_SHA256:
307 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_802_1X_SHA256;
308 break;
309 case RSN_AUTH_KEY_MGMT_PSK_SHA256:
310 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256;
311 break;
312 case RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE:
313 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_TPK_HANDSHAKE;
314 break;
315 case RSN_AUTH_KEY_MGMT_FT_SAE:
316 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE;
317 break;
318 case RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY:
319 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE_EXT_KEY;
320 break;
321 case RSN_AUTH_KEY_MGMT_FT_802_1X_SHA384:
322 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_802_1X_SHA384;
323 break;
324 case RSN_AUTH_KEY_MGMT_CCKM:
325 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_CCKM;
326 break;
327 case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B:
328 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B;
329 break;
330 case RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192:
331 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
332 break;
333 case RSN_AUTH_KEY_MGMT_OWE:
334 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_OWE;
335 break;
336 case RSN_AUTH_KEY_MGMT_DPP:
337 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_DPP;
338 break;
339 case RSN_AUTH_KEY_MGMT_FILS_SHA256:
340 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256;
341 break;
342 case RSN_AUTH_KEY_MGMT_FILS_SHA384:
343 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384;
344 break;
345 case RSN_AUTH_KEY_MGMT_FT_FILS_SHA256:
346 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256;
347 break;
348 case RSN_AUTH_KEY_MGMT_FT_FILS_SHA384:
349 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384;
350 break;
351 case RSN_AUTH_KEY_MGMT_SAE:
352 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SAE;
353 break;
354 case RSN_AUTH_KEY_MGMT_SAE_EXT_KEY:
355 key_mgmt |= WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY;
356 break;
357 }
358 }
359
360 return key_mgmt;
361 }
362
363
get_iface_akm_suites_info(struct wiphy_info_data * info,struct nlattr * nl_akms)364 static void get_iface_akm_suites_info(struct wiphy_info_data *info,
365 struct nlattr *nl_akms)
366 {
367 struct nlattr *tb[NL80211_IFTYPE_AKM_ATTR_MAX + 1];
368 struct nlattr *nl_iftype;
369 unsigned int key_mgmt;
370 int i;
371
372 if (!nl_akms)
373 return;
374
375 nla_parse(tb, NL80211_IFTYPE_AKM_ATTR_MAX,
376 nla_data(nl_akms), nla_len(nl_akms), NULL);
377
378 if (!tb[NL80211_IFTYPE_AKM_ATTR_IFTYPES] ||
379 !tb[NL80211_IFTYPE_AKM_ATTR_SUITES])
380 return;
381
382 info->has_key_mgmt_iftype = 1;
383 key_mgmt = get_akm_suites_info(tb[NL80211_IFTYPE_AKM_ATTR_SUITES]);
384
385 nla_for_each_nested(nl_iftype, tb[NL80211_IFTYPE_AKM_ATTR_IFTYPES], i) {
386 switch (nla_type(nl_iftype)) {
387 case NL80211_IFTYPE_ADHOC:
388 info->drv->capa.key_mgmt_iftype[WPA_IF_IBSS] = key_mgmt;
389 break;
390 case NL80211_IFTYPE_STATION:
391 info->drv->capa.key_mgmt_iftype[WPA_IF_STATION] =
392 key_mgmt;
393 break;
394 case NL80211_IFTYPE_AP:
395 info->drv->capa.key_mgmt_iftype[WPA_IF_AP_BSS] =
396 key_mgmt;
397 break;
398 case NL80211_IFTYPE_AP_VLAN:
399 info->drv->capa.key_mgmt_iftype[WPA_IF_AP_VLAN] =
400 key_mgmt;
401 break;
402 case NL80211_IFTYPE_MESH_POINT:
403 info->drv->capa.key_mgmt_iftype[WPA_IF_MESH] = key_mgmt;
404 break;
405 case NL80211_IFTYPE_P2P_CLIENT:
406 info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_CLIENT] =
407 key_mgmt;
408 break;
409 case NL80211_IFTYPE_P2P_GO:
410 info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_GO] =
411 key_mgmt;
412 break;
413 case NL80211_IFTYPE_P2P_DEVICE:
414 info->drv->capa.key_mgmt_iftype[WPA_IF_P2P_DEVICE] =
415 key_mgmt;
416 break;
417 case NL80211_IFTYPE_NAN:
418 info->drv->capa.key_mgmt_iftype[WPA_IF_NAN] = key_mgmt;
419 break;
420 }
421 wpa_printf(MSG_DEBUG, "nl80211: %s supported key_mgmt 0x%x",
422 nl80211_iftype_str(nla_type(nl_iftype)),
423 key_mgmt);
424 }
425 }
426
427
wiphy_info_iftype_akm_suites(struct wiphy_info_data * info,struct nlattr * tb)428 static void wiphy_info_iftype_akm_suites(struct wiphy_info_data *info,
429 struct nlattr *tb)
430 {
431 struct nlattr *nl_if;
432 int rem_if;
433
434 if (!tb)
435 return;
436
437 nla_for_each_nested(nl_if, tb, rem_if)
438 get_iface_akm_suites_info(info, nl_if);
439 }
440
441
wiphy_info_akm_suites(struct wiphy_info_data * info,struct nlattr * tb)442 static void wiphy_info_akm_suites(struct wiphy_info_data *info,
443 struct nlattr *tb)
444 {
445 if (!tb)
446 return;
447
448 info->has_key_mgmt = 1;
449 info->capa->key_mgmt = get_akm_suites_info(tb);
450 wpa_printf(MSG_DEBUG, "nl80211: wiphy supported key_mgmt 0x%x",
451 info->capa->key_mgmt);
452 }
453
454
wiphy_info_cipher_suites(struct wiphy_info_data * info,struct nlattr * tb)455 static void wiphy_info_cipher_suites(struct wiphy_info_data *info,
456 struct nlattr *tb)
457 {
458 int i, num;
459 u32 *ciphers;
460
461 if (tb == NULL)
462 return;
463
464 num = nla_len(tb) / sizeof(u32);
465 ciphers = nla_data(tb);
466 for (i = 0; i < num; i++) {
467 u32 c = ciphers[i];
468
469 wpa_printf(MSG_DEBUG, "nl80211: Supported cipher %02x-%02x-%02x:%d",
470 c >> 24, (c >> 16) & 0xff,
471 (c >> 8) & 0xff, c & 0xff);
472 switch (c) {
473 case RSN_CIPHER_SUITE_CCMP_256:
474 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP_256;
475 break;
476 case RSN_CIPHER_SUITE_GCMP_256:
477 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP_256;
478 break;
479 case RSN_CIPHER_SUITE_CCMP:
480 info->capa->enc |= WPA_DRIVER_CAPA_ENC_CCMP;
481 break;
482 case RSN_CIPHER_SUITE_GCMP:
483 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GCMP;
484 break;
485 case RSN_CIPHER_SUITE_TKIP:
486 info->capa->enc |= WPA_DRIVER_CAPA_ENC_TKIP;
487 break;
488 case RSN_CIPHER_SUITE_WEP104:
489 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP104;
490 break;
491 case RSN_CIPHER_SUITE_WEP40:
492 info->capa->enc |= WPA_DRIVER_CAPA_ENC_WEP40;
493 break;
494 case RSN_CIPHER_SUITE_AES_128_CMAC:
495 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP;
496 break;
497 case RSN_CIPHER_SUITE_BIP_GMAC_128:
498 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_128;
499 break;
500 case RSN_CIPHER_SUITE_BIP_GMAC_256:
501 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_GMAC_256;
502 break;
503 case RSN_CIPHER_SUITE_BIP_CMAC_256:
504 info->capa->enc |= WPA_DRIVER_CAPA_ENC_BIP_CMAC_256;
505 break;
506 case RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED:
507 info->capa->enc |= WPA_DRIVER_CAPA_ENC_GTK_NOT_USED;
508 break;
509 }
510 }
511 }
512
513
wiphy_info_max_roc(struct wpa_driver_capa * capa,struct nlattr * tb)514 static void wiphy_info_max_roc(struct wpa_driver_capa *capa,
515 struct nlattr *tb)
516 {
517 if (tb)
518 capa->max_remain_on_chan = nla_get_u32(tb);
519 }
520
521
wiphy_info_tdls(struct wpa_driver_capa * capa,struct nlattr * tdls,struct nlattr * ext_setup)522 static void wiphy_info_tdls(struct wpa_driver_capa *capa, struct nlattr *tdls,
523 struct nlattr *ext_setup)
524 {
525 if (tdls == NULL)
526 return;
527
528 wpa_printf(MSG_DEBUG, "nl80211: TDLS supported");
529 capa->flags |= WPA_DRIVER_FLAGS_TDLS_SUPPORT;
530
531 if (ext_setup) {
532 wpa_printf(MSG_DEBUG, "nl80211: TDLS external setup");
533 capa->flags |= WPA_DRIVER_FLAGS_TDLS_EXTERNAL_SETUP;
534 }
535 }
536
537
ext_feature_isset(const u8 * ext_features,int ext_features_len,enum nl80211_ext_feature_index ftidx)538 static int ext_feature_isset(const u8 *ext_features, int ext_features_len,
539 enum nl80211_ext_feature_index ftidx)
540 {
541 u8 ft_byte;
542
543 if ((int) ftidx / 8 >= ext_features_len)
544 return 0;
545
546 ft_byte = ext_features[ftidx / 8];
547 return (ft_byte & BIT(ftidx % 8)) != 0;
548 }
549
550
wiphy_info_ext_feature_flags(struct wiphy_info_data * info,struct nlattr * tb)551 static void wiphy_info_ext_feature_flags(struct wiphy_info_data *info,
552 struct nlattr *tb)
553 {
554 struct wpa_driver_capa *capa = info->capa;
555 u8 *ext_features;
556 int len;
557
558 if (tb == NULL)
559 return;
560
561 ext_features = nla_data(tb);
562 len = nla_len(tb);
563
564 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_VHT_IBSS))
565 capa->flags |= WPA_DRIVER_FLAGS_VHT_IBSS;
566
567 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_RRM))
568 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_RRM;
569
570 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_FILS_STA))
571 capa->flags |= WPA_DRIVER_FLAGS_SUPPORT_FILS;
572
573 if (ext_feature_isset(ext_features, len,
574 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
575 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_LEGACY;
576
577 if (ext_feature_isset(ext_features, len,
578 NL80211_EXT_FEATURE_BEACON_RATE_HT))
579 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_HT;
580
581 if (ext_feature_isset(ext_features, len,
582 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
583 capa->flags |= WPA_DRIVER_FLAGS_BEACON_RATE_VHT;
584
585 if (ext_feature_isset(ext_features, len,
586 NL80211_EXT_FEATURE_BEACON_RATE_HE))
587 capa->flags2 |= WPA_DRIVER_FLAGS2_BEACON_RATE_HE;
588
589 if (ext_feature_isset(ext_features, len,
590 NL80211_EXT_FEATURE_SET_SCAN_DWELL))
591 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_SET_SCAN_DWELL;
592
593 if (ext_feature_isset(ext_features, len,
594 NL80211_EXT_FEATURE_SCAN_START_TIME) &&
595 ext_feature_isset(ext_features, len,
596 NL80211_EXT_FEATURE_BSS_PARENT_TSF) &&
597 ext_feature_isset(ext_features, len,
598 NL80211_EXT_FEATURE_SET_SCAN_DWELL))
599 capa->rrm_flags |= WPA_DRIVER_FLAGS_SUPPORT_BEACON_REPORT;
600 if (ext_feature_isset(ext_features, len,
601 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
602 capa->flags |= WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA;
603 if (ext_feature_isset(ext_features, len,
604 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
605 capa->flags |= WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED;
606 if (ext_feature_isset(ext_features, len,
607 NL80211_EXT_FEATURE_ROC_ADDR_FILTER))
608 capa->flags2 |= WPA_DRIVER_FLAGS2_ROC_ADDR_FILTER;
609 if (ext_feature_isset(ext_features, len,
610 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI))
611 capa->flags |= WPA_DRIVER_FLAGS_SCHED_SCAN_RELATIVE_RSSI;
612 if (ext_feature_isset(ext_features, len,
613 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD))
614 capa->flags |= WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD;
615
616 if (ext_feature_isset(ext_features, len,
617 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
618 capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK;
619 if (ext_feature_isset(ext_features, len,
620 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
621 capa->flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X;
622
623 if (ext_feature_isset(ext_features, len,
624 NL80211_EXT_FEATURE_SAE_OFFLOAD))
625 capa->flags2 |= WPA_DRIVER_FLAGS2_SAE_OFFLOAD_STA;
626
627 if (ext_feature_isset(ext_features, len,
628 NL80211_EXT_FEATURE_MFP_OPTIONAL))
629 capa->flags |= WPA_DRIVER_FLAGS_MFP_OPTIONAL;
630
631 if (ext_feature_isset(ext_features, len,
632 NL80211_EXT_FEATURE_DFS_OFFLOAD))
633 capa->flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
634
635 #ifdef CONFIG_MBO
636 if (ext_feature_isset(ext_features, len,
637 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) &&
638 ext_feature_isset(ext_features, len,
639 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) &&
640 ext_feature_isset(ext_features, len,
641 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) &&
642 ext_feature_isset(
643 ext_features, len,
644 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION))
645 capa->flags |= WPA_DRIVER_FLAGS_OCE_STA;
646 #endif /* CONFIG_MBO */
647
648 if (ext_feature_isset(ext_features, len,
649 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
650 capa->flags |= WPA_DRIVER_FLAGS_FTM_RESPONDER;
651
652 if (ext_feature_isset(ext_features, len,
653 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
654 capa->flags |= WPA_DRIVER_FLAGS_CONTROL_PORT;
655 if (ext_feature_isset(ext_features, len,
656 NL80211_EXT_FEATURE_CONTROL_PORT_NO_PREAUTH))
657 capa->flags2 |= WPA_DRIVER_FLAGS2_CONTROL_PORT_RX;
658 if (ext_feature_isset(
659 ext_features, len,
660 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211_TX_STATUS))
661 capa->flags2 |= WPA_DRIVER_FLAGS2_CONTROL_PORT_TX_STATUS;
662
663 if (ext_feature_isset(ext_features, len,
664 NL80211_EXT_FEATURE_VLAN_OFFLOAD))
665 capa->flags |= WPA_DRIVER_FLAGS_VLAN_OFFLOAD;
666
667 if (ext_feature_isset(ext_features, len,
668 NL80211_EXT_FEATURE_CAN_REPLACE_PTK0))
669 capa->flags |= WPA_DRIVER_FLAGS_SAFE_PTK0_REKEYS;
670
671 if (ext_feature_isset(ext_features, len,
672 NL80211_EXT_FEATURE_BEACON_PROTECTION))
673 capa->flags |= WPA_DRIVER_FLAGS_BEACON_PROTECTION;
674
675 if (ext_feature_isset(ext_features, len,
676 NL80211_EXT_FEATURE_EXT_KEY_ID))
677 capa->flags |= WPA_DRIVER_FLAGS_EXTENDED_KEY_ID;
678
679 if (ext_feature_isset(ext_features, len,
680 NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS))
681 info->drv->multicast_registrations = 1;
682
683 if (ext_feature_isset(ext_features, len,
684 NL80211_EXT_FEATURE_FILS_DISCOVERY))
685 info->drv->fils_discovery = 1;
686
687 if (ext_feature_isset(ext_features, len,
688 NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP))
689 info->drv->unsol_bcast_probe_resp = 1;
690
691 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_PUNCT))
692 info->drv->puncturing = 1;
693
694 if (ext_feature_isset(ext_features, len,
695 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
696 capa->flags2 |= WPA_DRIVER_FLAGS2_BEACON_PROTECTION_CLIENT;
697
698 if (ext_feature_isset(ext_features, len,
699 NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION))
700 capa->flags2 |= WPA_DRIVER_FLAGS2_OCV;
701
702 if (ext_feature_isset(ext_features, len,
703 NL80211_EXT_FEATURE_RADAR_BACKGROUND))
704 capa->flags2 |= WPA_DRIVER_FLAGS2_RADAR_BACKGROUND;
705
706 if (ext_feature_isset(ext_features, len,
707 NL80211_EXT_FEATURE_SECURE_LTF)) {
708 capa->flags2 |= WPA_DRIVER_FLAGS2_SEC_LTF_STA;
709 capa->flags2 |= WPA_DRIVER_FLAGS2_SEC_LTF_AP;
710 }
711
712 if (ext_feature_isset(ext_features, len,
713 NL80211_EXT_FEATURE_SECURE_RTT)) {
714 capa->flags2 |= WPA_DRIVER_FLAGS2_SEC_RTT_STA;
715 capa->flags2 |= WPA_DRIVER_FLAGS2_SEC_RTT_AP;
716 }
717
718 if (ext_feature_isset(
719 ext_features, len,
720 NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE)) {
721 capa->flags2 |= WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_STA;
722 capa->flags2 |= WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP;
723 }
724
725 if (ext_feature_isset(ext_features, len,
726 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
727 capa->flags2 |= WPA_DRIVER_FLAGS2_SCAN_MIN_PREQ;
728
729 if (ext_feature_isset(ext_features, len,
730 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
731 capa->flags2 |= WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK;
732
733 if (ext_feature_isset(ext_features, len,
734 NL80211_EXT_FEATURE_OWE_OFFLOAD))
735 capa->flags2 |= WPA_DRIVER_FLAGS2_OWE_OFFLOAD_STA;
736
737 if (ext_feature_isset(ext_features, len,
738 NL80211_EXT_FEATURE_OWE_OFFLOAD_AP))
739 capa->flags2 |= WPA_DRIVER_FLAGS2_OWE_OFFLOAD_AP;
740
741 if (ext_feature_isset(ext_features, len,
742 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP))
743 capa->flags2 |= WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP;
744
745 if (ext_feature_isset(ext_features, len,
746 NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT))
747 capa->flags2 |= WPA_DRIVER_FLAGS2_SPP_AMSDU;
748
749 if (ext_feature_isset(ext_features, len,
750 NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION))
751 capa->flags2 |= WPA_DRIVER_FLAGS2_ASSOCIATION_FRAME_ENCRYPTION;
752
753 if (ext_feature_isset(ext_features, len, NL80211_EXT_FEATURE_EPPKE) &&
754 ext_feature_isset(ext_features, len,
755 NL80211_EXT_FEATURE_ASSOC_FRAME_ENCRYPTION)) {
756 capa->flags2 |= WPA_DRIVER_FLAGS2_EPPKE;
757 }
758
759 if (ext_feature_isset(ext_features, len,
760 NL80211_EXT_FEATURE_IEEE8021X_AUTH))
761 capa->flags2 |= WPA_DRIVER_FLAGS2_802_1X_AUTH;
762 }
763
764
wiphy_info_feature_flags(struct wiphy_info_data * info,struct nlattr * tb)765 static void wiphy_info_feature_flags(struct wiphy_info_data *info,
766 struct nlattr *tb)
767 {
768 u32 flags;
769 struct wpa_driver_capa *capa = info->capa;
770
771 if (tb == NULL)
772 return;
773
774 flags = nla_get_u32(tb);
775
776 if (flags & NL80211_FEATURE_SK_TX_STATUS)
777 info->data_tx_status = 1;
778
779 if (flags & NL80211_FEATURE_INACTIVITY_TIMER)
780 capa->flags |= WPA_DRIVER_FLAGS_INACTIVITY_TIMER;
781
782 if (flags & NL80211_FEATURE_SAE)
783 capa->flags |= WPA_DRIVER_FLAGS_SAE;
784
785 if (flags & NL80211_FEATURE_NEED_OBSS_SCAN)
786 capa->flags |= WPA_DRIVER_FLAGS_OBSS_SCAN;
787
788 if (flags & NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE) {
789 capa->flags |= WPA_DRIVER_FLAGS_HT_2040_COEX;
790 capa->flags2 |= WPA_DRIVER_FLAGS2_AP_CHANWIDTH_CHANGE;
791 }
792
793 if (flags & NL80211_FEATURE_TDLS_CHANNEL_SWITCH) {
794 wpa_printf(MSG_DEBUG, "nl80211: TDLS channel switch");
795 capa->flags |= WPA_DRIVER_FLAGS_TDLS_CHANNEL_SWITCH;
796 }
797
798 if (flags & NL80211_FEATURE_P2P_GO_CTWIN)
799 info->p2p_go_ctwindow_supported = 1;
800
801 if (flags & NL80211_FEATURE_LOW_PRIORITY_SCAN)
802 info->have_low_prio_scan = 1;
803
804 if (flags & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)
805 info->mac_addr_rand_scan_supported = 1;
806
807 if (flags & NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR)
808 info->mac_addr_rand_sched_scan_supported = 1;
809
810 if (flags & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
811 info->wmm_ac_supported = 1;
812
813 if (flags & NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES)
814 capa->rrm_flags |= WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES;
815
816 if (flags & NL80211_FEATURE_WFA_TPC_IE_IN_PROBES)
817 capa->rrm_flags |= WPA_DRIVER_FLAGS_WFA_TPC_IE_IN_PROBES;
818
819 if (flags & NL80211_FEATURE_QUIET)
820 capa->rrm_flags |= WPA_DRIVER_FLAGS_QUIET;
821
822 if (flags & NL80211_FEATURE_TX_POWER_INSERTION)
823 capa->rrm_flags |= WPA_DRIVER_FLAGS_TX_POWER_INSERTION;
824
825 if (flags & NL80211_FEATURE_HT_IBSS)
826 capa->flags |= WPA_DRIVER_FLAGS_HT_IBSS;
827
828 if (flags & NL80211_FEATURE_FULL_AP_CLIENT_STATE)
829 capa->flags |= WPA_DRIVER_FLAGS_FULL_AP_CLIENT_STATE;
830
831 if (flags & NL80211_FEATURE_AP_SCAN)
832 info->support_ap_scan = 1;
833 }
834
835
wiphy_info_probe_resp_offload(struct wpa_driver_capa * capa,struct nlattr * tb)836 static void wiphy_info_probe_resp_offload(struct wpa_driver_capa *capa,
837 struct nlattr *tb)
838 {
839 u32 protocols;
840
841 if (tb == NULL)
842 return;
843
844 protocols = nla_get_u32(tb);
845 wpa_printf(MSG_DEBUG, "nl80211: Supports Probe Response offload in AP "
846 "mode");
847 capa->flags |= WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD;
848 capa->probe_resp_offloads = probe_resp_offload_support(protocols);
849 }
850
851
wiphy_info_wowlan_triggers(struct wpa_driver_capa * capa,struct nlattr * tb)852 static void wiphy_info_wowlan_triggers(struct wpa_driver_capa *capa,
853 struct nlattr *tb)
854 {
855 struct nlattr *triggers[MAX_NL80211_WOWLAN_TRIG + 1];
856
857 if (tb == NULL)
858 return;
859
860 if (nla_parse_nested(triggers, MAX_NL80211_WOWLAN_TRIG,
861 tb, NULL))
862 return;
863
864 if (triggers[NL80211_WOWLAN_TRIG_ANY])
865 capa->wowlan_triggers.any = 1;
866 if (triggers[NL80211_WOWLAN_TRIG_DISCONNECT])
867 capa->wowlan_triggers.disconnect = 1;
868 if (triggers[NL80211_WOWLAN_TRIG_MAGIC_PKT])
869 capa->wowlan_triggers.magic_pkt = 1;
870 if (triggers[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE])
871 capa->wowlan_triggers.gtk_rekey_failure = 1;
872 if (triggers[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST])
873 capa->wowlan_triggers.eap_identity_req = 1;
874 if (triggers[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE])
875 capa->wowlan_triggers.four_way_handshake = 1;
876 if (triggers[NL80211_WOWLAN_TRIG_RFKILL_RELEASE])
877 capa->wowlan_triggers.rfkill_release = 1;
878 }
879
880
wiphy_info_extended_capab(struct wpa_driver_nl80211_data * drv,struct nlattr * tb)881 static void wiphy_info_extended_capab(struct wpa_driver_nl80211_data *drv,
882 struct nlattr *tb)
883 {
884 int rem = 0, i;
885 struct nlattr *tb1[NL80211_ATTR_MAX + 1], *attr;
886
887 if (!tb || drv->num_iface_capa == NL80211_IFTYPE_MAX)
888 return;
889
890 nla_for_each_nested(attr, tb, rem) {
891 unsigned int len;
892 struct drv_nl80211_iface_capa *capa;
893
894 nla_parse(tb1, NL80211_ATTR_MAX, nla_data(attr),
895 nla_len(attr), NULL);
896
897 if (!tb1[NL80211_ATTR_IFTYPE] ||
898 !tb1[NL80211_ATTR_EXT_CAPA] ||
899 !tb1[NL80211_ATTR_EXT_CAPA_MASK])
900 continue;
901
902 capa = &drv->iface_capa[drv->num_iface_capa];
903 capa->iftype = nla_get_u32(tb1[NL80211_ATTR_IFTYPE]);
904 wpa_printf(MSG_DEBUG,
905 "nl80211: Driver-advertised extended capabilities for interface type %s",
906 nl80211_iftype_str(capa->iftype));
907
908 len = nla_len(tb1[NL80211_ATTR_EXT_CAPA]);
909 capa->ext_capa = os_memdup(nla_data(tb1[NL80211_ATTR_EXT_CAPA]),
910 len);
911 if (!capa->ext_capa)
912 goto err;
913
914 capa->ext_capa_len = len;
915 wpa_hexdump(MSG_DEBUG, "nl80211: Extended capabilities",
916 capa->ext_capa, capa->ext_capa_len);
917
918 len = nla_len(tb1[NL80211_ATTR_EXT_CAPA_MASK]);
919 capa->ext_capa_mask =
920 os_memdup(nla_data(tb1[NL80211_ATTR_EXT_CAPA_MASK]),
921 len);
922 if (!capa->ext_capa_mask)
923 goto err;
924
925 wpa_hexdump(MSG_DEBUG, "nl80211: Extended capabilities mask",
926 capa->ext_capa_mask, capa->ext_capa_len);
927
928 if (tb1[NL80211_ATTR_EML_CAPABILITY] &&
929 tb1[NL80211_ATTR_MLD_CAPA_AND_OPS]) {
930 capa->eml_capa =
931 nla_get_u16(tb1[NL80211_ATTR_EML_CAPABILITY]);
932 capa->mld_capa_and_ops =
933 nla_get_u16(tb1[NL80211_ATTR_MLD_CAPA_AND_OPS]);
934 }
935
936 wpa_printf(MSG_DEBUG,
937 "nl80211: EML Capability: 0x%x MLD Capability: 0x%x",
938 capa->eml_capa, capa->mld_capa_and_ops);
939
940 drv->num_iface_capa++;
941 if (drv->num_iface_capa == NL80211_IFTYPE_MAX)
942 break;
943 }
944
945 return;
946
947 err:
948 /* Cleanup allocated memory on error */
949 for (i = 0; i < NL80211_IFTYPE_MAX; i++) {
950 os_free(drv->iface_capa[i].ext_capa);
951 drv->iface_capa[i].ext_capa = NULL;
952 os_free(drv->iface_capa[i].ext_capa_mask);
953 drv->iface_capa[i].ext_capa_mask = NULL;
954 drv->iface_capa[i].ext_capa_len = 0;
955 }
956 drv->num_iface_capa = 0;
957 }
958
959
wiphy_info_mbssid(struct wpa_driver_capa * cap,struct nlattr * attr)960 static void wiphy_info_mbssid(struct wpa_driver_capa *cap, struct nlattr *attr)
961 {
962 struct nlattr *config[NL80211_MBSSID_CONFIG_ATTR_MAX + 1];
963
964 if (nla_parse_nested(config, NL80211_MBSSID_CONFIG_ATTR_MAX, attr,
965 NULL))
966 return;
967
968 if (!config[NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES])
969 return;
970
971 cap->mbssid_max_interfaces =
972 nla_get_u8(config[NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES]);
973
974 if (config[NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY])
975 cap->ema_max_periodicity =
976 nla_get_u8(config[NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY]);
977
978 wpa_printf(MSG_DEBUG,
979 "mbssid: max interfaces %u, max profile periodicity %u",
980 cap->mbssid_max_interfaces, cap->ema_max_periodicity);
981 }
982
983
984 #ifdef CONFIG_NAN
985
wiphy_info_nan_capa_handler(struct wpa_driver_capa * capa,struct wiphy_info_data * info,struct nlattr * attr)986 static void wiphy_info_nan_capa_handler(struct wpa_driver_capa *capa,
987 struct wiphy_info_data *info,
988 struct nlattr *attr)
989 {
990 static struct nla_policy
991 nan_capa_policy[NL80211_NAN_CAPABILITIES_MAX + 1] = {
992 [NL80211_NAN_CAPA_CONFIGURABLE_SYNC] = { .type = NLA_FLAG },
993 [NL80211_NAN_CAPA_USERSPACE_DE] = { .type = NLA_FLAG },
994 };
995 struct nlattr *tb_nan_capa[NL80211_NAN_CAPABILITIES_MAX + 1];
996 static struct nla_policy
997 nan_capa_phy_policy[NL80211_NAN_PHY_CAP_ATTR_MAX + 1] = {
998 [NL80211_NAN_PHY_CAP_ATTR_HT_CAPA] = { .type = NLA_U16 },
999 [NL80211_NAN_PHY_CAP_ATTR_HT_AMPDU_FACTOR] = {
1000 .type = NLA_U8,
1001 },
1002 [NL80211_NAN_PHY_CAP_ATTR_HT_AMPDU_DENSITY] = {
1003 .type = NLA_U8,
1004 },
1005 [NL80211_NAN_PHY_CAP_ATTR_HT_MCS_SET] = {
1006 .type = NLA_BINARY, .minlen = 16, .maxlen = 16,
1007 },
1008 [NL80211_NAN_PHY_CAP_ATTR_VHT_CAPA] = { .type = NLA_U32 },
1009 [NL80211_NAN_PHY_CAP_ATTR_VHT_MCS_SET] = {
1010 .type = NLA_BINARY, .minlen = 8, .maxlen = 8,
1011 },
1012 [NL80211_NAN_PHY_CAP_ATTR_HE_MAC] = {
1013 .type = NLA_BINARY, .minlen = 6, .maxlen = 6
1014 },
1015 [NL80211_NAN_PHY_CAP_ATTR_HE_PHY] = {
1016 .type = NLA_BINARY, .minlen = 11, .maxlen = 11
1017 },
1018 [NL80211_NAN_PHY_CAP_ATTR_HE_MCS_SET] = {
1019 .type = NLA_BINARY, .minlen = 12, .maxlen = 12,
1020 },
1021 [NL80211_NAN_PHY_CAP_ATTR_HE_PPE] = {
1022 .type = NLA_BINARY, .maxlen = 255,
1023 },
1024 };
1025 struct nlattr *tb_phy[NL80211_NAN_PHY_CAP_ATTR_MAX + 1];
1026
1027 if (!attr)
1028 return;
1029
1030 wpa_printf(MSG_DEBUG, "nl80211: Parsing NAN capabilities");
1031
1032 if (nla_parse_nested(tb_nan_capa, NL80211_NAN_CAPABILITIES_MAX, attr,
1033 nan_capa_policy)) {
1034 wpa_printf(MSG_DEBUG,
1035 "nl80211: Failed to parse NAN capabilities");
1036 return;
1037 }
1038
1039 if (tb_nan_capa[NL80211_NAN_CAPA_CONFIGURABLE_SYNC]) {
1040 wpa_printf(MSG_DEBUG, "nl80211: NAN sync offload supported");
1041 capa->nan_capa.drv_flags |=
1042 WPA_DRIVER_FLAGS_NAN_SUPPORT_SYNC_CONFIG;
1043 }
1044
1045 if (tb_nan_capa[NL80211_NAN_CAPA_USERSPACE_DE]) {
1046 wpa_printf(MSG_DEBUG,
1047 "nl80211: NAN user space DE is supported");
1048 capa->nan_capa.drv_flags |=
1049 WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE;
1050 }
1051
1052 if (tb_nan_capa[NL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME])
1053 capa->nan_capa.max_channel_switch_time =
1054 nla_get_u16(tb_nan_capa[NL80211_NAN_CAPA_MAX_CHANNEL_SWITCH_TIME]);
1055
1056 if (tb_nan_capa[NL80211_NAN_CAPA_NUM_ANTENNAS])
1057 capa->nan_capa.num_antennas =
1058 nla_get_u8(tb_nan_capa[NL80211_NAN_CAPA_NUM_ANTENNAS]);
1059
1060 if (tb_nan_capa[NL80211_NAN_CAPA_OP_MODE])
1061 capa->nan_capa.op_modes =
1062 nla_get_u8(tb_nan_capa[NL80211_NAN_CAPA_OP_MODE]);
1063
1064 if (tb_nan_capa[NL80211_NAN_CAPA_CAPABILITIES])
1065 capa->nan_capa.dev_capa =
1066 nla_get_u8(tb_nan_capa[NL80211_NAN_CAPA_CAPABILITIES]);
1067
1068 if (!tb_nan_capa[NL80211_NAN_CAPA_PHY])
1069 return;
1070
1071 if (nla_parse_nested(tb_phy, NL80211_NAN_PHY_CAP_ATTR_MAX,
1072 tb_nan_capa[NL80211_NAN_CAPA_PHY],
1073 nan_capa_phy_policy)) {
1074 wpa_printf(MSG_DEBUG,
1075 "nl80211: Failed to parse NAN PHY capabilities");
1076 return;
1077 }
1078
1079 /* HT Capabilities */
1080 if (!tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_MCS_SET] ||
1081 !tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_CAPA] ||
1082 !tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_AMPDU_FACTOR] ||
1083 !tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_AMPDU_DENSITY])
1084 return;
1085
1086 capa->nan_capa.ht_capab = nla_get_u16(
1087 tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_CAPA]);
1088 capa->nan_capa.ht_ampdu_params = nla_get_u8(
1089 tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_AMPDU_FACTOR]) & 0x3;
1090 capa->nan_capa.ht_ampdu_params |= (nla_get_u8(
1091 tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_AMPDU_DENSITY]) & 0x7) << 2;
1092 os_memcpy(capa->nan_capa.ht_mcs_set,
1093 nla_data(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_MCS_SET]),
1094 nla_len(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HT_MCS_SET]));
1095
1096 info->nan_phy_capabilities_valid = 1;
1097
1098 /* VHT Capabilities */
1099 if (tb_phy[NL80211_NAN_PHY_CAP_ATTR_VHT_MCS_SET] &&
1100 tb_phy[NL80211_NAN_PHY_CAP_ATTR_VHT_CAPA]) {
1101 capa->nan_capa.vht_capab = nla_get_u32(
1102 tb_phy[NL80211_NAN_PHY_CAP_ATTR_VHT_CAPA]);
1103 os_memcpy(capa->nan_capa.vht_mcs_set,
1104 nla_data(tb_phy[NL80211_NAN_PHY_CAP_ATTR_VHT_MCS_SET]),
1105 nla_len(tb_phy[NL80211_NAN_PHY_CAP_ATTR_VHT_MCS_SET]));
1106 capa->nan_capa.vht_valid = true;
1107 }
1108
1109 /* HE Capabilities */
1110 if (!tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_MAC] ||
1111 !tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_PHY] ||
1112 !tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_MCS_SET] ||
1113 !tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_PPE])
1114 goto out;
1115
1116 os_memcpy(capa->nan_capa.he_capab.mac_cap,
1117 nla_data(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_MAC]),
1118 nla_len(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_MAC]));
1119 os_memcpy(capa->nan_capa.he_capab.phy_cap,
1120 nla_data(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_PHY]),
1121 nla_len(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_PHY]));
1122
1123 os_memcpy(capa->nan_capa.he_capab.mcs,
1124 nla_data(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_MCS_SET]),
1125 nla_len(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_MCS_SET]));
1126 os_memcpy(capa->nan_capa.he_capab.ppet,
1127 nla_data(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_PPE]),
1128 nla_len(tb_phy[NL80211_NAN_PHY_CAP_ATTR_HE_PPE]));
1129
1130 capa->nan_capa.he_valid = true;
1131 out:
1132 wpa_printf(MSG_DEBUG,
1133 "nl80211: NAN PHY capabilities vht_valid=%u, he_valid=%u",
1134 capa->nan_capa.vht_valid, capa->nan_capa.he_valid);
1135 }
1136
1137 #endif /* CONFIG_NAN */
1138
1139
1140 #ifdef CONFIG_PR
1141
nl80211_to_pd_bw_bitmap(u32 nl_bitmap)1142 static u32 nl80211_to_pd_bw_bitmap(u32 nl_bitmap)
1143 {
1144 u32 bandwidths = 0;
1145
1146 if (nl_bitmap & BIT(NL80211_CHAN_WIDTH_20))
1147 bandwidths |= BIT(WPA_PR_CHAN_WIDTH_20);
1148 if (nl_bitmap & BIT(NL80211_CHAN_WIDTH_40))
1149 bandwidths |= BIT(WPA_PR_CHAN_WIDTH_40);
1150 if (nl_bitmap & BIT(NL80211_CHAN_WIDTH_80))
1151 bandwidths |= BIT(WPA_PR_CHAN_WIDTH_80);
1152 if (nl_bitmap & BIT(NL80211_CHAN_WIDTH_80P80))
1153 bandwidths |= BIT(WPA_PR_CHAN_WIDTH_80P80);
1154 if (nl_bitmap & BIT(NL80211_CHAN_WIDTH_160))
1155 bandwidths |= BIT(WPA_PR_CHAN_WIDTH_160);
1156 return bandwidths;
1157 }
1158
1159
nl80211_to_pd_preamble_bitmap(u32 nl_bitmap)1160 static u32 nl80211_to_pd_preamble_bitmap(u32 nl_bitmap)
1161 {
1162 u32 preambles = 0;
1163
1164 if (nl_bitmap & BIT(NL80211_PREAMBLE_HT))
1165 preambles |= BIT(WPA_PR_PREAMBLE_HT);
1166 if (nl_bitmap & BIT(NL80211_PREAMBLE_VHT))
1167 preambles |= BIT(WPA_PR_PREAMBLE_VHT);
1168 if (nl_bitmap & BIT(NL80211_PREAMBLE_HE))
1169 preambles |= BIT(WPA_PR_PREAMBLE_HE);
1170 return preambles;
1171 }
1172
1173
pmsr_type_ftm_handler(struct wpa_driver_nl80211_data * drv,struct nlattr * capa)1174 static void pmsr_type_ftm_handler(struct wpa_driver_nl80211_data *drv,
1175 struct nlattr *capa)
1176 {
1177 u32 max_rx_sts, max_tx_sts;
1178 struct nlattr *tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX + 1];
1179 struct nlattr *ista_caps[NL80211_PMSR_FTM_CAPA_ATTR_MAX + 1];
1180 struct nlattr *type_caps[NL80211_PMSR_FTM_TYPE_CAPA_ATTR_MAX + 1];
1181 struct nlattr *rsta_caps[NL80211_PMSR_FTM_CAPA_ATTR_MAX + 1];
1182
1183 if (nla_parse_nested(tb, NL80211_PMSR_FTM_CAPA_ATTR_MAX, capa, NULL))
1184 return;
1185
1186 /* Parse ISTA capabilities */
1187 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_ISTA_CAPS] &&
1188 nla_parse_nested(ista_caps, NL80211_PMSR_FTM_CAPA_ATTR_MAX,
1189 tb[NL80211_PMSR_FTM_CAPA_ATTR_ISTA_CAPS],
1190 NULL) == 0) {
1191 drv->capa.ista.support_ntb =
1192 !!ista_caps[NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_NTB];
1193 drv->capa.ista.support_tb =
1194 !!ista_caps[NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_TB];
1195 drv->capa.ista.support_edca =
1196 !!ista_caps[NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_EDCA];
1197 if (ista_caps[NL80211_PMSR_ATTR_MAX_PEER_ISTA_ROLE])
1198 drv->capa.ista.max_peers =
1199 nla_get_u32(ista_caps[NL80211_PMSR_ATTR_MAX_PEER_ISTA_ROLE]);
1200 }
1201
1202 /* Parse ranging type capabilities */
1203 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_TYPE_CAPS] &&
1204 !nla_parse_nested(type_caps, NL80211_PMSR_FTM_TYPE_CAPA_ATTR_MAX,
1205 tb[NL80211_PMSR_FTM_CAPA_ATTR_TYPE_CAPS],
1206 NULL)) {
1207 drv->capa.ranging_type.infra_support =
1208 !!type_caps[NL80211_PMSR_FTM_TYPE_CAPA_ATTR_INFRA_SUPPORT];
1209 drv->capa.ranging_type.pd_support =
1210 !!type_caps[NL80211_PMSR_FTM_TYPE_CAPA_ATTR_PD_SUPPORT];
1211 }
1212
1213 drv->capa.concurrent_ista_rsta =
1214 !!tb[NL80211_PMSR_FTM_CAPA_ATTR_CONCURRENT_ISTA_RSTA_SUPPORT];
1215
1216 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_TX_LTF_REP])
1217 drv->capa.max_tx_ltf_repetations =
1218 nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_TX_LTF_REP]);
1219 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_RX_LTF_REP])
1220 drv->capa.max_rx_ltf_repetations =
1221 nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_RX_LTF_REP]);
1222
1223 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_RX_STS]) {
1224 max_rx_sts = nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_RX_STS]);
1225 drv->capa.max_rx_sts_le_80 = max_rx_sts;
1226 drv->capa.max_rx_sts_gt_80 = max_rx_sts;
1227 }
1228 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_TX_STS]) {
1229 max_tx_sts = nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_TX_STS]);
1230 drv->capa.max_tx_sts_le_80 = max_tx_sts;
1231 drv->capa.max_tx_sts_gt_80 = max_tx_sts;
1232 }
1233
1234 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_TOTAL_LTF_TX])
1235 drv->capa.max_tx_ltf_total =
1236 nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_TOTAL_LTF_TX]);
1237 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_TOTAL_LTF_RX])
1238 drv->capa.max_rx_ltf_total =
1239 nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_TOTAL_LTF_RX]);
1240 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST])
1241 drv->capa.max_ftms_per_burst =
1242 nla_get_u8(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST]);
1243
1244 /* Parse RSTA capabilities */
1245 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_RSTA_SUPPORT] &&
1246 tb[NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS] &&
1247 !nla_parse_nested(rsta_caps, NL80211_PMSR_FTM_CAPA_ATTR_MAX,
1248 tb[NL80211_PMSR_FTM_CAPA_ATTR_RSTA_CAPS],
1249 NULL)) {
1250 drv->capa.rsta.support_ntb =
1251 !!rsta_caps[NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_NTB];
1252 drv->capa.rsta.support_tb =
1253 !!rsta_caps[NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_TB];
1254 drv->capa.rsta.support_edca =
1255 !!rsta_caps[NL80211_PMSR_FTM_CAPA_ATTR_SUPPORT_EDCA];
1256 if (rsta_caps[NL80211_PMSR_ATTR_MAX_PEER_RSTA_ROLE])
1257 drv->capa.rsta.max_peers =
1258 nla_get_u32(rsta_caps[NL80211_PMSR_ATTR_MAX_PEER_RSTA_ROLE]);
1259 }
1260
1261 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_TX_ANTENNAS])
1262 drv->capa.max_tx_antenna =
1263 nla_get_u8(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_TX_ANTENNAS]);
1264 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_RX_ANTENNAS])
1265 drv->capa.max_rx_antenna =
1266 nla_get_u8(tb[NL80211_PMSR_FTM_CAPA_ATTR_MAX_NUM_RX_ANTENNAS]);
1267
1268 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_EDCA])
1269 drv->capa.edca_min_ranging_interval =
1270 nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_EDCA]);
1271 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB])
1272 drv->capa.ntb_min_ranging_interval =
1273 nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_MIN_INTERVAL_NTB]);
1274
1275 /* Parse additional ranging capabilities */
1276 drv->capa.support_6ghz = !!tb[NL80211_PMSR_FTM_CAPA_ATTR_6GHZ_SUPPORT];
1277
1278 drv->capa.asap_support = !!tb[NL80211_PMSR_FTM_CAPA_ATTR_ASAP];
1279
1280 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_PREAMBLES])
1281 drv->capa.pd_preambles = nl80211_to_pd_preamble_bitmap(
1282 nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_PREAMBLES]));
1283 if (tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_BANDWIDTHS])
1284 drv->capa.pd_bandwidths = nl80211_to_pd_bw_bitmap(
1285 nla_get_u32(tb[NL80211_PMSR_FTM_CAPA_ATTR_PD_BANDWIDTHS]));
1286 }
1287
1288
wiphy_info_pmsr_type_capa(struct wpa_driver_nl80211_data * drv,struct nlattr * attr)1289 static void wiphy_info_pmsr_type_capa(struct wpa_driver_nl80211_data *drv,
1290 struct nlattr *attr)
1291 {
1292 struct nlattr *pos;
1293 int rem;
1294
1295 nla_for_each_nested(pos, attr, rem) {
1296 if (nla_type(pos) == NL80211_PMSR_TYPE_FTM)
1297 pmsr_type_ftm_handler(drv, pos);
1298 }
1299 }
1300
1301
wiphy_info_pmsr_capa(struct wpa_driver_nl80211_data * drv,struct nlattr * tb[])1302 static void wiphy_info_pmsr_capa(struct wpa_driver_nl80211_data *drv,
1303 struct nlattr *tb[])
1304 {
1305 struct nlattr *pmsr_capa[NL80211_PMSR_ATTR_MAX + 1];
1306 static struct nla_policy
1307 pmsr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
1308 [NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_U32 },
1309 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_NESTED },
1310 };
1311
1312 if (nla_parse_nested(pmsr_capa, NL80211_PMSR_ATTR_MAX,
1313 tb[NL80211_ATTR_PEER_MEASUREMENTS],
1314 pmsr_policy)) {
1315 wpa_printf(MSG_DEBUG, "nl80211: Failed to parse PMSR capabilities");
1316 return;
1317 }
1318
1319 if (pmsr_capa[NL80211_PMSR_ATTR_MAX_PEERS])
1320 drv->capa.pmsr_max_peers =
1321 nla_get_u32(pmsr_capa[NL80211_PMSR_ATTR_MAX_PEERS]);
1322 if (pmsr_capa[NL80211_PMSR_ATTR_TYPE_CAPA])
1323 wiphy_info_pmsr_type_capa(drv,
1324 pmsr_capa[NL80211_PMSR_ATTR_TYPE_CAPA]);
1325 }
1326
1327 #endif /* CONFIG_PR */
1328
1329
wiphy_info_handler(struct nl_msg * msg,void * arg)1330 static int wiphy_info_handler(struct nl_msg *msg, void *arg)
1331 {
1332 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1333 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1334 struct wiphy_info_data *info = arg;
1335 struct wpa_driver_capa *capa = info->capa;
1336 struct wpa_driver_nl80211_data *drv = info->drv;
1337
1338 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1339 genlmsg_attrlen(gnlh, 0), NULL);
1340
1341 if (tb[NL80211_ATTR_WIPHY])
1342 drv->wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
1343
1344 if (tb[NL80211_ATTR_WIPHY_NAME])
1345 os_strlcpy(drv->phyname,
1346 nla_get_string(tb[NL80211_ATTR_WIPHY_NAME]),
1347 sizeof(drv->phyname));
1348 if (tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])
1349 capa->max_scan_ssids =
1350 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
1351
1352 if (tb[NL80211_ATTR_MAX_SCAN_IE_LEN])
1353 capa->max_probe_req_ie_len =
1354 nla_get_u16(tb[NL80211_ATTR_MAX_SCAN_IE_LEN]);
1355
1356 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS])
1357 capa->max_sched_scan_ssids =
1358 nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
1359
1360 if (tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS] &&
1361 tb[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL] &&
1362 tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]) {
1363 capa->max_sched_scan_plans =
1364 nla_get_u32(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS]);
1365
1366 capa->max_sched_scan_plan_interval =
1367 nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL]);
1368
1369 capa->max_sched_scan_plan_iterations =
1370 nla_get_u32(tb[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]);
1371 }
1372
1373 if (tb[NL80211_ATTR_MAX_MATCH_SETS])
1374 capa->max_match_sets =
1375 nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]);
1376
1377 if (tb[NL80211_ATTR_MAC_ACL_MAX])
1378 capa->max_acl_mac_addrs =
1379 nla_get_u32(tb[NL80211_ATTR_MAC_ACL_MAX]);
1380
1381 wiphy_info_supported_iftypes(info, tb[NL80211_ATTR_SUPPORTED_IFTYPES]);
1382 wiphy_info_iface_comb(info, tb[NL80211_ATTR_INTERFACE_COMBINATIONS]);
1383 wiphy_info_supp_cmds(info, tb[NL80211_ATTR_SUPPORTED_COMMANDS]);
1384 wiphy_info_cipher_suites(info, tb[NL80211_ATTR_CIPHER_SUITES]);
1385 wiphy_info_akm_suites(info, tb[NL80211_ATTR_AKM_SUITES]);
1386 wiphy_info_iftype_akm_suites(info, tb[NL80211_ATTR_IFTYPE_AKM_SUITES]);
1387
1388 if (tb[NL80211_ATTR_OFFCHANNEL_TX_OK]) {
1389 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based "
1390 "off-channel TX");
1391 capa->flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_TX;
1392 }
1393
1394 if (tb[NL80211_ATTR_ROAM_SUPPORT]) {
1395 wpa_printf(MSG_DEBUG, "nl80211: Using driver-based roaming");
1396 capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
1397 }
1398
1399 wiphy_info_max_roc(capa,
1400 tb[NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION]);
1401
1402 if (tb[NL80211_ATTR_SUPPORT_AP_UAPSD])
1403 capa->flags |= WPA_DRIVER_FLAGS_AP_UAPSD;
1404
1405 wiphy_info_tdls(capa, tb[NL80211_ATTR_TDLS_SUPPORT],
1406 tb[NL80211_ATTR_TDLS_EXTERNAL_SETUP]);
1407
1408 if (tb[NL80211_ATTR_DEVICE_AP_SME]) {
1409 u32 ap_sme_features_flags =
1410 nla_get_u32(tb[NL80211_ATTR_DEVICE_AP_SME]);
1411
1412 if (ap_sme_features_flags & NL80211_AP_SME_SA_QUERY_OFFLOAD)
1413 capa->flags2 |= WPA_DRIVER_FLAGS2_SA_QUERY_OFFLOAD_AP;
1414
1415 info->device_ap_sme = 1;
1416 }
1417
1418 wiphy_info_feature_flags(info, tb[NL80211_ATTR_FEATURE_FLAGS]);
1419 wiphy_info_ext_feature_flags(info, tb[NL80211_ATTR_EXT_FEATURES]);
1420 wiphy_info_probe_resp_offload(capa,
1421 tb[NL80211_ATTR_PROBE_RESP_OFFLOAD]);
1422
1423 if (tb[NL80211_ATTR_EXT_CAPA] && tb[NL80211_ATTR_EXT_CAPA_MASK] &&
1424 drv->extended_capa == NULL) {
1425 drv->extended_capa =
1426 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA]));
1427 if (drv->extended_capa) {
1428 os_memcpy(drv->extended_capa,
1429 nla_data(tb[NL80211_ATTR_EXT_CAPA]),
1430 nla_len(tb[NL80211_ATTR_EXT_CAPA]));
1431 drv->extended_capa_len =
1432 nla_len(tb[NL80211_ATTR_EXT_CAPA]);
1433 wpa_hexdump(MSG_DEBUG,
1434 "nl80211: Driver-advertised extended capabilities (default)",
1435 drv->extended_capa, drv->extended_capa_len);
1436 }
1437 drv->extended_capa_mask =
1438 os_malloc(nla_len(tb[NL80211_ATTR_EXT_CAPA_MASK]));
1439 if (drv->extended_capa_mask) {
1440 os_memcpy(drv->extended_capa_mask,
1441 nla_data(tb[NL80211_ATTR_EXT_CAPA_MASK]),
1442 nla_len(tb[NL80211_ATTR_EXT_CAPA_MASK]));
1443 wpa_hexdump(MSG_DEBUG,
1444 "nl80211: Driver-advertised extended capabilities mask (default)",
1445 drv->extended_capa_mask,
1446 drv->extended_capa_len);
1447 } else {
1448 os_free(drv->extended_capa);
1449 drv->extended_capa = NULL;
1450 drv->extended_capa_len = 0;
1451 }
1452 }
1453
1454 wiphy_info_extended_capab(drv, tb[NL80211_ATTR_IFTYPE_EXT_CAPA]);
1455
1456 #ifdef CONFIG_PR
1457 if (tb[NL80211_ATTR_PEER_MEASUREMENTS])
1458 wiphy_info_pmsr_capa(drv, tb);
1459 #endif /* CONFIG_PR */
1460
1461 if (tb[NL80211_ATTR_VENDOR_DATA]) {
1462 struct nlattr *nl;
1463 int rem;
1464
1465 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_DATA], rem) {
1466 struct nl80211_vendor_cmd_info *vinfo;
1467 if (nla_len(nl) != sizeof(*vinfo)) {
1468 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
1469 continue;
1470 }
1471 vinfo = nla_data(nl);
1472 if (vinfo->vendor_id == OUI_QCA) {
1473 switch (vinfo->subcmd) {
1474 case QCA_NL80211_VENDOR_SUBCMD_TEST:
1475 drv->vendor_cmd_test_avail = 1;
1476 break;
1477 #ifdef CONFIG_DRIVER_NL80211_QCA
1478 case QCA_NL80211_VENDOR_SUBCMD_ROAMING:
1479 drv->roaming_vendor_cmd_avail = 1;
1480 break;
1481 case QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY:
1482 drv->dfs_vendor_cmd_avail = 1;
1483 break;
1484 case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
1485 drv->get_features_vendor_cmd_avail = 1;
1486 break;
1487 case QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST:
1488 drv->get_pref_freq_list = 1;
1489 break;
1490 case QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL:
1491 drv->set_prob_oper_freq = 1;
1492 break;
1493 case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
1494 drv->capa.flags |=
1495 WPA_DRIVER_FLAGS_ACS_OFFLOAD;
1496 drv->qca_do_acs = 1;
1497 break;
1498 case QCA_NL80211_VENDOR_SUBCMD_SETBAND:
1499 drv->setband_vendor_cmd_avail = 1;
1500 break;
1501 case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
1502 drv->scan_vendor_cmd_avail = 1;
1503 break;
1504 case QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION:
1505 drv->set_wifi_conf_vendor_cmd_avail = 1;
1506 break;
1507 case QCA_NL80211_VENDOR_SUBCMD_FETCH_BSS_TRANSITION_STATUS:
1508 drv->fetch_bss_trans_status = 1;
1509 break;
1510 case QCA_NL80211_VENDOR_SUBCMD_ROAM:
1511 drv->roam_vendor_cmd_avail = 1;
1512 break;
1513 case QCA_NL80211_VENDOR_SUBCMD_ADD_STA_NODE:
1514 drv->add_sta_node_vendor_cmd_avail = 1;
1515 break;
1516 case QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO:
1517 drv->get_sta_info_vendor_cmd_avail = 1;
1518 break;
1519 case QCA_NL80211_VENDOR_SUBCMD_SECURE_RANGING_CONTEXT:
1520 drv->secure_ranging_ctx_vendor_cmd_avail = 1;
1521 break;
1522 case QCA_NL80211_VENDOR_SUBCMD_CONNECT_EXT:
1523 drv->connect_ext_vendor_cmd_avail = 1;
1524 break;
1525 #endif /* CONFIG_DRIVER_NL80211_QCA */
1526 }
1527 #ifdef CONFIG_DRIVER_NL80211_BRCM
1528 } else if (vinfo->vendor_id == OUI_BRCM) {
1529 switch (vinfo->subcmd) {
1530 case BRCM_VENDOR_SCMD_ACS:
1531 drv->capa.flags |=
1532 WPA_DRIVER_FLAGS_ACS_OFFLOAD;
1533 wpa_printf(MSG_DEBUG,
1534 "Enabled BRCM ACS");
1535 drv->brcm_do_acs = 1;
1536 break;
1537 }
1538 #endif /* CONFIG_DRIVER_NL80211_BRCM */
1539 }
1540
1541 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
1542 vinfo->vendor_id, vinfo->subcmd);
1543 }
1544 }
1545
1546 if (tb[NL80211_ATTR_VENDOR_EVENTS]) {
1547 struct nlattr *nl;
1548 int rem;
1549
1550 nla_for_each_nested(nl, tb[NL80211_ATTR_VENDOR_EVENTS], rem) {
1551 struct nl80211_vendor_cmd_info *vinfo;
1552 if (nla_len(nl) != sizeof(*vinfo)) {
1553 wpa_printf(MSG_DEBUG, "nl80211: Unexpected vendor data info");
1554 continue;
1555 }
1556 vinfo = nla_data(nl);
1557 wpa_printf(MSG_DEBUG, "nl80211: Supported vendor event: vendor_id=0x%x subcmd=%u",
1558 vinfo->vendor_id, vinfo->subcmd);
1559 }
1560 }
1561
1562 wiphy_info_wowlan_triggers(capa,
1563 tb[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]);
1564
1565 if (tb[NL80211_ATTR_MAX_AP_ASSOC_STA])
1566 capa->max_stations =
1567 nla_get_u32(tb[NL80211_ATTR_MAX_AP_ASSOC_STA]);
1568
1569 if (tb[NL80211_ATTR_MAX_CSA_COUNTERS])
1570 capa->max_csa_counters =
1571 nla_get_u8(tb[NL80211_ATTR_MAX_CSA_COUNTERS]);
1572
1573 if (tb[NL80211_ATTR_WIPHY_SELF_MANAGED_REG])
1574 capa->flags |= WPA_DRIVER_FLAGS_SELF_MANAGED_REGULATORY;
1575
1576 if (tb[NL80211_ATTR_MAX_NUM_AKM_SUITES])
1577 capa->max_num_akms =
1578 nla_get_u16(tb[NL80211_ATTR_MAX_NUM_AKM_SUITES]);
1579
1580 if (tb[NL80211_ATTR_MBSSID_CONFIG])
1581 wiphy_info_mbssid(capa, tb[NL80211_ATTR_MBSSID_CONFIG]);
1582
1583 if (tb[NL80211_ATTR_MLO_SUPPORT])
1584 capa->flags2 |= WPA_DRIVER_FLAGS2_MLO;
1585
1586 #ifdef CONFIG_NAN
1587 if (tb[NL80211_ATTR_BANDS]) {
1588 u32 bands;
1589
1590 bands = nla_get_u32(tb[NL80211_ATTR_BANDS]);
1591 wpa_printf(MSG_DEBUG, "nl80211: NAN supported bands 0x%x",
1592 bands);
1593 if ((bands & BIT(NL80211_BAND_2GHZ)) &&
1594 (bands & BIT(NL80211_BAND_5GHZ)))
1595 capa->nan_capa.drv_flags |=
1596 WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND;
1597 }
1598
1599 wiphy_info_nan_capa_handler(capa, info,
1600 tb[NL80211_ATTR_NAN_CAPABILITIES]);
1601 #endif /* CONFIG_NAN */
1602
1603 return NL_SKIP;
1604 }
1605
1606
wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data * drv,struct wiphy_info_data * info)1607 static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
1608 struct wiphy_info_data *info)
1609 {
1610 u32 feat;
1611 struct nl_msg *msg;
1612 int flags = 0;
1613
1614 os_memset(info, 0, sizeof(*info));
1615 info->capa = &drv->capa;
1616 info->drv = drv;
1617
1618 /* Default to large buffer of extra IE(s) to maintain previous behavior
1619 * if the driver does not support reporting an accurate limit. */
1620 info->capa->max_probe_req_ie_len = 1500;
1621
1622 feat = get_nl80211_protocol_features(drv);
1623 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
1624 flags = NLM_F_DUMP;
1625 msg = nl80211_cmd_msg(drv->first_bss, flags, NL80211_CMD_GET_WIPHY);
1626 if (!msg || nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
1627 nlmsg_free(msg);
1628 return -1;
1629 }
1630
1631 if (send_and_recv_resp(drv, msg, wiphy_info_handler, info))
1632 return -1;
1633
1634 if (info->auth_supported)
1635 drv->capa.flags |= WPA_DRIVER_FLAGS_SME;
1636 else if (!info->connect_supported) {
1637 wpa_printf(MSG_INFO, "nl80211: Driver does not support "
1638 "authentication/association or connect commands");
1639 info->error = 1;
1640 }
1641
1642 if (info->p2p_go_supported && info->p2p_client_supported)
1643 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CAPABLE;
1644 if (info->p2p_concurrent) {
1645 wpa_printf(MSG_DEBUG, "nl80211: Use separate P2P group "
1646 "interface (driver advertised support)");
1647 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_CONCURRENT;
1648 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P;
1649 }
1650 if (info->num_multichan_concurrent > 1) {
1651 wpa_printf(MSG_DEBUG, "nl80211: Enable multi-channel "
1652 "concurrent (driver advertised support)");
1653 drv->capa.num_multichan_concurrent =
1654 info->num_multichan_concurrent;
1655 }
1656 if (drv->capa.flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
1657 wpa_printf(MSG_DEBUG, "nl80211: use P2P_DEVICE support");
1658
1659 /* default to 5000 since early versions of mac80211 don't set it */
1660 if (!drv->capa.max_remain_on_chan)
1661 drv->capa.max_remain_on_chan = 5000;
1662
1663 drv->capa.wmm_ac_supported = info->wmm_ac_supported;
1664
1665 drv->capa.mac_addr_rand_sched_scan_supported =
1666 info->mac_addr_rand_sched_scan_supported;
1667 drv->capa.mac_addr_rand_scan_supported =
1668 info->mac_addr_rand_scan_supported;
1669
1670 if (info->channel_switch_supported) {
1671 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_CSA;
1672 if (!drv->capa.max_csa_counters)
1673 drv->capa.max_csa_counters = 1;
1674 }
1675
1676 if (!drv->capa.max_sched_scan_plans) {
1677 drv->capa.max_sched_scan_plans = 1;
1678 drv->capa.max_sched_scan_plan_interval = UINT32_MAX;
1679 drv->capa.max_sched_scan_plan_iterations = 0;
1680 }
1681
1682 if (info->update_ft_ies_supported)
1683 drv->capa.flags |= WPA_DRIVER_FLAGS_UPDATE_FT_IES;
1684
1685 if (!drv->capa.max_num_akms)
1686 drv->capa.max_num_akms = NL80211_MAX_NR_AKM_SUITES;
1687
1688 #ifdef CONFIG_NAN
1689 if (info->nan_supported) {
1690 if (info->nan_ndp_supported) {
1691 if (info->nan_phy_capabilities_valid) {
1692 wpa_printf(MSG_DEBUG, "nl80211: NAN supported");
1693 drv->capa.nan_capa.drv_flags |=
1694 WPA_DRIVER_FLAGS_NAN_SUPPORT_NDP;
1695 } else {
1696 wpa_printf(MSG_DEBUG,
1697 "nl80211: NAN NDP supported but NAN PHY capabilities not valid");
1698 }
1699 }
1700
1701 /* TODO: Currently support only a single radio */
1702 drv->capa.nan_capa.num_radios = 1;
1703 drv->capa.nan_capa.sched_chans =
1704 info->num_multichan_concurrent_nan;
1705
1706 /*
1707 * nl80211 supports only a single configuration that uses 16 TU
1708 * slots and a period of 512 TUs.
1709 */
1710 drv->capa.nan_capa.slot_duration = 16;
1711 drv->capa.nan_capa.schedule_period = 512;
1712
1713 /*
1714 * Support NAN beacon protection only if at least one of the NAN
1715 * management group ciphers is supported and the driver supports
1716 * beacon protection.
1717 */
1718 if ((info->capa->enc & (WPA_DRIVER_CAPA_ENC_BIP |
1719 WPA_DRIVER_CAPA_ENC_BIP_GMAC_256)) &&
1720 (drv->capa.flags & WPA_DRIVER_FLAGS_BEACON_PROTECTION))
1721 drv->capa.nan_capa.drv_flags |=
1722 WPA_DRIVER_FLAGS_NAN_SUPPORT_BEACON_PROT;
1723
1724 if (drv->capa.nan_capa.drv_flags &
1725 WPA_DRIVER_FLAGS_NAN_SUPPORT_BEACON_PROT)
1726 wpa_printf(MSG_DEBUG,
1727 "nl80211: NAN: beacon protection supported");
1728 }
1729 #endif /* CONFIG_NAN */
1730
1731 return 0;
1732 }
1733
1734
1735 #ifdef CONFIG_DRIVER_NL80211_QCA
1736
dfs_info_handler(struct nl_msg * msg,void * arg)1737 static int dfs_info_handler(struct nl_msg *msg, void *arg)
1738 {
1739 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1740 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1741 int *dfs_capability_ptr = arg;
1742
1743 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1744 genlmsg_attrlen(gnlh, 0), NULL);
1745
1746 if (tb[NL80211_ATTR_VENDOR_DATA]) {
1747 struct nlattr *nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
1748 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
1749
1750 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
1751 nla_data(nl_vend), nla_len(nl_vend), NULL);
1752
1753 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]) {
1754 u32 val;
1755 val = nla_get_u32(tb_vendor[QCA_WLAN_VENDOR_ATTR_DFS]);
1756 wpa_printf(MSG_DEBUG, "nl80211: DFS offload capability: %u",
1757 val);
1758 *dfs_capability_ptr = val;
1759 }
1760 }
1761
1762 return NL_SKIP;
1763 }
1764
1765
qca_nl80211_check_dfs_capa(struct wpa_driver_nl80211_data * drv)1766 static void qca_nl80211_check_dfs_capa(struct wpa_driver_nl80211_data *drv)
1767 {
1768 struct nl_msg *msg;
1769 int dfs_capability = 0;
1770 int ret;
1771
1772 if (!drv->dfs_vendor_cmd_avail)
1773 return;
1774
1775 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
1776 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
1777 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
1778 QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY)) {
1779 nlmsg_free(msg);
1780 return;
1781 }
1782
1783 ret = send_and_recv_resp(drv, msg, dfs_info_handler, &dfs_capability);
1784 if (!ret && dfs_capability)
1785 drv->capa.flags |= WPA_DRIVER_FLAGS_DFS_OFFLOAD;
1786 }
1787
1788
1789 struct features_info {
1790 u8 *flags;
1791 size_t flags_len;
1792 struct wpa_driver_capa *capa;
1793 };
1794
1795
features_info_handler(struct nl_msg * msg,void * arg)1796 static int features_info_handler(struct nl_msg *msg, void *arg)
1797 {
1798 struct nlattr *tb[NL80211_ATTR_MAX + 1];
1799 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
1800 struct features_info *info = arg;
1801 struct nlattr *nl_vend, *attr;
1802
1803 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
1804 genlmsg_attrlen(gnlh, 0), NULL);
1805
1806 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
1807 if (nl_vend) {
1808 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
1809
1810 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
1811 nla_data(nl_vend), nla_len(nl_vend), NULL);
1812
1813 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
1814 if (attr) {
1815 int len = nla_len(attr);
1816 info->flags = os_malloc(len);
1817 if (info->flags != NULL) {
1818 os_memcpy(info->flags, nla_data(attr), len);
1819 info->flags_len = len;
1820 }
1821 }
1822 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA];
1823 if (attr)
1824 info->capa->conc_capab = nla_get_u32(attr);
1825
1826 attr = tb_vendor[
1827 QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND];
1828 if (attr)
1829 info->capa->max_conc_chan_2_4 = nla_get_u32(attr);
1830
1831 attr = tb_vendor[
1832 QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND];
1833 if (attr)
1834 info->capa->max_conc_chan_5_0 = nla_get_u32(attr);
1835 }
1836
1837 return NL_SKIP;
1838 }
1839
1840
check_feature(enum qca_wlan_vendor_features feature,struct features_info * info)1841 static int check_feature(enum qca_wlan_vendor_features feature,
1842 struct features_info *info)
1843 {
1844 size_t idx = feature / 8;
1845
1846 return (idx < info->flags_len) &&
1847 (info->flags[idx] & BIT(feature % 8));
1848 }
1849
1850
qca_nl80211_get_features(struct wpa_driver_nl80211_data * drv)1851 static void qca_nl80211_get_features(struct wpa_driver_nl80211_data *drv)
1852 {
1853 struct nl_msg *msg;
1854 struct features_info info;
1855 int ret;
1856
1857 if (!drv->get_features_vendor_cmd_avail)
1858 return;
1859
1860 if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
1861 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
1862 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
1863 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
1864 nlmsg_free(msg);
1865 return;
1866 }
1867
1868 os_memset(&info, 0, sizeof(info));
1869 info.capa = &drv->capa;
1870 ret = send_and_recv_resp(drv, msg, features_info_handler, &info);
1871 if (ret || !info.flags)
1872 return;
1873
1874 if (check_feature(QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD, &info))
1875 drv->capa.flags |= WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD;
1876
1877 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY, &info))
1878 drv->capa.flags |= WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY;
1879
1880 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS,
1881 &info))
1882 drv->capa.flags |= WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS;
1883 if (check_feature(QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD, &info))
1884 drv->capa.flags |= WPA_DRIVER_FLAGS_P2P_LISTEN_OFFLOAD;
1885 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OCE_STA, &info))
1886 drv->capa.flags |= WPA_DRIVER_FLAGS_OCE_STA;
1887 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OCE_AP, &info))
1888 drv->capa.flags |= WPA_DRIVER_FLAGS_OCE_AP;
1889 if (check_feature(QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON, &info))
1890 drv->capa.flags |= WPA_DRIVER_FLAGS_OCE_STA_CFON;
1891 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_STA, &info))
1892 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_SEC_LTF_STA;
1893 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SECURE_LTF_AP, &info))
1894 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_SEC_LTF_AP;
1895 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SECURE_RTT_STA, &info))
1896 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_SEC_RTT_STA;
1897 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SECURE_RTT_AP, &info))
1898 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_SEC_RTT_AP;
1899 if (check_feature(
1900 QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_STA,
1901 &info))
1902 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_STA;
1903 if (check_feature(
1904 QCA_WLAN_VENDOR_FEATURE_PROT_RANGE_NEGO_AND_MEASURE_AP,
1905 &info))
1906 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_AP;
1907 if (check_feature(QCA_WLAN_VENDOR_FEATURE_AP_ALLOWED_FREQ_LIST,
1908 &info))
1909 drv->qca_ap_allowed_freqs = 1;
1910 if (check_feature(QCA_WLAN_VENDOR_FEATURE_HT_VHT_TWT_RESPONDER, &info))
1911 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_HT_VHT_TWT_RESPONDER;
1912 if (check_feature(QCA_WLAN_VENDOR_FEATURE_RSN_OVERRIDE_STA, &info)) {
1913 wpa_printf(MSG_DEBUG,
1914 "The driver supports RSN overriding in STA mode");
1915 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_RSN_OVERRIDE_STA;
1916 }
1917 if (check_feature(QCA_WLAN_VENDOR_FEATURE_NAN_USD_OFFLOAD, &info))
1918 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_NAN_USD_OFFLOAD;
1919
1920 if (check_feature(QCA_WLAN_VENDOR_FEATURE_P2P_V2, &info))
1921 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_P2P_FEATURE_V2;
1922
1923 if (check_feature(QCA_WLAN_VENDOR_FEATURE_PCC_MODE, &info))
1924 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_P2P_FEATURE_PCC_MODE;
1925
1926 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_P2P_ASSISTED_DFS,
1927 &info))
1928 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_P2P_ASSISTED_DFS;
1929
1930 if (check_feature(QCA_WLAN_VENDOR_FEATURE_SUPPORT_PMKSA_CACHING_PRIVACY,
1931 &info))
1932 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_PMKSA_PRIVACY;
1933
1934 os_free(info.flags);
1935 }
1936
1937 #endif /* CONFIG_DRIVER_NL80211_QCA */
1938
1939
wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data * drv)1940 int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv)
1941 {
1942 struct wiphy_info_data info;
1943 int i;
1944
1945 if (wpa_driver_nl80211_get_info(drv, &info))
1946 return -1;
1947
1948 if (info.error)
1949 return -1;
1950
1951 drv->has_capability = 1;
1952 drv->has_driver_key_mgmt = info.has_key_mgmt | info.has_key_mgmt_iftype;
1953
1954 /* Fallback to hardcoded defaults if the driver does not advertise any
1955 * AKM capabilities. */
1956 if (!drv->has_driver_key_mgmt) {
1957 drv->capa.key_mgmt = WPA_DRIVER_CAPA_KEY_MGMT_WPA |
1958 WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
1959 WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
1960 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK |
1961 WPA_DRIVER_CAPA_KEY_MGMT_PSK_SHA256 |
1962 WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B |
1963 WPA_DRIVER_CAPA_KEY_MGMT_OWE |
1964 WPA_DRIVER_CAPA_KEY_MGMT_DPP;
1965
1966 if (drv->capa.enc & (WPA_DRIVER_CAPA_ENC_CCMP_256 |
1967 WPA_DRIVER_CAPA_ENC_GCMP_256))
1968 drv->capa.key_mgmt |=
1969 WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192;
1970
1971 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME)
1972 drv->capa.key_mgmt |=
1973 WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256 |
1974 WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384 |
1975 WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA256 |
1976 WPA_DRIVER_CAPA_KEY_MGMT_FT_FILS_SHA384 |
1977 WPA_DRIVER_CAPA_KEY_MGMT_SAE_EXT_KEY |
1978 WPA_DRIVER_CAPA_KEY_MGMT_SAE;
1979 else if (drv->capa.flags & WPA_DRIVER_FLAGS_FILS_SK_OFFLOAD)
1980 drv->capa.key_mgmt |=
1981 WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256 |
1982 WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384;
1983 }
1984
1985 if (!info.has_key_mgmt_iftype) {
1986 /* If the driver does not advertize per interface AKM
1987 * capabilities, consider all interfaces to support default AKMs
1988 * in key_mgmt. */
1989 for (i = 0; i < WPA_IF_MAX; i++)
1990 drv->capa.key_mgmt_iftype[i] = drv->capa.key_mgmt;
1991 } else if (info.has_key_mgmt_iftype && !info.has_key_mgmt) {
1992 /* If the driver advertizes only per interface supported AKMs
1993 * but does not advertize per wiphy AKM capabilities, consider
1994 * the default key_mgmt as a mask of per interface supported
1995 * AKMs. */
1996 drv->capa.key_mgmt = 0;
1997 for (i = 0; i < WPA_IF_MAX; i++)
1998 drv->capa.key_mgmt |= drv->capa.key_mgmt_iftype[i];
1999 } else if (info.has_key_mgmt_iftype && info.has_key_mgmt) {
2000 /* If the driver advertizes AKM capabilities both per wiphy and
2001 * per interface, consider the interfaces for which per
2002 * interface AKM capabilities were not received to support the
2003 * default key_mgmt capabilities.
2004 */
2005 for (i = 0; i < WPA_IF_MAX; i++)
2006 if (!drv->capa.key_mgmt_iftype[i])
2007 drv->capa.key_mgmt_iftype[i] =
2008 drv->capa.key_mgmt;
2009 }
2010
2011 drv->capa.auth = WPA_DRIVER_AUTH_OPEN |
2012 WPA_DRIVER_AUTH_SHARED |
2013 WPA_DRIVER_AUTH_LEAP;
2014
2015 drv->capa.flags |= WPA_DRIVER_FLAGS_VALID_ERROR_CODES;
2016 drv->capa.flags |= WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE;
2017 drv->capa.flags |= WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
2018
2019 /*
2020 * As all cfg80211 drivers must support cases where the AP interface is
2021 * removed without the knowledge of wpa_supplicant/hostapd, e.g., in
2022 * case that the user space daemon has crashed, they must be able to
2023 * cleanup all stations and key entries in the AP tear down flow. Thus,
2024 * this flag can/should always be set for cfg80211 drivers.
2025 */
2026 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT;
2027
2028 if (!info.device_ap_sme) {
2029 drv->capa.flags |= WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS;
2030 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_AP_SME;
2031
2032 /*
2033 * No AP SME is currently assumed to also indicate no AP MLME
2034 * in the driver/firmware.
2035 */
2036 drv->capa.flags |= WPA_DRIVER_FLAGS_AP_MLME;
2037 }
2038
2039 drv->device_ap_sme = info.device_ap_sme;
2040 drv->poll_command_supported = info.poll_command_supported;
2041 drv->data_tx_status = info.data_tx_status;
2042 drv->p2p_go_ctwindow_supported = info.p2p_go_ctwindow_supported;
2043 if (info.set_qos_map_supported)
2044 drv->capa.flags |= WPA_DRIVER_FLAGS_QOS_MAPPING;
2045 drv->have_low_prio_scan = info.have_low_prio_scan;
2046 drv->support_ap_scan = info.support_ap_scan;
2047
2048 /*
2049 * If the driver doesn't support data TX status, we won't get TX
2050 * status for EAPOL frames.
2051 */
2052 if (!info.data_tx_status)
2053 drv->capa.flags &= ~WPA_DRIVER_FLAGS_EAPOL_TX_STATUS;
2054
2055 /* Enable P2P2 and PCC mode capabilities by default for the drivers
2056 * for which SME runs in wpa_supplicant
2057 */
2058 if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
2059 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_P2P_FEATURE_V2;
2060 drv->capa.flags2 |= WPA_DRIVER_FLAGS2_P2P_FEATURE_PCC_MODE;
2061 }
2062
2063 #ifdef CONFIG_DRIVER_NL80211_QCA
2064 if (!(info.capa->flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD))
2065 qca_nl80211_check_dfs_capa(drv);
2066 qca_nl80211_get_features(drv);
2067
2068 /*
2069 * To enable offchannel simultaneous support in wpa_supplicant, the
2070 * underlying driver needs to support the same along with offchannel TX.
2071 * Offchannel TX support is needed since remain_on_channel and
2072 * action_tx use some common data structures and hence cannot be
2073 * scheduled simultaneously.
2074 */
2075 if (!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX))
2076 drv->capa.flags &= ~WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS;
2077 #endif /* CONFIG_DRIVER_NL80211_QCA */
2078
2079 wpa_printf(MSG_DEBUG,
2080 "nl80211: key_mgmt=0x%x enc=0x%x auth=0x%x flags=0x%llx flags2=0x%llx rrm_flags=0x%x probe_resp_offloads=0x%x max_stations=%u max_remain_on_chan=%u max_scan_ssids=%d",
2081 drv->capa.key_mgmt, drv->capa.enc, drv->capa.auth,
2082 (unsigned long long) drv->capa.flags,
2083 (unsigned long long) drv->capa.flags2, drv->capa.rrm_flags,
2084 drv->capa.probe_resp_offloads, drv->capa.max_stations,
2085 drv->capa.max_remain_on_chan, drv->capa.max_scan_ssids);
2086 return 0;
2087 }
2088
2089
2090 struct phy_info_arg {
2091 u16 *num_modes;
2092 struct hostapd_hw_modes *modes;
2093 int last_mode, last_chan_idx;
2094 int failed;
2095 u8 dfs_domain;
2096 char alpha2[3]; /* Country code from NL80211_ATTR_REG_ALPHA2 */
2097 };
2098
phy_info_ht_capa(struct hostapd_hw_modes * mode,struct nlattr * capa,struct nlattr * ampdu_factor,struct nlattr * ampdu_density,struct nlattr * mcs_set)2099 static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
2100 struct nlattr *ampdu_factor,
2101 struct nlattr *ampdu_density,
2102 struct nlattr *mcs_set)
2103 {
2104 if (capa)
2105 mode->ht_capab = nla_get_u16(capa);
2106
2107 if (ampdu_factor)
2108 mode->a_mpdu_params |= nla_get_u8(ampdu_factor) & 0x03;
2109
2110 if (ampdu_density)
2111 mode->a_mpdu_params |= nla_get_u8(ampdu_density) << 2;
2112
2113 if (mcs_set && nla_len(mcs_set) >= 16) {
2114 u8 *mcs;
2115 mcs = nla_data(mcs_set);
2116 os_memcpy(mode->mcs_set, mcs, 16);
2117 }
2118 }
2119
2120
phy_info_vht_capa(struct hostapd_hw_modes * mode,struct nlattr * capa,struct nlattr * mcs_set)2121 static void phy_info_vht_capa(struct hostapd_hw_modes *mode,
2122 struct nlattr *capa,
2123 struct nlattr *mcs_set)
2124 {
2125 if (capa)
2126 mode->vht_capab = nla_get_u32(capa);
2127
2128 if (mcs_set && nla_len(mcs_set) >= 8) {
2129 u8 *mcs;
2130 mcs = nla_data(mcs_set);
2131 os_memcpy(mode->vht_mcs_set, mcs, 8);
2132 }
2133 }
2134
2135
phy_info_edmg_capa(struct hostapd_hw_modes * mode,struct nlattr * bw_config,struct nlattr * channels)2136 static int phy_info_edmg_capa(struct hostapd_hw_modes *mode,
2137 struct nlattr *bw_config,
2138 struct nlattr *channels)
2139 {
2140 if (!bw_config || !channels)
2141 return NL_OK;
2142
2143 mode->edmg.bw_config = nla_get_u8(bw_config);
2144 mode->edmg.channels = nla_get_u8(channels);
2145
2146 if (!mode->edmg.channels || !mode->edmg.bw_config)
2147 return NL_STOP;
2148
2149 return NL_OK;
2150 }
2151
2152
cw2ecw(unsigned int cw)2153 static int cw2ecw(unsigned int cw)
2154 {
2155 int bit;
2156
2157 if (cw == 0)
2158 return 0;
2159
2160 for (bit = 1; cw != 1; bit++)
2161 cw >>= 1;
2162
2163 return bit;
2164 }
2165
2166
phy_info_freq(struct hostapd_hw_modes * mode,struct hostapd_channel_data * chan,struct nlattr * tb_freq[])2167 static void phy_info_freq(struct hostapd_hw_modes *mode,
2168 struct hostapd_channel_data *chan,
2169 struct nlattr *tb_freq[])
2170 {
2171 u8 channel;
2172
2173 os_memset(chan, 0, sizeof(*chan));
2174 chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
2175 chan->flag = 0;
2176 chan->allowed_bw = ~0;
2177 chan->dfs_cac_ms = 0;
2178 if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES)
2179 chan->chan = channel;
2180 else
2181 wpa_printf(MSG_DEBUG,
2182 "nl80211: No channel number found for frequency %u MHz",
2183 chan->freq);
2184
2185 if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
2186 chan->flag |= HOSTAPD_CHAN_DISABLED;
2187 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
2188 chan->flag |= HOSTAPD_CHAN_NO_IR;
2189 if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
2190 chan->flag |= HOSTAPD_CHAN_RADAR;
2191 if (tb_freq[NL80211_FREQUENCY_ATTR_INDOOR_ONLY])
2192 chan->flag |= HOSTAPD_CHAN_INDOOR_ONLY;
2193 if (tb_freq[NL80211_FREQUENCY_ATTR_GO_CONCURRENT])
2194 chan->flag |= HOSTAPD_CHAN_GO_CONCURRENT;
2195
2196 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_10MHZ])
2197 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_10;
2198 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_20MHZ])
2199 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_20;
2200 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS])
2201 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40P;
2202 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS])
2203 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_40M;
2204 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_80MHZ])
2205 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_80;
2206 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ])
2207 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_160;
2208 if (tb_freq[NL80211_FREQUENCY_ATTR_NO_320MHZ])
2209 chan->allowed_bw &= ~HOSTAPD_CHAN_WIDTH_320;
2210
2211 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) {
2212 enum nl80211_dfs_state state =
2213 nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]);
2214
2215 switch (state) {
2216 case NL80211_DFS_USABLE:
2217 chan->flag |= HOSTAPD_CHAN_DFS_USABLE;
2218 break;
2219 case NL80211_DFS_AVAILABLE:
2220 chan->flag |= HOSTAPD_CHAN_DFS_AVAILABLE;
2221 break;
2222 case NL80211_DFS_UNAVAILABLE:
2223 chan->flag |= HOSTAPD_CHAN_DFS_UNAVAILABLE;
2224 break;
2225 }
2226 }
2227
2228 if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]) {
2229 chan->dfs_cac_ms = nla_get_u32(
2230 tb_freq[NL80211_FREQUENCY_ATTR_DFS_CAC_TIME]);
2231 }
2232
2233 chan->wmm_rules_valid = 0;
2234 if (tb_freq[NL80211_FREQUENCY_ATTR_WMM]) {
2235 static struct nla_policy wmm_policy[NL80211_WMMR_MAX + 1] = {
2236 [NL80211_WMMR_CW_MIN] = { .type = NLA_U16 },
2237 [NL80211_WMMR_CW_MAX] = { .type = NLA_U16 },
2238 [NL80211_WMMR_AIFSN] = { .type = NLA_U8 },
2239 [NL80211_WMMR_TXOP] = { .type = NLA_U16 },
2240 };
2241 static const u8 wmm_map[4] = {
2242 [NL80211_AC_BE] = WMM_AC_BE,
2243 [NL80211_AC_BK] = WMM_AC_BK,
2244 [NL80211_AC_VI] = WMM_AC_VI,
2245 [NL80211_AC_VO] = WMM_AC_VO,
2246 };
2247 struct nlattr *nl_wmm;
2248 struct nlattr *tb_wmm[NL80211_WMMR_MAX + 1];
2249 int rem_wmm, ac, count = 0;
2250
2251 nla_for_each_nested(nl_wmm, tb_freq[NL80211_FREQUENCY_ATTR_WMM],
2252 rem_wmm) {
2253 if (nla_parse_nested(tb_wmm, NL80211_WMMR_MAX, nl_wmm,
2254 wmm_policy)) {
2255 wpa_printf(MSG_DEBUG,
2256 "nl80211: Failed to parse WMM rules attribute");
2257 return;
2258 }
2259 if (!tb_wmm[NL80211_WMMR_CW_MIN] ||
2260 !tb_wmm[NL80211_WMMR_CW_MAX] ||
2261 !tb_wmm[NL80211_WMMR_AIFSN] ||
2262 !tb_wmm[NL80211_WMMR_TXOP]) {
2263 wpa_printf(MSG_DEBUG,
2264 "nl80211: Channel is missing WMM rule attribute");
2265 return;
2266 }
2267 ac = nl_wmm->nla_type;
2268 if ((unsigned int) ac >= ARRAY_SIZE(wmm_map)) {
2269 wpa_printf(MSG_DEBUG,
2270 "nl80211: Invalid AC value %d", ac);
2271 return;
2272 }
2273
2274 ac = wmm_map[ac];
2275 chan->wmm_rules[ac].min_cwmin =
2276 cw2ecw(nla_get_u16(
2277 tb_wmm[NL80211_WMMR_CW_MIN]));
2278 chan->wmm_rules[ac].min_cwmax =
2279 cw2ecw(nla_get_u16(
2280 tb_wmm[NL80211_WMMR_CW_MAX]));
2281 chan->wmm_rules[ac].min_aifs =
2282 nla_get_u8(tb_wmm[NL80211_WMMR_AIFSN]);
2283 chan->wmm_rules[ac].max_txop =
2284 nla_get_u16(tb_wmm[NL80211_WMMR_TXOP]) / 32;
2285 count++;
2286 }
2287
2288 /* Set valid flag if all the AC rules are present */
2289 if (count == WMM_AC_NUM)
2290 chan->wmm_rules_valid = 1;
2291 }
2292 }
2293
2294
phy_info_freqs(struct phy_info_arg * phy_info,struct hostapd_hw_modes * mode,struct nlattr * tb)2295 static int phy_info_freqs(struct phy_info_arg *phy_info,
2296 struct hostapd_hw_modes *mode, struct nlattr *tb)
2297 {
2298 static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
2299 [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
2300 [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
2301 [NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
2302 [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
2303 [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
2304 [NL80211_FREQUENCY_ATTR_DFS_STATE] = { .type = NLA_U32 },
2305 [NL80211_FREQUENCY_ATTR_NO_10MHZ] = { .type = NLA_FLAG },
2306 [NL80211_FREQUENCY_ATTR_NO_20MHZ] = { .type = NLA_FLAG },
2307 [NL80211_FREQUENCY_ATTR_NO_HT40_PLUS] = { .type = NLA_FLAG },
2308 [NL80211_FREQUENCY_ATTR_NO_HT40_MINUS] = { .type = NLA_FLAG },
2309 [NL80211_FREQUENCY_ATTR_NO_80MHZ] = { .type = NLA_FLAG },
2310 [NL80211_FREQUENCY_ATTR_NO_160MHZ] = { .type = NLA_FLAG },
2311 [NL80211_FREQUENCY_ATTR_NO_320MHZ] = { .type = NLA_FLAG },
2312
2313 };
2314 int new_channels = 0;
2315 struct hostapd_channel_data *channel;
2316 struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
2317 struct nlattr *nl_freq;
2318 int rem_freq, idx;
2319
2320 if (tb == NULL)
2321 return NL_OK;
2322
2323 nla_for_each_nested(nl_freq, tb, rem_freq) {
2324 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
2325 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
2326 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
2327 continue;
2328 new_channels++;
2329 }
2330
2331 channel = os_realloc_array(mode->channels,
2332 mode->num_channels + new_channels,
2333 sizeof(struct hostapd_channel_data));
2334 if (!channel)
2335 return NL_STOP;
2336
2337 mode->channels = channel;
2338 mode->num_channels += new_channels;
2339
2340 idx = phy_info->last_chan_idx;
2341
2342 nla_for_each_nested(nl_freq, tb, rem_freq) {
2343 nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX,
2344 nla_data(nl_freq), nla_len(nl_freq), freq_policy);
2345 if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
2346 continue;
2347 phy_info_freq(mode, &mode->channels[idx], tb_freq);
2348 idx++;
2349 }
2350 phy_info->last_chan_idx = idx;
2351
2352 return NL_OK;
2353 }
2354
2355
phy_info_rates(struct hostapd_hw_modes * mode,struct nlattr * tb)2356 static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
2357 {
2358 static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = {
2359 [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 },
2360 [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] =
2361 { .type = NLA_FLAG },
2362 };
2363 struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
2364 struct nlattr *nl_rate;
2365 int rem_rate, idx;
2366
2367 if (tb == NULL)
2368 return NL_OK;
2369
2370 nla_for_each_nested(nl_rate, tb, rem_rate) {
2371 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
2372 nla_data(nl_rate), nla_len(nl_rate),
2373 rate_policy);
2374 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
2375 continue;
2376 mode->num_rates++;
2377 }
2378
2379 mode->rates = os_calloc(mode->num_rates, sizeof(int));
2380 if (!mode->rates)
2381 return NL_STOP;
2382
2383 idx = 0;
2384
2385 nla_for_each_nested(nl_rate, tb, rem_rate) {
2386 nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX,
2387 nla_data(nl_rate), nla_len(nl_rate),
2388 rate_policy);
2389 if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
2390 continue;
2391 mode->rates[idx] = nla_get_u32(
2392 tb_rate[NL80211_BITRATE_ATTR_RATE]);
2393 idx++;
2394 }
2395
2396 return NL_OK;
2397 }
2398
2399
phy_info_iftype_copy(struct hostapd_hw_modes * mode,enum ieee80211_op_mode opmode,struct nlattr ** tb,struct nlattr ** tb_flags)2400 static void phy_info_iftype_copy(struct hostapd_hw_modes *mode,
2401 enum ieee80211_op_mode opmode,
2402 struct nlattr **tb, struct nlattr **tb_flags)
2403 {
2404 enum nl80211_iftype iftype;
2405 size_t len;
2406 struct he_capabilities *he_capab = &mode->he_capab[opmode];
2407 struct eht_capabilities *eht_capab = &mode->eht_capab[opmode];
2408
2409 switch (opmode) {
2410 case IEEE80211_MODE_INFRA:
2411 iftype = NL80211_IFTYPE_STATION;
2412 break;
2413 case IEEE80211_MODE_IBSS:
2414 iftype = NL80211_IFTYPE_ADHOC;
2415 break;
2416 case IEEE80211_MODE_AP:
2417 iftype = NL80211_IFTYPE_AP;
2418 break;
2419 case IEEE80211_MODE_MESH:
2420 iftype = NL80211_IFTYPE_MESH_POINT;
2421 break;
2422 default:
2423 return;
2424 }
2425
2426 if (!nla_get_flag(tb_flags[iftype]))
2427 return;
2428
2429 he_capab->he_supported = 1;
2430
2431 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]) {
2432 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]);
2433
2434 if (len > sizeof(he_capab->phy_cap))
2435 len = sizeof(he_capab->phy_cap);
2436 os_memcpy(he_capab->phy_cap,
2437 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY]),
2438 len);
2439 }
2440
2441 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]) {
2442 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]);
2443
2444 if (len > sizeof(he_capab->mac_cap))
2445 len = sizeof(he_capab->mac_cap);
2446 os_memcpy(he_capab->mac_cap,
2447 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC]),
2448 len);
2449 }
2450
2451 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]) {
2452 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]);
2453
2454 if (len > sizeof(he_capab->mcs))
2455 len = sizeof(he_capab->mcs);
2456 os_memcpy(he_capab->mcs,
2457 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET]),
2458 len);
2459 }
2460
2461 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]) {
2462 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]);
2463
2464 if (len > sizeof(he_capab->ppet))
2465 len = sizeof(he_capab->ppet);
2466 os_memcpy(&he_capab->ppet,
2467 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE]),
2468 len);
2469 }
2470
2471 if (tb[NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA] &&
2472 nla_len(tb[NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA]) >= 2)
2473 he_capab->he_6ghz_capa = WPA_GET_LE16(
2474 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA]));
2475
2476 if (!tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC] ||
2477 !tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY])
2478 return;
2479
2480 eht_capab->eht_supported = true;
2481
2482 if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC] &&
2483 nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]) >= 2) {
2484 const u8 *pos;
2485
2486 pos = nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]);
2487 eht_capab->mac_cap = WPA_GET_LE16(pos);
2488 }
2489
2490 if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) {
2491 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]);
2492 if (len > sizeof(eht_capab->phy_cap))
2493 len = sizeof(eht_capab->phy_cap);
2494 os_memcpy(eht_capab->phy_cap,
2495 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]),
2496 len);
2497 }
2498
2499 if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]) {
2500 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]);
2501 if (len > sizeof(eht_capab->mcs))
2502 len = sizeof(eht_capab->mcs);
2503 os_memcpy(eht_capab->mcs,
2504 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]),
2505 len);
2506 }
2507
2508 if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]) {
2509 len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]);
2510 if (len > sizeof(eht_capab->ppet))
2511 len = sizeof(eht_capab->ppet);
2512 os_memcpy(&eht_capab->ppet,
2513 nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]),
2514 len);
2515 }
2516 }
2517
2518
phy_info_iftype(struct hostapd_hw_modes * mode,struct nlattr * nl_iftype)2519 static int phy_info_iftype(struct hostapd_hw_modes *mode,
2520 struct nlattr *nl_iftype)
2521 {
2522 struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
2523 struct nlattr *tb_flags[NL80211_IFTYPE_MAX + 1];
2524 unsigned int i;
2525
2526 nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
2527 nla_data(nl_iftype), nla_len(nl_iftype), NULL);
2528
2529 if (!tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES])
2530 return NL_STOP;
2531
2532 if (nla_parse_nested(tb_flags, NL80211_IFTYPE_MAX,
2533 tb[NL80211_BAND_IFTYPE_ATTR_IFTYPES], NULL))
2534 return NL_STOP;
2535
2536 for (i = 0; i < IEEE80211_MODE_NUM; i++)
2537 phy_info_iftype_copy(mode, i, tb, tb_flags);
2538
2539 return NL_OK;
2540 }
2541
2542
phy_info_band(struct phy_info_arg * phy_info,struct nlattr * nl_band)2543 static int phy_info_band(struct phy_info_arg *phy_info, struct nlattr *nl_band)
2544 {
2545 struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
2546 struct hostapd_hw_modes *mode;
2547 int ret;
2548
2549 if (phy_info->last_mode != nl_band->nla_type) {
2550 mode = os_realloc_array(phy_info->modes,
2551 *phy_info->num_modes + 1,
2552 sizeof(*mode));
2553 if (!mode) {
2554 phy_info->failed = 1;
2555 return NL_STOP;
2556 }
2557 phy_info->modes = mode;
2558
2559 mode = &phy_info->modes[*(phy_info->num_modes)];
2560 os_memset(mode, 0, sizeof(*mode));
2561 mode->mode = NUM_HOSTAPD_MODES;
2562 mode->flags = HOSTAPD_MODE_FLAG_HT_INFO_KNOWN |
2563 HOSTAPD_MODE_FLAG_VHT_INFO_KNOWN |
2564 HOSTAPD_MODE_FLAG_HE_INFO_KNOWN |
2565 HOSTAPD_MODE_FLAG_EHT_INFO_KNOWN;
2566
2567 /*
2568 * Unsupported VHT MCS stream is defined as value 3, so the VHT
2569 * MCS RX/TX map must be initialized with 0xffff to mark all 8
2570 * possible streams as unsupported. This will be overridden if
2571 * driver advertises VHT support.
2572 */
2573 mode->vht_mcs_set[0] = 0xff;
2574 mode->vht_mcs_set[1] = 0xff;
2575 mode->vht_mcs_set[4] = 0xff;
2576 mode->vht_mcs_set[5] = 0xff;
2577
2578 *(phy_info->num_modes) += 1;
2579 phy_info->last_mode = nl_band->nla_type;
2580 phy_info->last_chan_idx = 0;
2581 } else
2582 mode = &phy_info->modes[*(phy_info->num_modes) - 1];
2583
2584 nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band),
2585 nla_len(nl_band), NULL);
2586
2587 phy_info_ht_capa(mode, tb_band[NL80211_BAND_ATTR_HT_CAPA],
2588 tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR],
2589 tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY],
2590 tb_band[NL80211_BAND_ATTR_HT_MCS_SET]);
2591 phy_info_vht_capa(mode, tb_band[NL80211_BAND_ATTR_VHT_CAPA],
2592 tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]);
2593 ret = phy_info_edmg_capa(mode,
2594 tb_band[NL80211_BAND_ATTR_EDMG_BW_CONFIG],
2595 tb_band[NL80211_BAND_ATTR_EDMG_CHANNELS]);
2596 if (ret == NL_OK)
2597 ret = phy_info_freqs(phy_info, mode,
2598 tb_band[NL80211_BAND_ATTR_FREQS]);
2599 if (ret == NL_OK)
2600 ret = phy_info_rates(mode, tb_band[NL80211_BAND_ATTR_RATES]);
2601 if (ret != NL_OK) {
2602 phy_info->failed = 1;
2603 return ret;
2604 }
2605
2606 if (tb_band[NL80211_BAND_ATTR_IFTYPE_DATA]) {
2607 struct nlattr *nl_iftype;
2608 int rem_band;
2609
2610 nla_for_each_nested(nl_iftype,
2611 tb_band[NL80211_BAND_ATTR_IFTYPE_DATA],
2612 rem_band) {
2613 ret = phy_info_iftype(mode, nl_iftype);
2614 if (ret != NL_OK)
2615 return ret;
2616 }
2617 }
2618
2619 return NL_OK;
2620 }
2621
2622
phy_info_handler(struct nl_msg * msg,void * arg)2623 static int phy_info_handler(struct nl_msg *msg, void *arg)
2624 {
2625 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
2626 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2627 struct phy_info_arg *phy_info = arg;
2628 struct nlattr *nl_band;
2629 int rem_band;
2630
2631 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2632 genlmsg_attrlen(gnlh, 0), NULL);
2633
2634 if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
2635 return NL_SKIP;
2636
2637 nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
2638 {
2639 int res = phy_info_band(phy_info, nl_band);
2640 if (res != NL_OK)
2641 return res;
2642 }
2643
2644 return NL_SKIP;
2645 }
2646
2647
2648 static struct hostapd_hw_modes *
wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes * modes,u16 * num_modes)2649 wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
2650 u16 *num_modes)
2651 {
2652 u16 m;
2653 struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
2654 int i, mode11g_idx = -1;
2655
2656 /* heuristic to set up modes */
2657 for (m = 0; m < *num_modes; m++) {
2658 if (!modes[m].num_channels)
2659 continue;
2660
2661 modes[m].is_6ghz = false;
2662
2663 if (modes[m].channels[0].freq < 2000) {
2664 modes[m].num_channels = 0;
2665 continue;
2666 } else if (modes[m].channels[0].freq < 4000) {
2667 modes[m].mode = HOSTAPD_MODE_IEEE80211B;
2668 for (i = 0; i < modes[m].num_rates; i++) {
2669 if (modes[m].rates[i] > 200) {
2670 modes[m].mode = HOSTAPD_MODE_IEEE80211G;
2671 break;
2672 }
2673 }
2674 } else if (modes[m].channels[0].freq > 50000) {
2675 modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
2676 } else if (is_6ghz_freq(modes[m].channels[0].freq)) {
2677 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
2678 modes[m].is_6ghz = true;
2679 } else {
2680 modes[m].mode = HOSTAPD_MODE_IEEE80211A;
2681 }
2682 }
2683
2684 /* Remove unsupported bands */
2685 m = 0;
2686 while (m < *num_modes) {
2687 if (modes[m].mode == NUM_HOSTAPD_MODES) {
2688 wpa_printf(MSG_DEBUG,
2689 "nl80211: Remove unsupported mode");
2690 os_free(modes[m].channels);
2691 os_free(modes[m].rates);
2692 if (m + 1 < *num_modes)
2693 os_memmove(&modes[m], &modes[m + 1],
2694 sizeof(struct hostapd_hw_modes) *
2695 (*num_modes - (m + 1)));
2696 (*num_modes)--;
2697 continue;
2698 }
2699 m++;
2700 }
2701
2702 /* If only 802.11g mode is included, use it to construct matching
2703 * 802.11b mode data. */
2704
2705 for (m = 0; m < *num_modes; m++) {
2706 if (modes[m].mode == HOSTAPD_MODE_IEEE80211B)
2707 return modes; /* 802.11b already included */
2708 if (modes[m].mode == HOSTAPD_MODE_IEEE80211G)
2709 mode11g_idx = m;
2710 }
2711
2712 if (mode11g_idx < 0)
2713 return modes; /* 2.4 GHz band not supported at all */
2714
2715 nmodes = os_realloc_array(modes, *num_modes + 1, sizeof(*nmodes));
2716 if (nmodes == NULL)
2717 return modes; /* Could not add 802.11b mode */
2718
2719 mode = &nmodes[*num_modes];
2720 os_memset(mode, 0, sizeof(*mode));
2721 (*num_modes)++;
2722 modes = nmodes;
2723
2724 mode->mode = HOSTAPD_MODE_IEEE80211B;
2725
2726 mode11g = &modes[mode11g_idx];
2727 mode->num_channels = mode11g->num_channels;
2728 mode->channels = os_memdup(mode11g->channels,
2729 mode11g->num_channels *
2730 sizeof(struct hostapd_channel_data));
2731 if (mode->channels == NULL) {
2732 (*num_modes)--;
2733 return modes; /* Could not add 802.11b mode */
2734 }
2735
2736 mode->num_rates = 0;
2737 mode->rates = os_malloc(4 * sizeof(int));
2738 if (mode->rates == NULL) {
2739 os_free(mode->channels);
2740 (*num_modes)--;
2741 return modes; /* Could not add 802.11b mode */
2742 }
2743
2744 for (i = 0; i < mode11g->num_rates; i++) {
2745 if (mode11g->rates[i] != 10 && mode11g->rates[i] != 20 &&
2746 mode11g->rates[i] != 55 && mode11g->rates[i] != 110)
2747 continue;
2748 mode->rates[mode->num_rates] = mode11g->rates[i];
2749 mode->num_rates++;
2750 if (mode->num_rates == 4)
2751 break;
2752 }
2753
2754 if (mode->num_rates == 0) {
2755 os_free(mode->channels);
2756 os_free(mode->rates);
2757 (*num_modes)--;
2758 return modes; /* No 802.11b rates */
2759 }
2760
2761 wpa_printf(MSG_DEBUG, "nl80211: Added 802.11b mode based on 802.11g "
2762 "information");
2763
2764 return modes;
2765 }
2766
2767
nl80211_set_ht40_mode(struct hostapd_hw_modes * mode,int start,int end)2768 static void nl80211_set_ht40_mode(struct hostapd_hw_modes *mode, int start,
2769 int end)
2770 {
2771 int c;
2772
2773 for (c = 0; c < mode->num_channels; c++) {
2774 struct hostapd_channel_data *chan = &mode->channels[c];
2775 if (chan->freq - 10 >= start && chan->freq + 10 <= end)
2776 chan->flag |= HOSTAPD_CHAN_HT40;
2777 }
2778 }
2779
2780
nl80211_set_ht40_mode_sec(struct hostapd_hw_modes * mode,int start,int end)2781 static void nl80211_set_ht40_mode_sec(struct hostapd_hw_modes *mode, int start,
2782 int end)
2783 {
2784 int c;
2785
2786 for (c = 0; c < mode->num_channels; c++) {
2787 struct hostapd_channel_data *chan = &mode->channels[c];
2788 if (!(chan->flag & HOSTAPD_CHAN_HT40))
2789 continue;
2790 if (chan->freq - 30 >= start && chan->freq - 10 <= end)
2791 chan->flag |= HOSTAPD_CHAN_HT40MINUS;
2792 if (chan->freq + 10 >= start && chan->freq + 30 <= end)
2793 chan->flag |= HOSTAPD_CHAN_HT40PLUS;
2794 }
2795 }
2796
2797
nl80211_reg_rule_max_eirp(u32 start,u32 end,u32 max_eirp,struct phy_info_arg * results)2798 static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
2799 struct phy_info_arg *results)
2800 {
2801 u16 m;
2802
2803 for (m = 0; m < *results->num_modes; m++) {
2804 int c;
2805 struct hostapd_hw_modes *mode = &results->modes[m];
2806
2807 for (c = 0; c < mode->num_channels; c++) {
2808 struct hostapd_channel_data *chan = &mode->channels[c];
2809 if ((u32) chan->freq - 10 >= start &&
2810 (u32) chan->freq + 10 <= end)
2811 chan->max_tx_power = max_eirp;
2812 }
2813 }
2814 }
2815
2816
nl80211_reg_rule_ht40(u32 start,u32 end,struct phy_info_arg * results)2817 static void nl80211_reg_rule_ht40(u32 start, u32 end,
2818 struct phy_info_arg *results)
2819 {
2820 u16 m;
2821
2822 for (m = 0; m < *results->num_modes; m++) {
2823 if (!(results->modes[m].ht_capab &
2824 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
2825 continue;
2826 nl80211_set_ht40_mode(&results->modes[m], start, end);
2827 }
2828 }
2829
2830
nl80211_reg_rule_sec(struct nlattr * tb[],struct phy_info_arg * results)2831 static void nl80211_reg_rule_sec(struct nlattr *tb[],
2832 struct phy_info_arg *results)
2833 {
2834 u32 start, end, max_bw;
2835 u16 m;
2836
2837 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
2838 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
2839 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
2840 return;
2841
2842 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
2843 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
2844 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
2845
2846 if (max_bw < 20)
2847 return;
2848
2849 for (m = 0; m < *results->num_modes; m++) {
2850 if (!(results->modes[m].ht_capab &
2851 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
2852 continue;
2853 nl80211_set_ht40_mode_sec(&results->modes[m], start, end);
2854 }
2855 }
2856
2857
nl80211_set_vht_mode(struct hostapd_hw_modes * mode,int start,int end,int max_bw,u32 flags)2858 static void nl80211_set_vht_mode(struct hostapd_hw_modes *mode, int start,
2859 int end, int max_bw, u32 flags)
2860 {
2861 int c;
2862
2863 for (c = 0; c < mode->num_channels; c++) {
2864 struct hostapd_channel_data *chan = &mode->channels[c];
2865
2866 if (chan->freq - 10 < start || chan->freq + 10 > end)
2867 continue;
2868
2869 if (max_bw >= 80)
2870 chan->flag |= HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL;
2871
2872 if (max_bw >= 160)
2873 chan->flag |= HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL;
2874
2875 if (flags & NL80211_RRF_AUTO_BW)
2876 chan->flag |= HOSTAPD_CHAN_AUTO_BW;
2877 }
2878 }
2879
2880
nl80211_reg_rule_vht(struct nlattr * tb[],struct phy_info_arg * results)2881 static void nl80211_reg_rule_vht(struct nlattr *tb[],
2882 struct phy_info_arg *results)
2883 {
2884 u32 start, end, max_bw, flags = 0;
2885 u16 m;
2886
2887 if (tb[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
2888 tb[NL80211_ATTR_FREQ_RANGE_END] == NULL ||
2889 tb[NL80211_ATTR_FREQ_RANGE_MAX_BW] == NULL)
2890 return;
2891
2892 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
2893 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
2894 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
2895
2896 if (tb[NL80211_ATTR_REG_RULE_FLAGS])
2897 flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
2898
2899 if (max_bw < 80)
2900 return;
2901
2902 for (m = 0; m < *results->num_modes; m++) {
2903 if (!(results->modes[m].ht_capab &
2904 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
2905 continue;
2906 /* TODO: use a real VHT support indication */
2907 if (!results->modes[m].vht_capab)
2908 continue;
2909
2910 nl80211_set_vht_mode(&results->modes[m], start, end,
2911 max_bw, flags);
2912 }
2913 }
2914
2915
nl80211_set_6ghz_mode(struct hostapd_hw_modes * mode,int start,int end,int max_bw)2916 static void nl80211_set_6ghz_mode(struct hostapd_hw_modes *mode, int start,
2917 int end, int max_bw)
2918 {
2919 int c;
2920
2921 for (c = 0; c < mode->num_channels; c++) {
2922 struct hostapd_channel_data *chan = &mode->channels[c];
2923
2924 if (chan->freq - 10 < start || chan->freq + 10 > end)
2925 continue;
2926
2927 if (max_bw >= 80)
2928 chan->flag |= HOSTAPD_CHAN_VHT_80MHZ_SUBCHANNEL;
2929
2930 if (max_bw >= 160)
2931 chan->flag |= HOSTAPD_CHAN_VHT_160MHZ_SUBCHANNEL;
2932
2933 if (max_bw >= 320)
2934 chan->flag |= HOSTAPD_CHAN_EHT_320MHZ_SUBCHANNEL;
2935 }
2936 }
2937
2938
nl80211_reg_rule_6ghz(struct nlattr * tb[],struct phy_info_arg * results)2939 static void nl80211_reg_rule_6ghz(struct nlattr *tb[],
2940 struct phy_info_arg *results)
2941 {
2942 u32 start, end, max_bw;
2943 u16 m;
2944
2945 if (!tb[NL80211_ATTR_FREQ_RANGE_START] ||
2946 !tb[NL80211_ATTR_FREQ_RANGE_END] ||
2947 !tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
2948 return;
2949
2950 start = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
2951 end = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
2952 max_bw = nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
2953
2954 if (max_bw < 80)
2955 return;
2956
2957 for (m = 0; m < *results->num_modes; m++) {
2958 if (results->modes[m].num_channels == 0 ||
2959 !is_6ghz_freq(results->modes[m].channels[0].freq))
2960 continue;
2961
2962 nl80211_set_6ghz_mode(&results->modes[m], start, end, max_bw);
2963 }
2964 }
2965
2966
nl80211_set_dfs_domain(enum nl80211_dfs_regions region,u8 * dfs_domain)2967 static void nl80211_set_dfs_domain(enum nl80211_dfs_regions region,
2968 u8 *dfs_domain)
2969 {
2970 if (region == NL80211_DFS_FCC)
2971 *dfs_domain = HOSTAPD_DFS_REGION_FCC;
2972 else if (region == NL80211_DFS_ETSI)
2973 *dfs_domain = HOSTAPD_DFS_REGION_ETSI;
2974 else if (region == NL80211_DFS_JP)
2975 *dfs_domain = HOSTAPD_DFS_REGION_JP;
2976 else
2977 *dfs_domain = 0;
2978 }
2979
2980
dfs_domain_name(enum nl80211_dfs_regions region)2981 static const char * dfs_domain_name(enum nl80211_dfs_regions region)
2982 {
2983 switch (region) {
2984 case NL80211_DFS_UNSET:
2985 return "DFS-UNSET";
2986 case NL80211_DFS_FCC:
2987 return "DFS-FCC";
2988 case NL80211_DFS_ETSI:
2989 return "DFS-ETSI";
2990 case NL80211_DFS_JP:
2991 return "DFS-JP";
2992 default:
2993 return "DFS-invalid";
2994 }
2995 }
2996
2997
nl80211_get_reg(struct nl_msg * msg,void * arg)2998 static int nl80211_get_reg(struct nl_msg *msg, void *arg)
2999 {
3000 struct phy_info_arg *results = arg;
3001 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3002 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3003 struct nlattr *nl_rule;
3004 struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1];
3005 int rem_rule;
3006 static struct nla_policy reg_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
3007 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
3008 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
3009 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
3010 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
3011 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
3012 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
3013 };
3014
3015 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3016 genlmsg_attrlen(gnlh, 0), NULL);
3017 if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
3018 !tb_msg[NL80211_ATTR_REG_RULES]) {
3019 wpa_printf(MSG_DEBUG, "nl80211: No regulatory information "
3020 "available");
3021 return NL_SKIP;
3022 }
3023
3024 if (tb_msg[NL80211_ATTR_DFS_REGION]) {
3025 enum nl80211_dfs_regions dfs_domain;
3026 dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]);
3027 nl80211_set_dfs_domain(dfs_domain, &results->dfs_domain);
3028 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s (%s)",
3029 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
3030 dfs_domain_name(dfs_domain));
3031 } else {
3032 wpa_printf(MSG_DEBUG, "nl80211: Regulatory information - country=%s",
3033 (char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]));
3034 }
3035
3036 /* Store the alpha2 country code for the caller */
3037 os_strlcpy(results->alpha2,
3038 (const char *) nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]),
3039 sizeof(results->alpha2));
3040
3041 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
3042 {
3043 u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
3044 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
3045 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
3046 if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
3047 tb_rule[NL80211_ATTR_FREQ_RANGE_END] == NULL)
3048 continue;
3049 start = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]) / 1000;
3050 end = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]) / 1000;
3051 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
3052 max_eirp = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]) / 100;
3053 if (tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW])
3054 max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
3055 if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
3056 flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
3057
3058 wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
3059 start, end, max_bw, max_eirp,
3060 flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
3061 flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
3062 flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
3063 flags & NL80211_RRF_NO_OUTDOOR ? " (no outdoor)" :
3064 "",
3065 flags & NL80211_RRF_DFS ? " (DFS)" : "",
3066 flags & NL80211_RRF_PTP_ONLY ? " (PTP only)" : "",
3067 flags & NL80211_RRF_PTMP_ONLY ? " (PTMP only)" : "",
3068 flags & NL80211_RRF_NO_IR ? " (no IR)" : "");
3069 if (max_bw >= 40)
3070 nl80211_reg_rule_ht40(start, end, results);
3071 if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
3072 nl80211_reg_rule_max_eirp(start, end, max_eirp,
3073 results);
3074 }
3075
3076 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
3077 {
3078 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
3079 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
3080 nl80211_reg_rule_sec(tb_rule, results);
3081 }
3082
3083 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
3084 {
3085 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
3086 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
3087 nl80211_reg_rule_vht(tb_rule, results);
3088 }
3089
3090 nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
3091 {
3092 nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
3093 nla_data(nl_rule), nla_len(nl_rule), reg_policy);
3094 nl80211_reg_rule_6ghz(tb_rule, results);
3095 }
3096
3097 return NL_SKIP;
3098 }
3099
3100
nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data * drv,struct phy_info_arg * results)3101 static int nl80211_set_regulatory_flags(struct wpa_driver_nl80211_data *drv,
3102 struct phy_info_arg *results)
3103 {
3104 struct nl_msg *msg;
3105
3106 msg = nlmsg_alloc();
3107 if (!msg)
3108 return -ENOMEM;
3109
3110 nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_REG);
3111 if (drv->capa.flags & WPA_DRIVER_FLAGS_SELF_MANAGED_REGULATORY) {
3112 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, drv->wiphy_idx)) {
3113 nlmsg_free(msg);
3114 return -1;
3115 }
3116 }
3117
3118 return send_and_recv_resp(drv, msg, nl80211_get_reg, results);
3119 }
3120
3121
modestr(enum hostapd_hw_mode mode)3122 static const char * modestr(enum hostapd_hw_mode mode)
3123 {
3124 switch (mode) {
3125 case HOSTAPD_MODE_IEEE80211B:
3126 return "802.11b";
3127 case HOSTAPD_MODE_IEEE80211G:
3128 return "802.11g";
3129 case HOSTAPD_MODE_IEEE80211A:
3130 return "802.11a";
3131 case HOSTAPD_MODE_IEEE80211AD:
3132 return "802.11ad";
3133 default:
3134 return "?";
3135 }
3136 }
3137
3138
nl80211_dump_chan_list(struct wpa_driver_nl80211_data * drv,struct hostapd_hw_modes * modes,u16 num_modes)3139 static void nl80211_dump_chan_list(struct wpa_driver_nl80211_data *drv,
3140 struct hostapd_hw_modes *modes,
3141 u16 num_modes)
3142 {
3143 int i;
3144
3145 if (!modes)
3146 return;
3147
3148 for (i = 0; i < num_modes; i++) {
3149 struct hostapd_hw_modes *mode = &modes[i];
3150 char str[1000];
3151 char *pos = str;
3152 char *end = pos + sizeof(str);
3153 int j, res;
3154
3155 for (j = 0; j < mode->num_channels; j++) {
3156 struct hostapd_channel_data *chan = &mode->channels[j];
3157
3158 if (is_6ghz_freq(chan->freq))
3159 drv->uses_6ghz = true;
3160 if (chan->freq >= 900 && chan->freq < 1000)
3161 drv->uses_s1g = true;
3162 res = os_snprintf(pos, end - pos, " %d%s%s%s",
3163 chan->freq,
3164 (chan->flag & HOSTAPD_CHAN_DISABLED) ?
3165 "[DISABLED]" : "",
3166 (chan->flag & HOSTAPD_CHAN_NO_IR) ?
3167 "[NO_IR]" : "",
3168 (chan->flag & HOSTAPD_CHAN_RADAR) ?
3169 "[RADAR]" : "");
3170 if (os_snprintf_error(end - pos, res))
3171 break;
3172 pos += res;
3173 }
3174
3175 *pos = '\0';
3176 wpa_printf(MSG_DEBUG, "nl80211: Mode IEEE %s:%s",
3177 modestr(mode->mode), str);
3178 }
3179 }
3180
3181
3182 struct hostapd_hw_modes *
nl80211_get_hw_feature_data(void * priv,u16 * num_modes,u16 * flags,u8 * dfs_domain,char * alpha2,size_t alpha2_len)3183 nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
3184 u8 *dfs_domain, char *alpha2, size_t alpha2_len)
3185 {
3186 u32 feat;
3187 struct i802_bss *bss = priv;
3188 struct wpa_driver_nl80211_data *drv = bss->drv;
3189 int nl_flags = 0;
3190 struct nl_msg *msg;
3191 struct phy_info_arg result = {
3192 .num_modes = num_modes,
3193 .modes = NULL,
3194 .last_mode = -1,
3195 .failed = 0,
3196 .dfs_domain = 0,
3197 .alpha2 = "",
3198 };
3199
3200 *num_modes = 0;
3201 *flags = 0;
3202 *dfs_domain = 0;
3203 if (alpha2 && alpha2_len)
3204 alpha2[0] = '\0';
3205
3206 feat = get_nl80211_protocol_features(drv);
3207 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
3208 nl_flags = NLM_F_DUMP;
3209 if (!(msg = nl80211_cmd_msg(bss, nl_flags, NL80211_CMD_GET_WIPHY)) ||
3210 nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
3211 nlmsg_free(msg);
3212 return NULL;
3213 }
3214
3215 if (send_and_recv_resp(drv, msg, phy_info_handler, &result) == 0) {
3216 struct hostapd_hw_modes *modes;
3217
3218 nl80211_set_regulatory_flags(drv, &result);
3219 if (result.failed) {
3220 int i;
3221
3222 for (i = 0; result.modes && i < *num_modes; i++) {
3223 os_free(result.modes[i].channels);
3224 os_free(result.modes[i].rates);
3225 }
3226 os_free(result.modes);
3227 *num_modes = 0;
3228 return NULL;
3229 }
3230
3231 *dfs_domain = result.dfs_domain;
3232 if (alpha2 && alpha2_len)
3233 os_strlcpy(alpha2, result.alpha2, alpha2_len);
3234
3235 modes = wpa_driver_nl80211_postprocess_modes(result.modes,
3236 num_modes);
3237 nl80211_dump_chan_list(drv, modes, *num_modes);
3238 return modes;
3239 }
3240
3241 return NULL;
3242 }
3243
3244
phy_multi_hw_info_parse(struct hostapd_multi_hw_info * hw_info,struct nlattr * radio_attr)3245 static int phy_multi_hw_info_parse(struct hostapd_multi_hw_info *hw_info,
3246 struct nlattr *radio_attr)
3247 {
3248 struct nlattr *tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_MAX + 1];
3249 int start_freq, end_freq;
3250
3251 switch (nla_type(radio_attr)) {
3252 case NL80211_WIPHY_RADIO_ATTR_INDEX:
3253 hw_info->hw_idx = nla_get_u32(radio_attr);
3254 return NL_OK;
3255 case NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE:
3256 if (nla_parse_nested(tb_freq, NL80211_WIPHY_RADIO_FREQ_ATTR_MAX,
3257 radio_attr, NULL) ||
3258 !tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_START] ||
3259 !tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_END])
3260 return NL_STOP;
3261
3262 start_freq = nla_get_u32(
3263 tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_START]);
3264 end_freq = nla_get_u32(
3265 tb_freq[NL80211_WIPHY_RADIO_FREQ_ATTR_END]);
3266
3267 /* Convert to MHz and store */
3268 hw_info->start_freq = start_freq / 1000;
3269 hw_info->end_freq = end_freq / 1000;
3270 return NL_OK;
3271 default:
3272 return NL_OK;
3273 }
3274 }
3275
3276
3277 struct phy_multi_hw_info_arg {
3278 bool failed;
3279 unsigned int *num_multi_hws;
3280 struct hostapd_multi_hw_info *multi_hws;
3281 };
3282
3283
phy_multi_hw_info_handler(struct nl_msg * msg,void * arg)3284 static int phy_multi_hw_info_handler(struct nl_msg *msg, void *arg)
3285 {
3286 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3287 struct phy_multi_hw_info_arg *multi_hw_info = arg;
3288 struct hostapd_multi_hw_info *multi_hws, hw_info;
3289 struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
3290 struct nlattr *nl_hw, *radio_attr;
3291 int rem_hw, rem_radio_prop, res;
3292
3293 nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
3294 genlmsg_attrlen(gnlh, 0), NULL);
3295
3296 if (!tb_msg[NL80211_ATTR_WIPHY_RADIOS])
3297 return NL_SKIP;
3298
3299 *multi_hw_info->num_multi_hws = 0;
3300
3301 nla_for_each_nested(nl_hw, tb_msg[NL80211_ATTR_WIPHY_RADIOS], rem_hw) {
3302 os_memset(&hw_info, 0, sizeof(hw_info));
3303
3304 nla_for_each_nested(radio_attr, nl_hw, rem_radio_prop) {
3305 res = phy_multi_hw_info_parse(&hw_info, radio_attr);
3306 if (res != NL_OK)
3307 goto out;
3308 }
3309
3310 if (hw_info.start_freq == 0 || hw_info.end_freq == 0)
3311 goto out;
3312
3313 multi_hws = os_realloc_array(multi_hw_info->multi_hws,
3314 *multi_hw_info->num_multi_hws + 1,
3315 sizeof(*multi_hws));
3316 if (!multi_hws)
3317 goto out;
3318
3319 multi_hw_info->multi_hws = multi_hws;
3320 os_memcpy(&multi_hws[*(multi_hw_info->num_multi_hws)],
3321 &hw_info, sizeof(struct hostapd_multi_hw_info));
3322 *(multi_hw_info->num_multi_hws) += 1;
3323 }
3324
3325 return NL_OK;
3326 out:
3327 multi_hw_info->failed = true;
3328 return NL_STOP;
3329 }
3330
3331
3332 struct hostapd_multi_hw_info *
nl80211_get_multi_hw_info(struct i802_bss * bss,unsigned int * num_multi_hws)3333 nl80211_get_multi_hw_info(struct i802_bss *bss, unsigned int *num_multi_hws)
3334 {
3335 u32 feat;
3336 struct wpa_driver_nl80211_data *drv = bss->drv;
3337 int nl_flags = 0;
3338 struct nl_msg *msg;
3339 struct phy_multi_hw_info_arg result = {
3340 .failed = false,
3341 .num_multi_hws = num_multi_hws,
3342 .multi_hws = NULL,
3343 };
3344
3345 *num_multi_hws = 0;
3346
3347 if (!drv->has_capability || !(drv->capa.flags2 & WPA_DRIVER_FLAGS2_MLO))
3348 return NULL;
3349
3350 feat = get_nl80211_protocol_features(drv);
3351 if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP)
3352 nl_flags = NLM_F_DUMP;
3353 if (!(msg = nl80211_cmd_msg(bss, nl_flags, NL80211_CMD_GET_WIPHY)) ||
3354 nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP)) {
3355 nlmsg_free(msg);
3356 return NULL;
3357 }
3358
3359 if (send_and_recv_resp(drv, msg, phy_multi_hw_info_handler,
3360 &result) == 0) {
3361 if (result.failed) {
3362 os_free(result.multi_hws);
3363 *num_multi_hws = 0;
3364 return NULL;
3365 }
3366
3367 return result.multi_hws;
3368 }
3369
3370 return NULL;
3371 }
3372