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