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