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