1 /*
2  * Driver interaction with Linux nl80211/cfg80211 - Event processing
3  * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
4  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
5  * Copyright (c) 2009-2010, Atheros Communications
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10 
11 #include "includes.h"
12 #include <netlink/genl/genl.h>
13 
14 #include "utils/common.h"
15 #include "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