[wpa_supplicant] Cumulative patch from fe468b071

Bug: 124017368
Test: Device boots up and connects to WPA3/OWE wifi networks, run traffic.
Test: Able to turn on/off softap, associate wifi STA, run traffic.
Test: DPP functional test.
Test: Regression test passed (Bug: 124301325)

fe468b071 HE: Fix set_he_cap() parsing of config options for MU EDCA Params
f3a841bbf Do not disassociate not-associated STA on timeout
91205c8eb OpenSSL: Fix uninitialized variable in CRL reloading corner case
092a19222 Use for_each_element() in ieee802_11_parse_elems()
b50a63896 common: Use for_each_element_id/_extid for get_ie/get_ie_ext/get_vendor_ie
b64479742 common: Use for_each_element_id() in mb_ies_info_by_ies()
9008048f0 common: Use for_each_element_id() in ieee802_11_vendor_ie_concat()
eb84238df common: Use for_each_element() in ieee802_11_ie_count()
0e0c31bdc common: Add strongly typed element iteration macros
525923b1d tests: EAPOL-Key fuzzing tool
02a0a2393 RSN: Do not start preauthentication timer without candidates
1e5506588 JSON: Fix string parsing when \\ escape is at the end of buffer
0dedcb315 JSON: Fix parsing of a number from the end of the buffer
79fa1b453 tests: JSON parser fuzzer
62269c8d8 TLS: Fix X.509 certificate name conversion into empty string
3eae9766b TLS: Fix ASN.1 parsing with no room for the header
fbc2123a1 TLS: Fix AlertDescription for missing partial processing case
1ac9c020b tests: TLS fuzzing tool
f3cca8b1e TLS server: Check credentials have been configured before using them
19dd7a736 TLS server: Local failure information on verify_data mismatch
f08ab18bf TLS server: Add internal callbacks get_failed, get_*_alerts
b642ab406 TLS server: More complete logging of ClientHello decode errors
fdd8a2f0b TLS client: Fix peer certificate event checking for probing
e5bffe1aa OpenSSL: Add more handshake message names to debug
21cd8f831 nl80211: Use wpa_ssid_txt() for debug messages more consistently
bbdb50146 Note HT overrides in debug log only if set
f2a6ac63e P2P: Update find_start timer only when p2p_scan is started.
c4e90da6d MBO: Move the WNM-Notification subtype definitions to common location
105b14f54 HS 2.0: Update the T&C Acceptance subtype value
65b487ae5 HS 2.0: Add QUIET=1 support for building hs20-osu-client
73f285dad Add FT-PSK to GET_CAPABILITY key_mgmt
6110753b1 nl80211: Clear PMKID add command message buffer
0fa33e05b nl80211: Clear connect command message buffer
b14e8ea1d nl80211: Request kernel to trim off payload of netlink requests from acks
789b48bb4 EAP peer: Clear temporary message buffers before freeing
8f99a3c26 Clear config item writing buffer before freeing it
a68e9b698 D-Bus: Fix P2P DeleteService dict iteration
0607346f1 D-Bus: Fix a memory leak in DeleteService handler
d05dda61d PEAP: Explicitly clear temporary keys from memory when using CMK
4e1cd3468 EAP-PEAP: Derive EMSK and use 128-octet derivation for MSK
d8c20ec59 DPP: Clear dpp_listen_freq on remain-on-channel failure
59fa20538 P2P: Allow the avoid channels for P2P discovery/negotiation
e34cd9f06 WNM: Fix WNM-Sleep Mode Request bounds checking
159a7fbde crl_reload_interval: Add CRL reloading support
83c860813 AP: Add wpa_psk_file reloading in runtime
ec5c39a55 AP: Allow identifying which passphrase station used with wpa_psk_file
b08c9ad0c AP: Expose PMK outside of wpa_auth module
89896c000 tests: Use python3 compatible print statement
bab493b90 tests: Use python3 compatible "except" statement
0dab47733 Write multi_ap_backhaul_sta to wpa_supplicant config
98251c6f2 dbus: Document more possible BSS/RSA/KeyMgmt values
1e591df06 Check supported types in wpas_mac_addr_rand_scan_set()
c85249aa1 Fix test compilation error related to sme_event_unprot_disconnect()
42d308635 SAE: Advertise Password Identifier use
59c693064 HS 2.0 server: Command line option to fetch the version information
2d1762fa4 HS 2.0 server: Alternative subrem updateNode for certificate credentials
d97cf2a11 HS 2.0 server: Use noMOUpdate in client certificate subrem
13a200a92 FILS: Remove notes about experimental implementation
86d4e0537 dbus: Expose support of SAE key management in BSS properties

Change-Id: Id507b73f1f4a2e356cbcd3bfcfb9dcd23c8fd9e0
diff --git a/src/common/defs.h b/src/common/defs.h
index c968cd6..4faf1c8 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -59,6 +59,13 @@
 #define WPA_KEY_MGMT_DPP BIT(23)
 #define WPA_KEY_MGMT_FT_IEEE8021X_SHA384 BIT(24)
 
+#define WPA_KEY_MGMT_FT (WPA_KEY_MGMT_FT_PSK | \
+			 WPA_KEY_MGMT_FT_IEEE8021X | \
+			 WPA_KEY_MGMT_FT_IEEE8021X_SHA384 | \
+			 WPA_KEY_MGMT_FT_SAE | \
+			 WPA_KEY_MGMT_FT_FILS_SHA256 | \
+			 WPA_KEY_MGMT_FT_FILS_SHA384)
+
 static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
 {
 	return !!(akm & (WPA_KEY_MGMT_IEEE8021X |
@@ -86,12 +93,14 @@
 
 static inline int wpa_key_mgmt_ft(int akm)
 {
-	return !!(akm & (WPA_KEY_MGMT_FT_PSK |
-			 WPA_KEY_MGMT_FT_IEEE8021X |
-			 WPA_KEY_MGMT_FT_IEEE8021X_SHA384 |
-			 WPA_KEY_MGMT_FT_SAE |
-			 WPA_KEY_MGMT_FT_FILS_SHA256 |
-			 WPA_KEY_MGMT_FT_FILS_SHA384));
+	return !!(akm & WPA_KEY_MGMT_FT);
+}
+
+static inline int wpa_key_mgmt_only_ft(int akm)
+{
+	int ft = wpa_key_mgmt_ft(akm);
+	akm &= ~WPA_KEY_MGMT_FT;
+	return ft && !akm;
 }
 
 static inline int wpa_key_mgmt_ft_psk(int akm)
@@ -399,4 +408,15 @@
 #define OCE_STA_CFON BIT(1)
 #define OCE_AP BIT(2)
 
+/* enum chan_width - Channel width definitions */
+enum chan_width {
+	CHAN_WIDTH_20_NOHT,
+	CHAN_WIDTH_20,
+	CHAN_WIDTH_40,
+	CHAN_WIDTH_80,
+	CHAN_WIDTH_80P80,
+	CHAN_WIDTH_160,
+	CHAN_WIDTH_UNKNOWN
+};
+
 #endif /* DEFS_H */
diff --git a/src/common/dpp.c b/src/common/dpp.c
index 677f586..bcb694b 100644
--- a/src/common/dpp.c
+++ b/src/common/dpp.c
@@ -813,7 +813,9 @@
 	const unsigned char *pk;
 	int ppklen;
 	X509_ALGOR *pa;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+	(defined(LIBRESSL_VERSION_NUMBER) && \
+	 LIBRESSL_VERSION_NUMBER < 0x20800000L)
 	ASN1_OBJECT *pa_oid;
 #else
 	const ASN1_OBJECT *pa_oid;
@@ -2854,7 +2856,7 @@
 		i_pubkey_hash = test_hash;
 	} else if (dpp_test == DPP_TEST_NO_STATUS_AUTH_RESP) {
 		wpa_printf(MSG_INFO, "DPP: TESTING - no Status");
-		status = -1;
+		status = 255;
 	} else if (dpp_test == DPP_TEST_NO_I_NONCE_AUTH_RESP) {
 		wpa_printf(MSG_INFO, "DPP: TESTING - no I-nonce");
 		i_nonce = NULL;
@@ -3457,7 +3459,7 @@
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
-	if (!auth->initiator) {
+	if (!auth->initiator || !auth->peer_bi) {
 		dpp_auth_fail(auth, "Unexpected Authentication Response");
 		return NULL;
 	}
@@ -3638,7 +3640,7 @@
 		goto fail;
 	}
 
-	if (auth->own_bi && auth->peer_bi) {
+	if (auth->own_bi) {
 		/* Mutual authentication */
 		if (dpp_auth_derive_l_initiator(auth) < 0)
 			goto fail;
@@ -3846,7 +3848,7 @@
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
-	if (auth->initiator) {
+	if (auth->initiator || !auth->own_bi) {
 		dpp_auth_fail(auth, "Unexpected Authentication Confirm");
 		return -1;
 	}
@@ -3904,7 +3906,7 @@
 				      "Initiator Bootstrapping Key Hash mismatch");
 			return -1;
 		}
-	} else if (auth->own_bi && auth->peer_bi) {
+	} else if (auth->peer_bi) {
 		/* Mutual authentication and peer did not include its
 		 * Bootstrapping Key Hash attribute. */
 		dpp_auth_fail(auth,
@@ -4757,7 +4759,7 @@
 		goto fail;
 	}
 	if (os_strcmp(token->string, "EC") != 0) {
-		wpa_printf(MSG_DEBUG, "DPP: Unexpected JWK kty '%s",
+		wpa_printf(MSG_DEBUG, "DPP: Unexpected JWK kty '%s'",
 			   token->string);
 		goto fail;
 	}
@@ -6586,6 +6588,32 @@
 }
 
 
+static int dpp_pkex_identifier_match(const u8 *attr_id, u16 attr_id_len,
+				     const char *identifier)
+{
+	if (!attr_id && identifier) {
+		wpa_printf(MSG_DEBUG,
+			   "DPP: No PKEX code identifier received, but expected one");
+		return 0;
+	}
+
+	if (attr_id && !identifier) {
+		wpa_printf(MSG_DEBUG,
+			   "DPP: PKEX code identifier received, but not expecting one");
+		return 0;
+	}
+
+	if (attr_id && identifier &&
+	    (os_strlen(identifier) != attr_id_len ||
+	     os_memcmp(identifier, attr_id, attr_id_len) != 0)) {
+		wpa_printf(MSG_DEBUG, "DPP: PKEX code identifier mismatch");
+		return 0;
+	}
+
+	return 1;
+}
+
+
 struct dpp_pkex * dpp_pkex_rx_exchange_req(void *msg_ctx,
 					   struct dpp_bootstrap_info *bi,
 					   const u8 *own_mac,
@@ -6630,19 +6658,11 @@
 	}
 #endif /* CONFIG_TESTING_OPTIONS */
 
+	attr_id_len = 0;
 	attr_id = dpp_get_attr(buf, len, DPP_ATTR_CODE_IDENTIFIER,
 			       &attr_id_len);
-	if (!attr_id && identifier) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: No PKEX code identifier received, but expected one");
+	if (!dpp_pkex_identifier_match(attr_id, attr_id_len, identifier))
 		return NULL;
-	}
-	if (attr_id && identifier &&
-	    (os_strlen(identifier) != attr_id_len ||
-	     os_memcmp(identifier, attr_id, attr_id_len) != 0)) {
-		wpa_printf(MSG_DEBUG, "DPP: PKEX code identifier mismatch");
-		return NULL;
-	}
 
 	attr_group = dpp_get_attr(buf, len, DPP_ATTR_FINITE_CYCLIC_GROUP,
 				  &attr_group_len);
@@ -7014,16 +7034,11 @@
 		return NULL;
 	}
 
+	attr_id_len = 0;
 	attr_id = dpp_get_attr(buf, buflen, DPP_ATTR_CODE_IDENTIFIER,
 			       &attr_id_len);
-	if (!attr_id && pkex->identifier) {
-		wpa_printf(MSG_DEBUG,
-			   "DPP: No PKEX code identifier received, but expected one");
-		return NULL;
-	}
-	if (attr_id && pkex->identifier &&
-	    (os_strlen(pkex->identifier) != attr_id_len ||
-	     os_memcmp(pkex->identifier, attr_id, attr_id_len) != 0)) {
+	if (!dpp_pkex_identifier_match(attr_id, attr_id_len,
+				       pkex->identifier)) {
 		dpp_pkex_fail(pkex, "PKEX code identifier mismatch");
 		return NULL;
 	}
diff --git a/src/common/gas_server.c b/src/common/gas_server.c
index b258675..ca46758 100644
--- a/src/common/gas_server.c
+++ b/src/common/gas_server.c
@@ -97,8 +97,10 @@
 		return;
 
 	response = os_zalloc(sizeof(*response));
-	if (!response)
+	if (!response) {
+		wpabuf_free(query_resp);
 		return;
+	}
 	wpa_printf(MSG_DEBUG, "DPP: Allocated GAS response @%p", response);
 	response->freq = freq;
 	response->handler = handler;
@@ -119,6 +121,7 @@
 				      handler->adv_proto_id_len +
 				      resp_frag_len);
 	if (!resp) {
+		wpabuf_free(query_resp);
 		gas_server_free_response(response);
 		return;
 	}
@@ -257,6 +260,7 @@
 				       handler->adv_proto_id_len +
 				       resp_frag_len);
 	if (!resp) {
+		dl_list_del(&response->list);
 		gas_server_free_response(response);
 		return;
 	}
diff --git a/src/common/hw_features_common.c b/src/common/hw_features_common.c
index db40379..49ed806 100644
--- a/src/common/hw_features_common.c
+++ b/src/common/hw_features_common.c
@@ -87,13 +87,29 @@
 int allowed_ht40_channel_pair(struct hostapd_hw_modes *mode, int pri_chan,
 			      int sec_chan)
 {
-	int ok, j, first;
+	int ok, first;
 	int allowed[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 140,
 			  149, 157, 165, 184, 192 };
 	size_t k;
+	struct hostapd_channel_data *p_chan, *s_chan;
+	const int ht40_plus = pri_chan < sec_chan;
 
-	if (pri_chan == sec_chan || !sec_chan)
-		return 1; /* HT40 not used */
+	p_chan = hw_get_channel_chan(mode, pri_chan, NULL);
+	if (!p_chan)
+		return 0;
+
+	if (pri_chan == sec_chan || !sec_chan) {
+		if (chan_pri_allowed(p_chan))
+			return 1; /* HT40 not used */
+
+		wpa_printf(MSG_ERROR, "Channel %d is not allowed as primary",
+			   pri_chan);
+		return 0;
+	}
+
+	s_chan = hw_get_channel_chan(mode, sec_chan, NULL);
+	if (!s_chan)
+		return 0;
 
 	wpa_printf(MSG_DEBUG,
 		   "HT40: control channel: %d  secondary channel: %d",
@@ -101,16 +117,9 @@
 
 	/* Verify that HT40 secondary channel is an allowed 20 MHz
 	 * channel */
-	ok = 0;
-	for (j = 0; j < mode->num_channels; j++) {
-		struct hostapd_channel_data *chan = &mode->channels[j];
-		if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
-		    chan->chan == sec_chan) {
-			ok = 1;
-			break;
-		}
-	}
-	if (!ok) {
+	if ((s_chan->flag & HOSTAPD_CHAN_DISABLED) ||
+	    (ht40_plus && !(p_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)) ||
+	    (!ht40_plus && !(p_chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40M))) {
 		wpa_printf(MSG_ERROR, "HT40 secondary channel %d not allowed",
 			   sec_chan);
 		return 0;
@@ -553,3 +562,59 @@
 }
 
 #endif /* CONFIG_IEEE80211AC */
+
+
+u32 num_chan_to_bw(int num_chans)
+{
+	switch (num_chans) {
+	case 2:
+	case 4:
+	case 8:
+		return num_chans * 20;
+	default:
+		return 20;
+	}
+}
+
+
+/* check if BW is applicable for channel */
+int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw,
+		    int ht40_plus, int pri)
+{
+	u32 bw_mask;
+
+	switch (bw) {
+	case 20:
+		bw_mask = HOSTAPD_CHAN_WIDTH_20;
+		break;
+	case 40:
+		/* HT 40 MHz support declared only for primary channel,
+		 * just skip 40 MHz secondary checking */
+		if (pri && ht40_plus)
+			bw_mask = HOSTAPD_CHAN_WIDTH_40P;
+		else if (pri && !ht40_plus)
+			bw_mask = HOSTAPD_CHAN_WIDTH_40M;
+		else
+			bw_mask = 0;
+		break;
+	case 80:
+		bw_mask = HOSTAPD_CHAN_WIDTH_80;
+		break;
+	case 160:
+		bw_mask = HOSTAPD_CHAN_WIDTH_160;
+		break;
+	default:
+		bw_mask = 0;
+		break;
+	}
+
+	return (chan->allowed_bw & bw_mask) == bw_mask;
+}
+
+
+/* check if channel is allowed to be used as primary */
+int chan_pri_allowed(const struct hostapd_channel_data *chan)
+{
+	return !(chan->flag & HOSTAPD_CHAN_DISABLED) &&
+		(chan->allowed_bw & HOSTAPD_CHAN_WIDTH_20);
+}
diff --git a/src/common/hw_features_common.h b/src/common/hw_features_common.h
index 9cddbd5..eb1f1c5 100644
--- a/src/common/hw_features_common.h
+++ b/src/common/hw_features_common.h
@@ -39,4 +39,9 @@
 		      int disabled);
 int ieee80211ac_cap_check(u32 hw, u32 conf);
 
+u32 num_chan_to_bw(int num_chans);
+int chan_bw_allowed(const struct hostapd_channel_data *chan, u32 bw,
+		    int ht40_plus, int pri);
+int chan_pri_allowed(const struct hostapd_channel_data *chan);
+
 #endif /* HW_FEATURES_COMMON_H */
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index 4fd3357..51e4e0c 100644
--- a/src/common/ieee802_11_common.c
+++ b/src/common/ieee802_11_common.c
@@ -1,6 +1,6 @@
 /*
  * IEEE 802.11 Common routines
- * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -126,6 +126,10 @@
 			elems->roaming_cons_sel = pos;
 			elems->roaming_cons_sel_len = elen;
 			break;
+		case MULTI_AP_OUI_TYPE:
+			elems->multi_ap = pos;
+			elems->multi_ap_len = elen;
+			break;
 		default:
 			wpa_printf(MSG_MSGDUMP, "Unknown WFA "
 				   "information element ignored "
@@ -266,6 +270,10 @@
 		elems->password_id = pos;
 		elems->password_id_len = elen;
 		break;
+	case WLAN_EID_EXT_OCV_OCI:
+		elems->oci = pos;
+		elems->oci_len = elen;
+		break;
 	default:
 		if (show_errors) {
 			wpa_printf(MSG_MSGDUMP,
@@ -291,29 +299,17 @@
 				struct ieee802_11_elems *elems,
 				int show_errors)
 {
-	size_t left = len;
-	const u8 *pos = start;
+	const struct element *elem;
 	int unknown = 0;
 
 	os_memset(elems, 0, sizeof(*elems));
 
-	while (left >= 2) {
-		u8 id, elen;
+	if (!start)
+		return ParseOK;
 
-		id = *pos++;
-		elen = *pos++;
-		left -= 2;
-
-		if (elen > left) {
-			if (show_errors) {
-				wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
-					   "parse failed (id=%d elen=%d "
-					   "left=%lu)",
-					   id, elen, (unsigned long) left);
-				wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
-			}
-			return ParseFailed;
-		}
+	for_each_element(elem, start, len) {
+		u8 id = elem->id, elen = elem->datalen;
+		const u8 *pos = elem->data;
 
 		switch (id) {
 		case WLAN_EID_SSID:
@@ -461,8 +457,7 @@
 			elems->mic = pos;
 			elems->mic_len = elen;
 			/* after mic everything is encrypted, so stop. */
-			left = elen;
-			break;
+			goto done;
 		case WLAN_EID_MULTI_BAND:
 			if (elems->mb_ies.nof_ies >= MAX_NOF_MB_IES_SUPPORTED) {
 				wpa_printf(MSG_MSGDUMP,
@@ -521,35 +516,33 @@
 				   id, elen);
 			break;
 		}
-
-		left -= elen;
-		pos += elen;
 	}
 
-	if (left)
+	if (!for_each_element_completed(elem, start, len)) {
+		if (show_errors) {
+			wpa_printf(MSG_DEBUG,
+				   "IEEE 802.11 element parse failed @%d",
+				   (int) (start + len - (const u8 *) elem));
+			wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
+		}
 		return ParseFailed;
+	}
 
+done:
 	return unknown ? ParseUnknown : ParseOK;
 }
 
 
 int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
 {
+	const struct element *elem;
 	int count = 0;
-	const u8 *pos, *end;
 
 	if (ies == NULL)
 		return 0;
 
-	pos = ies;
-	end = ies + ies_len;
-
-	while (end - pos >= 2) {
-		if (2 + pos[1] > end - pos)
-			break;
+	for_each_element(elem, ies, ies_len)
 		count++;
-		pos += 2 + pos[1];
-	}
 
 	return count;
 }
@@ -559,24 +552,17 @@
 					    u32 oui_type)
 {
 	struct wpabuf *buf;
-	const u8 *end, *pos, *ie;
+	const struct element *elem, *found = NULL;
 
-	pos = ies;
-	end = ies + ies_len;
-	ie = NULL;
-
-	while (end - pos > 1) {
-		if (2 + pos[1] > end - pos)
-			return NULL;
-		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
-		    WPA_GET_BE32(&pos[2]) == oui_type) {
-			ie = pos;
+	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
+		if (elem->datalen >= 4 &&
+		    WPA_GET_BE32(elem->data) == oui_type) {
+			found = elem;
 			break;
 		}
-		pos += 2 + pos[1];
 	}
 
-	if (ie == NULL)
+	if (!found)
 		return NULL; /* No specified vendor IE found */
 
 	buf = wpabuf_alloc(ies_len);
@@ -587,13 +573,9 @@
 	 * There may be multiple vendor IEs in the message, so need to
 	 * concatenate their data fields.
 	 */
-	while (end - pos > 1) {
-		if (2 + pos[1] > end - pos)
-			break;
-		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
-		    WPA_GET_BE32(&pos[2]) == oui_type)
-			wpabuf_put_data(buf, pos + 6, pos[1] - 4);
-		pos += 2 + pos[1];
+	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, ies_len) {
+		if (elem->datalen >= 4 && WPA_GET_BE32(elem->data) == oui_type)
+			wpabuf_put_data(buf, elem->data + 4, elem->datalen - 4);
 	}
 
 	return buf;
@@ -898,6 +880,41 @@
 }
 
 
+int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
+				  int sec_channel, u8 *op_class, u8 *channel)
+{
+	int vht = CHAN_WIDTH_UNKNOWN;
+
+	switch (chanwidth) {
+	case CHAN_WIDTH_UNKNOWN:
+	case CHAN_WIDTH_20_NOHT:
+	case CHAN_WIDTH_20:
+	case CHAN_WIDTH_40:
+		vht = VHT_CHANWIDTH_USE_HT;
+		break;
+	case CHAN_WIDTH_80:
+		vht = VHT_CHANWIDTH_80MHZ;
+		break;
+	case CHAN_WIDTH_80P80:
+		vht = VHT_CHANWIDTH_80P80MHZ;
+		break;
+	case CHAN_WIDTH_160:
+		vht = VHT_CHANWIDTH_160MHZ;
+		break;
+	}
+
+	if (ieee80211_freq_to_channel_ext(freq, sec_channel, vht, op_class,
+					  channel) == NUM_HOSTAPD_MODES) {
+		wpa_printf(MSG_WARNING,
+			   "Cannot determine operating class and channel (freq=%u chanwidth=%d sec_channel=%d)",
+			   freq, chanwidth, sec_channel);
+		return -1;
+	}
+
+	return 0;
+}
+
+
 static const char *const us_op_class_cc[] = {
 	"US", "CA", NULL
 };
@@ -1299,27 +1316,27 @@
 int mb_ies_info_by_ies(struct mb_ies_info *info, const u8 *ies_buf,
 		       size_t ies_len)
 {
+	const struct element *elem;
+
 	os_memset(info, 0, sizeof(*info));
 
-	while (ies_buf && ies_len >= 2 &&
-	       info->nof_ies < MAX_NOF_MB_IES_SUPPORTED) {
-		size_t len = 2 + ies_buf[1];
+	if (!ies_buf)
+		return 0;
 
-		if (len > ies_len) {
-			wpa_hexdump(MSG_DEBUG, "Truncated IEs",
-				    ies_buf, ies_len);
-			return -1;
-		}
+	for_each_element_id(elem, WLAN_EID_MULTI_BAND, ies_buf, ies_len) {
+		if (info->nof_ies >= MAX_NOF_MB_IES_SUPPORTED)
+			return 0;
 
-		if (ies_buf[0] == WLAN_EID_MULTI_BAND) {
-			wpa_printf(MSG_DEBUG, "MB IE of %zu bytes found", len);
-			info->ies[info->nof_ies].ie = ies_buf + 2;
-			info->ies[info->nof_ies].ie_len = ies_buf[1];
-			info->nof_ies++;
-		}
+		wpa_printf(MSG_DEBUG, "MB IE of %u bytes found",
+			   elem->datalen + 2);
+		info->ies[info->nof_ies].ie = elem->data;
+		info->ies[info->nof_ies].ie_len = elem->datalen;
+		info->nof_ies++;
+	}
 
-		ies_len -= len;
-		ies_buf += len;
+	if (!for_each_element_completed(elem, ies_buf, ies_len)) {
+		wpa_hexdump(MSG_DEBUG, "Truncated IEs", ies_buf, ies_len);
+		return -1;
 	}
 
 	return 0;
@@ -1442,22 +1459,13 @@
  */
 const u8 * get_ie(const u8 *ies, size_t len, u8 eid)
 {
-	const u8 *end;
+	const struct element *elem;
 
 	if (!ies)
 		return NULL;
 
-	end = ies + len;
-
-	while (end - ies > 1) {
-		if (2 + ies[1] > end - ies)
-			break;
-
-		if (ies[0] == eid)
-			return ies;
-
-		ies += 2 + ies[1];
-	}
+	for_each_element_id(elem, eid, ies, len)
+		return &elem->id;
 
 	return NULL;
 }
@@ -1475,22 +1483,26 @@
  */
 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext)
 {
-	const u8 *end;
+	const struct element *elem;
 
 	if (!ies)
 		return NULL;
 
-	end = ies + len;
+	for_each_element_extid(elem, ext, ies, len)
+		return &elem->id;
 
-	while (end - ies > 1) {
-		if (2 + ies[1] > end - ies)
-			break;
+	return NULL;
+}
 
-		if (ies[0] == WLAN_EID_EXTENSION && ies[1] >= 1 &&
-		    ies[2] == ext)
-			return ies;
 
-		ies += 2 + ies[1];
+const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type)
+{
+	const struct element *elem;
+
+	for_each_element_id(elem, WLAN_EID_VENDOR_SPECIFIC, ies, len) {
+		if (elem->datalen >= 4 &&
+		    vendor_type == WPA_GET_BE32(elem->data))
+			return &elem->id;
 	}
 
 	return NULL;
@@ -1521,6 +1533,26 @@
 }
 
 
+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value)
+{
+	u8 *pos = buf;
+
+	if (len < 9)
+		return 0;
+
+	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
+	*pos++ = 7; /* len */
+	WPA_PUT_BE24(pos, OUI_WFA);
+	pos += 3;
+	*pos++ = MULTI_AP_OUI_TYPE;
+	*pos++ = MULTI_AP_SUB_ELEM_TYPE;
+	*pos++ = 1; /* len */
+	*pos++ = value;
+
+	return pos - buf;
+}
+
+
 static const struct country_op_class us_op_class[] = {
 	{ 1, 115 },
 	{ 2, 118 },
@@ -1666,6 +1698,27 @@
 }
 
 
+int oper_class_bw_to_int(const struct oper_class_map *map)
+{
+	switch (map->bw) {
+	case BW20:
+		return 20;
+	case BW40PLUS:
+	case BW40MINUS:
+		return 40;
+	case BW80:
+		return 80;
+	case BW80P80:
+	case BW160:
+		return 160;
+	case BW2160:
+		return 2160;
+	default:
+		return 0;
+	}
+}
+
+
 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
 				    size_t nei_rep_len)
 {
@@ -1766,3 +1819,11 @@
 
 	return nei_pos - nei_rep;
 }
+
+
+int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
+{
+	if (!ie || ie[1] <= capab / 8)
+		return 0;
+	return !!(ie[2 + capab / 8] & BIT(capab % 8));
+}
diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h
index ff7e51d..4e35b79 100644
--- a/src/common/ieee802_11_common.h
+++ b/src/common/ieee802_11_common.h
@@ -1,6 +1,6 @@
 /*
  * IEEE 802.11 Common routines
- * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -10,6 +10,13 @@
 #define IEEE802_11_COMMON_H
 
 #include "defs.h"
+#include "ieee802_11_defs.h"
+
+struct element {
+	u8 id;
+	u8 datalen;
+	u8 data[];
+} STRUCT_PACKED;
 
 struct hostapd_hw_modes;
 
@@ -84,6 +91,8 @@
 	const u8 *power_capab;
 	const u8 *roaming_cons_sel;
 	const u8 *password_id;
+	const u8 *oci;
+	const u8 *multi_ap;
 
 	u8 ssid_len;
 	u8 supp_rates_len;
@@ -130,6 +139,8 @@
 	u8 power_capab_len;
 	u8 roaming_cons_sel_len;
 	u8 password_id_len;
+	u8 oci_len;
+	u8 multi_ap_len;
 
 	struct mb_ies_info mb_ies;
 };
@@ -160,6 +171,8 @@
 enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq,
 						   int sec_channel, int vht,
 						   u8 *op_class, u8 *channel);
+int ieee80211_chaninfo_to_channel(unsigned int freq, enum chan_width chanwidth,
+				  int sec_channel, u8 *op_class, u8 *channel);
 int ieee80211_is_dfs(int freq, const struct hostapd_hw_modes *modes,
 		     u16 num_modes);
 enum phy_type ieee80211_get_phy_type(int freq, int ht, int vht);
@@ -186,9 +199,12 @@
 
 const u8 * get_ie(const u8 *ies, size_t len, u8 eid);
 const u8 * get_ie_ext(const u8 *ies, size_t len, u8 ext);
+const u8 * get_vendor_ie(const u8 *ies, size_t len, u32 vendor_type);
 
 size_t mbo_add_ie(u8 *buf, size_t len, const u8 *attr, size_t attr_len);
 
+size_t add_multi_ap_ie(u8 *buf, size_t len, u8 value);
+
 struct country_op_class {
 	u8 country_op_class;
 	u8 global_op_class;
@@ -197,8 +213,58 @@
 u8 country_to_global_op_class(const char *country, u8 op_class);
 
 const struct oper_class_map * get_oper_class(const char *country, u8 op_class);
+int oper_class_bw_to_int(const struct oper_class_map *map);
 
 int ieee802_11_parse_candidate_list(const char *pos, u8 *nei_rep,
 				    size_t nei_rep_len);
 
+int ieee802_11_ext_capab(const u8 *ie, unsigned int capab);
+
+/* element iteration helpers */
+#define for_each_element(_elem, _data, _datalen)			\
+	for (_elem = (const struct element *) (_data);			\
+	     (const u8 *) (_data) + (_datalen) - (const u8 *) _elem >=	\
+		(int) sizeof(*_elem) &&					\
+	     (const u8 *) (_data) + (_datalen) - (const u8 *) _elem >=	\
+		(int) sizeof(*_elem) + _elem->datalen;			\
+	     _elem = (const struct element *) (_elem->data + _elem->datalen))
+
+#define for_each_element_id(element, _id, data, datalen)		\
+	for_each_element(element, data, datalen)			\
+		if (element->id == (_id))
+
+#define for_each_element_extid(element, extid, _data, _datalen)		\
+	for_each_element(element, _data, _datalen)			\
+		if (element->id == WLAN_EID_EXTENSION &&		\
+		    element->datalen > 0 &&				\
+		    element->data[0] == (extid))
+
+#define for_each_subelement(sub, element)				\
+	for_each_element(sub, (element)->data, (element)->datalen)
+
+#define for_each_subelement_id(sub, id, element)			\
+	for_each_element_id(sub, id, (element)->data, (element)->datalen)
+
+#define for_each_subelement_extid(sub, extid, element)			\
+	for_each_element_extid(sub, extid, (element)->data, (element)->datalen)
+
+/**
+ * for_each_element_completed - Determine if element parsing consumed all data
+ * @element: Element pointer after for_each_element() or friends
+ * @data: Same data pointer as passed to for_each_element() or friends
+ * @datalen: Same data length as passed to for_each_element() or friends
+ *
+ * This function returns 1 if all the data was parsed or considered
+ * while walking the elements. Only use this if your for_each_element()
+ * loop cannot be broken out of, otherwise it always returns 0.
+ *
+ * If some data was malformed, this returns %false since the last parsed
+ * element will not fill the whole remaining data.
+ */
+static inline int for_each_element_completed(const struct element *element,
+					     const void *data, size_t datalen)
+{
+	return (const u8 *) element == (const u8 *) data + datalen;
+}
+
 #endif /* IEEE802_11_COMMON_H */
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 762e731..b285d13 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -1,6 +1,6 @@
 /*
  * IEEE 802.11 Frame type definitions
- * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
  * Copyright (c) 2007-2008 Intel Corporation
  *
  * This software may be distributed under the terms of the BSD license.
@@ -467,7 +467,89 @@
 #define WLAN_EID_EXT_PASSWORD_IDENTIFIER 33
 #define WLAN_EID_EXT_HE_CAPABILITIES 35
 #define WLAN_EID_EXT_HE_OPERATION 36
+#define WLAN_EID_EXT_HE_MU_EDCA_PARAMS 38
+#define WLAN_EID_EXT_OCV_OCI 54
 
+/* Extended Capabilities field */
+#define WLAN_EXT_CAPAB_20_40_COEX 0
+#define WLAN_EXT_CAPAB_GLK 1
+#define WLAN_EXT_CAPAB_EXT_CHAN_SWITCH 2
+#define WLAN_EXT_CAPAB_GLK_GCR 3
+#define WLAN_EXT_CAPAB_PSMP 4
+/* 5 - Reserved */
+#define WLAN_EXT_CAPAB_S_PSMP 6
+#define WLAN_EXT_CAPAB_EVENT 7
+#define WLAN_EXT_CAPAB_DIAGNOSTICS 8
+#define WLAN_EXT_CAPAB_MULTICAST_DIAGNOSTICS 9
+#define WLAN_EXT_CAPAB_LOCATION_TRACKING 10
+#define WLAN_EXT_CAPAB_FMS 11
+#define WLAN_EXT_CAPAB_PROXY_ARP 12
+#define WLAN_EXT_CAPAB_COLL_INTERF_REP 13
+#define WLAN_EXT_CAPAB_CIVIC_LOCATION 14
+#define WLAN_EXT_CAPAB_GEOSPATIAL_LOCATION 15
+#define WLAN_EXT_CAPAB_TFS 16
+#define WLAN_EXT_CAPAB_WNM_SLEEP_MODE 17
+#define WLAN_EXT_CAPAB_TIM_BROADCAST 18
+#define WLAN_EXT_CAPAB_BSS_TRANSITION 19
+#define WLAN_EXT_CAPAB_QOS_TRAFFIC 20
+#define WLAN_EXT_CAPAB_AC_STA_COUNT 21
+#define WLAN_EXT_CAPAB_MULTIPLE_BSSID 22
+#define WLAN_EXT_CAPAB_TIMING_MEASUREMENT 23
+#define WLAN_EXT_CAPAB_CHANNEL_USAGE 24
+#define WLAN_EXT_CAPAB_SSID_LIST 25
+#define WLAN_EXT_CAPAB_DMS 26
+#define WLAN_EXT_CAPAB_UTF_TSF_OFFSET 27
+#define WLAN_EXT_CAPAB_TPU_BUFFER_STA 28
+#define WLAN_EXT_CAPAB_TDLS_PEER_PSM 29
+#define WLAN_EXT_CAPAB_TDLS_CHANNEL_SWITCH 30
+#define WLAN_EXT_CAPAB_INTERWORKING 31
+#define WLAN_EXT_CAPAB_QOS_MAP 32
+#define WLAN_EXT_CAPAB_EBR 33
+#define WLAN_EXT_CAPAB_SSPN_INTERFACE 34
+/* 35 - Reserved */
+#define WLAN_EXT_CAPAB_MSGCF 36
+#define WLAN_EXT_CAPAB_TDLS 37
+#define WLAN_EXT_CAPAB_TDLS_PROHIBITED 38
+#define WLAN_EXT_CAPAB_TDLS_CHANNEL_SWITCH_PROHIBITED 39
+#define WLAN_EXT_CAPAB_REJECT_UNADMITTED_FRAME 40
+#define WLAN_EXT_CAPAB_
+/* 41-43 - Service Interval Granularity */
+#define WLAN_EXT_CAPAB_IDENTIFIER_LOCATION 44
+#define WLAN_EXT_CAPAB_U_APSD_COEX 45
+#define WLAN_EXT_CAPAB_WNM_NOTIFCATION 46
+#define WLAN_EXT_CAPAB_QAB 47
+#define WLAN_EXT_CAPAB_UTF_8_SSID 48
+#define WLAN_EXT_CAPAB_QMF 49
+#define WLAN_EXT_CAPAB_QMF_RECONFIG 50
+#define WLAN_EXT_CAPAB_ROBUST_AV_STREAMING 51
+#define WLAN_EXT_CAPAB_ADVANCED_GCR 52
+#define WLAN_EXT_CAPAB_MESH_GCR 53
+#define WLAN_EXT_CAPAB_SCS 54
+#define WLAN_EXT_CAPAB_QLOAD_REPORT 55
+#define WLAN_EXT_CAPAB_ALT_EDCA 56
+#define WLAN_EXT_CAPAB_UNPROT_TXOP_NEG 57
+#define WLAN_EXT_CAPAB_PROT_TXOP_NEG 58
+/* 59 - Reserved */
+#define WLAN_EXT_CAPAB_PROT_QLOAD_REPORT 60
+#define WLAN_EXT_CAPAB_TDLS_WIDER_BW 61
+#define WLAN_EXT_CAPAB_OPMODE_NOTIF 62
+#define WLAN_EXT_CAPAB_
+/* 63-64 - Max Number of MSDUs In A-MSDU */
+#define WLAN_EXT_CAPAB_CHANNEL_SCHEDULE_MGMT 65
+#define WLAN_EXT_CAPAB_GEODB_INBAND_ENABLING_SIGNAL 66
+#define WLAN_EXT_CAPAB_NETWORK_CHANNEL_CTRL 67
+#define WLAN_EXT_CAPAB_WHITE_SPACE_MAP 68
+#define WLAN_EXT_CAPAB_CHANNEL_AVAIL_QUERY 69
+#define WLAN_EXT_CAPAB_FTM_RESPONDER 70
+#define WLAN_EXT_CAPAB_FTM_INITIATOR 71
+#define WLAN_EXT_CAPAB_FILS 72
+#define WLAN_EXT_CAPAB_EXT_SPECTRUM_MGMT 73
+#define WLAN_EXT_CAPAB_FUTURE_CHANNEL_GUIDANCE 74
+#define WLAN_EXT_CAPAB_PAD 75
+/* 76-79 - Reserved */
+#define WLAN_EXT_CAPAB_COMPLETE_NON_TX_BSSID_PROFILE 80
+#define WLAN_EXT_CAPAB_SAE_PW_ID 81
+#define WLAN_EXT_CAPAB_SAE_PW_ID_EXCLUSIVELY 82
 
 /* Action frame categories (IEEE Std 802.11-2016, 9.4.1.11, Table 9-76) */
 #define WLAN_ACTION_SPECTRUM_MGMT 0
@@ -865,10 +947,12 @@
 				struct {
 					u8 action;
 					u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+					u8 variable[]; /* OCI element */
 				} STRUCT_PACKED sa_query_req;
 				struct {
 					u8 action; /* */
 					u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+					u8 variable[]; /* OCI element */
 				} STRUCT_PACKED sa_query_resp;
 				struct {
 					u8 action;
@@ -1210,6 +1294,13 @@
 #define MBO_OUI_TYPE 22
 #define OWE_IE_VENDOR_TYPE 0x506f9a1c
 #define OWE_OUI_TYPE 28
+#define MULTI_AP_OUI_TYPE 0x1B
+
+#define MULTI_AP_SUB_ELEM_TYPE 0x06
+#define MULTI_AP_TEAR_DOWN BIT(4)
+#define MULTI_AP_FRONTHAUL_BSS BIT(5)
+#define MULTI_AP_BACKHAUL_BSS BIT(6)
+#define MULTI_AP_BACKHAUL_STA BIT(7)
 
 #define WMM_OUI_TYPE 2
 #define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0
@@ -1347,13 +1438,15 @@
 #define HS20_PPS_MO_ID_PRESENT 0x02
 #define HS20_ANQP_DOMAIN_ID_PRESENT 0x04
 #ifndef HS20_VERSION
-#define HS20_VERSION 0x10 /* Release 2 */
+#define HS20_VERSION 0x20 /* Release 3 */
 #endif /* HS20_VERSION */
 
 /* WNM-Notification WFA vendors specific subtypes */
 #define HS20_WNM_SUB_REM_NEEDED 0
 #define HS20_WNM_DEAUTH_IMMINENT_NOTICE 1
-#define HS20_WNM_T_C_ACCEPTANCE 2
+#define WFA_WNM_NOTIF_SUBELEM_NON_PREF_CHAN_REPORT 2
+#define WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA 3
+#define HS20_WNM_T_C_ACCEPTANCE 4
 
 #define HS20_DEAUTH_REASON_CODE_BSS 0
 #define HS20_DEAUTH_REASON_CODE_ESS 1
@@ -1442,12 +1535,6 @@
 	MBO_TRANSITION_REJECT_REASON_SERVICES = 6,
 };
 
-/* MBO v0.0_r19, 4.4: WNM-Notification vendor subelements */
-enum wfa_wnm_notif_subelem_id {
-	WFA_WNM_NOTIF_SUBELEM_NON_PREF_CHAN_REPORT = 2,
-	WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA = 3,
-};
-
 /* MBO v0.0_r27, 4.3: MBO ANQP-elements */
 #define MBO_ANQP_OUI_TYPE 0x12
 #define MBO_ANQP_SUBTYPE_QUERY_LIST 1
@@ -1841,11 +1928,14 @@
 };
 
 /* IEEE Std 802.11-2016, Table 9-88 - Beacon Request subelement IDs */
+/* IEEE P802.11-REVmd/D2.0, Table 9-106 - Optional subelement IDs for
+ * Beacon request */
 #define WLAN_BEACON_REQUEST_SUBELEM_SSID	0
 #define WLAN_BEACON_REQUEST_SUBELEM_INFO	1 /* Beacon Reporting */
 #define WLAN_BEACON_REQUEST_SUBELEM_DETAIL	2 /* Reporting Detail */
 #define WLAN_BEACON_REQUEST_SUBELEM_REQUEST	10
 #define WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL	51 /* AP Channel Report */
+#define WLAN_BEACON_REQUEST_SUBELEM_LAST_INDICATION	164
 #define WLAN_BEACON_REQUEST_SUBELEM_VENDOR	221
 
 /*
@@ -1895,9 +1985,21 @@
 } STRUCT_PACKED;
 
 /* IEEE Std 802.11-2016, Table 9-112 - Beacon report Subelement IDs */
+/* IEEE P802.11-REVmd/D2.0, Table 9-130 - Optional subelement IDs for
+ * Beacon report */
 #define WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY	1
+#define WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY_FRAGMENT_ID	2
+#define WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION	164
 #define WLAN_BEACON_REPORT_SUBELEM_VENDOR	221
 
+/* IEEE P802.11-REVmd/D2.0, Table 9-232 - Data field format of the
+ * Reported Frame Body Fragment ID subelement */
+#define REPORTED_FRAME_BODY_SUBELEM_LEN		4
+#define REPORTED_FRAME_BODY_MORE_FRAGMENTS	BIT(7)
+
+/* IEEE P802.11-REVmd/D2.0, 9.4.2.21.7 - Beacon report  */
+#define BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN	3
+
 /* IEEE Std 802.11ad-2012 - Multi-band element */
 struct multi_band_ie {
 	u8 eid; /* WLAN_EID_MULTI_BAND */
@@ -2000,14 +2102,15 @@
 };
 
 struct ieee80211_he_capabilities {
-	u8 he_mac_capab_info[5];
-	u8 he_phy_capab_info[9];
+	u8 he_mac_capab_info[6];
+	u8 he_phy_capab_info[11];
 	u8 he_txrx_mcs_support[12]; /* TODO: 4, 8, or 12 octets */
 	/* PPE Thresholds (optional) */
 } STRUCT_PACKED;
 
 struct ieee80211_he_operation {
-	u32 he_oper_params;
+	u32 he_oper_params; /* HE Operation Parameters[3] and
+			     * BSS Color Information[1] */
 	u8 he_mcs_nss_set[2];
 	u8 vht_op_info_chwidth;
 	u8 vht_op_info_chan_center_freq_seg0_idx;
@@ -2024,28 +2127,55 @@
 #define HE_PHYCAP_MU_BEAMFORMER_CAPAB		((u8) BIT(1))
 
 /* HE Operation defines */
+/* HE Operation Parameters and BSS Color Information fields */
 #define HE_OPERATION_BSS_COLOR_MASK		((u32) (BIT(0) | BIT(1) | \
 							BIT(2) | BIT(3) | \
 							BIT(4) | BIT(5)))
-#define HE_OPERATION_DFLT_PE_DURATION_MASK	((u32) (BIT(6) | BIT(7) | \
-							BIT(8)))
-#define HE_OPERATION_DFLT_PE_DURATION_OFFSET	6
-#define HE_OPERATION_TWT_REQUIRED		((u32) BIT(9))
-#define HE_OPERATION_RTS_THRESHOLD_MASK	((u32) (BIT(10) | BIT(11) | \
-						BIT(12) | BIT(13) | \
+#define HE_OPERATION_PARTIAL_BSS_COLOR		((u32) BIT(6))
+#define HE_OPERATION_BSS_COLOR_DISABLED		((u32) BIT(7))
+#define HE_OPERATION_DFLT_PE_DURATION_MASK	((u32) (BIT(8) | BIT(9) | \
+							BIT(10)))
+#define HE_OPERATION_DFLT_PE_DURATION_OFFSET	8
+#define HE_OPERATION_TWT_REQUIRED		((u32) BIT(11))
+#define HE_OPERATION_RTS_THRESHOLD_MASK	((u32) (BIT(12) | BIT(13) | \
 						BIT(14) | BIT(15) | \
 						BIT(16) | BIT(17) | \
-						BIT(18) | BIT(19)))
-#define HE_OPERATION_RTS_THRESHOLD_OFFSET	10
-#define HE_OPERATION_PARTIAL_BSS_COLOR		((u32) BIT(20))
-#define HE_OPERATION_MAX_BSSID_INDICATOR_MASK	((u32) (BIT(21) | BIT(22) | \
-							BIT(23) | BIT(24) | \
-							BIT(25) | BIT(26) | \
-							BIT(27) | BIT(28)))
-#define HE_OPERATION_MAX_BSSID_INDICATOR_OFFSET 21
-#define HE_OPERATION_TX_BSSID_INDICATOR		((u32) BIT(29))
-#define HE_OPERATION_BSS_COLOR_DISABLED		((u32) BIT(30))
-#define HE_OPERATION_BSS_DUAL_BEACON		((u32) BIT(31))
+						BIT(18) | BIT(19) | \
+						BIT(20) | BIT(21)))
+#define HE_OPERATION_RTS_THRESHOLD_OFFSET	12
+
+struct ieee80211_he_mu_edca_parameter_set {
+	u8 he_qos_info;
+	u8 he_mu_ac_be_param[3];
+	u8 he_mu_ac_bk_param[3];
+	u8 he_mu_ac_vi_param[3];
+	u8 he_mu_ac_vo_param[3];
+} STRUCT_PACKED;
+
+/* HE MU AC parameter record field format */
+/* ACI/AIFSN */
+#define HE_MU_AC_PARAM_ACI_IDX 0
+#define HE_MU_AC_PARAM_AIFSN ((u8) (BIT(0) | BIT(1) | BIT(2) | BIT(3)))
+#define HE_MU_AC_PARAM_ACM ((u8) BIT(4))
+#define HE_MU_AC_PARAM_ACI ((u8) (BIT(5) | BIT(6)))
+/* B7: Reserved */
+
+/* ECWmin/ECWmax */
+#define HE_MU_AC_PARAM_ECW_IDX 1
+#define HE_MU_AC_PARAM_ECWMIN ((u8) (BIT(0) | BIT(1) | BIT(2) | BIT(3)))
+#define HE_MU_AC_PARAM_ECWMAX ((u8) (BIT(4) | BIT(5) | BIT(6) | BIT(7)))
+
+/* MU EDCA Timer */
+#define HE_MU_AC_PARAM_TIMER_IDX 2
+
+/* HE QoS Info field */
+#define HE_QOS_INFO_EDCA_PARAM_SET_COUNT ((u8) (BIT(0) | BIT(1) | \
+						BIT(2) | BIT(3)))
+#define HE_QOS_INFO_Q_ACK ((u8) (BIT(4)))
+#define HE_QOS_INFO_QUEUE_REQUEST ((u8) (BIT(5)))
+#define HE_QOS_INFO_TXOP_REQUEST ((u8) (BIT(6)))
+/* B7: Reserved if sent by an AP; More Data Ack if sent by a non-AP STA */
+#define HE_QOS_INFO_MORE_DATA_ACK ((u8) (BIT(7)))
 
 /* DPP Public Action frame identifiers - OUI_WFA */
 #define DPP_OUI_TYPE 0x1A
diff --git a/src/common/linux_bridge.h b/src/common/linux_bridge.h
index 7b76846..84386e6 100644
--- a/src/common/linux_bridge.h
+++ b/src/common/linux_bridge.h
@@ -9,6 +9,21 @@
 #ifndef LINUX_BRIDGE_H
 #define LINUX_BRIDGE_H
 
+/* This ioctl is defined in linux/sockios.h */
+
+#ifndef SIOCBRADDBR
+#define SIOCBRADDBR 0x89a0
+#endif
+#ifndef SIOCBRDELBR
+#define SIOCBRDELBR 0x89a1
+#endif
+#ifndef SIOCBRADDIF
+#define SIOCBRADDIF 0x89a2
+#endif
+#ifndef SIOCBRDELIF
+#define SIOCBRDELIF 0x89a3
+#endif
+
 /* This interface is defined in linux/if_bridge.h */
 
 #define BRCTL_GET_VERSION 0
diff --git a/src/common/ocv.c b/src/common/ocv.c
new file mode 100644
index 0000000..06badfb
--- /dev/null
+++ b/src/common/ocv.c
@@ -0,0 +1,172 @@
+/*
+ * Operating Channel Validation (OCV)
+ * Copyright (c) 2018, Mathy Vanhoef
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+#include "utils/common.h"
+#include "drivers/driver.h"
+#include "common/ieee802_11_common.h"
+#include "ocv.h"
+
+/**
+ * Caller of OCV functionality may use various debug output functions, so store
+ * the error here and let the caller use an appropriate debug output function.
+ */
+char ocv_errorstr[256];
+
+
+int ocv_derive_all_parameters(struct oci_info *oci)
+{
+	const struct oper_class_map *op_class_map;
+
+	oci->freq = ieee80211_chan_to_freq(NULL, oci->op_class, oci->channel);
+	if (oci->freq < 0) {
+		wpa_printf(MSG_INFO,
+			   "Error interpreting OCI: unrecognized opclass/channel pair (%d/%d)",
+			   oci->op_class, oci->channel);
+		return -1;
+	}
+
+	op_class_map = get_oper_class(NULL, oci->op_class);
+	if (!op_class_map) {
+		wpa_printf(MSG_INFO,
+			   "Error interpreting OCI: Unrecognized opclass (%d)",
+			   oci->op_class);
+		return -1;
+	}
+
+	oci->chanwidth = oper_class_bw_to_int(op_class_map);
+	oci->sec_channel = 0;
+	if (op_class_map->bw == BW40PLUS)
+		oci->sec_channel = 1;
+	else if (op_class_map->bw == BW40MINUS)
+		oci->sec_channel = -1;
+
+	return 0;
+}
+
+
+int ocv_insert_oci(struct wpa_channel_info *ci, u8 **argpos)
+{
+	u8 op_class, channel;
+	u8 *pos = *argpos;
+
+	if (ieee80211_chaninfo_to_channel(ci->frequency, ci->chanwidth,
+					  ci->sec_channel,
+					  &op_class, &channel) < 0) {
+		wpa_printf(MSG_WARNING,
+			   "Cannot determine operating class and channel for OCI element");
+		return -1;
+	}
+
+	*pos++ = op_class;
+	*pos++ = channel;
+	*pos++ = ci->seg1_idx;
+
+	*argpos = pos;
+	return 0;
+}
+
+
+int ocv_insert_oci_kde(struct wpa_channel_info *ci, u8 **argpos)
+{
+	u8 *pos = *argpos;
+
+	*pos++ = WLAN_EID_VENDOR_SPECIFIC;
+	*pos++ = RSN_SELECTOR_LEN + 3;
+	RSN_SELECTOR_PUT(pos, RSN_KEY_DATA_OCI);
+	pos += RSN_SELECTOR_LEN;
+
+	*argpos = pos;
+	return ocv_insert_oci(ci, argpos);
+}
+
+
+int ocv_insert_extended_oci(struct wpa_channel_info *ci, u8 *pos)
+{
+	*pos++ = WLAN_EID_EXTENSION;
+	*pos++ = 1 + OCV_OCI_LEN;
+	*pos++ = WLAN_EID_EXT_OCV_OCI;
+	return ocv_insert_oci(ci, &pos);
+}
+
+
+int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
+			 struct wpa_channel_info *ci, int tx_chanwidth,
+			 int tx_seg1_idx)
+{
+	struct oci_info oci;
+
+	if (!oci_ie) {
+		os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
+			    "OCV failed: did not receive mandatory OCI");
+		return -1;
+	}
+
+	if (oci_ie_len != 3) {
+		os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
+			    "OCV failed: received OCI of unexpected length (%d)",
+			    (int) oci_ie_len);
+		return -1;
+	}
+
+	os_memset(&oci, 0, sizeof(oci));
+	oci.op_class = oci_ie[0];
+	oci.channel = oci_ie[1];
+	oci.seg1_idx = oci_ie[2];
+	if (ocv_derive_all_parameters(&oci) != 0) {
+		os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
+			    "OCV failed: unable to interpret received OCI");
+		return -1;
+	}
+
+	/* Primary frequency used to send frames to STA must match the STA's */
+	if ((int) ci->frequency != oci.freq) {
+		os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
+			    "OCV failed: primary channel mismatch in received OCI (we use %d but receiver is using %d)",
+			    ci->frequency, oci.freq);
+		return -1;
+	}
+
+	/* We shouldn't transmit with a higher bandwidth than the STA supports
+	 */
+	if (tx_chanwidth > oci.chanwidth) {
+		os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
+			    "OCV failed: channel bandwidth mismatch in received OCI (we use %d but receiver only supports %d)",
+			    tx_chanwidth, oci.chanwidth);
+		return -1;
+	}
+
+	/*
+	 * Secondary channel only needs be checked for 40 MHz in the 2.4 GHz
+	 * band. In the 5 GHz band it's verified through the primary frequency.
+	 * Note that the field ci->sec_channel is only filled in when we use
+	 * 40 MHz.
+	 */
+	if (tx_chanwidth == 40 && ci->frequency < 2500 &&
+	    ci->sec_channel != oci.sec_channel) {
+		os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
+			    "OCV failed: secondary channel mismatch in received OCI (we use %d but receiver is using %d)",
+			    ci->sec_channel, oci.sec_channel);
+		return -1;
+	}
+
+	/*
+	 * When using a 160 or 80+80 MHz channel to transmit, verify that we use
+	 * the same segments as the receiver by comparing frequency segment 1.
+	 */
+	if ((ci->chanwidth == CHAN_WIDTH_160 ||
+	     ci->chanwidth == CHAN_WIDTH_80P80) &&
+	    tx_seg1_idx != oci.seg1_idx) {
+		os_snprintf(ocv_errorstr, sizeof(ocv_errorstr),
+			    "OCV failed: frequency segment 1 mismatch in received OCI (we use %d but receiver is using %d)",
+			    tx_seg1_idx, oci.seg1_idx);
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/src/common/ocv.h b/src/common/ocv.h
new file mode 100644
index 0000000..6379d9d
--- /dev/null
+++ b/src/common/ocv.h
@@ -0,0 +1,40 @@
+/*
+ * Operating Channel Validation (OCV)
+ * Copyright (c) 2018, Mathy Vanhoef
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef OCV_H
+#define OCV_H
+
+struct wpa_channel_info;
+
+struct oci_info {
+	/* Values in the OCI element */
+	u8 op_class;
+	u8 channel;
+	u8 seg1_idx;
+
+	/* Derived values for easier verification */
+	int freq;
+	int sec_channel;
+	int chanwidth;
+};
+
+#define OCV_OCI_LEN		3
+#define OCV_OCI_EXTENDED_LEN	(3 + OCV_OCI_LEN)
+#define OCV_OCI_KDE_LEN		(2 + RSN_SELECTOR_LEN + OCV_OCI_LEN)
+
+extern char ocv_errorstr[256];
+
+int ocv_derive_all_parameters(struct oci_info *oci);
+int ocv_insert_oci(struct wpa_channel_info *ci, u8 **argpos);
+int ocv_insert_oci_kde(struct wpa_channel_info *ci, u8 **argpos);
+int ocv_insert_extended_oci(struct wpa_channel_info *ci, u8 *pos);
+int ocv_verify_tx_params(const u8 *oci_ie, size_t oci_ie_len,
+			 struct wpa_channel_info *ci, int tx_chanwidth,
+			 int tx_seg1_idx);
+
+#endif /* OCV_H */
diff --git a/src/common/qca-vendor.h b/src/common/qca-vendor.h
index 7a4da46..6f5b87e 100644
--- a/src/common/qca-vendor.h
+++ b/src/common/qca-vendor.h
@@ -42,8 +42,12 @@
  *
  * @QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY: Recommendation of frequency
  *	ranges to avoid to reduce issues due to interference or internal
- *	co-existence information in the driver. The event data structure is
- *	defined in struct qca_avoid_freq_list.
+ *	co-existence information in the driver. These frequencies aim to
+ *	minimize the traffic but not to totally avoid the traffic. That said
+ *	for a P2P use case, these frequencies are allowed for the P2P
+ *	discovery/negotiation but avoid the group to get formed on these
+ *	frequencies. The event data structure is defined in
+ *	struct qca_avoid_freq_list.
  *
  * @QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY: Command to check driver support
  *	for DFS offloading.
@@ -158,6 +162,11 @@
  *	timer value. Uses the attributes defines in
  *	enum qca_wlan_vendor_attr_ocb_get_tsf_resp.
  *
+ * @QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES: Command/event to update the
+ *	link properties of the respective interface. As an event, is used
+ *	to notify the connected station's status. The attributes for this
+ *	command are defined in enum qca_wlan_vendor_attr_link_properties.
+ *
  * @QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_START: Command used to
  *	start the P2P Listen offload function in device and pass the listen
  *	channel, period, interval, count, device types, and vendor specific
@@ -474,6 +483,30 @@
  *	configure parameters per peer to capture Channel Frequency Response
  *	(CFR) and enable Periodic CFR capture. The attributes for this command
  *	are defined in enum qca_wlan_vendor_peer_cfr_capture_attr.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT: Event to indicate changes
+ *	in throughput dynamically. The driver estimates the throughput based on
+ *	number of packets being transmitted/received per second and indicates
+ *	the changes in throughput to user space. Userspace tools can use this
+ *	information to configure kernel's TCP parameters in order to achieve
+ *	peak throughput. Optionally, the driver will also send guidance on
+ *	modifications to kernel's TCP parameters which can be referred by
+ *	userspace tools. The attributes used with this event are defined in enum
+ *	qca_wlan_vendor_attr_throughput_change.
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG: This command is used to set
+ *	priorities among different types of traffic during coex scenarios.
+ *	Current supported prioritization is among WLAN/BT/ZIGBEE with different
+ *	profiles mentioned in enum qca_coex_config_profiles. The associated
+ *	attributes used with this command are defined in enum
+ *	qca_vendor_attr_coex_config.
+ *
+ *	Based on the config provided, FW will boost the weight and prioritize
+ *	the traffic for that subsystem (WLAN/BT/Zigbee).
+ *
+ * @QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_AKMS: This command is used to query
+ *	the supported AKM suite selectorss from the driver. It returns the list
+ *	of supported AKMs in the attribute NL80211_ATTR_AKM_SUITES.
  */
 enum qca_nl80211_vendor_subcmds {
 	QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
@@ -636,6 +669,9 @@
 	QCA_NL80211_VENDOR_SUBCMD_NAN_EXT = 171,
 	QCA_NL80211_VENDOR_SUBCMD_ROAM_SCAN_EVENT = 172,
 	QCA_NL80211_VENDOR_SUBCMD_PEER_CFR_CAPTURE_CFG = 173,
+	QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT = 174,
+	QCA_NL80211_VENDOR_SUBCMD_COEX_CONFIG = 175,
+	QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_AKMS = 176,
 };
 
 enum qca_wlan_vendor_attr {
@@ -816,6 +852,12 @@
 	 * to report the corresponding antenna index to the chain RSSI value
 	 */
 	QCA_WLAN_VENDOR_ATTR_ANTENNA_INFO = 40,
+	/* Used in QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI command to report
+	 * the specific antenna EVM value (unsigned 32 bit value). With a
+	 * determinate group of antennas, the driver specifies the EVM value
+	 * for each antenna ID, and application extract them in user space.
+	 */
+	QCA_WLAN_VENDOR_ATTR_CHAIN_EVM = 41,
 
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_AFTER_LAST,
@@ -4406,6 +4448,27 @@
 	 * qca_wlan_vendor_spectral_scan_cap_hw_gen.
 	 */
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HW_GEN = 5,
+	/* Spectral bin scaling formula ID. u16 attribute.
+	 * It uses values defined in enum
+	 * qca_wlan_vendor_spectral_scan_cap_formula_id.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID = 6,
+	/* Spectral bin scaling param - low level offset.
+	 * s16 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_LOW_LEVEL_OFFSET = 7,
+	/* Spectral bin scaling param - high level offset.
+	 * s16 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_HIGH_LEVEL_OFFSET = 8,
+	/* Spectral bin scaling param - RSSI threshold.
+	 * s16 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_RSSI_THR = 9,
+	/* Spectral bin scaling param - default AGC max gain.
+	 * u8 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_DEFAULT_AGC_MAX_GAIN = 10,
 
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_MAX =
@@ -4551,6 +4614,20 @@
 };
 
 /**
+ * qca_wlan_vendor_spectral_scan_cap_formula_id: Attribute values for
+ * QCA_WLAN_VENDOR_ATTR_SPECTRAL_SCAN_CAP_FORMULA_ID in the vendor subcmd
+ * QCA_NL80211_VENDOR_SUBCMD_SPECTRAL_SCAN_GET_CAP_INFO. This represents the
+ * Spectral bin scaling formula ID.
+ * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_NO_SCALING: No scaling
+ * @QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_AGC_GAIN_RSSI_CORR_BASED: AGC gain
+ * and RSSI threshold based formula.
+ */
+enum qca_wlan_vendor_spectral_scan_cap_formula_id {
+	QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_NO_SCALING = 0,
+	QCA_WLAN_VENDOR_SPECTRAL_SCAN_CAP_AGC_GAIN_RSSI_CORR_BASED = 1,
+};
+
+/**
  * enum qca_wlan_vendor_attr_rropavail_info - Specifies whether Representative
  * RF Operating Parameter (RROP) information is available, and if so, at which
  * point in the application-driver interaction sequence it can be retrieved by
@@ -5413,6 +5490,60 @@
 	QCA_WLAN_HE_16US_OF_PROCESS_TIME = 2,
 };
 
+/**
+ * enum qca_wlan_he_om_ctrl_ch_bw - HE OM control field BW configuration
+ *
+ * Indicates the HE Operating mode control channel width setting value.
+ *
+ * @QCA_WLAN_HE_OM_CTRL_BW_20M: Primary 20 MHz
+ * @QCA_WLAN_HE_OM_CTRL_BW_40M: Primary 40 MHz
+ * @QCA_WLAN_HE_OM_CTRL_BW_80M: Primary 80 MHz
+ * @QCA_WLAN_HE_OM_CTRL_BW_160M: 160 MHz and 80+80 MHz
+ */
+enum qca_wlan_he_om_ctrl_ch_bw {
+	QCA_WLAN_HE_OM_CTRL_BW_20M = 0,
+	QCA_WLAN_HE_OM_CTRL_BW_40M = 1,
+	QCA_WLAN_HE_OM_CTRL_BW_80M = 2,
+	QCA_WLAN_HE_OM_CTRL_BW_160M = 3,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_he_omi_tx: Represents attributes for
+ * HE operating mode control transmit request. These attributes are
+ * sent as part of QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX and
+ * QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS: Mandatory 8-bit unsigned value
+ * indicates the maximum number of spatial streams, NSS, that the STA
+ * supports in reception for PPDU bandwidths less than or equal to 80 MHz
+ * and is set to NSS - 1.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW: Mandatory 8-bit unsigned value
+ * indicates the operating channel width supported by the STA for both
+ * reception and transmission. Uses enum qca_wlan_he_om_ctrl_ch_bw values.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE: Mandatory 8-bit unsigned value
+ * indicates the all trigger based UL MU operations by the STA.
+ * 0 - UL MU operations are enabled by the STA.
+ * 1 - All triggered UL MU transmissions are suspended by the STA.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS: Mandatory 8-bit unsigned value
+ * indicates the maximum number of space-time streams, NSTS, that
+ * the STA supports in transmission and is set to NSTS - 1.
+ */
+enum qca_wlan_vendor_attr_he_omi_tx {
+	QCA_WLAN_VENDOR_ATTR_HE_OMI_INVALID = 0,
+	QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS = 1,
+	QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW = 2,
+	QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE = 3,
+	QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS = 4,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_HE_OMI_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX =
+	QCA_WLAN_VENDOR_ATTR_HE_OMI_AFTER_LAST - 1,
+};
+
 /* Attributes for data used by
  * QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION
  */
@@ -5604,6 +5735,79 @@
 	 */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_RESUME = 26,
 
+	/* 8-bit unsigned value to set the HE operating mode control
+	 * (OM CTRL) Channel Width subfield.
+	 * The Channel Width subfield indicates the operating channel width
+	 * supported by the STA for both reception and transmission.
+	 * Uses the enum qca_wlan_he_om_ctrl_ch_bw values.
+	 * This setting is cleared with the
+	 * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG
+	 * flag attribute to reset defaults.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW = 27,
+
+	/* 8-bit unsigned value to configure the number of spatial
+	 * streams in HE operating mode control field.
+	 * This setting is cleared with the
+	 * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG
+	 * flag attribute to reset defaults.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS = 28,
+
+	/* Flag attribute to configure the UL MU disable bit in
+	 * HE operating mode control field.
+	 * This setting is cleared with the
+	 * QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG
+	 * flag attribute to reset defaults.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_UL_MU_DISABLE = 29,
+
+	/* Flag attribute to clear the previously set HE operating mode
+	 * control field configuration.
+	 * This attribute is used to configure the testbed device to reset
+	 * defaults to clear any previously set HE operating mode control
+	 * field configuration.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG = 30,
+
+	/* 8-bit unsigned value to configure HE single user PPDU
+	 * transmission. By default this setting is disabled and it
+	 * is disabled in the reset defaults of the device configuration.
+	 * This attribute is used to configure the testbed device.
+	 * 1-enable, 0-disable
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU = 31,
+
+	/* 8-bit unsigned value to configure action frame transmission
+	 * in HE trigger based PPDU transmission.
+	 * By default this setting is disabled and it is disabled in
+	 * the reset defaults of the device configuration.
+	 * This attribute is used to configure the testbed device.
+	 * 1-enable, 0-disable
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU = 32,
+
+	/* Nested attribute to indicate HE operating mode control field
+	 * transmission. It contains operating mode control field Nss,
+	 * channel bandwidth, Tx Nsts and UL MU disable attributes.
+	 * These nested attributes are used to send HE operating mode control
+	 * with configured values.
+	 * Uses the enum qca_wlan_vendor_attr_he_omi_tx attributes.
+	 * This attribute is used to configure the testbed device.
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX = 33,
+
+	/* 8-bit unsigned value to configure +HTC_HE support to indicate the
+	 * support for the reception of a frame that carries an HE variant
+	 * HT Control field.
+	 * This attribute is used to configure the testbed device.
+	 * 1-enable, 0-disable
+	 */
+	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP = 34,
+
 	/* keep last */
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_AFTER_LAST,
 	QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX =
@@ -5990,4 +6194,159 @@
 	QCA_WLAN_VENDOR_ATTR_PEER_CFR_AFTER_LAST - 1,
 };
 
+/**
+ * enum qca_wlan_throughput_level - Current throughput level
+ *
+ * Indicates the current level of throughput calculated by the driver. The
+ * driver may choose different thresholds to decide whether the throughput level
+ * is low or medium or high based on variety of parameters like physical link
+ * capacity of the current connection, the number of packets being dispatched
+ * per second, etc. The throughput level events might not be consistent with the
+ * actual current throughput value being observed.
+ *
+ * @QCA_WLAN_THROUGHPUT_LEVEL_LOW: Low level of throughput
+ * @QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM: Medium level of throughput
+ * @QCA_WLAN_THROUGHPUT_LEVEL_HIGH: High level of throughput
+ */
+enum qca_wlan_throughput_level {
+	QCA_WLAN_THROUGHPUT_LEVEL_LOW = 0,
+	QCA_WLAN_THROUGHPUT_LEVEL_MEDIUM = 1,
+	QCA_WLAN_THROUGHPUT_LEVEL_HIGH = 2,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_throughput_change - Vendor subcmd attributes to
+ * report throughput changes from the driver to user space. enum values are used
+ * for netlink attributes sent with
+ * %QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT sub command.
+ */
+enum qca_wlan_vendor_attr_throughput_change {
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_INVALID = 0,
+	/* Indicates the direction of throughput in which the change is being
+	 * reported. u8 attribute. Value is 0 for TX and 1 for RX.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION = 1,
+	/* Indicates the newly observed throughput level. enum
+	 * qca_wlan_throughput_level describes the possible range of values.
+	 * u8 attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL = 2,
+	/* Indicates the driver's guidance on the new value to be set to
+	 * kernel's TCP parameter tcp_limit_output_bytes. u32 attribute. The
+	 * driver may optionally include this attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES = 3,
+	/* Indicates the driver's guidance on the new value to be set to
+	 * kernel's TCP parameter tcp_adv_win_scale. s8 attribute. Possible
+	 * values are from -31 to 31. The driver may optionally include this
+	 * attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE = 4,
+	/* Indicates the driver's guidance on the new value to be set to
+	 * kernel's TCP parameter tcp_delack_seg. u32 attribute. The driver may
+	 * optionally include this attribute.
+	 */
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG = 5,
+
+	/* keep last */
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_AFTER_LAST,
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_MAX =
+	QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_coex_config_profiles - This enum defines different types of
+ * traffic streams that can be prioritized one over the other during coex
+ * scenarios.
+ * The types defined in this enum are categorized in the below manner.
+ * 0 - 31 values corresponds to WLAN
+ * 32 - 63 values corresponds to BT
+ * 64 - 95 values corresponds to Zigbee
+ * @QCA_WIFI_STA_DISCOVERY: Prioritize discovery frames for WLAN STA
+ * @QCA_WIFI_STA_CONNECTION: Prioritize connection frames for WLAN STA
+ * @QCA_WIFI_STA_CLASS_3_MGMT: Prioritize class 3 mgmt frames for WLAN STA
+ * @QCA_WIFI_STA_DATA : Prioritize data frames for WLAN STA
+ * @QCA_WIFI_STA_ALL: Priritize all frames for WLAN STA
+ * @QCA_WIFI_SAP_DISCOVERY: Prioritize discovery frames for WLAN SAP
+ * @QCA_WIFI_SAP_CONNECTION: Prioritize connection frames for WLAN SAP
+ * @QCA_WIFI_SAP_CLASS_3_MGMT: Prioritize class 3 mgmt frames for WLAN SAP
+ * @QCA_WIFI_SAP_DATA: Prioritize data frames for WLAN SAP
+ * @QCA_WIFI_SAP_ALL: Prioritize all frames for WLAN SAP
+ * @QCA_BT_A2DP: Prioritize BT A2DP
+ * @QCA_BT_BLE: Prioritize BT BLE
+ * @QCA_BT_SCO: Prioritize BT SCO
+ * @QCA_ZB_LOW: Prioritize Zigbee Low
+ * @QCA_ZB_HIGH: Prioritize Zigbee High
+ */
+enum qca_coex_config_profiles {
+	/* 0 - 31 corresponds to WLAN */
+	QCA_WIFI_STA_DISCOVERY = 0,
+	QCA_WIFI_STA_CONNECTION = 1,
+	QCA_WIFI_STA_CLASS_3_MGMT = 2,
+	QCA_WIFI_STA_DATA = 3,
+	QCA_WIFI_STA_ALL = 4,
+	QCA_WIFI_SAP_DISCOVERY = 5,
+	QCA_WIFI_SAP_CONNECTION = 6,
+	QCA_WIFI_SAP_CLASS_3_MGMT = 7,
+	QCA_WIFI_SAP_DATA = 8,
+	QCA_WIFI_SAP_ALL = 9,
+	/* 32 - 63 corresponds to BT */
+	QCA_BT_A2DP = 32,
+	QCA_BT_BLE = 33,
+	QCA_BT_SCO = 34,
+	/* 64 - 95 corresponds to Zigbee */
+	QCA_ZB_LOW = 64,
+	QCA_ZB_HIGH = 65
+};
+
+/**
+ * enum qca_vendor_attr_coex_config - Specifies vendor coex config attributes
+ *
+ * @QCA_VENDOR_ATTR_COEX_CONFIG_PROFILES: This attribute contains variable
+ * length array of 8-bit values from enum qca_coex_config_profiles.
+ * FW will prioritize the profiles in the order given in the array encapsulated
+ * in this attribute.
+ * For example:
+ * -----------------------------------------------------------------------
+ * |     1       |       34       |        32         |         65       |
+ * -----------------------------------------------------------------------
+ * If the attribute contains the values defined in above array then it means
+ * 1) Wifi STA connection has priority over BT_SCO, BT_A2DP and ZIGBEE HIGH.
+ * 2) BT_SCO has priority over BT_A2DP.
+ * 3) BT_A2DP has priority over ZIGBEE HIGH.
+ * Profiles which are not listed in this array shall not be preferred over the
+ * profiles which are listed in the array as a part of this attribute.
+ */
+enum qca_vendor_attr_coex_config {
+	QCA_VENDOR_ATTR_COEX_CONFIG_INVALID = 0,
+	QCA_VENDOR_ATTR_COEX_CONFIG_PROFILES = 1,
+
+	/* Keep last */
+	QCA_VENDOR_ATTR_COEX_CONFIG_AFTER_LAST,
+	QCA_VENDOR_ATTR_COEX_CONFIG_MAX =
+	QCA_VENDOR_ATTR_COEX_CONFIG_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_link_properties - Represent the link properties.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR: MAC address of the peer
+ * (STA/AP) for the connected link.
+ * @QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS: Attribute containing a
+ * &struct nl80211_sta_flag_update for the respective connected link. MAC
+ * address of the peer represented by
+ * QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR.
+ */
+enum qca_wlan_vendor_attr_link_properties {
+	QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_INVALID = 0,
+	/* 1 - 3 are reserved */
+	QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR = 4,
+	QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS = 5,
+
+	/* Keep last */
+	QCA_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST,
+	QCA_VENDOR_ATTR_LINK_PROPERTIES_MAX =
+	QCA_VENDOR_ATTR_LINK_PROPERTIES_AFTER_LAST - 1,
+};
+
 #endif /* QCA_VENDOR_H */
diff --git a/src/common/version.h b/src/common/version.h
index 16c1004..eb4f313 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -9,6 +9,6 @@
 #define GIT_VERSION_STR_POSTFIX ""
 #endif /* GIT_VERSION_STR_POSTFIX */
 
-#define VERSION_STR "2.7-devel" VERSION_STR_POSTFIX GIT_VERSION_STR_POSTFIX
+#define VERSION_STR "2.8-devel" VERSION_STR_POSTFIX GIT_VERSION_STR_POSTFIX
 
 #endif /* VERSION_H */
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index 14c5769..b47f632 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -880,6 +880,12 @@
 			parse->igtk_len = len;
 			break;
 #endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_OCV
+		case FTIE_SUBELEM_OCI:
+			parse->oci = pos;
+			parse->oci_len = len;
+			break;
+#endif /* CONFIG_OCV */
 		default:
 			wpa_printf(MSG_DEBUG, "FT: Unknown subelem id %u", id);
 			break;
@@ -1202,6 +1208,8 @@
 		pos = rsn_ie + 6;
 		left = rsn_ie_len - 6;
 
+		data->group_cipher = WPA_CIPHER_GTK_NOT_USED;
+		data->key_mgmt = WPA_KEY_MGMT_OSEN;
 		data->proto = WPA_PROTO_OSEN;
 	} else {
 		const struct rsn_ie_hdr *hdr;
diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h
index 6261744..37b5834 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -110,6 +110,7 @@
 #define RSN_KEY_DATA_KEYID RSN_SELECTOR(0x00, 0x0f, 0xac, 10)
 #define RSN_KEY_DATA_MULTIBAND_GTK RSN_SELECTOR(0x00, 0x0f, 0xac, 11)
 #define RSN_KEY_DATA_MULTIBAND_KEYID RSN_SELECTOR(0x00, 0x0f, 0xac, 12)
+#define RSN_KEY_DATA_OCI RSN_SELECTOR(0x00, 0x0f, 0xac, 13)
 
 #define WFA_KEY_DATA_IP_ADDR_REQ RSN_SELECTOR(0x50, 0x6f, 0x9a, 4)
 #define WFA_KEY_DATA_IP_ADDR_ALLOC RSN_SELECTOR(0x50, 0x6f, 0x9a, 5)
@@ -148,7 +149,8 @@
 #define WPA_CAPABILITY_SPP_A_MSDU_REQUIRED BIT(11)
 #define WPA_CAPABILITY_PBAC BIT(12)
 #define WPA_CAPABILITY_EXT_KEY_ID_FOR_UNICAST BIT(13)
-/* B14-B15: Reserved */
+#define WPA_CAPABILITY_OCVC BIT(14)
+/* B15: Reserved */
 
 
 /* IEEE 802.11r */
@@ -326,6 +328,7 @@
 #define FTIE_SUBELEM_GTK 2
 #define FTIE_SUBELEM_R0KH_ID 3
 #define FTIE_SUBELEM_IGTK 4
+#define FTIE_SUBELEM_OCI 5
 
 struct rsn_rdie {
 	u8 id;
@@ -451,6 +454,10 @@
 	size_t tie_len;
 	const u8 *igtk;
 	size_t igtk_len;
+#ifdef CONFIG_OCV
+	const u8 *oci;
+	size_t oci_len;
+#endif /* CONFIG_OCV */
 	const u8 *ric;
 	size_t ric_len;
 	int key_mgmt;
diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c
index a0fe822..8722b19 100644
--- a/src/common/wpa_ctrl.c
+++ b/src/common/wpa_ctrl.c
@@ -11,6 +11,8 @@
 #ifdef CONFIG_CTRL_IFACE
 
 #ifdef CONFIG_CTRL_IFACE_UNIX
+#include <sys/stat.h>
+#include <fcntl.h>
 #include <sys/un.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -141,6 +143,19 @@
 		return NULL;
 	}
 	tries++;
+#ifdef ANDROID
+	/* Set client socket file permissions so that bind() creates the client
+	 * socket with these permissions and there is no need to try to change
+	 * them with chmod() after bind() which would have potential issues with
+	 * race conditions. These permissions are needed to make sure the server
+	 * side (wpa_supplicant or hostapd) can reply to the control interface
+	 * messages.
+	 *
+	 * The lchown() calls below after bind() are also part of the needed
+	 * operations to allow the response to go through. Those are using the
+	 * no-deference-symlinks version to avoid races. */
+	fchmod(ctrl->s, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+#endif /* ANDROID */
 	if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
 		    sizeof(ctrl->local)) < 0) {
 		if (errno == EADDRINUSE && tries < 2) {
@@ -159,7 +174,6 @@
 	}
 
 #ifdef ANDROID
-	chmod(ctrl->local.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
 	/* Set group even if we do not have privileges to change owner */
 	grp_wifi = getgrnam("wifi");
 	gid_wifi = grp_wifi ? grp_wifi->gr_gid : 0;
@@ -171,8 +185,8 @@
 		os_free(ctrl);
 		return NULL;
 	}
-	chown(ctrl->local.sun_path, -1, gid_wifi);
-	chown(ctrl->local.sun_path, uid_system, gid_wifi);
+	lchown(ctrl->local.sun_path, -1, gid_wifi);
+	lchown(ctrl->local.sun_path, uid_system, gid_wifi);
 
 	if (os_strncmp(ctrl_path, "@android:", 9) == 0) {
 		if (socket_local_client_connect(
@@ -558,7 +572,8 @@
 			res = recv(ctrl->s, reply, *reply_len, 0);
 			if (res < 0)
 				return res;
-			if (res > 0 && reply[0] == '<') {
+			if ((res > 0 && reply[0] == '<') ||
+			    (res > 6 && strncmp(reply, "IFNAME=", 7) == 0)) {
 				/* This is an unsolicited message from
 				 * wpa_supplicant, not the reply to the
 				 * request. Use msg_cb to report this to the