Home | History | Annotate | Download | only in drivers
      1 /*
      2  * Driver interaction with Linux nl80211/cfg80211 - Event processing
      3  * Copyright (c) 2002-2017, 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 "utils/eloop.h"
     16 #include "common/qca-vendor.h"
     17 #include "common/qca-vendor-attr.h"
     18 #include "common/ieee802_11_defs.h"
     19 #include "common/ieee802_11_common.h"
     20 #include "driver_nl80211.h"
     21 
     22 
     23 static const char * nl80211_command_to_string(enum nl80211_commands cmd)
     24 {
     25 #define C2S(x) case x: return #x;
     26 	switch (cmd) {
     27 	C2S(NL80211_CMD_UNSPEC)
     28 	C2S(NL80211_CMD_GET_WIPHY)
     29 	C2S(NL80211_CMD_SET_WIPHY)
     30 	C2S(NL80211_CMD_NEW_WIPHY)
     31 	C2S(NL80211_CMD_DEL_WIPHY)
     32 	C2S(NL80211_CMD_GET_INTERFACE)
     33 	C2S(NL80211_CMD_SET_INTERFACE)
     34 	C2S(NL80211_CMD_NEW_INTERFACE)
     35 	C2S(NL80211_CMD_DEL_INTERFACE)
     36 	C2S(NL80211_CMD_GET_KEY)
     37 	C2S(NL80211_CMD_SET_KEY)
     38 	C2S(NL80211_CMD_NEW_KEY)
     39 	C2S(NL80211_CMD_DEL_KEY)
     40 	C2S(NL80211_CMD_GET_BEACON)
     41 	C2S(NL80211_CMD_SET_BEACON)
     42 	C2S(NL80211_CMD_START_AP)
     43 	C2S(NL80211_CMD_STOP_AP)
     44 	C2S(NL80211_CMD_GET_STATION)
     45 	C2S(NL80211_CMD_SET_STATION)
     46 	C2S(NL80211_CMD_NEW_STATION)
     47 	C2S(NL80211_CMD_DEL_STATION)
     48 	C2S(NL80211_CMD_GET_MPATH)
     49 	C2S(NL80211_CMD_SET_MPATH)
     50 	C2S(NL80211_CMD_NEW_MPATH)
     51 	C2S(NL80211_CMD_DEL_MPATH)
     52 	C2S(NL80211_CMD_SET_BSS)
     53 	C2S(NL80211_CMD_SET_REG)
     54 	C2S(NL80211_CMD_REQ_SET_REG)
     55 	C2S(NL80211_CMD_GET_MESH_CONFIG)
     56 	C2S(NL80211_CMD_SET_MESH_CONFIG)
     57 	C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
     58 	C2S(NL80211_CMD_GET_REG)
     59 	C2S(NL80211_CMD_GET_SCAN)
     60 	C2S(NL80211_CMD_TRIGGER_SCAN)
     61 	C2S(NL80211_CMD_NEW_SCAN_RESULTS)
     62 	C2S(NL80211_CMD_SCAN_ABORTED)
     63 	C2S(NL80211_CMD_REG_CHANGE)
     64 	C2S(NL80211_CMD_AUTHENTICATE)
     65 	C2S(NL80211_CMD_ASSOCIATE)
     66 	C2S(NL80211_CMD_DEAUTHENTICATE)
     67 	C2S(NL80211_CMD_DISASSOCIATE)
     68 	C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
     69 	C2S(NL80211_CMD_REG_BEACON_HINT)
     70 	C2S(NL80211_CMD_JOIN_IBSS)
     71 	C2S(NL80211_CMD_LEAVE_IBSS)
     72 	C2S(NL80211_CMD_TESTMODE)
     73 	C2S(NL80211_CMD_CONNECT)
     74 	C2S(NL80211_CMD_ROAM)
     75 	C2S(NL80211_CMD_DISCONNECT)
     76 	C2S(NL80211_CMD_SET_WIPHY_NETNS)
     77 	C2S(NL80211_CMD_GET_SURVEY)
     78 	C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
     79 	C2S(NL80211_CMD_SET_PMKSA)
     80 	C2S(NL80211_CMD_DEL_PMKSA)
     81 	C2S(NL80211_CMD_FLUSH_PMKSA)
     82 	C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
     83 	C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
     84 	C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
     85 	C2S(NL80211_CMD_REGISTER_FRAME)
     86 	C2S(NL80211_CMD_FRAME)
     87 	C2S(NL80211_CMD_FRAME_TX_STATUS)
     88 	C2S(NL80211_CMD_SET_POWER_SAVE)
     89 	C2S(NL80211_CMD_GET_POWER_SAVE)
     90 	C2S(NL80211_CMD_SET_CQM)
     91 	C2S(NL80211_CMD_NOTIFY_CQM)
     92 	C2S(NL80211_CMD_SET_CHANNEL)
     93 	C2S(NL80211_CMD_SET_WDS_PEER)
     94 	C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
     95 	C2S(NL80211_CMD_JOIN_MESH)
     96 	C2S(NL80211_CMD_LEAVE_MESH)
     97 	C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
     98 	C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
     99 	C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
    100 	C2S(NL80211_CMD_GET_WOWLAN)
    101 	C2S(NL80211_CMD_SET_WOWLAN)
    102 	C2S(NL80211_CMD_START_SCHED_SCAN)
    103 	C2S(NL80211_CMD_STOP_SCHED_SCAN)
    104 	C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
    105 	C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
    106 	C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
    107 	C2S(NL80211_CMD_PMKSA_CANDIDATE)
    108 	C2S(NL80211_CMD_TDLS_OPER)
    109 	C2S(NL80211_CMD_TDLS_MGMT)
    110 	C2S(NL80211_CMD_UNEXPECTED_FRAME)
    111 	C2S(NL80211_CMD_PROBE_CLIENT)
    112 	C2S(NL80211_CMD_REGISTER_BEACONS)
    113 	C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
    114 	C2S(NL80211_CMD_SET_NOACK_MAP)
    115 	C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
    116 	C2S(NL80211_CMD_START_P2P_DEVICE)
    117 	C2S(NL80211_CMD_STOP_P2P_DEVICE)
    118 	C2S(NL80211_CMD_CONN_FAILED)
    119 	C2S(NL80211_CMD_SET_MCAST_RATE)
    120 	C2S(NL80211_CMD_SET_MAC_ACL)
    121 	C2S(NL80211_CMD_RADAR_DETECT)
    122 	C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
    123 	C2S(NL80211_CMD_UPDATE_FT_IES)
    124 	C2S(NL80211_CMD_FT_EVENT)
    125 	C2S(NL80211_CMD_CRIT_PROTOCOL_START)
    126 	C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
    127 	C2S(NL80211_CMD_GET_COALESCE)
    128 	C2S(NL80211_CMD_SET_COALESCE)
    129 	C2S(NL80211_CMD_CHANNEL_SWITCH)
    130 	C2S(NL80211_CMD_VENDOR)
    131 	C2S(NL80211_CMD_SET_QOS_MAP)
    132 	C2S(NL80211_CMD_ADD_TX_TS)
    133 	C2S(NL80211_CMD_DEL_TX_TS)
    134 	C2S(NL80211_CMD_WIPHY_REG_CHANGE)
    135 	C2S(NL80211_CMD_PORT_AUTHORIZED)
    136 	C2S(NL80211_CMD_EXTERNAL_AUTH)
    137 	C2S(NL80211_CMD_STA_OPMODE_CHANGED)
    138 	C2S(NL80211_CMD_CONTROL_PORT_FRAME)
    139 	default:
    140 		return "NL80211_CMD_UNKNOWN";
    141 	}
    142 #undef C2S
    143 }
    144 
    145 
    146 static void mlme_event_auth(struct wpa_driver_nl80211_data *drv,
    147 			    const u8 *frame, size_t len)
    148 {
    149 	const struct ieee80211_mgmt *mgmt;
    150 	union wpa_event_data event;
    151 
    152 	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
    153 	    drv->force_connect_cmd) {
    154 		/*
    155 		 * Avoid reporting two association events that would confuse
    156 		 * the core code.
    157 		 */
    158 		wpa_printf(MSG_DEBUG,
    159 			   "nl80211: Ignore auth event when using driver SME");
    160 		return;
    161 	}
    162 
    163 	wpa_printf(MSG_DEBUG, "nl80211: Authenticate event");
    164 	mgmt = (const struct ieee80211_mgmt *) frame;
    165 	if (len < 24 + sizeof(mgmt->u.auth)) {
    166 		wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
    167 			   "frame");
    168 		return;
    169 	}
    170 
    171 	os_memcpy(drv->auth_bssid, mgmt->sa, ETH_ALEN);
    172 	os_memset(drv->auth_attempt_bssid, 0, ETH_ALEN);
    173 	os_memset(&event, 0, sizeof(event));
    174 	os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
    175 	event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
    176 	event.auth.auth_transaction =
    177 		le_to_host16(mgmt->u.auth.auth_transaction);
    178 	event.auth.status_code = le_to_host16(mgmt->u.auth.status_code);
    179 	if (len > 24 + sizeof(mgmt->u.auth)) {
    180 		event.auth.ies = mgmt->u.auth.variable;
    181 		event.auth.ies_len = len - 24 - sizeof(mgmt->u.auth);
    182 	}
    183 
    184 	wpa_supplicant_event(drv->ctx, EVENT_AUTH, &event);
    185 }
    186 
    187 
    188 static void nl80211_parse_wmm_params(struct nlattr *wmm_attr,
    189 				     struct wmm_params *wmm_params)
    190 {
    191 	struct nlattr *wmm_info[NL80211_STA_WME_MAX + 1];
    192 	static struct nla_policy wme_policy[NL80211_STA_WME_MAX + 1] = {
    193 		[NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
    194 	};
    195 
    196 	if (!wmm_attr ||
    197 	    nla_parse_nested(wmm_info, NL80211_STA_WME_MAX, wmm_attr,
    198 			     wme_policy) ||
    199 	    !wmm_info[NL80211_STA_WME_UAPSD_QUEUES])
    200 		return;
    201 
    202 	wmm_params->uapsd_queues =
    203 		nla_get_u8(wmm_info[NL80211_STA_WME_UAPSD_QUEUES]);
    204 	wmm_params->info_bitmap |= WMM_PARAMS_UAPSD_QUEUES_INFO;
    205 }
    206 
    207 
    208 static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
    209 			     const u8 *frame, size_t len, struct nlattr *wmm,
    210 			     struct nlattr *req_ie)
    211 {
    212 	const struct ieee80211_mgmt *mgmt;
    213 	union wpa_event_data event;
    214 	u16 status;
    215 	int ssid_len;
    216 
    217 	if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
    218 	    drv->force_connect_cmd) {
    219 		/*
    220 		 * Avoid reporting two association events that would confuse
    221 		 * the core code.
    222 		 */
    223 		wpa_printf(MSG_DEBUG,
    224 			   "nl80211: Ignore assoc event when using driver SME");
    225 		return;
    226 	}
    227 
    228 	wpa_printf(MSG_DEBUG, "nl80211: Associate event");
    229 	mgmt = (const struct ieee80211_mgmt *) frame;
    230 	if (len < 24 + sizeof(mgmt->u.assoc_resp)) {
    231 		wpa_printf(MSG_DEBUG, "nl80211: Too short association event "
    232 			   "frame");
    233 		return;
    234 	}
    235 
    236 	status = le_to_host16(mgmt->u.assoc_resp.status_code);
    237 	if (status != WLAN_STATUS_SUCCESS) {
    238 		os_memset(&event, 0, sizeof(event));
    239 		event.assoc_reject.bssid = mgmt->bssid;
    240 		if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
    241 			event.assoc_reject.resp_ies =
    242 				(u8 *) mgmt->u.assoc_resp.variable;
    243 			event.assoc_reject.resp_ies_len =
    244 				len - 24 - sizeof(mgmt->u.assoc_resp);
    245 		}
    246 		event.assoc_reject.status_code = status;
    247 
    248 		wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
    249 		return;
    250 	}
    251 
    252 	drv->associated = 1;
    253 	os_memcpy(drv->bssid, mgmt->sa, ETH_ALEN);
    254 	os_memcpy(drv->prev_bssid, mgmt->sa, ETH_ALEN);
    255 
    256 	os_memset(&event, 0, sizeof(event));
    257 	event.assoc_info.resp_frame = frame;
    258 	event.assoc_info.resp_frame_len = len;
    259 	if (len > 24 + sizeof(mgmt->u.assoc_resp)) {
    260 		event.assoc_info.resp_ies = (u8 *) mgmt->u.assoc_resp.variable;
    261 		event.assoc_info.resp_ies_len =
    262 			len - 24 - sizeof(mgmt->u.assoc_resp);
    263 	}
    264 
    265 	if (req_ie) {
    266 		event.assoc_info.req_ies = nla_data(req_ie);
    267 		event.assoc_info.req_ies_len = nla_len(req_ie);
    268 	}
    269 
    270 	/* When this association was initiated outside of wpa_supplicant,
    271 	 * drv->ssid needs to be set here to satisfy later checking. */
    272 	ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid);
    273 	if (ssid_len > 0) {
    274 		drv->ssid_len = ssid_len;
    275 		wpa_printf(MSG_DEBUG,
    276 			   "nl80211: Set drv->ssid based on scan res info to '%s'",
    277 			   wpa_ssid_txt(drv->ssid, drv->ssid_len));
    278 	}
    279 
    280 	event.assoc_info.freq = drv->assoc_freq;
    281 	drv->first_bss->freq = drv->assoc_freq;
    282 
    283 	nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
    284 
    285 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
    286 }
    287 
    288 
    289 static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
    290 			       enum nl80211_commands cmd, struct nlattr *status,
    291 			       struct nlattr *addr, struct nlattr *req_ie,
    292 			       struct nlattr *resp_ie,
    293 			       struct nlattr *timed_out,
    294 			       struct nlattr *timeout_reason,
    295 			       struct nlattr *authorized,
    296 			       struct nlattr *key_replay_ctr,
    297 			       struct nlattr *ptk_kck,
    298 			       struct nlattr *ptk_kek,
    299 			       struct nlattr *subnet_status,
    300 			       struct nlattr *fils_erp_next_seq_num,
    301 			       struct nlattr *fils_pmk,
    302 			       struct nlattr *fils_pmkid)
    303 {
    304 	union wpa_event_data event;
    305 	const u8 *ssid = NULL;
    306 	u16 status_code;
    307 	int ssid_len;
    308 
    309 	if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
    310 		/*
    311 		 * Avoid reporting two association events that would confuse
    312 		 * the core code.
    313 		 */
    314 		wpa_printf(MSG_DEBUG, "nl80211: Ignore connect event (cmd=%d) "
    315 			   "when using userspace SME", cmd);
    316 		return;
    317 	}
    318 
    319 	drv->connect_reassoc = 0;
    320 
    321 	status_code = status ? nla_get_u16(status) : WLAN_STATUS_SUCCESS;
    322 
    323 	if (cmd == NL80211_CMD_CONNECT) {
    324 		wpa_printf(MSG_DEBUG,
    325 			   "nl80211: Connect event (status=%u ignore_next_local_disconnect=%d)",
    326 			   status_code, drv->ignore_next_local_disconnect);
    327 	} else if (cmd == NL80211_CMD_ROAM) {
    328 		wpa_printf(MSG_DEBUG, "nl80211: Roam event");
    329 	}
    330 
    331 	os_memset(&event, 0, sizeof(event));
    332 	if (cmd == NL80211_CMD_CONNECT && status_code != WLAN_STATUS_SUCCESS) {
    333 		if (addr)
    334 			event.assoc_reject.bssid = nla_data(addr);
    335 		if (drv->ignore_next_local_disconnect) {
    336 			drv->ignore_next_local_disconnect = 0;
    337 			if (!event.assoc_reject.bssid ||
    338 			    (os_memcmp(event.assoc_reject.bssid,
    339 				       drv->auth_attempt_bssid,
    340 				       ETH_ALEN) != 0)) {
    341 				/*
    342 				 * Ignore the event that came without a BSSID or
    343 				 * for the old connection since this is likely
    344 				 * not relevant to the new Connect command.
    345 				 */
    346 				wpa_printf(MSG_DEBUG,
    347 					   "nl80211: Ignore connection failure event triggered during reassociation");
    348 				return;
    349 			}
    350 		}
    351 		if (resp_ie) {
    352 			event.assoc_reject.resp_ies = nla_data(resp_ie);
    353 			event.assoc_reject.resp_ies_len = nla_len(resp_ie);
    354 		}
    355 		event.assoc_reject.status_code = status_code;
    356 		event.assoc_reject.timed_out = timed_out != NULL;
    357 		if (timed_out && timeout_reason) {
    358 			enum nl80211_timeout_reason reason;
    359 
    360 			reason = nla_get_u32(timeout_reason);
    361 			switch (reason) {
    362 			case NL80211_TIMEOUT_SCAN:
    363 				event.assoc_reject.timeout_reason = "scan";
    364 				break;
    365 			case NL80211_TIMEOUT_AUTH:
    366 				event.assoc_reject.timeout_reason = "auth";
    367 				break;
    368 			case NL80211_TIMEOUT_ASSOC:
    369 				event.assoc_reject.timeout_reason = "assoc";
    370 				break;
    371 			default:
    372 				break;
    373 			}
    374 		}
    375 		if (fils_erp_next_seq_num)
    376 			event.assoc_reject.fils_erp_next_seq_num =
    377 				nla_get_u16(fils_erp_next_seq_num);
    378 		wpa_supplicant_event(drv->ctx, EVENT_ASSOC_REJECT, &event);
    379 		return;
    380 	}
    381 
    382 	drv->associated = 1;
    383 	if (addr) {
    384 		os_memcpy(drv->bssid, nla_data(addr), ETH_ALEN);
    385 		os_memcpy(drv->prev_bssid, drv->bssid, ETH_ALEN);
    386 	}
    387 
    388 	if (req_ie) {
    389 		event.assoc_info.req_ies = nla_data(req_ie);
    390 		event.assoc_info.req_ies_len = nla_len(req_ie);
    391 
    392 		if (cmd == NL80211_CMD_ROAM) {
    393 			ssid = get_ie(event.assoc_info.req_ies,
    394 				      event.assoc_info.req_ies_len,
    395 				      WLAN_EID_SSID);
    396 			if (ssid && ssid[1] > 0 && ssid[1] <= 32) {
    397 				drv->ssid_len = ssid[1];
    398 				os_memcpy(drv->ssid, ssid + 2, ssid[1]);
    399 				wpa_printf(MSG_DEBUG,
    400 					   "nl80211: Set drv->ssid based on req_ie to '%s'",
    401 					   wpa_ssid_txt(drv->ssid,
    402 							drv->ssid_len));
    403 			}
    404 		}
    405 	}
    406 	if (resp_ie) {
    407 		event.assoc_info.resp_ies = nla_data(resp_ie);
    408 		event.assoc_info.resp_ies_len = nla_len(resp_ie);
    409 	}
    410 
    411 	event.assoc_info.freq = nl80211_get_assoc_freq(drv);
    412 	drv->first_bss->freq = drv->assoc_freq;
    413 
    414 	if ((!ssid || ssid[1] == 0 || ssid[1] > 32) &&
    415 	    (ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid)) > 0) {
    416 		/* When this connection was initiated outside of wpa_supplicant,
    417 		 * drv->ssid needs to be set here to satisfy later checking. */
    418 		drv->ssid_len = ssid_len;
    419 		wpa_printf(MSG_DEBUG,
    420 			   "nl80211: Set drv->ssid based on scan res info to '%s'",
    421 			   wpa_ssid_txt(drv->ssid, drv->ssid_len));
    422 	}
    423 
    424 	if (authorized && nla_get_u8(authorized)) {
    425 		event.assoc_info.authorized = 1;
    426 		wpa_printf(MSG_DEBUG, "nl80211: connection authorized");
    427 	}
    428 	if (key_replay_ctr) {
    429 		event.assoc_info.key_replay_ctr = nla_data(key_replay_ctr);
    430 		event.assoc_info.key_replay_ctr_len = nla_len(key_replay_ctr);
    431 	}
    432 	if (ptk_kck) {
    433 		event.assoc_info.ptk_kck = nla_data(ptk_kck);
    434 		event.assoc_info.ptk_kck_len = nla_len(ptk_kck);
    435 	}
    436 	if (ptk_kek) {
    437 		event.assoc_info.ptk_kek = nla_data(ptk_kek);
    438 		event.assoc_info.ptk_kek_len = nla_len(ptk_kek);
    439 	}
    440 
    441 	if (subnet_status) {
    442 		/*
    443 		 * At least for now, this is only available from
    444 		 * QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS and that
    445 		 * attribute has the same values 0, 1, 2 as are used in the
    446 		 * variable here, so no mapping between different values are
    447 		 * needed.
    448 		 */
    449 		event.assoc_info.subnet_status = nla_get_u8(subnet_status);
    450 	}
    451 
    452 	if (fils_erp_next_seq_num)
    453 		event.assoc_info.fils_erp_next_seq_num =
    454 			nla_get_u16(fils_erp_next_seq_num);
    455 
    456 	if (fils_pmk) {
    457 		event.assoc_info.fils_pmk = nla_data(fils_pmk);
    458 		event.assoc_info.fils_pmk_len = nla_len(fils_pmk);
    459 	}
    460 
    461 	if (fils_pmkid)
    462 		event.assoc_info.fils_pmkid = nla_data(fils_pmkid);
    463 
    464 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
    465 }
    466 
    467 
    468 static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
    469 				  struct nlattr *reason, struct nlattr *addr,
    470 				  struct nlattr *by_ap)
    471 {
    472 	union wpa_event_data data;
    473 	unsigned int locally_generated = by_ap == NULL;
    474 
    475 	if (drv->capa.flags & WPA_DRIVER_FLAGS_SME) {
    476 		/*
    477 		 * Avoid reporting two disassociation events that could
    478 		 * confuse the core code.
    479 		 */
    480 		wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
    481 			   "event when using userspace SME");
    482 		return;
    483 	}
    484 
    485 	if (drv->ignore_next_local_disconnect) {
    486 		drv->ignore_next_local_disconnect = 0;
    487 		if (locally_generated) {
    488 			wpa_printf(MSG_DEBUG, "nl80211: Ignore disconnect "
    489 				   "event triggered during reassociation");
    490 			return;
    491 		}
    492 		wpa_printf(MSG_WARNING, "nl80211: Was expecting local "
    493 			   "disconnect but got another disconnect "
    494 			   "event first");
    495 	}
    496 
    497 	wpa_printf(MSG_DEBUG, "nl80211: Disconnect event");
    498 	nl80211_mark_disconnected(drv);
    499 	os_memset(&data, 0, sizeof(data));
    500 	if (reason)
    501 		data.deauth_info.reason_code = nla_get_u16(reason);
    502 	data.deauth_info.locally_generated = by_ap == NULL;
    503 	wpa_supplicant_event(drv->ctx, EVENT_DEAUTH, &data);
    504 }
    505 
    506 
    507 static int calculate_chan_offset(int width, int freq, int cf1, int cf2)
    508 {
    509 	int freq1 = 0;
    510 
    511 	switch (convert2width(width)) {
    512 	case CHAN_WIDTH_20_NOHT:
    513 	case CHAN_WIDTH_20:
    514 		return 0;
    515 	case CHAN_WIDTH_40:
    516 		freq1 = cf1 - 10;
    517 		break;
    518 	case CHAN_WIDTH_80:
    519 		freq1 = cf1 - 30;
    520 		break;
    521 	case CHAN_WIDTH_160:
    522 		freq1 = cf1 - 70;
    523 		break;
    524 	case CHAN_WIDTH_UNKNOWN:
    525 	case CHAN_WIDTH_80P80:
    526 		/* FIXME: implement this */
    527 		return 0;
    528 	}
    529 
    530 	return (abs(freq - freq1) / 20) % 2 == 0 ? 1 : -1;
    531 }
    532 
    533 
    534 static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
    535 				 struct nlattr *ifindex, struct nlattr *freq,
    536 				 struct nlattr *type, struct nlattr *bw,
    537 				 struct nlattr *cf1, struct nlattr *cf2)
    538 {
    539 	struct i802_bss *bss;
    540 	union wpa_event_data data;
    541 	int ht_enabled = 1;
    542 	int chan_offset = 0;
    543 	int ifidx;
    544 
    545 	wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
    546 
    547 	if (!freq)
    548 		return;
    549 
    550 	ifidx = nla_get_u32(ifindex);
    551 	bss = get_bss_ifindex(drv, ifidx);
    552 	if (bss == NULL) {
    553 		wpa_printf(MSG_WARNING, "nl80211: Unknown ifindex (%d) for channel switch, ignoring",
    554 			   ifidx);
    555 		return;
    556 	}
    557 
    558 	if (type) {
    559 		enum nl80211_channel_type ch_type = nla_get_u32(type);
    560 
    561 		wpa_printf(MSG_DEBUG, "nl80211: Channel type: %d", ch_type);
    562 		switch (ch_type) {
    563 		case NL80211_CHAN_NO_HT:
    564 			ht_enabled = 0;
    565 			break;
    566 		case NL80211_CHAN_HT20:
    567 			break;
    568 		case NL80211_CHAN_HT40PLUS:
    569 			chan_offset = 1;
    570 			break;
    571 		case NL80211_CHAN_HT40MINUS:
    572 			chan_offset = -1;
    573 			break;
    574 		}
    575 	} else if (bw && cf1) {
    576 		/* This can happen for example with VHT80 ch switch */
    577 		chan_offset = calculate_chan_offset(nla_get_u32(bw),
    578 						    nla_get_u32(freq),
    579 						    nla_get_u32(cf1),
    580 						    cf2 ? nla_get_u32(cf2) : 0);
    581 	} else {
    582 		wpa_printf(MSG_WARNING, "nl80211: Unknown secondary channel information - following channel definition calculations may fail");
    583 	}
    584 
    585 	os_memset(&data, 0, sizeof(data));
    586 	data.ch_switch.freq = nla_get_u32(freq);
    587 	data.ch_switch.ht_enabled = ht_enabled;
    588 	data.ch_switch.ch_offset = chan_offset;
    589 	if (bw)
    590 		data.ch_switch.ch_width = convert2width(nla_get_u32(bw));
    591 	if (cf1)
    592 		data.ch_switch.cf1 = nla_get_u32(cf1);
    593 	if (cf2)
    594 		data.ch_switch.cf2 = nla_get_u32(cf2);
    595 
    596 	bss->freq = data.ch_switch.freq;
    597 	drv->assoc_freq = data.ch_switch.freq;
    598 
    599 	wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data);
    600 }
    601 
    602 
    603 static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
    604 			       enum nl80211_commands cmd, struct nlattr *addr)
    605 {
    606 	union wpa_event_data event;
    607 	enum wpa_event_type ev;
    608 
    609 	if (nla_len(addr) != ETH_ALEN)
    610 		return;
    611 
    612 	wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
    613 		   cmd, MAC2STR((u8 *) nla_data(addr)));
    614 
    615 	if (cmd == NL80211_CMD_AUTHENTICATE)
    616 		ev = EVENT_AUTH_TIMED_OUT;
    617 	else if (cmd == NL80211_CMD_ASSOCIATE)
    618 		ev = EVENT_ASSOC_TIMED_OUT;
    619 	else
    620 		return;
    621 
    622 	os_memset(&event, 0, sizeof(event));
    623 	os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
    624 	wpa_supplicant_event(drv->ctx, ev, &event);
    625 }
    626 
    627 
    628 static void mlme_event_mgmt(struct i802_bss *bss,
    629 			    struct nlattr *freq, struct nlattr *sig,
    630 			    const u8 *frame, size_t len)
    631 {
    632 	struct wpa_driver_nl80211_data *drv = bss->drv;
    633 	const struct ieee80211_mgmt *mgmt;
    634 	union wpa_event_data event;
    635 	u16 fc, stype;
    636 	int ssi_signal = 0;
    637 	int rx_freq = 0;
    638 
    639 	wpa_printf(MSG_MSGDUMP, "nl80211: Frame event");
    640 	mgmt = (const struct ieee80211_mgmt *) frame;
    641 	if (len < 24) {
    642 		wpa_printf(MSG_DEBUG, "nl80211: Too short management frame");
    643 		return;
    644 	}
    645 
    646 	fc = le_to_host16(mgmt->frame_control);
    647 	stype = WLAN_FC_GET_STYPE(fc);
    648 
    649 	if (sig)
    650 		ssi_signal = (s32) nla_get_u32(sig);
    651 
    652 	os_memset(&event, 0, sizeof(event));
    653 	if (freq) {
    654 		event.rx_mgmt.freq = nla_get_u32(freq);
    655 		rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq;
    656 	}
    657 	wpa_printf(MSG_DEBUG,
    658 		   "nl80211: RX frame da=" MACSTR " sa=" MACSTR " bssid=" MACSTR
    659 		   " freq=%d ssi_signal=%d fc=0x%x seq_ctrl=0x%x stype=%u (%s) len=%u",
    660 		   MAC2STR(mgmt->da), MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid),
    661 		   rx_freq, ssi_signal, fc,
    662 		   le_to_host16(mgmt->seq_ctrl), stype, fc2str(fc),
    663 		   (unsigned int) len);
    664 	event.rx_mgmt.frame = frame;
    665 	event.rx_mgmt.frame_len = len;
    666 	event.rx_mgmt.ssi_signal = ssi_signal;
    667 	event.rx_mgmt.drv_priv = bss;
    668 	wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event);
    669 }
    670 
    671 
    672 static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
    673 				      struct nlattr *cookie, const u8 *frame,
    674 				      size_t len, struct nlattr *ack)
    675 {
    676 	union wpa_event_data event;
    677 	const struct ieee80211_hdr *hdr;
    678 	u16 fc;
    679 
    680 	wpa_printf(MSG_DEBUG, "nl80211: Frame TX status event");
    681 	if (!is_ap_interface(drv->nlmode)) {
    682 		u64 cookie_val;
    683 
    684 		if (!cookie)
    685 			return;
    686 
    687 		cookie_val = nla_get_u64(cookie);
    688 		wpa_printf(MSG_DEBUG, "nl80211: Action TX status:"
    689 			   " cookie=0x%llx%s (ack=%d)",
    690 			   (long long unsigned int) cookie_val,
    691 			   cookie_val == drv->send_action_cookie ?
    692 			   " (match)" : " (unknown)", ack != NULL);
    693 		if (cookie_val != drv->send_action_cookie)
    694 			return;
    695 	}
    696 
    697 	hdr = (const struct ieee80211_hdr *) frame;
    698 	fc = le_to_host16(hdr->frame_control);
    699 
    700 	os_memset(&event, 0, sizeof(event));
    701 	event.tx_status.type = WLAN_FC_GET_TYPE(fc);
    702 	event.tx_status.stype = WLAN_FC_GET_STYPE(fc);
    703 	event.tx_status.dst = hdr->addr1;
    704 	event.tx_status.data = frame;
    705 	event.tx_status.data_len = len;
    706 	event.tx_status.ack = ack != NULL;
    707 	wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
    708 }
    709 
    710 
    711 static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
    712 				       enum wpa_event_type type,
    713 				       const u8 *frame, size_t len)
    714 {
    715 	const struct ieee80211_mgmt *mgmt;
    716 	union wpa_event_data event;
    717 	const u8 *bssid = NULL;
    718 	u16 reason_code = 0;
    719 
    720 	if (type == EVENT_DEAUTH)
    721 		wpa_printf(MSG_DEBUG, "nl80211: Deauthenticate event");
    722 	else
    723 		wpa_printf(MSG_DEBUG, "nl80211: Disassociate event");
    724 
    725 	mgmt = (const struct ieee80211_mgmt *) frame;
    726 	if (len >= 24) {
    727 		bssid = mgmt->bssid;
    728 
    729 		if ((drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
    730 		    !drv->associated &&
    731 		    os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0 &&
    732 		    os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0 &&
    733 		    os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0) {
    734 			/*
    735 			 * Avoid issues with some roaming cases where
    736 			 * disconnection event for the old AP may show up after
    737 			 * we have started connection with the new AP.
    738 			 * In case of locally generated event clear
    739 			 * ignore_next_local_deauth as well, to avoid next local
    740 			 * deauth event be wrongly ignored.
    741 			 */
    742 			if (!os_memcmp(mgmt->sa, drv->first_bss->addr,
    743 				       ETH_ALEN)) {
    744 				wpa_printf(MSG_DEBUG,
    745 					   "nl80211: Received a locally generated deauth event. Clear ignore_next_local_deauth flag");
    746 				drv->ignore_next_local_deauth = 0;
    747 			} else {
    748 				wpa_printf(MSG_DEBUG,
    749 					   "nl80211: Ignore deauth/disassoc event from old AP " MACSTR " when already authenticating with " MACSTR,
    750 					   MAC2STR(bssid),
    751 					   MAC2STR(drv->auth_attempt_bssid));
    752 			}
    753 			return;
    754 		}
    755 
    756 		if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
    757 		    drv->connect_reassoc && drv->associated &&
    758 		    os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0 &&
    759 		    os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0) {
    760 			/*
    761 			 * Avoid issues with some roaming cases where
    762 			 * disconnection event for the old AP may show up after
    763 			 * we have started connection with the new AP.
    764 			 */
    765 			wpa_printf(MSG_DEBUG,
    766 				   "nl80211: Ignore deauth/disassoc event from old AP "
    767 				   MACSTR
    768 				   " when already connecting with " MACSTR,
    769 				   MAC2STR(bssid),
    770 				   MAC2STR(drv->auth_attempt_bssid));
    771 			return;
    772 		}
    773 
    774 		if (drv->associated != 0 &&
    775 		    os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
    776 		    os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
    777 			/*
    778 			 * We have presumably received this deauth as a
    779 			 * response to a clear_state_mismatch() outgoing
    780 			 * deauth.  Don't let it take us offline!
    781 			 */
    782 			wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
    783 				   "from Unknown BSSID " MACSTR " -- ignoring",
    784 				   MAC2STR(bssid));
    785 			return;
    786 		}
    787 	}
    788 
    789 	nl80211_mark_disconnected(drv);
    790 	os_memset(&event, 0, sizeof(event));
    791 
    792 	/* Note: Same offset for Reason Code in both frame subtypes */
    793 	if (len >= 24 + sizeof(mgmt->u.deauth))
    794 		reason_code = le_to_host16(mgmt->u.deauth.reason_code);
    795 
    796 	if (type == EVENT_DISASSOC) {
    797 		event.disassoc_info.locally_generated =
    798 			!os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
    799 		event.disassoc_info.addr = bssid;
    800 		event.disassoc_info.reason_code = reason_code;
    801 		if (frame + len > mgmt->u.disassoc.variable) {
    802 			event.disassoc_info.ie = mgmt->u.disassoc.variable;
    803 			event.disassoc_info.ie_len = frame + len -
    804 				mgmt->u.disassoc.variable;
    805 		}
    806 	} else {
    807 		event.deauth_info.locally_generated =
    808 			!os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
    809 		if (drv->ignore_deauth_event) {
    810 			wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event due to previous forced deauth-during-auth");
    811 			drv->ignore_deauth_event = 0;
    812 			if (event.deauth_info.locally_generated)
    813 				drv->ignore_next_local_deauth = 0;
    814 			return;
    815 		}
    816 		if (drv->ignore_next_local_deauth) {
    817 			drv->ignore_next_local_deauth = 0;
    818 			if (event.deauth_info.locally_generated) {
    819 				wpa_printf(MSG_DEBUG, "nl80211: Ignore deauth event triggered due to own deauth request");
    820 				return;
    821 			}
    822 			wpa_printf(MSG_WARNING, "nl80211: Was expecting local deauth but got another disconnect event first");
    823 		}
    824 		event.deauth_info.addr = bssid;
    825 		event.deauth_info.reason_code = reason_code;
    826 		if (frame + len > mgmt->u.deauth.variable) {
    827 			event.deauth_info.ie = mgmt->u.deauth.variable;
    828 			event.deauth_info.ie_len = frame + len -
    829 				mgmt->u.deauth.variable;
    830 		}
    831 	}
    832 
    833 	wpa_supplicant_event(drv->ctx, type, &event);
    834 }
    835 
    836 
    837 static void mlme_event_unprot_disconnect(struct wpa_driver_nl80211_data *drv,
    838 					 enum wpa_event_type type,
    839 					 const u8 *frame, size_t len)
    840 {
    841 	const struct ieee80211_mgmt *mgmt;
    842 	union wpa_event_data event;
    843 	u16 reason_code = 0;
    844 
    845 	if (type == EVENT_UNPROT_DEAUTH)
    846 		wpa_printf(MSG_DEBUG, "nl80211: Unprot Deauthenticate event");
    847 	else
    848 		wpa_printf(MSG_DEBUG, "nl80211: Unprot Disassociate event");
    849 
    850 	if (len < 24)
    851 		return;
    852 
    853 	mgmt = (const struct ieee80211_mgmt *) frame;
    854 
    855 	os_memset(&event, 0, sizeof(event));
    856 	/* Note: Same offset for Reason Code in both frame subtypes */
    857 	if (len >= 24 + sizeof(mgmt->u.deauth))
    858 		reason_code = le_to_host16(mgmt->u.deauth.reason_code);
    859 
    860 	if (type == EVENT_UNPROT_DISASSOC) {
    861 		event.unprot_disassoc.sa = mgmt->sa;
    862 		event.unprot_disassoc.da = mgmt->da;
    863 		event.unprot_disassoc.reason_code = reason_code;
    864 	} else {
    865 		event.unprot_deauth.sa = mgmt->sa;
    866 		event.unprot_deauth.da = mgmt->da;
    867 		event.unprot_deauth.reason_code = reason_code;
    868 	}
    869 
    870 	wpa_supplicant_event(drv->ctx, type, &event);
    871 }
    872 
    873 
    874 static void mlme_event(struct i802_bss *bss,
    875 		       enum nl80211_commands cmd, struct nlattr *frame,
    876 		       struct nlattr *addr, struct nlattr *timed_out,
    877 		       struct nlattr *freq, struct nlattr *ack,
    878 		       struct nlattr *cookie, struct nlattr *sig,
    879 		       struct nlattr *wmm, struct nlattr *req_ie)
    880 {
    881 	struct wpa_driver_nl80211_data *drv = bss->drv;
    882 	const u8 *data;
    883 	size_t len;
    884 
    885 	if (timed_out && addr) {
    886 		mlme_timeout_event(drv, cmd, addr);
    887 		return;
    888 	}
    889 
    890 	if (frame == NULL) {
    891 		wpa_printf(MSG_DEBUG,
    892 			   "nl80211: MLME event %d (%s) without frame data",
    893 			   cmd, nl80211_command_to_string(cmd));
    894 		return;
    895 	}
    896 
    897 	data = nla_data(frame);
    898 	len = nla_len(frame);
    899 	if (len < 4 + 2 * ETH_ALEN) {
    900 		wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s("
    901 			   MACSTR ") - too short",
    902 			   cmd, nl80211_command_to_string(cmd), bss->ifname,
    903 			   MAC2STR(bss->addr));
    904 		return;
    905 	}
    906 	wpa_printf(MSG_MSGDUMP, "nl80211: MLME event %d (%s) on %s(" MACSTR
    907 		   ") A1=" MACSTR " A2=" MACSTR, cmd,
    908 		   nl80211_command_to_string(cmd), bss->ifname,
    909 		   MAC2STR(bss->addr), MAC2STR(data + 4),
    910 		   MAC2STR(data + 4 + ETH_ALEN));
    911 	if (cmd != NL80211_CMD_FRAME_TX_STATUS && !(data[4] & 0x01) &&
    912 	    os_memcmp(bss->addr, data + 4, ETH_ALEN) != 0 &&
    913 	    (is_zero_ether_addr(bss->rand_addr) ||
    914 	     os_memcmp(bss->rand_addr, data + 4, ETH_ALEN) != 0) &&
    915 	    os_memcmp(bss->addr, data + 4 + ETH_ALEN, ETH_ALEN) != 0) {
    916 		wpa_printf(MSG_MSGDUMP, "nl80211: %s: Ignore MLME frame event "
    917 			   "for foreign address", bss->ifname);
    918 		return;
    919 	}
    920 	wpa_hexdump(MSG_MSGDUMP, "nl80211: MLME event frame",
    921 		    nla_data(frame), nla_len(frame));
    922 
    923 	switch (cmd) {
    924 	case NL80211_CMD_AUTHENTICATE:
    925 		mlme_event_auth(drv, nla_data(frame), nla_len(frame));
    926 		break;
    927 	case NL80211_CMD_ASSOCIATE:
    928 		mlme_event_assoc(drv, nla_data(frame), nla_len(frame), wmm,
    929 				 req_ie);
    930 		break;
    931 	case NL80211_CMD_DEAUTHENTICATE:
    932 		mlme_event_deauth_disassoc(drv, EVENT_DEAUTH,
    933 					   nla_data(frame), nla_len(frame));
    934 		break;
    935 	case NL80211_CMD_DISASSOCIATE:
    936 		mlme_event_deauth_disassoc(drv, EVENT_DISASSOC,
    937 					   nla_data(frame), nla_len(frame));
    938 		break;
    939 	case NL80211_CMD_FRAME:
    940 		mlme_event_mgmt(bss, freq, sig, nla_data(frame),
    941 				nla_len(frame));
    942 		break;
    943 	case NL80211_CMD_FRAME_TX_STATUS:
    944 		mlme_event_mgmt_tx_status(drv, cookie, nla_data(frame),
    945 					  nla_len(frame), ack);
    946 		break;
    947 	case NL80211_CMD_UNPROT_DEAUTHENTICATE:
    948 		mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DEAUTH,
    949 					     nla_data(frame), nla_len(frame));
    950 		break;
    951 	case NL80211_CMD_UNPROT_DISASSOCIATE:
    952 		mlme_event_unprot_disconnect(drv, EVENT_UNPROT_DISASSOC,
    953 					     nla_data(frame), nla_len(frame));
    954 		break;
    955 	default:
    956 		break;
    957 	}
    958 }
    959 
    960 
    961 static void mlme_event_michael_mic_failure(struct i802_bss *bss,
    962 					   struct nlattr *tb[])
    963 {
    964 	union wpa_event_data data;
    965 
    966 	wpa_printf(MSG_DEBUG, "nl80211: MLME event Michael MIC failure");
    967 	os_memset(&data, 0, sizeof(data));
    968 	if (tb[NL80211_ATTR_MAC]) {
    969 		wpa_hexdump(MSG_DEBUG, "nl80211: Source MAC address",
    970 			    nla_data(tb[NL80211_ATTR_MAC]),
    971 			    nla_len(tb[NL80211_ATTR_MAC]));
    972 		data.michael_mic_failure.src = nla_data(tb[NL80211_ATTR_MAC]);
    973 	}
    974 	if (tb[NL80211_ATTR_KEY_SEQ]) {
    975 		wpa_hexdump(MSG_DEBUG, "nl80211: TSC",
    976 			    nla_data(tb[NL80211_ATTR_KEY_SEQ]),
    977 			    nla_len(tb[NL80211_ATTR_KEY_SEQ]));
    978 	}
    979 	if (tb[NL80211_ATTR_KEY_TYPE]) {
    980 		enum nl80211_key_type key_type =
    981 			nla_get_u32(tb[NL80211_ATTR_KEY_TYPE]);
    982 		wpa_printf(MSG_DEBUG, "nl80211: Key Type %d", key_type);
    983 		if (key_type == NL80211_KEYTYPE_PAIRWISE)
    984 			data.michael_mic_failure.unicast = 1;
    985 	} else
    986 		data.michael_mic_failure.unicast = 1;
    987 
    988 	if (tb[NL80211_ATTR_KEY_IDX]) {
    989 		u8 key_id = nla_get_u8(tb[NL80211_ATTR_KEY_IDX]);
    990 		wpa_printf(MSG_DEBUG, "nl80211: Key Id %d", key_id);
    991 	}
    992 
    993 	wpa_supplicant_event(bss->ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
    994 }
    995 
    996 
    997 static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
    998 				 struct nlattr *tb[])
    999 {
   1000 	unsigned int freq;
   1001 	union wpa_event_data event;
   1002 
   1003 	if (tb[NL80211_ATTR_MAC] == NULL) {
   1004 		wpa_printf(MSG_DEBUG, "nl80211: No address in IBSS joined "
   1005 			   "event");
   1006 		return;
   1007 	}
   1008 	os_memcpy(drv->bssid, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
   1009 
   1010 	drv->associated = 1;
   1011 	wpa_printf(MSG_DEBUG, "nl80211: IBSS " MACSTR " joined",
   1012 		   MAC2STR(drv->bssid));
   1013 
   1014 	freq = nl80211_get_assoc_freq(drv);
   1015 	if (freq) {
   1016 		wpa_printf(MSG_DEBUG, "nl80211: IBSS on frequency %u MHz",
   1017 			   freq);
   1018 		drv->first_bss->freq = freq;
   1019 	}
   1020 
   1021 	os_memset(&event, 0, sizeof(event));
   1022 	event.assoc_info.freq = freq;
   1023 
   1024 	wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
   1025 }
   1026 
   1027 
   1028 static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv,
   1029 					 int cancel_event, struct nlattr *tb[])
   1030 {
   1031 	unsigned int freq, chan_type, duration;
   1032 	union wpa_event_data data;
   1033 	u64 cookie;
   1034 
   1035 	if (tb[NL80211_ATTR_WIPHY_FREQ])
   1036 		freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
   1037 	else
   1038 		freq = 0;
   1039 
   1040 	if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
   1041 		chan_type = nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
   1042 	else
   1043 		chan_type = 0;
   1044 
   1045 	if (tb[NL80211_ATTR_DURATION])
   1046 		duration = nla_get_u32(tb[NL80211_ATTR_DURATION]);
   1047 	else
   1048 		duration = 0;
   1049 
   1050 	if (tb[NL80211_ATTR_COOKIE])
   1051 		cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
   1052 	else
   1053 		cookie = 0;
   1054 
   1055 	wpa_printf(MSG_DEBUG, "nl80211: Remain-on-channel event (cancel=%d "
   1056 		   "freq=%u channel_type=%u duration=%u cookie=0x%llx (%s))",
   1057 		   cancel_event, freq, chan_type, duration,
   1058 		   (long long unsigned int) cookie,
   1059 		   cookie == drv->remain_on_chan_cookie ? "match" : "unknown");
   1060 
   1061 	if (cookie != drv->remain_on_chan_cookie)
   1062 		return; /* not for us */
   1063 
   1064 	if (cancel_event)
   1065 		drv->pending_remain_on_chan = 0;
   1066 
   1067 	os_memset(&data, 0, sizeof(data));
   1068 	data.remain_on_channel.freq = freq;
   1069 	data.remain_on_channel.duration = duration;
   1070 	wpa_supplicant_event(drv->ctx, cancel_event ?
   1071 			     EVENT_CANCEL_REMAIN_ON_CHANNEL :
   1072 			     EVENT_REMAIN_ON_CHANNEL, &data);
   1073 }
   1074 
   1075 
   1076 static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv,
   1077 				struct nlattr *tb[])
   1078 {
   1079 	union wpa_event_data data;
   1080 
   1081 	os_memset(&data, 0, sizeof(data));
   1082 
   1083 	if (tb[NL80211_ATTR_IE]) {
   1084 		data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]);
   1085 		data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]);
   1086 	}
   1087 
   1088 	if (tb[NL80211_ATTR_IE_RIC]) {
   1089 		data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]);
   1090 		data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]);
   1091 	}
   1092 
   1093 	if (tb[NL80211_ATTR_MAC])
   1094 		os_memcpy(data.ft_ies.target_ap,
   1095 			  nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
   1096 
   1097 	wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR,
   1098 		   MAC2STR(data.ft_ies.target_ap));
   1099 
   1100 	wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data);
   1101 }
   1102 
   1103 
   1104 static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,
   1105 			    struct nlattr *tb[], int external_scan)
   1106 {
   1107 	union wpa_event_data event;
   1108 	struct nlattr *nl;
   1109 	int rem;
   1110 	struct scan_info *info;
   1111 #define MAX_REPORT_FREQS 50
   1112 	int freqs[MAX_REPORT_FREQS];
   1113 	int num_freqs = 0;
   1114 
   1115 	if (!external_scan && drv->scan_for_auth) {
   1116 		drv->scan_for_auth = 0;
   1117 		wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "
   1118 			   "cfg80211 BSS entry");
   1119 		wpa_driver_nl80211_authenticate_retry(drv);
   1120 		return;
   1121 	}
   1122 
   1123 	os_memset(&event, 0, sizeof(event));
   1124 	info = &event.scan_info;
   1125 	info->aborted = aborted;
   1126 	info->external_scan = external_scan;
   1127 	info->nl_scan_event = 1;
   1128 
   1129 	if (tb[NL80211_ATTR_SCAN_SSIDS]) {
   1130 		nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {
   1131 			struct wpa_driver_scan_ssid *s =
   1132 				&info->ssids[info->num_ssids];
   1133 			s->ssid = nla_data(nl);
   1134 			s->ssid_len = nla_len(nl);
   1135 			wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",
   1136 				   wpa_ssid_txt(s->ssid, s->ssid_len));
   1137 			info->num_ssids++;
   1138 			if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
   1139 				break;
   1140 		}
   1141 	}
   1142 	if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {
   1143 		char msg[300], *pos, *end;
   1144 		int res;
   1145 
   1146 		pos = msg;
   1147 		end = pos + sizeof(msg);
   1148 		*pos = '\0';
   1149 
   1150 		nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)
   1151 		{
   1152 			freqs[num_freqs] = nla_get_u32(nl);
   1153 			res = os_snprintf(pos, end - pos, " %d",
   1154 					  freqs[num_freqs]);
   1155 			if (!os_snprintf_error(end - pos, res))
   1156 				pos += res;
   1157 			num_freqs++;
   1158 			if (num_freqs == MAX_REPORT_FREQS - 1)
   1159 				break;
   1160 		}
   1161 		info->freqs = freqs;
   1162 		info->num_freqs = num_freqs;
   1163 		wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
   1164 			   msg);
   1165 	}
   1166 
   1167 	if (tb[NL80211_ATTR_SCAN_START_TIME_TSF] &&
   1168 	    tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]) {
   1169 		info->scan_start_tsf =
   1170 			nla_get_u64(tb[NL80211_ATTR_SCAN_START_TIME_TSF]);
   1171 		os_memcpy(info->scan_start_tsf_bssid,
   1172 			  nla_data(tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]),
   1173 			  ETH_ALEN);
   1174 	}
   1175 
   1176 	wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
   1177 }
   1178 
   1179 
   1180 static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
   1181 			      struct nlattr *tb[])
   1182 {
   1183 	static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
   1184 		[NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
   1185 		[NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
   1186 		[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
   1187 		[NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
   1188 		[NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
   1189 		[NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
   1190 		[NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
   1191 		[NL80211_ATTR_CQM_BEACON_LOSS_EVENT] = { .type = NLA_FLAG },
   1192 	};
   1193 	struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
   1194 	enum nl80211_cqm_rssi_threshold_event event;
   1195 	union wpa_event_data ed;
   1196 	struct wpa_signal_info sig;
   1197 	int res;
   1198 
   1199 	if (tb[NL80211_ATTR_CQM] == NULL ||
   1200 	    nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, tb[NL80211_ATTR_CQM],
   1201 			     cqm_policy)) {
   1202 		wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid CQM event");
   1203 		return;
   1204 	}
   1205 
   1206 	os_memset(&ed, 0, sizeof(ed));
   1207 
   1208 	if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]) {
   1209 		if (!tb[NL80211_ATTR_MAC])
   1210 			return;
   1211 		os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
   1212 			  ETH_ALEN);
   1213 		ed.low_ack.num_packets =
   1214 			nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
   1215 		wpa_printf(MSG_DEBUG, "nl80211: Packet loss event for " MACSTR
   1216 			   " (num_packets %u)",
   1217 			   MAC2STR(ed.low_ack.addr), ed.low_ack.num_packets);
   1218 		wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
   1219 		return;
   1220 	}
   1221 
   1222 	if (cqm[NL80211_ATTR_CQM_BEACON_LOSS_EVENT]) {
   1223 		wpa_printf(MSG_DEBUG, "nl80211: Beacon loss event");
   1224 		wpa_supplicant_event(drv->ctx, EVENT_BEACON_LOSS, NULL);
   1225 		return;
   1226 	}
   1227 
   1228 	if (cqm[NL80211_ATTR_CQM_TXE_RATE] &&
   1229 	    cqm[NL80211_ATTR_CQM_TXE_PKTS] &&
   1230 	    cqm[NL80211_ATTR_CQM_TXE_INTVL] &&
   1231 	    cqm[NL80211_ATTR_MAC]) {
   1232 		wpa_printf(MSG_DEBUG, "nl80211: CQM TXE event for " MACSTR
   1233 			   " (rate: %u pkts: %u interval: %u)",
   1234 			   MAC2STR((u8 *) nla_data(cqm[NL80211_ATTR_MAC])),
   1235 			   nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_RATE]),
   1236 			   nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_PKTS]),
   1237 			   nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_INTVL]));
   1238 		return;
   1239 	}
   1240 
   1241 	if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL) {
   1242 		wpa_printf(MSG_DEBUG,
   1243 			   "nl80211: Not a CQM RSSI threshold event");
   1244 		return;
   1245 	}
   1246 	event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
   1247 
   1248 	if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
   1249 		wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
   1250 			   "event: RSSI high");
   1251 		ed.signal_change.above_threshold = 1;
   1252 	} else if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW) {
   1253 		wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
   1254 			   "event: RSSI low");
   1255 		ed.signal_change.above_threshold = 0;
   1256 	} else {
   1257 		wpa_printf(MSG_DEBUG,
   1258 			   "nl80211: Unknown CQM RSSI threshold event: %d",
   1259 			   event);
   1260 		return;
   1261 	}
   1262 
   1263 	res = nl80211_get_link_signal(drv, &sig);
   1264 	if (res == 0) {
   1265 		ed.signal_change.current_signal = sig.current_signal;
   1266 		ed.signal_change.current_txrate = sig.current_txrate;
   1267 		wpa_printf(MSG_DEBUG, "nl80211: Signal: %d dBm  txrate: %d",
   1268 			   sig.current_signal, sig.current_txrate);
   1269 	}
   1270 
   1271 	res = nl80211_get_link_noise(drv, &sig);
   1272 	if (res == 0) {
   1273 		ed.signal_change.current_noise = sig.current_noise;
   1274 		wpa_printf(MSG_DEBUG, "nl80211: Noise: %d dBm",
   1275 			   sig.current_noise);
   1276 	}
   1277 
   1278 	wpa_supplicant_event(drv->ctx, EVENT_SIGNAL_CHANGE, &ed);
   1279 }
   1280 
   1281 
   1282 static void nl80211_new_peer_candidate(struct wpa_driver_nl80211_data *drv,
   1283 				       struct nlattr **tb)
   1284 {
   1285 	const u8 *addr;
   1286 	union wpa_event_data data;
   1287 
   1288 	if (drv->nlmode != NL80211_IFTYPE_MESH_POINT ||
   1289 	    !tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_IE])
   1290 		return;
   1291 
   1292 	addr = nla_data(tb[NL80211_ATTR_MAC]);
   1293 	wpa_printf(MSG_DEBUG, "nl80211: New peer candidate " MACSTR,
   1294 		   MAC2STR(addr));
   1295 
   1296 	os_memset(&data, 0, sizeof(data));
   1297 	data.mesh_peer.peer = addr;
   1298 	data.mesh_peer.ies = nla_data(tb[NL80211_ATTR_IE]);
   1299 	data.mesh_peer.ie_len = nla_len(tb[NL80211_ATTR_IE]);
   1300 	wpa_supplicant_event(drv->ctx, EVENT_NEW_PEER_CANDIDATE, &data);
   1301 }
   1302 
   1303 
   1304 static void nl80211_new_station_event(struct wpa_driver_nl80211_data *drv,
   1305 				      struct i802_bss *bss,
   1306 				      struct nlattr **tb)
   1307 {
   1308 	u8 *addr;
   1309 	union wpa_event_data data;
   1310 
   1311 	if (tb[NL80211_ATTR_MAC] == NULL)
   1312 		return;
   1313 	addr = nla_data(tb[NL80211_ATTR_MAC]);
   1314 	wpa_printf(MSG_DEBUG, "nl80211: New station " MACSTR, MAC2STR(addr));
   1315 
   1316 	if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
   1317 		u8 *ies = NULL;
   1318 		size_t ies_len = 0;
   1319 		if (tb[NL80211_ATTR_IE]) {
   1320 			ies = nla_data(tb[NL80211_ATTR_IE]);
   1321 			ies_len = nla_len(tb[NL80211_ATTR_IE]);
   1322 		}
   1323 		wpa_hexdump(MSG_DEBUG, "nl80211: Assoc Req IEs", ies, ies_len);
   1324 		drv_event_assoc(bss->ctx, addr, ies, ies_len, 0);
   1325 		return;
   1326 	}
   1327 
   1328 	if (drv->nlmode != NL80211_IFTYPE_ADHOC)
   1329 		return;
   1330 
   1331 	os_memset(&data, 0, sizeof(data));
   1332 	os_memcpy(data.ibss_rsn_start.peer, addr, ETH_ALEN);
   1333 	wpa_supplicant_event(bss->ctx, EVENT_IBSS_RSN_START, &data);
   1334 }
   1335 
   1336 
   1337 static void nl80211_del_station_event(struct wpa_driver_nl80211_data *drv,
   1338 				      struct i802_bss *bss,
   1339 				      struct nlattr **tb)
   1340 {
   1341 	u8 *addr;
   1342 	union wpa_event_data data;
   1343 
   1344 	if (tb[NL80211_ATTR_MAC] == NULL)
   1345 		return;
   1346 	addr = nla_data(tb[NL80211_ATTR_MAC]);
   1347 	wpa_printf(MSG_DEBUG, "nl80211: Delete station " MACSTR,
   1348 		   MAC2STR(addr));
   1349 
   1350 	if (is_ap_interface(drv->nlmode) && drv->device_ap_sme) {
   1351 		drv_event_disassoc(bss->ctx, addr);
   1352 		return;
   1353 	}
   1354 
   1355 	if (drv->nlmode != NL80211_IFTYPE_ADHOC)
   1356 		return;
   1357 
   1358 	os_memset(&data, 0, sizeof(data));
   1359 	os_memcpy(data.ibss_peer_lost.peer, addr, ETH_ALEN);
   1360 	wpa_supplicant_event(bss->ctx, EVENT_IBSS_PEER_LOST, &data);
   1361 }
   1362 
   1363 
   1364 static void nl80211_rekey_offload_event(struct wpa_driver_nl80211_data *drv,
   1365 					struct nlattr **tb)
   1366 {
   1367 	struct nlattr *rekey_info[NUM_NL80211_REKEY_DATA];
   1368 	static struct nla_policy rekey_policy[NUM_NL80211_REKEY_DATA] = {
   1369 		[NL80211_REKEY_DATA_KEK] = {
   1370 			.minlen = NL80211_KEK_LEN,
   1371 			.maxlen = NL80211_KEK_LEN,
   1372 		},
   1373 		[NL80211_REKEY_DATA_KCK] = {
   1374 			.minlen = NL80211_KCK_LEN,
   1375 			.maxlen = NL80211_KCK_LEN,
   1376 		},
   1377 		[NL80211_REKEY_DATA_REPLAY_CTR] = {
   1378 			.minlen = NL80211_REPLAY_CTR_LEN,
   1379 			.maxlen = NL80211_REPLAY_CTR_LEN,
   1380 		},
   1381 	};
   1382 	union wpa_event_data data;
   1383 
   1384 	if (!tb[NL80211_ATTR_MAC] ||
   1385 	    !tb[NL80211_ATTR_REKEY_DATA] ||
   1386 	    nla_parse_nested(rekey_info, MAX_NL80211_REKEY_DATA,
   1387 			     tb[NL80211_ATTR_REKEY_DATA], rekey_policy) ||
   1388 	    !rekey_info[NL80211_REKEY_DATA_REPLAY_CTR])
   1389 		return;
   1390 
   1391 	os_memset(&data, 0, sizeof(data));
   1392 	data.driver_gtk_rekey.bssid = nla_data(tb[NL80211_ATTR_MAC]);
   1393 	wpa_printf(MSG_DEBUG, "nl80211: Rekey offload event for BSSID " MACSTR,
   1394 		   MAC2STR(data.driver_gtk_rekey.bssid));
   1395 	data.driver_gtk_rekey.replay_ctr =
   1396 		nla_data(rekey_info[NL80211_REKEY_DATA_REPLAY_CTR]);
   1397 	wpa_hexdump(MSG_DEBUG, "nl80211: Rekey offload - Replay Counter",
   1398 		    data.driver_gtk_rekey.replay_ctr, NL80211_REPLAY_CTR_LEN);
   1399 	wpa_supplicant_event(drv->ctx, EVENT_DRIVER_GTK_REKEY, &data);
   1400 }
   1401 
   1402 
   1403 static void nl80211_pmksa_candidate_event(struct wpa_driver_nl80211_data *drv,
   1404 					  struct nlattr **tb)
   1405 {
   1406 	struct nlattr *cand[NUM_NL80211_PMKSA_CANDIDATE];
   1407 	static struct nla_policy cand_policy[NUM_NL80211_PMKSA_CANDIDATE] = {
   1408 		[NL80211_PMKSA_CANDIDATE_INDEX] = { .type = NLA_U32 },
   1409 		[NL80211_PMKSA_CANDIDATE_BSSID] = {
   1410 			.minlen = ETH_ALEN,
   1411 			.maxlen = ETH_ALEN,
   1412 		},
   1413 		[NL80211_PMKSA_CANDIDATE_PREAUTH] = { .type = NLA_FLAG },
   1414 	};
   1415 	union wpa_event_data data;
   1416 
   1417 	wpa_printf(MSG_DEBUG, "nl80211: PMKSA candidate event");
   1418 
   1419 	if (!tb[NL80211_ATTR_PMKSA_CANDIDATE] ||
   1420 	    nla_parse_nested(cand, MAX_NL80211_PMKSA_CANDIDATE,
   1421 			     tb[NL80211_ATTR_PMKSA_CANDIDATE], cand_policy) ||
   1422 	    !cand[NL80211_PMKSA_CANDIDATE_INDEX] ||
   1423 	    !cand[NL80211_PMKSA_CANDIDATE_BSSID])
   1424 		return;
   1425 
   1426 	os_memset(&data, 0, sizeof(data));
   1427 	os_memcpy(data.pmkid_candidate.bssid,
   1428 		  nla_data(cand[NL80211_PMKSA_CANDIDATE_BSSID]), ETH_ALEN);
   1429 	data.pmkid_candidate.index =
   1430 		nla_get_u32(cand[NL80211_PMKSA_CANDIDATE_INDEX]);
   1431 	data.pmkid_candidate.preauth =
   1432 		cand[NL80211_PMKSA_CANDIDATE_PREAUTH] != NULL;
   1433 	wpa_supplicant_event(drv->ctx, EVENT_PMKID_CANDIDATE, &data);
   1434 }
   1435 
   1436 
   1437 static void nl80211_client_probe_event(struct wpa_driver_nl80211_data *drv,
   1438 				       struct nlattr **tb)
   1439 {
   1440 	union wpa_event_data data;
   1441 	const u8 *addr;
   1442 	u64 cookie = 0;
   1443 
   1444 	addr = nla_data(tb[NL80211_ATTR_MAC]);
   1445 	if (!addr)
   1446 		return;
   1447 	if (tb[NL80211_ATTR_COOKIE])
   1448 		cookie = nla_get_u64(tb[NL80211_ATTR_COOKIE]);
   1449 	wpa_printf(MSG_DEBUG, "nl80211: Probe client event (addr=" MACSTR
   1450 		   " ack=%d cookie=%llu)", MAC2STR(addr),
   1451 		   tb[NL80211_ATTR_ACK] != NULL,
   1452 		   (long long unsigned int) cookie);
   1453 	if (!tb[NL80211_ATTR_ACK])
   1454 		return;
   1455 
   1456 	os_memset(&data, 0, sizeof(data));
   1457 	os_memcpy(data.client_poll.addr, addr, ETH_ALEN);
   1458 	wpa_supplicant_event(drv->ctx, EVENT_DRIVER_CLIENT_POLL_OK, &data);
   1459 }
   1460 
   1461 
   1462 static void nl80211_tdls_oper_event(struct wpa_driver_nl80211_data *drv,
   1463 				    struct nlattr **tb)
   1464 {
   1465 	union wpa_event_data data;
   1466 
   1467 	wpa_printf(MSG_DEBUG, "nl80211: TDLS operation event");
   1468 
   1469 	if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_TDLS_OPERATION])
   1470 		return;
   1471 
   1472 	os_memset(&data, 0, sizeof(data));
   1473 	os_memcpy(data.tdls.peer, nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
   1474 	switch (nla_get_u8(tb[NL80211_ATTR_TDLS_OPERATION])) {
   1475 	case NL80211_TDLS_SETUP:
   1476 		wpa_printf(MSG_DEBUG, "nl80211: TDLS setup request for peer "
   1477 			   MACSTR, MAC2STR(data.tdls.peer));
   1478 		data.tdls.oper = TDLS_REQUEST_SETUP;
   1479 		break;
   1480 	case NL80211_TDLS_TEARDOWN:
   1481 		wpa_printf(MSG_DEBUG, "nl80211: TDLS teardown request for peer "
   1482 			   MACSTR, MAC2STR(data.tdls.peer));
   1483 		data.tdls.oper = TDLS_REQUEST_TEARDOWN;
   1484 		break;
   1485 	case NL80211_TDLS_DISCOVERY_REQ:
   1486 		wpa_printf(MSG_DEBUG,
   1487 			   "nl80211: TDLS discovery request for peer " MACSTR,
   1488 			   MAC2STR(data.tdls.peer));
   1489 		data.tdls.oper = TDLS_REQUEST_DISCOVER;
   1490 		break;
   1491 	default:
   1492 		wpa_printf(MSG_DEBUG, "nl80211: Unsupported TDLS operatione "
   1493 			   "event");
   1494 		return;
   1495 	}
   1496 	if (tb[NL80211_ATTR_REASON_CODE]) {
   1497 		data.tdls.reason_code =
   1498 			nla_get_u16(tb[NL80211_ATTR_REASON_CODE]);
   1499 	}
   1500 
   1501 	wpa_supplicant_event(drv->ctx, EVENT_TDLS, &data);
   1502 }
   1503 
   1504 
   1505 static void nl80211_stop_ap(struct wpa_driver_nl80211_data *drv,
   1506 			    struct nlattr **tb)
   1507 {
   1508 	wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_UNAVAILABLE, NULL);
   1509 }
   1510 
   1511 
   1512 static void nl80211_connect_failed_event(struct wpa_driver_nl80211_data *drv,
   1513 					 struct nlattr **tb)
   1514 {
   1515 	union wpa_event_data data;
   1516 	u32 reason;
   1517 
   1518 	wpa_printf(MSG_DEBUG, "nl80211: Connect failed event");
   1519 
   1520 	if (!tb[NL80211_ATTR_MAC] || !tb[NL80211_ATTR_CONN_FAILED_REASON])
   1521 		return;
   1522 
   1523 	os_memset(&data, 0, sizeof(data));
   1524 	os_memcpy(data.connect_failed_reason.addr,
   1525 		  nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN);
   1526 
   1527 	reason = nla_get_u32(tb[NL80211_ATTR_CONN_FAILED_REASON]);
   1528 	switch (reason) {
   1529 	case NL80211_CONN_FAIL_MAX_CLIENTS:
   1530 		wpa_printf(MSG_DEBUG, "nl80211: Max client reached");
   1531 		data.connect_failed_reason.code = MAX_CLIENT_REACHED;
   1532 		break;
   1533 	case NL80211_CONN_FAIL_BLOCKED_CLIENT:
   1534 		wpa_printf(MSG_DEBUG, "nl80211: Blocked client " MACSTR
   1535 			   " tried to connect",
   1536 			   MAC2STR(data.connect_failed_reason.addr));
   1537 		data.connect_failed_reason.code = BLOCKED_CLIENT;
   1538 		break;
   1539 	default:
   1540 		wpa_printf(MSG_DEBUG, "nl8021l: Unknown connect failed reason "
   1541 			   "%u", reason);
   1542 		return;
   1543 	}
   1544 
   1545 	wpa_supplicant_event(drv->ctx, EVENT_CONNECT_FAILED_REASON, &data);
   1546 }
   1547 
   1548 
   1549 static void nl80211_radar_event(struct wpa_driver_nl80211_data *drv,
   1550 				struct nlattr **tb)
   1551 {
   1552 	union wpa_event_data data;
   1553 	enum nl80211_radar_event event_type;
   1554 
   1555 	if (!tb[NL80211_ATTR_WIPHY_FREQ] || !tb[NL80211_ATTR_RADAR_EVENT])
   1556 		return;
   1557 
   1558 	os_memset(&data, 0, sizeof(data));
   1559 	data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
   1560 	event_type = nla_get_u32(tb[NL80211_ATTR_RADAR_EVENT]);
   1561 
   1562 	/* Check HT params */
   1563 	if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
   1564 		data.dfs_event.ht_enabled = 1;
   1565 		data.dfs_event.chan_offset = 0;
   1566 
   1567 		switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
   1568 		case NL80211_CHAN_NO_HT:
   1569 			data.dfs_event.ht_enabled = 0;
   1570 			break;
   1571 		case NL80211_CHAN_HT20:
   1572 			break;
   1573 		case NL80211_CHAN_HT40PLUS:
   1574 			data.dfs_event.chan_offset = 1;
   1575 			break;
   1576 		case NL80211_CHAN_HT40MINUS:
   1577 			data.dfs_event.chan_offset = -1;
   1578 			break;
   1579 		}
   1580 	}
   1581 
   1582 	/* Get VHT params */
   1583 	if (tb[NL80211_ATTR_CHANNEL_WIDTH])
   1584 		data.dfs_event.chan_width =
   1585 			convert2width(nla_get_u32(
   1586 					      tb[NL80211_ATTR_CHANNEL_WIDTH]));
   1587 	if (tb[NL80211_ATTR_CENTER_FREQ1])
   1588 		data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
   1589 	if (tb[NL80211_ATTR_CENTER_FREQ2])
   1590 		data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
   1591 
   1592 	wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
   1593 		   data.dfs_event.freq, data.dfs_event.ht_enabled,
   1594 		   data.dfs_event.chan_offset, data.dfs_event.chan_width,
   1595 		   data.dfs_event.cf1, data.dfs_event.cf2);
   1596 
   1597 	switch (event_type) {
   1598 	case NL80211_RADAR_DETECTED:
   1599 		wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
   1600 		break;
   1601 	case NL80211_RADAR_CAC_FINISHED:
   1602 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
   1603 		break;
   1604 	case NL80211_RADAR_CAC_ABORTED:
   1605 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
   1606 		break;
   1607 	case NL80211_RADAR_NOP_FINISHED:
   1608 		wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
   1609 		break;
   1610 	case NL80211_RADAR_PRE_CAC_EXPIRED:
   1611 		wpa_supplicant_event(drv->ctx, EVENT_DFS_PRE_CAC_EXPIRED,
   1612 				     &data);
   1613 		break;
   1614 	case NL80211_RADAR_CAC_STARTED:
   1615 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
   1616 		break;
   1617 	default:
   1618 		wpa_printf(MSG_DEBUG, "nl80211: Unknown radar event %d "
   1619 			   "received", event_type);
   1620 		break;
   1621 	}
   1622 }
   1623 
   1624 
   1625 static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
   1626 				   int wds)
   1627 {
   1628 	struct wpa_driver_nl80211_data *drv = bss->drv;
   1629 	union wpa_event_data event;
   1630 
   1631 	if (!tb[NL80211_ATTR_MAC])
   1632 		return;
   1633 
   1634 	os_memset(&event, 0, sizeof(event));
   1635 	event.rx_from_unknown.bssid = bss->addr;
   1636 	event.rx_from_unknown.addr = nla_data(tb[NL80211_ATTR_MAC]);
   1637 	event.rx_from_unknown.wds = wds;
   1638 
   1639 	wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event);
   1640 }
   1641 
   1642 
   1643 #ifdef CONFIG_DRIVER_NL80211_QCA
   1644 
   1645 static void qca_nl80211_avoid_freq(struct wpa_driver_nl80211_data *drv,
   1646 				   const u8 *data, size_t len)
   1647 {
   1648 	u32 i, count;
   1649 	union wpa_event_data event;
   1650 	struct wpa_freq_range *range = NULL;
   1651 	const struct qca_avoid_freq_list *freq_range;
   1652 
   1653 	freq_range = (const struct qca_avoid_freq_list *) data;
   1654 	if (len < sizeof(freq_range->count))
   1655 		return;
   1656 
   1657 	count = freq_range->count;
   1658 	if (len < sizeof(freq_range->count) +
   1659 	    count * sizeof(struct qca_avoid_freq_range)) {
   1660 		wpa_printf(MSG_DEBUG, "nl80211: Ignored too short avoid frequency list (len=%u)",
   1661 			   (unsigned int) len);
   1662 		return;
   1663 	}
   1664 
   1665 	if (count > 0) {
   1666 		range = os_calloc(count, sizeof(struct wpa_freq_range));
   1667 		if (range == NULL)
   1668 			return;
   1669 	}
   1670 
   1671 	os_memset(&event, 0, sizeof(event));
   1672 	for (i = 0; i < count; i++) {
   1673 		unsigned int idx = event.freq_range.num;
   1674 		range[idx].min = freq_range->range[i].start_freq;
   1675 		range[idx].max = freq_range->range[i].end_freq;
   1676 		wpa_printf(MSG_DEBUG, "nl80211: Avoid frequency range: %u-%u",
   1677 			   range[idx].min, range[idx].max);
   1678 		if (range[idx].min > range[idx].max) {
   1679 			wpa_printf(MSG_DEBUG, "nl80211: Ignore invalid frequency range");
   1680 			continue;
   1681 		}
   1682 		event.freq_range.num++;
   1683 	}
   1684 	event.freq_range.range = range;
   1685 
   1686 	wpa_supplicant_event(drv->ctx, EVENT_AVOID_FREQUENCIES, &event);
   1687 
   1688 	os_free(range);
   1689 }
   1690 
   1691 
   1692 static enum hostapd_hw_mode get_qca_hw_mode(u8 hw_mode)
   1693 {
   1694 	switch (hw_mode) {
   1695 	case QCA_ACS_MODE_IEEE80211B:
   1696 		return HOSTAPD_MODE_IEEE80211B;
   1697 	case QCA_ACS_MODE_IEEE80211G:
   1698 		return HOSTAPD_MODE_IEEE80211G;
   1699 	case QCA_ACS_MODE_IEEE80211A:
   1700 		return HOSTAPD_MODE_IEEE80211A;
   1701 	case QCA_ACS_MODE_IEEE80211AD:
   1702 		return HOSTAPD_MODE_IEEE80211AD;
   1703 	case QCA_ACS_MODE_IEEE80211ANY:
   1704 		return HOSTAPD_MODE_IEEE80211ANY;
   1705 	default:
   1706 		return NUM_HOSTAPD_MODES;
   1707 	}
   1708 }
   1709 
   1710 
   1711 static void qca_nl80211_acs_select_ch(struct wpa_driver_nl80211_data *drv,
   1712 				   const u8 *data, size_t len)
   1713 {
   1714 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
   1715 	union wpa_event_data event;
   1716 
   1717 	wpa_printf(MSG_DEBUG,
   1718 		   "nl80211: ACS channel selection vendor event received");
   1719 
   1720 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX,
   1721 		      (struct nlattr *) data, len, NULL) ||
   1722 	    !tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL] ||
   1723 	    !tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL])
   1724 		return;
   1725 
   1726 	os_memset(&event, 0, sizeof(event));
   1727 	event.acs_selected_channels.pri_channel =
   1728 		nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL]);
   1729 	event.acs_selected_channels.sec_channel =
   1730 		nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL]);
   1731 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
   1732 		event.acs_selected_channels.vht_seg0_center_ch =
   1733 			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL]);
   1734 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL])
   1735 		event.acs_selected_channels.vht_seg1_center_ch =
   1736 			nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL]);
   1737 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH])
   1738 		event.acs_selected_channels.ch_width =
   1739 			nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
   1740 	if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
   1741 		u8 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
   1742 
   1743 		event.acs_selected_channels.hw_mode = get_qca_hw_mode(hw_mode);
   1744 		if (event.acs_selected_channels.hw_mode == NUM_HOSTAPD_MODES ||
   1745 		    event.acs_selected_channels.hw_mode ==
   1746 		    HOSTAPD_MODE_IEEE80211ANY) {
   1747 			wpa_printf(MSG_DEBUG,
   1748 				   "nl80211: Invalid hw_mode %d in ACS selection event",
   1749 				   hw_mode);
   1750 			return;
   1751 		}
   1752 	}
   1753 
   1754 	wpa_printf(MSG_INFO,
   1755 		   "nl80211: ACS Results: PCH: %d SCH: %d BW: %d VHT0: %d VHT1: %d HW_MODE: %d",
   1756 		   event.acs_selected_channels.pri_channel,
   1757 		   event.acs_selected_channels.sec_channel,
   1758 		   event.acs_selected_channels.ch_width,
   1759 		   event.acs_selected_channels.vht_seg0_center_ch,
   1760 		   event.acs_selected_channels.vht_seg1_center_ch,
   1761 		   event.acs_selected_channels.hw_mode);
   1762 
   1763 	/* Ignore ACS channel list check for backwards compatibility */
   1764 
   1765 	wpa_supplicant_event(drv->ctx, EVENT_ACS_CHANNEL_SELECTED, &event);
   1766 }
   1767 
   1768 
   1769 static void qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv,
   1770 				      const u8 *data, size_t len)
   1771 {
   1772 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX + 1];
   1773 	u8 *bssid;
   1774 
   1775 	wpa_printf(MSG_DEBUG,
   1776 		   "nl80211: Key management roam+auth vendor event received");
   1777 
   1778 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_MAX,
   1779 		      (struct nlattr *) data, len, NULL) ||
   1780 	    !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID] ||
   1781 	    nla_len(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]) != ETH_ALEN ||
   1782 	    !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE] ||
   1783 	    !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE] ||
   1784 	    !tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED])
   1785 		return;
   1786 
   1787 	bssid = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID]);
   1788 	wpa_printf(MSG_DEBUG, "  * roam BSSID " MACSTR, MAC2STR(bssid));
   1789 
   1790 	mlme_event_connect(drv, NL80211_CMD_ROAM, NULL,
   1791 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID],
   1792 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE],
   1793 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE],
   1794 			   NULL, NULL,
   1795 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED],
   1796 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR],
   1797 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK],
   1798 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK],
   1799 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS],
   1800 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM],
   1801 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK],
   1802 			   tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID]);
   1803 }
   1804 
   1805 
   1806 static void qca_nl80211_dfs_offload_radar_event(
   1807 	struct wpa_driver_nl80211_data *drv, u32 subcmd, u8 *msg, int length)
   1808 {
   1809 	union wpa_event_data data;
   1810 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
   1811 
   1812 	wpa_printf(MSG_DEBUG,
   1813 		   "nl80211: DFS offload radar vendor event received");
   1814 
   1815 	if (nla_parse(tb, NL80211_ATTR_MAX,
   1816 		      (struct nlattr *) msg, length, NULL))
   1817 		return;
   1818 
   1819 	if (!tb[NL80211_ATTR_WIPHY_FREQ]) {
   1820 		wpa_printf(MSG_INFO,
   1821 			   "nl80211: Error parsing WIPHY_FREQ in FS offload radar vendor event");
   1822 		return;
   1823 	}
   1824 
   1825 	os_memset(&data, 0, sizeof(data));
   1826 	data.dfs_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
   1827 
   1828 	wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz",
   1829 		   data.dfs_event.freq);
   1830 
   1831 	/* Check HT params */
   1832 	if (tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
   1833 		data.dfs_event.ht_enabled = 1;
   1834 		data.dfs_event.chan_offset = 0;
   1835 
   1836 		switch (nla_get_u32(tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE])) {
   1837 		case NL80211_CHAN_NO_HT:
   1838 			data.dfs_event.ht_enabled = 0;
   1839 			break;
   1840 		case NL80211_CHAN_HT20:
   1841 			break;
   1842 		case NL80211_CHAN_HT40PLUS:
   1843 			data.dfs_event.chan_offset = 1;
   1844 			break;
   1845 		case NL80211_CHAN_HT40MINUS:
   1846 			data.dfs_event.chan_offset = -1;
   1847 			break;
   1848 		}
   1849 	}
   1850 
   1851 	/* Get VHT params */
   1852 	if (tb[NL80211_ATTR_CHANNEL_WIDTH])
   1853 		data.dfs_event.chan_width =
   1854 			convert2width(nla_get_u32(
   1855 					      tb[NL80211_ATTR_CHANNEL_WIDTH]));
   1856 	if (tb[NL80211_ATTR_CENTER_FREQ1])
   1857 		data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
   1858 	if (tb[NL80211_ATTR_CENTER_FREQ2])
   1859 		data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
   1860 
   1861 	wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, "
   1862 		    "offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz",
   1863 		    data.dfs_event.freq, data.dfs_event.ht_enabled,
   1864 		    data.dfs_event.chan_offset, data.dfs_event.chan_width,
   1865 		    data.dfs_event.cf1, data.dfs_event.cf2);
   1866 
   1867 	switch (subcmd) {
   1868 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
   1869 		wpa_supplicant_event(drv->ctx, EVENT_DFS_RADAR_DETECTED, &data);
   1870 		break;
   1871 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
   1872 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_STARTED, &data);
   1873 		break;
   1874 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
   1875 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_FINISHED, &data);
   1876 		break;
   1877 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
   1878 		wpa_supplicant_event(drv->ctx, EVENT_DFS_CAC_ABORTED, &data);
   1879 		break;
   1880 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
   1881 		wpa_supplicant_event(drv->ctx, EVENT_DFS_NOP_FINISHED, &data);
   1882 		break;
   1883 	default:
   1884 		wpa_printf(MSG_DEBUG,
   1885 			   "nl80211: Unknown DFS offload radar event %d received",
   1886 			   subcmd);
   1887 		break;
   1888 	}
   1889 }
   1890 
   1891 
   1892 static void qca_nl80211_scan_trigger_event(struct wpa_driver_nl80211_data *drv,
   1893 					   u8 *data, size_t len)
   1894 {
   1895 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
   1896 	u64 cookie = 0;
   1897 	union wpa_event_data event;
   1898 	struct scan_info *info;
   1899 
   1900 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
   1901 		      (struct nlattr *) data, len, NULL) ||
   1902 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
   1903 		return;
   1904 
   1905 	cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
   1906 	if (cookie != drv->vendor_scan_cookie) {
   1907 		/* External scan trigger event, ignore */
   1908 		return;
   1909 	}
   1910 
   1911 	/* Cookie match, own scan */
   1912 	os_memset(&event, 0, sizeof(event));
   1913 	info = &event.scan_info;
   1914 	info->external_scan = 0;
   1915 	info->nl_scan_event = 0;
   1916 
   1917 	drv->scan_state = SCAN_STARTED;
   1918 	wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, &event);
   1919 }
   1920 
   1921 
   1922 static void send_vendor_scan_event(struct wpa_driver_nl80211_data *drv,
   1923 				   int aborted, struct nlattr *tb[],
   1924 				   int external_scan)
   1925 {
   1926 	union wpa_event_data event;
   1927 	struct nlattr *nl;
   1928 	int rem;
   1929 	struct scan_info *info;
   1930 	int freqs[MAX_REPORT_FREQS];
   1931 	int num_freqs = 0;
   1932 
   1933 	os_memset(&event, 0, sizeof(event));
   1934 	info = &event.scan_info;
   1935 	info->aborted = aborted;
   1936 	info->external_scan = external_scan;
   1937 
   1938 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS]) {
   1939 		nla_for_each_nested(nl,
   1940 				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_SSIDS], rem) {
   1941 			struct wpa_driver_scan_ssid *s =
   1942 				&info->ssids[info->num_ssids];
   1943 			s->ssid = nla_data(nl);
   1944 			s->ssid_len = nla_len(nl);
   1945 			wpa_printf(MSG_DEBUG,
   1946 				   "nl80211: Scan probed for SSID '%s'",
   1947 				   wpa_ssid_txt(s->ssid, s->ssid_len));
   1948 			info->num_ssids++;
   1949 			if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)
   1950 				break;
   1951 		}
   1952 	}
   1953 
   1954 	if (tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES]) {
   1955 		char msg[300], *pos, *end;
   1956 		int res;
   1957 
   1958 		pos = msg;
   1959 		end = pos + sizeof(msg);
   1960 		*pos = '\0';
   1961 
   1962 		nla_for_each_nested(nl,
   1963 				    tb[QCA_WLAN_VENDOR_ATTR_SCAN_FREQUENCIES],
   1964 				    rem) {
   1965 			freqs[num_freqs] = nla_get_u32(nl);
   1966 			res = os_snprintf(pos, end - pos, " %d",
   1967 					  freqs[num_freqs]);
   1968 			if (!os_snprintf_error(end - pos, res))
   1969 				pos += res;
   1970 			num_freqs++;
   1971 			if (num_freqs == MAX_REPORT_FREQS - 1)
   1972 				break;
   1973 		}
   1974 
   1975 		info->freqs = freqs;
   1976 		info->num_freqs = num_freqs;
   1977 		wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",
   1978 			   msg);
   1979 	}
   1980 	wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);
   1981 }
   1982 
   1983 
   1984 static void qca_nl80211_scan_done_event(struct wpa_driver_nl80211_data *drv,
   1985 					u8 *data, size_t len)
   1986 {
   1987 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SCAN_MAX + 1];
   1988 	u64 cookie = 0;
   1989 	enum scan_status status;
   1990 	int external_scan;
   1991 
   1992 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SCAN_MAX,
   1993 		      (struct nlattr *) data, len, NULL) ||
   1994 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS] ||
   1995 	    !tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE])
   1996 		return;
   1997 
   1998 	status = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SCAN_STATUS]);
   1999 	if (status >= VENDOR_SCAN_STATUS_MAX)
   2000 		return; /* invalid status */
   2001 
   2002 	cookie = nla_get_u64(tb[QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE]);
   2003 	if (cookie != drv->vendor_scan_cookie) {
   2004 		/* Event from an external scan, get scan results */
   2005 		external_scan = 1;
   2006 	} else {
   2007 		external_scan = 0;
   2008 		if (status == VENDOR_SCAN_STATUS_NEW_RESULTS)
   2009 			drv->scan_state = SCAN_COMPLETED;
   2010 		else
   2011 			drv->scan_state = SCAN_ABORTED;
   2012 
   2013 		eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv,
   2014 				     drv->ctx);
   2015 		drv->vendor_scan_cookie = 0;
   2016 		drv->last_scan_cmd = 0;
   2017 	}
   2018 
   2019 	send_vendor_scan_event(drv, (status == VENDOR_SCAN_STATUS_ABORTED), tb,
   2020 			       external_scan);
   2021 }
   2022 
   2023 
   2024 static void qca_nl80211_p2p_lo_stop_event(struct wpa_driver_nl80211_data *drv,
   2025 					  u8 *data, size_t len)
   2026 {
   2027 	struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX + 1];
   2028 	union wpa_event_data event;
   2029 
   2030 	wpa_printf(MSG_DEBUG,
   2031 		   "nl80211: P2P listen offload stop vendor event received");
   2032 
   2033 	if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_MAX,
   2034 		      (struct nlattr *) data, len, NULL) ||
   2035 	    !tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON])
   2036 		return;
   2037 
   2038 	os_memset(&event, 0, sizeof(event));
   2039 	event.p2p_lo_stop.reason_code =
   2040 		nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON]);
   2041 
   2042 	wpa_printf(MSG_DEBUG,
   2043 		   "nl80211: P2P Listen offload stop reason: %d",
   2044 		   event.p2p_lo_stop.reason_code);
   2045 	wpa_supplicant_event(drv->ctx, EVENT_P2P_LO_STOP, &event);
   2046 }
   2047 
   2048 #endif /* CONFIG_DRIVER_NL80211_QCA */
   2049 
   2050 
   2051 static void nl80211_vendor_event_qca(struct wpa_driver_nl80211_data *drv,
   2052 				     u32 subcmd, u8 *data, size_t len)
   2053 {
   2054 	switch (subcmd) {
   2055 	case QCA_NL80211_VENDOR_SUBCMD_TEST:
   2056 		wpa_hexdump(MSG_DEBUG, "nl80211: QCA test event", data, len);
   2057 		break;
   2058 #ifdef CONFIG_DRIVER_NL80211_QCA
   2059 	case QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY:
   2060 		qca_nl80211_avoid_freq(drv, data, len);
   2061 		break;
   2062 	case QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
   2063 		qca_nl80211_key_mgmt_auth(drv, data, len);
   2064 		break;
   2065 	case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
   2066 		qca_nl80211_acs_select_ch(drv, data, len);
   2067 		break;
   2068 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED:
   2069 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED:
   2070 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED:
   2071 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED:
   2072 	case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED:
   2073 		qca_nl80211_dfs_offload_radar_event(drv, subcmd, data, len);
   2074 		break;
   2075 	case QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN:
   2076 		qca_nl80211_scan_trigger_event(drv, data, len);
   2077 		break;
   2078 	case QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE:
   2079 		qca_nl80211_scan_done_event(drv, data, len);
   2080 		break;
   2081 	case QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP:
   2082 		qca_nl80211_p2p_lo_stop_event(drv, data, len);
   2083 		break;
   2084 #endif /* CONFIG_DRIVER_NL80211_QCA */
   2085 	default:
   2086 		wpa_printf(MSG_DEBUG,
   2087 			   "nl80211: Ignore unsupported QCA vendor event %u",
   2088 			   subcmd);
   2089 		break;
   2090 	}
   2091 }
   2092 
   2093 
   2094 static void nl80211_vendor_event(struct wpa_driver_nl80211_data *drv,
   2095 				 struct nlattr **tb)
   2096 {
   2097 	u32 vendor_id, subcmd, wiphy = 0;
   2098 	int wiphy_idx;
   2099 	u8 *data = NULL;
   2100 	size_t len = 0;
   2101 
   2102 	if (!tb[NL80211_ATTR_VENDOR_ID] ||
   2103 	    !tb[NL80211_ATTR_VENDOR_SUBCMD])
   2104 		return;
   2105 
   2106 	vendor_id = nla_get_u32(tb[NL80211_ATTR_VENDOR_ID]);
   2107 	subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
   2108 
   2109 	if (tb[NL80211_ATTR_WIPHY])
   2110 		wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
   2111 
   2112 	wpa_printf(MSG_DEBUG, "nl80211: Vendor event: wiphy=%u vendor_id=0x%x subcmd=%u",
   2113 		   wiphy, vendor_id, subcmd);
   2114 
   2115 	if (tb[NL80211_ATTR_VENDOR_DATA]) {
   2116 		data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
   2117 		len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
   2118 		wpa_hexdump(MSG_MSGDUMP, "nl80211: Vendor data", data, len);
   2119 	}
   2120 
   2121 	wiphy_idx = nl80211_get_wiphy_index(drv->first_bss);
   2122 	if (wiphy_idx >= 0 && wiphy_idx != (int) wiphy) {
   2123 		wpa_printf(MSG_DEBUG, "nl80211: Ignore vendor event for foreign wiphy %u (own: %d)",
   2124 			   wiphy, wiphy_idx);
   2125 		return;
   2126 	}
   2127 
   2128 	switch (vendor_id) {
   2129 	case OUI_QCA:
   2130 		nl80211_vendor_event_qca(drv, subcmd, data, len);
   2131 		break;
   2132 	default:
   2133 		wpa_printf(MSG_DEBUG, "nl80211: Ignore unsupported vendor event");
   2134 		break;
   2135 	}
   2136 }
   2137 
   2138 
   2139 static void nl80211_reg_change_event(struct wpa_driver_nl80211_data *drv,
   2140 				     struct nlattr *tb[])
   2141 {
   2142 	union wpa_event_data data;
   2143 	enum nl80211_reg_initiator init;
   2144 
   2145 	wpa_printf(MSG_DEBUG, "nl80211: Regulatory domain change");
   2146 
   2147 	if (tb[NL80211_ATTR_REG_INITIATOR] == NULL)
   2148 		return;
   2149 
   2150 	os_memset(&data, 0, sizeof(data));
   2151 	init = nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]);
   2152 	wpa_printf(MSG_DEBUG, " * initiator=%d", init);
   2153 	switch (init) {
   2154 	case NL80211_REGDOM_SET_BY_CORE:
   2155 		data.channel_list_changed.initiator = REGDOM_SET_BY_CORE;
   2156 		break;
   2157 	case NL80211_REGDOM_SET_BY_USER:
   2158 		data.channel_list_changed.initiator = REGDOM_SET_BY_USER;
   2159 		break;
   2160 	case NL80211_REGDOM_SET_BY_DRIVER:
   2161 		data.channel_list_changed.initiator = REGDOM_SET_BY_DRIVER;
   2162 		break;
   2163 	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
   2164 		data.channel_list_changed.initiator = REGDOM_SET_BY_COUNTRY_IE;
   2165 		break;
   2166 	}
   2167 
   2168 	if (tb[NL80211_ATTR_REG_TYPE]) {
   2169 		enum nl80211_reg_type type;
   2170 		type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]);
   2171 		wpa_printf(MSG_DEBUG, " * type=%d", type);
   2172 		switch (type) {
   2173 		case NL80211_REGDOM_TYPE_COUNTRY:
   2174 			data.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
   2175 			break;
   2176 		case NL80211_REGDOM_TYPE_WORLD:
   2177 			data.channel_list_changed.type = REGDOM_TYPE_WORLD;
   2178 			break;
   2179 		case NL80211_REGDOM_TYPE_CUSTOM_WORLD:
   2180 			data.channel_list_changed.type =
   2181 				REGDOM_TYPE_CUSTOM_WORLD;
   2182 			break;
   2183 		case NL80211_REGDOM_TYPE_INTERSECTION:
   2184 			data.channel_list_changed.type =
   2185 				REGDOM_TYPE_INTERSECTION;
   2186 			break;
   2187 		}
   2188 	}
   2189 
   2190 	if (tb[NL80211_ATTR_REG_ALPHA2]) {
   2191 		os_strlcpy(data.channel_list_changed.alpha2,
   2192 			   nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]),
   2193 			   sizeof(data.channel_list_changed.alpha2));
   2194 		wpa_printf(MSG_DEBUG, " * alpha2=%s",
   2195 			   data.channel_list_changed.alpha2);
   2196 	}
   2197 
   2198 	wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
   2199 }
   2200 
   2201 
   2202 static void nl80211_dump_freq(const char *title, struct nlattr *nl_freq)
   2203 {
   2204 	static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = {
   2205 		[NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 },
   2206 		[NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG },
   2207 		[NL80211_FREQUENCY_ATTR_NO_IR] = { .type = NLA_FLAG },
   2208 		[NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG },
   2209 		[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 },
   2210 	};
   2211 	struct nlattr *tb[NL80211_FREQUENCY_ATTR_MAX + 1];
   2212 	u32 freq = 0, max_tx_power = 0;
   2213 
   2214 	nla_parse(tb, NL80211_FREQUENCY_ATTR_MAX,
   2215 		  nla_data(nl_freq), nla_len(nl_freq), freq_policy);
   2216 
   2217 	if (tb[NL80211_FREQUENCY_ATTR_FREQ])
   2218 		freq = nla_get_u32(tb[NL80211_FREQUENCY_ATTR_FREQ]);
   2219 	if (tb[NL80211_FREQUENCY_ATTR_MAX_TX_POWER])
   2220 		max_tx_power =
   2221 			nla_get_u32(tb[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
   2222 
   2223 	wpa_printf(MSG_DEBUG,
   2224 		   "nl80211: Channel (%s): freq=%u max_tx_power=%u%s%s%s",
   2225 		   title, freq, max_tx_power,
   2226 		   tb[NL80211_FREQUENCY_ATTR_DISABLED] ? " disabled" : "",
   2227 		   tb[NL80211_FREQUENCY_ATTR_NO_IR] ? " no-IR" : "",
   2228 		   tb[NL80211_FREQUENCY_ATTR_RADAR] ? " radar" : "");
   2229 }
   2230 
   2231 
   2232 static void nl80211_reg_beacon_hint_event(struct wpa_driver_nl80211_data *drv,
   2233 					   struct nlattr *tb[])
   2234 {
   2235 	union wpa_event_data data;
   2236 
   2237 	wpa_printf(MSG_DEBUG, "nl80211: Regulatory beacon hint");
   2238 	os_memset(&data, 0, sizeof(data));
   2239 	data.channel_list_changed.initiator = REGDOM_BEACON_HINT;
   2240 
   2241 	if (tb[NL80211_ATTR_FREQ_BEFORE])
   2242 		nl80211_dump_freq("before", tb[NL80211_ATTR_FREQ_BEFORE]);
   2243 	if (tb[NL80211_ATTR_FREQ_AFTER])
   2244 		nl80211_dump_freq("after", tb[NL80211_ATTR_FREQ_AFTER]);
   2245 
   2246 	wpa_supplicant_event(drv->ctx, EVENT_CHANNEL_LIST_CHANGED, &data);
   2247 }
   2248 
   2249 
   2250 static void nl80211_external_auth(struct wpa_driver_nl80211_data *drv,
   2251 				  struct nlattr **tb)
   2252 {
   2253 	union wpa_event_data event;
   2254 	enum nl80211_external_auth_action act;
   2255 
   2256 	if (!tb[NL80211_ATTR_AKM_SUITES] ||
   2257 	    !tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION] ||
   2258 	    !tb[NL80211_ATTR_BSSID] ||
   2259 	    !tb[NL80211_ATTR_SSID])
   2260 		return;
   2261 
   2262 	os_memset(&event, 0, sizeof(event));
   2263 	act = nla_get_u32(tb[NL80211_ATTR_EXTERNAL_AUTH_ACTION]);
   2264 	switch (act) {
   2265 	case NL80211_EXTERNAL_AUTH_START:
   2266 		event.external_auth.action = EXT_AUTH_START;
   2267 		break;
   2268 	case NL80211_EXTERNAL_AUTH_ABORT:
   2269 		event.external_auth.action = EXT_AUTH_ABORT;
   2270 		break;
   2271 	default:
   2272 		return;
   2273 	}
   2274 
   2275 	event.external_auth.key_mgmt_suite =
   2276 		nla_get_u32(tb[NL80211_ATTR_AKM_SUITES]);
   2277 
   2278 	event.external_auth.ssid_len = nla_len(tb[NL80211_ATTR_SSID]);
   2279 	if (event.external_auth.ssid_len > SSID_MAX_LEN)
   2280 		return;
   2281 	event.external_auth.ssid = nla_data(tb[NL80211_ATTR_SSID]);
   2282 
   2283 	event.external_auth.bssid = nla_data(tb[NL80211_ATTR_BSSID]);
   2284 
   2285 	wpa_printf(MSG_DEBUG,
   2286 		   "nl80211: External auth action: %u, AKM: 0x%x",
   2287 		   event.external_auth.action,
   2288 		   event.external_auth.key_mgmt_suite);
   2289 	wpa_supplicant_event(drv->ctx, EVENT_EXTERNAL_AUTH, &event);
   2290 }
   2291 
   2292 
   2293 static void nl80211_port_authorized(struct wpa_driver_nl80211_data *drv,
   2294 				    struct nlattr **tb)
   2295 {
   2296 	const u8 *addr;
   2297 
   2298 	if (!tb[NL80211_ATTR_MAC] ||
   2299 	    nla_len(tb[NL80211_ATTR_MAC]) != ETH_ALEN) {
   2300 		wpa_printf(MSG_DEBUG,
   2301 			   "nl80211: Ignore port authorized event without BSSID");
   2302 		return;
   2303 	}
   2304 
   2305 	addr = nla_data(tb[NL80211_ATTR_MAC]);
   2306 	if (os_memcmp(addr, drv->bssid, ETH_ALEN) != 0) {
   2307 		wpa_printf(MSG_DEBUG,
   2308 			   "nl80211: Ignore port authorized event for " MACSTR
   2309 			   " (not the currently connected BSSID " MACSTR ")",
   2310 			   MAC2STR(addr), MAC2STR(drv->bssid));
   2311 		return;
   2312 	}
   2313 
   2314 	wpa_supplicant_event(drv->ctx, EVENT_PORT_AUTHORIZED, NULL);
   2315 }
   2316 
   2317 
   2318 static void nl80211_sta_opmode_change_event(struct wpa_driver_nl80211_data *drv,
   2319 					    struct nlattr **tb)
   2320 {
   2321 	union wpa_event_data ed;
   2322 	u8 smps_mode, max_bw;
   2323 
   2324 	if (!tb[NL80211_ATTR_MAC] ||
   2325 	    (!tb[NL80211_ATTR_CHANNEL_WIDTH] &&
   2326 	     !tb[NL80211_ATTR_SMPS_MODE] &&
   2327 	     !tb[NL80211_ATTR_NSS]))
   2328 		return;
   2329 
   2330 	ed.sta_opmode.smps_mode = SMPS_INVALID;
   2331 	ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
   2332 	ed.sta_opmode.rx_nss = 0xff;
   2333 	ed.sta_opmode.addr = nla_data(tb[NL80211_ATTR_MAC]);
   2334 
   2335 	if (tb[NL80211_ATTR_SMPS_MODE]) {
   2336 		smps_mode = nla_get_u8(tb[NL80211_ATTR_SMPS_MODE]);
   2337 		switch (smps_mode) {
   2338 		case NL80211_SMPS_OFF:
   2339 			ed.sta_opmode.smps_mode = SMPS_OFF;
   2340 			break;
   2341 		case NL80211_SMPS_STATIC:
   2342 			ed.sta_opmode.smps_mode = SMPS_STATIC;
   2343 			break;
   2344 		case NL80211_SMPS_DYNAMIC:
   2345 			ed.sta_opmode.smps_mode = SMPS_DYNAMIC;
   2346 			break;
   2347 		default:
   2348 			ed.sta_opmode.smps_mode = SMPS_INVALID;
   2349 			break;
   2350 		}
   2351 	}
   2352 
   2353 	if (tb[NL80211_ATTR_CHANNEL_WIDTH]) {
   2354 		max_bw = nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]);
   2355 		switch (max_bw) {
   2356 		case NL80211_CHAN_WIDTH_20_NOHT:
   2357 			ed.sta_opmode.chan_width = CHAN_WIDTH_20_NOHT;
   2358 			break;
   2359 		case NL80211_CHAN_WIDTH_20:
   2360 			ed.sta_opmode.chan_width = CHAN_WIDTH_20;
   2361 			break;
   2362 		case NL80211_CHAN_WIDTH_40:
   2363 			ed.sta_opmode.chan_width = CHAN_WIDTH_40;
   2364 			break;
   2365 		case NL80211_CHAN_WIDTH_80:
   2366 			ed.sta_opmode.chan_width = CHAN_WIDTH_80;
   2367 			break;
   2368 		case NL80211_CHAN_WIDTH_80P80:
   2369 			ed.sta_opmode.chan_width = CHAN_WIDTH_80P80;
   2370 			break;
   2371 		case NL80211_CHAN_WIDTH_160:
   2372 			ed.sta_opmode.chan_width = CHAN_WIDTH_160;
   2373 			break;
   2374 		default:
   2375 			ed.sta_opmode.chan_width = CHAN_WIDTH_UNKNOWN;
   2376 			break;
   2377 
   2378 		}
   2379 	}
   2380 
   2381 	if (tb[NL80211_ATTR_NSS])
   2382 		ed.sta_opmode.rx_nss = nla_get_u8(tb[NL80211_ATTR_NSS]);
   2383 
   2384 	wpa_supplicant_event(drv->ctx, EVENT_STATION_OPMODE_CHANGED, &ed);
   2385 }
   2386 
   2387 
   2388 static void do_process_drv_event(struct i802_bss *bss, int cmd,
   2389 				 struct nlattr **tb)
   2390 {
   2391 	struct wpa_driver_nl80211_data *drv = bss->drv;
   2392 	int external_scan_event = 0;
   2393 
   2394 	wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",
   2395 		   cmd, nl80211_command_to_string(cmd), bss->ifname);
   2396 
   2397 	if (cmd == NL80211_CMD_ROAM &&
   2398 	    (drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {
   2399 		/*
   2400 		 * Device will use roam+auth vendor event to indicate
   2401 		 * roaming, so ignore the regular roam event.
   2402 		 */
   2403 		wpa_printf(MSG_DEBUG,
   2404 			   "nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",
   2405 			   cmd);
   2406 		return;
   2407 	}
   2408 
   2409 	if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
   2410 	    (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
   2411 	     cmd == NL80211_CMD_SCAN_ABORTED)) {
   2412 		wpa_driver_nl80211_set_mode(drv->first_bss,
   2413 					    drv->ap_scan_as_station);
   2414 		drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
   2415 	}
   2416 
   2417 	switch (cmd) {
   2418 	case NL80211_CMD_TRIGGER_SCAN:
   2419 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
   2420 		drv->scan_state = SCAN_STARTED;
   2421 		if (drv->scan_for_auth) {
   2422 			/*
   2423 			 * Cannot indicate EVENT_SCAN_STARTED here since we skip
   2424 			 * EVENT_SCAN_RESULTS in scan_for_auth case and the
   2425 			 * upper layer implementation could get confused about
   2426 			 * scanning state.
   2427 			 */
   2428 			wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
   2429 			break;
   2430 		}
   2431 		wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
   2432 		break;
   2433 	case NL80211_CMD_START_SCHED_SCAN:
   2434 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");
   2435 		drv->scan_state = SCHED_SCAN_STARTED;
   2436 		break;
   2437 	case NL80211_CMD_SCHED_SCAN_STOPPED:
   2438 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");
   2439 		drv->scan_state = SCHED_SCAN_STOPPED;
   2440 		wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);
   2441 		break;
   2442 	case NL80211_CMD_NEW_SCAN_RESULTS:
   2443 		wpa_dbg(drv->ctx, MSG_DEBUG,
   2444 			"nl80211: New scan results available");
   2445 		if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
   2446 			drv->scan_state = SCAN_COMPLETED;
   2447 		drv->scan_complete_events = 1;
   2448 		if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
   2449 			eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
   2450 					     drv, drv->ctx);
   2451 			drv->last_scan_cmd = 0;
   2452 		} else {
   2453 			external_scan_event = 1;
   2454 		}
   2455 		send_scan_event(drv, 0, tb, external_scan_event);
   2456 		break;
   2457 	case NL80211_CMD_SCHED_SCAN_RESULTS:
   2458 		wpa_dbg(drv->ctx, MSG_DEBUG,
   2459 			"nl80211: New sched scan results available");
   2460 		drv->scan_state = SCHED_SCAN_RESULTS;
   2461 		send_scan_event(drv, 0, tb, 0);
   2462 		break;
   2463 	case NL80211_CMD_SCAN_ABORTED:
   2464 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted");
   2465 		if (drv->last_scan_cmd != NL80211_CMD_VENDOR)
   2466 			drv->scan_state = SCAN_ABORTED;
   2467 		if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {
   2468 			/*
   2469 			 * Need to indicate that scan results are available in
   2470 			 * order not to make wpa_supplicant stop its scanning.
   2471 			 */
   2472 			eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,
   2473 					     drv, drv->ctx);
   2474 			drv->last_scan_cmd = 0;
   2475 		} else {
   2476 			external_scan_event = 1;
   2477 		}
   2478 		send_scan_event(drv, 1, tb, external_scan_event);
   2479 		break;
   2480 	case NL80211_CMD_AUTHENTICATE:
   2481 	case NL80211_CMD_ASSOCIATE:
   2482 	case NL80211_CMD_DEAUTHENTICATE:
   2483 	case NL80211_CMD_DISASSOCIATE:
   2484 	case NL80211_CMD_FRAME_TX_STATUS:
   2485 	case NL80211_CMD_UNPROT_DEAUTHENTICATE:
   2486 	case NL80211_CMD_UNPROT_DISASSOCIATE:
   2487 		mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME],
   2488 			   tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
   2489 			   tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
   2490 			   tb[NL80211_ATTR_COOKIE],
   2491 			   tb[NL80211_ATTR_RX_SIGNAL_DBM],
   2492 			   tb[NL80211_ATTR_STA_WME],
   2493 			   tb[NL80211_ATTR_REQ_IE]);
   2494 		break;
   2495 	case NL80211_CMD_CONNECT:
   2496 	case NL80211_CMD_ROAM:
   2497 		mlme_event_connect(drv, cmd,
   2498 				   tb[NL80211_ATTR_STATUS_CODE],
   2499 				   tb[NL80211_ATTR_MAC],
   2500 				   tb[NL80211_ATTR_REQ_IE],
   2501 				   tb[NL80211_ATTR_RESP_IE],
   2502 				   tb[NL80211_ATTR_TIMED_OUT],
   2503 				   tb[NL80211_ATTR_TIMEOUT_REASON],
   2504 				   NULL, NULL, NULL,
   2505 				   tb[NL80211_ATTR_FILS_KEK],
   2506 				   NULL,
   2507 				   tb[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM],
   2508 				   tb[NL80211_ATTR_PMK],
   2509 				   tb[NL80211_ATTR_PMKID]);
   2510 		break;
   2511 	case NL80211_CMD_CH_SWITCH_NOTIFY:
   2512 		mlme_event_ch_switch(drv,
   2513 				     tb[NL80211_ATTR_IFINDEX],
   2514 				     tb[NL80211_ATTR_WIPHY_FREQ],
   2515 				     tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
   2516 				     tb[NL80211_ATTR_CHANNEL_WIDTH],
   2517 				     tb[NL80211_ATTR_CENTER_FREQ1],
   2518 				     tb[NL80211_ATTR_CENTER_FREQ2]);
   2519 		break;
   2520 	case NL80211_CMD_DISCONNECT:
   2521 		mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
   2522 				      tb[NL80211_ATTR_MAC],
   2523 				      tb[NL80211_ATTR_DISCONNECTED_BY_AP]);
   2524 		break;
   2525 	case NL80211_CMD_MICHAEL_MIC_FAILURE:
   2526 		mlme_event_michael_mic_failure(bss, tb);
   2527 		break;
   2528 	case NL80211_CMD_JOIN_IBSS:
   2529 		mlme_event_join_ibss(drv, tb);
   2530 		break;
   2531 	case NL80211_CMD_REMAIN_ON_CHANNEL:
   2532 		mlme_event_remain_on_channel(drv, 0, tb);
   2533 		break;
   2534 	case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL:
   2535 		mlme_event_remain_on_channel(drv, 1, tb);
   2536 		break;
   2537 	case NL80211_CMD_NOTIFY_CQM:
   2538 		nl80211_cqm_event(drv, tb);
   2539 		break;
   2540 	case NL80211_CMD_REG_CHANGE:
   2541 	case NL80211_CMD_WIPHY_REG_CHANGE:
   2542 		nl80211_reg_change_event(drv, tb);
   2543 		break;
   2544 	case NL80211_CMD_REG_BEACON_HINT:
   2545 		nl80211_reg_beacon_hint_event(drv, tb);
   2546 		break;
   2547 	case NL80211_CMD_NEW_STATION:
   2548 		nl80211_new_station_event(drv, bss, tb);
   2549 		break;
   2550 	case NL80211_CMD_DEL_STATION:
   2551 		nl80211_del_station_event(drv, bss, tb);
   2552 		break;
   2553 	case NL80211_CMD_SET_REKEY_OFFLOAD:
   2554 		nl80211_rekey_offload_event(drv, tb);
   2555 		break;
   2556 	case NL80211_CMD_PMKSA_CANDIDATE:
   2557 		nl80211_pmksa_candidate_event(drv, tb);
   2558 		break;
   2559 	case NL80211_CMD_PROBE_CLIENT:
   2560 		nl80211_client_probe_event(drv, tb);
   2561 		break;
   2562 	case NL80211_CMD_TDLS_OPER:
   2563 		nl80211_tdls_oper_event(drv, tb);
   2564 		break;
   2565 	case NL80211_CMD_CONN_FAILED:
   2566 		nl80211_connect_failed_event(drv, tb);
   2567 		break;
   2568 	case NL80211_CMD_FT_EVENT:
   2569 		mlme_event_ft_event(drv, tb);
   2570 		break;
   2571 	case NL80211_CMD_RADAR_DETECT:
   2572 		nl80211_radar_event(drv, tb);
   2573 		break;
   2574 	case NL80211_CMD_STOP_AP:
   2575 		nl80211_stop_ap(drv, tb);
   2576 		break;
   2577 	case NL80211_CMD_VENDOR:
   2578 		nl80211_vendor_event(drv, tb);
   2579 		break;
   2580 	case NL80211_CMD_NEW_PEER_CANDIDATE:
   2581 		nl80211_new_peer_candidate(drv, tb);
   2582 		break;
   2583 	case NL80211_CMD_PORT_AUTHORIZED:
   2584 		nl80211_port_authorized(drv, tb);
   2585 		break;
   2586 	case NL80211_CMD_STA_OPMODE_CHANGED:
   2587 		nl80211_sta_opmode_change_event(drv, tb);
   2588 		break;
   2589 	default:
   2590 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
   2591 			"(cmd=%d)", cmd);
   2592 		break;
   2593 	}
   2594 }
   2595 
   2596 
   2597 int process_global_event(struct nl_msg *msg, void *arg)
   2598 {
   2599 	struct nl80211_global *global = arg;
   2600 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
   2601 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
   2602 	struct wpa_driver_nl80211_data *drv, *tmp;
   2603 	int ifidx = -1, wiphy_idx = -1, wiphy_idx_rx = -1;
   2604 	struct i802_bss *bss;
   2605 	u64 wdev_id = 0;
   2606 	int wdev_id_set = 0;
   2607 	int wiphy_idx_set = 0;
   2608 
   2609 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
   2610 		  genlmsg_attrlen(gnlh, 0), NULL);
   2611 
   2612 	if (tb[NL80211_ATTR_IFINDEX])
   2613 		ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
   2614 	else if (tb[NL80211_ATTR_WDEV]) {
   2615 		wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
   2616 		wdev_id_set = 1;
   2617 	} else if (tb[NL80211_ATTR_WIPHY]) {
   2618 		wiphy_idx_rx = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
   2619 		wiphy_idx_set = 1;
   2620 	}
   2621 
   2622 	dl_list_for_each_safe(drv, tmp, &global->interfaces,
   2623 			      struct wpa_driver_nl80211_data, list) {
   2624 		for (bss = drv->first_bss; bss; bss = bss->next) {
   2625 			if (wiphy_idx_set)
   2626 				wiphy_idx = nl80211_get_wiphy_index(bss);
   2627 			if ((ifidx == -1 && !wiphy_idx_set && !wdev_id_set) ||
   2628 			    ifidx == bss->ifindex ||
   2629 			    (wiphy_idx_set && wiphy_idx == wiphy_idx_rx) ||
   2630 			    (wdev_id_set && bss->wdev_id_set &&
   2631 			     wdev_id == bss->wdev_id)) {
   2632 				do_process_drv_event(bss, gnlh->cmd, tb);
   2633 				return NL_SKIP;
   2634 			}
   2635 		}
   2636 		wpa_printf(MSG_DEBUG,
   2637 			   "nl80211: Ignored event (cmd=%d) for foreign interface (ifindex %d wdev 0x%llx)",
   2638 			   gnlh->cmd, ifidx, (long long unsigned int) wdev_id);
   2639 	}
   2640 
   2641 	return NL_SKIP;
   2642 }
   2643 
   2644 
   2645 int process_bss_event(struct nl_msg *msg, void *arg)
   2646 {
   2647 	struct i802_bss *bss = arg;
   2648 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
   2649 	struct nlattr *tb[NL80211_ATTR_MAX + 1];
   2650 
   2651 	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
   2652 		  genlmsg_attrlen(gnlh, 0), NULL);
   2653 
   2654 	wpa_printf(MSG_DEBUG, "nl80211: BSS Event %d (%s) received for %s",
   2655 		   gnlh->cmd, nl80211_command_to_string(gnlh->cmd),
   2656 		   bss->ifname);
   2657 
   2658 	switch (gnlh->cmd) {
   2659 	case NL80211_CMD_FRAME:
   2660 	case NL80211_CMD_FRAME_TX_STATUS:
   2661 		mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME],
   2662 			   tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT],
   2663 			   tb[NL80211_ATTR_WIPHY_FREQ], tb[NL80211_ATTR_ACK],
   2664 			   tb[NL80211_ATTR_COOKIE],
   2665 			   tb[NL80211_ATTR_RX_SIGNAL_DBM],
   2666 			   tb[NL80211_ATTR_STA_WME], NULL);
   2667 		break;
   2668 	case NL80211_CMD_UNEXPECTED_FRAME:
   2669 		nl80211_spurious_frame(bss, tb, 0);
   2670 		break;
   2671 	case NL80211_CMD_UNEXPECTED_4ADDR_FRAME:
   2672 		nl80211_spurious_frame(bss, tb, 1);
   2673 		break;
   2674 	case NL80211_CMD_EXTERNAL_AUTH:
   2675 		nl80211_external_auth(bss->drv, tb);
   2676 		break;
   2677 	default:
   2678 		wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event "
   2679 			   "(cmd=%d)", gnlh->cmd);
   2680 		break;
   2681 	}
   2682 
   2683 	return NL_SKIP;
   2684 }
   2685