Cumulative patch from commit 128f6a98b3d4d6ed103db759707309f451db9682

128f6a98b mka: Fix the order of operations in secure channel deletion
213eb1885 dbus: Set mode to mesh in bss properties when mesh is supported
21fda4ee7 RSN: Fix pre-authentication EAPOL-Start startPeriod configuration
3f23260da nl80211: Notify reason for connection timeout failure
ca1ab9db2 hostapd: Get vendor HE capabilities
7785c70bb QCA vendor command for fetching HE capabilities
d512f406f hostapd: Add IEEE 802.11ax HE IEs into Beacon/Probe Response frames
94380cb40 hostapd: Initial IEEE 802.11ax (HE) definitions
5972dc73c mesh: Use correct rate in VHT and HT mixed environment
84ea61cff mesh: Use correct rate in HT and legacy mixed environment
025c6a47f VHT: Remove a redundant check
a7a638c2c hw_features: Move VHT capabilities checks to common
e01cf2afc Define eapol_sm_get_eap_proxy_imsi() only with CONFIG_EAP_PROXY=y
a8e25deeb FT: Merge similar error paths to use common steps
c6c41f6ea FT: Support addition of RIC elements into Reassociation Request frame
ecbdc1a1f Mark RSN msg 1/2 key data debug dump as key material
834c5d681 FILS: Fix PMK length for initial connection with FILS SHA384 AKM
e491389eb FILS: Fix ifdef for PTK derivation with SHA384-based AKM
62944f7d2 Add HMAC-SHA384 with internal crypto
aeecd4eae OpenSSL: Fix hmac_sha384_vector() implementation
5db32adc9 browser-wpadebug: Send HTTP response with HTTP/1.1 header
79329ae0a P2P: Verify local driver preferred frequencies for P2P use cases
3a7819f0a P2P: Add P2P_SET override_pref_op_chan to allow overriding preference
c06fca04f Add wpa_supplicant SET get_pref_freq_list_override
b4d56efb1 Use throughput estimate-based BSS selection with larger SNR difference
142041487 Drop GREAT_SNR definition from 30 to 25 dB
364c064a4 FT: Check key derivation results explicitly in AP operations
b5562a1a6 FILS: Remove CRC32 dependency from build
5cf0930f9 testS: Additional BSS TM error case coverage
885bbd4de WNM: Remove unused code from BSS TM Req generation
e7ddd86a9 WNM: Use a common error path in ieee802_11_send_wnmsleep_resp()
d6d5970e2 WNM: Fix WNM-Sleep Mode Request parsing for WNM-Sleep element
8492cc79c PeerKey: Remove dead code related to STSL negotiation state
e37c0aa5d OSU server: Remove invalid options from documentation
0d6056703 WMM: Fix estimated medium time calculation for some corner cases
ae26d3021 Fix "IEEE 802.11: Ignored Action frame" debug message
4ead4c7ec WMM: Remove obsolete TODO comments
577e794eb Sync android.config with wpa_supplicant defconfig changes
784710b7f Add bgscan options to wpa_supplicant defconfig
212a8f487 Fix wpa_supplicant defconfig copy-paste description
57c3a605c Add support to sched scan to report relatively better BSSs
20c846d9e nl80211: sched_scan relative RSSI parameters
37e9f511e mka: Send MKPDUs forever if mode is PSK
76aa31838 EAP: Call deinit_for_reauth() for Phase 2 EAP methods
02156b98b EAP-AKA: Don't use anonymous identity in phase2
9e2afe10e EAP-SIM: Don't use anonymous identity in phase2
ed9b1c16d EAP peer: Cache decrypted requests for EAP-SIM/AKA/AKA'
5f11880f6 SME: Remove null ie param from CTRL-EVENT-AUTH-REJECT
4d70b2a4e RRM: Fix a memory leak in beacon request handling
401243b73 RRM: Fix range request overriding
fb81c0a3d RRM: Merge similar error returns to a single one
13b30052d RRM: Fix Range Request max age parsing
bd6ec7f7c Fix MAC ACL query freeing on deinit
b4fd1f0ed Allow PNO scan also in connection completed state
4c6f450ca Add radio_work_is_connect() helper
85b6b6b6e Serialize scan/p2p-scan if already scheduled on the same interface
fcb303a57 P2P: Clear driver scan cache after BSS_FLUSH
0d6dc6830 FILS: Clean up HLP resize check
1d9d21f37 GAS: Add support to randomize transmitter address
8331c9b31 nl80211: Add support for mgmt_tx with random TA
14fa723a9 Sync with mac80211-next.git include/uapi/linux/nl80211.h
65ab7eb1f GAS: Fix OSU Providers List response with invalid configuration
f3e157057 VHT: Fill VHT capability with hardware capability
4bb9b674c Add a log message when GTK rekeying failed
41f140d38 Add hostapd options wpa_group_update_count and wpa_pairwise_update_count
e54691106 mka: Some bug fixes for MACsec in PSK mode
7faf403f9 mka: Fix an incorrect update of participant->to_use_sak
00e0f0b01 hs20-osu-client: Hide a trivial compiler warning
276e93654 hw_features: Clean center freq for falling back HT40 channels
f47f93617 P2P: Override P2P_PEER group_capab with 0 if no matching BSS entry found
bcf66493c Fix estimated throughput based skip-roam case
84bb12aa6 FILS: Fix send_assoc_resp() HLP extension to cover sta == NULL
275cc9428 FILS: Stop processing if fils_rmsk_to_pmk() fails
caab23f19 Set EAPOL-Key Key Length field to 0 for group message 1/2 in RSN
b0fb2be77 Do not send GNonce in EAPOL-Key group message 1/2
3bbc47050 Fix EAPOL-Key Install bit in Group Key 1/2 with FT and FILS auth
db5e53cb0 mesh: Fix struct hostapd_data initialization
9b170991a mesh: Fix mesh interface removal fix
945604a35 Update wpaspy.py to be python3 compatible
4d6e79f86 Use defines in hostapd_set_freq_params()
0217b8d87 eloop: Fix comments mismatch eloop_event/timeout_handler definitions
09a97eb27 Update the copyright notice years for QCA vendor definitions
841e9a8c7 QCA vendor command to set the trace levels for the specific QCA module
d77f33041 FILS: Fix AES-SIV AAD for (Re)Association Request frame decryption
7a6c3de23 ERP: Use macro for EMSKname length instead of hardcoded integer value
bb3ea71a2 ERP: Fix rIK derivation
124ddfa19 FILS: Parse and report received FILS HLP Containers from response
91d91abf6 FILS: DHCP relay for HLP requests
54b04d6f3 FILS: Move HLP request handling into a separate file
5a9d50493 ProxyARP: Use more robust DHCP option parsing
e64c13feb Move DHCP definitions into a common file
70407ee5c Add QCA vendor definitions for BSS transition status
53d171440 AP: Check ACL upon association request for 802.11ad
4cc61c386 GAS: Set temporary session timeout bigger than gas_comeback_delay

Test: Wifi Suite

Change-Id: Id597d7cba5d2b3875f2dbbeb9a10fd5e69a6a7c2
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 71e08e7..91f42dc 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -247,7 +247,6 @@
 
 ifdef CONFIG_FILS
 L_CFLAGS += -DCONFIG_FILS
-NEED_CRC32=y
 NEED_SHA384=y
 NEED_AES_SIV=y
 endif
@@ -828,6 +827,9 @@
 ifdef CONFIG_IEEE80211AC
 OBJS += src/ap/ieee802_11_vht.c
 endif
+ifdef CONFIG_IEEE80211AX
+OBJS += src/ap/ieee802_11_he.c
+endif
 endif
 ifdef CONFIG_WNM
 OBJS += src/ap/wnm_ap.c
@@ -835,6 +837,9 @@
 ifdef CONFIG_MBO
 OBJS += src/ap/mbo_ap.c
 endif
+ifdef CONFIG_FILS
+OBJS += src/ap/fils_hlp.c
+endif
 ifdef CONFIG_CTRL_IFACE
 OBJS += src/ap/ctrl_iface_ap.c
 endif
@@ -849,6 +854,9 @@
 ifdef CONFIG_IEEE80211AC
 L_CFLAGS += -DCONFIG_IEEE80211AC
 endif
+ifdef CONFIG_IEEE80211AX
+L_CFLAGS += -DCONFIG_IEEE80211AX
+endif
 endif
 
 ifdef NEED_AP_MLME
@@ -1283,6 +1291,9 @@
 endif
 ifdef NEED_SHA384
 L_CFLAGS += -DCONFIG_SHA384
+ifneq ($(CONFIG_TLS), openssl)
+OBJS += src/crypto/sha384.c
+endif
 OBJS += src/crypto/sha384-prf.c
 endif
 
@@ -1302,10 +1313,6 @@
 L_CFLAGS += -DCONFIG_ECC
 endif
 
-ifdef NEED_CRC32
-OBJS += src/utils/crc32.c
-endif
-
 ifdef CONFIG_NO_RANDOM_POOL
 L_CFLAGS += -DCONFIG_NO_RANDOM_POOL
 else
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index dae6911..7bcb7e4 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -280,7 +280,6 @@
 
 ifdef CONFIG_FILS
 CFLAGS += -DCONFIG_FILS
-NEED_CRC32=y
 NEED_SHA384=y
 NEED_AES_SIV=y
 endif
@@ -869,6 +868,9 @@
 ifdef CONFIG_IEEE80211AC
 OBJS += ../src/ap/ieee802_11_vht.o
 endif
+ifdef CONFIG_IEEE80211AX
+OBJS += ../src/ap/ieee802_11_he.o
+endif
 endif
 ifdef CONFIG_WNM
 OBJS += ../src/ap/wnm_ap.o
@@ -876,6 +878,9 @@
 ifdef CONFIG_MBO
 OBJS += ../src/ap/mbo_ap.o
 endif
+ifdef CONFIG_FILS
+OBJS += ../src/ap/fils_hlp.o
+endif
 ifdef CONFIG_CTRL_IFACE
 OBJS += ../src/ap/ctrl_iface_ap.o
 endif
@@ -890,6 +895,9 @@
 ifdef CONFIG_IEEE80211AC
 CFLAGS += -DCONFIG_IEEE80211AC
 endif
+ifdef CONFIG_IEEE80211AX
+CFLAGS += -DCONFIG_IEEE80211AX
+endif
 endif
 
 ifdef NEED_AP_MLME
@@ -1328,6 +1336,9 @@
 OBJS += $(SHA256OBJS)
 endif
 ifdef NEED_SHA384
+ifneq ($(CONFIG_TLS), openssl)
+OBJS += ../src/crypto/sha384.o
+endif
 CFLAGS += -DCONFIG_SHA384
 OBJS += ../src/crypto/sha384-prf.o
 endif
@@ -1348,10 +1359,6 @@
 CFLAGS += -DCONFIG_ECC
 endif
 
-ifdef NEED_CRC32
-OBJS += ../src/utils/crc32.o
-endif
-
 ifdef CONFIG_NO_RANDOM_POOL
 CFLAGS += -DCONFIG_NO_RANDOM_POOL
 else
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index f320667..1679347 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -1,9 +1,9 @@
 # Example wpa_supplicant build time configuration
 #
 # This file lists the configuration options that are used when building the
-# hostapd binary. All lines starting with # are ignored. Configuration option
-# lines must be commented out complete, if they are not to be included, i.e.,
-# just setting VARIABLE=n is not disabling that variable.
+# wpa_supplicant binary. All lines starting with # are ignored. Configuration
+# option lines must be commented out complete, if they are not to be included,
+# i.e., just setting VARIABLE=n is not disabling that variable.
 #
 # This file is included in Makefile, so variables like CFLAGS and LIBS can also
 # be modified from here. In most cases, these lines should use += in order not
@@ -91,10 +91,9 @@
 CONFIG_EAP_TTLS=y
 
 # EAP-FAST
-# Note: Default OpenSSL package does not include support for all the
-# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
-# the OpenSSL library must be patched (openssl-0.9.8d-tls-extensions.patch)
-# to add the needed functions.
+# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
+# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
+# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
 #CONFIG_EAP_FAST=y
 
 # EAP-GTC
@@ -152,6 +151,9 @@
 # EAP-IKEv2
 #CONFIG_EAP_IKEV2=y
 
+# EAP-EKE
+#CONFIG_EAP_EKE=y
+
 # PKCS#12 (PFX) support (used to read private key and certificate file from
 # a file that usually has extension .p12 or .pfx)
 CONFIG_PKCS12=y
@@ -176,8 +178,10 @@
 # Select control interface backend for external programs, e.g, wpa_cli:
 # unix = UNIX domain sockets (default for Linux/*BSD)
 # udp = UDP sockets using localhost (127.0.0.1)
+# udp6 = UDP IPv6 sockets using localhost (::1)
 # named_pipe = Windows Named Pipe (default for Windows)
 # udp-remote = UDP sockets with remote access (only for tests systems/purpose)
+# udp6-remote = UDP IPv6 sockets with remote access (only for tests purpose)
 # y = use default (backwards compatibility)
 # If this option is commented out, control interface is not included in the
 # build.
@@ -254,6 +258,9 @@
 # Should we use epoll instead of select? Select is used by default.
 #CONFIG_ELOOP_EPOLL=y
 
+# Should we use kqueue instead of select? Select is used by default.
+#CONFIG_ELOOP_KQUEUE=y
+
 # Select layer 2 packet implementation
 # linux = Linux packet socket (default)
 # pcap = libpcap/libdnet/WinPcap
@@ -263,6 +270,12 @@
 # none = Empty template
 CONFIG_L2_PACKET=linux
 
+# Disable Linux packet socket workaround applicable for station interface
+# in a bridge for EAPOL frames. This should be uncommented only if the kernel
+# is known to not have the regression issue in packet socket behavior with
+# bridge interfaces (commit 'bridge: respect RFC2863 operational state')').
+#CONFIG_NO_LINUX_PACKET_SOCKET_WAR=y
+
 # PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
 CONFIG_PEERKEY=y
 
@@ -349,9 +362,13 @@
 # amount of memory/flash.
 #CONFIG_DYNAMIC_EAP_METHODS=y
 
-# IEEE Std 802.11r-2008 (Fast BSS Transition)
+# IEEE Std 802.11r-2008 (Fast BSS Transition) for station mode
 CONFIG_IEEE80211R=y
 
+# IEEE Std 802.11r-2008 (Fast BSS Transition) for AP mode (implies
+# CONFIG_IEEE80211R).
+#CONFIG_IEEE80211R_AP=y
+
 # Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
 #CONFIG_DEBUG_FILE=y
 
@@ -429,6 +446,10 @@
 # IEEE 802.11n (High Throughput) support (mainly for AP mode)
 CONFIG_IEEE80211N=y
 
+# IEEE 802.11ac (Very High Throughput) support (mainly for AP mode)
+# (depends on CONFIG_IEEE80211N)
+#CONFIG_IEEE80211AC=y
+
 # Wireless Network Management (IEEE Std 802.11v-2011)
 # Note: This is experimental and not complete implementation.
 CONFIG_WNM=y
@@ -442,6 +463,9 @@
 # Hotspot 2.0
 CONFIG_HS20=y
 
+# Enable interface matching in wpa_supplicant
+#CONFIG_MATCH_IFACE=y
+
 # Disable roaming in wpa_supplicant
 CONFIG_NO_ROAMING=y
 
@@ -489,9 +513,32 @@
 # Support Multi Band Operation
 #CONFIG_MBO=y
 
+# Fast Initial Link Setup (FILS) (IEEE 802.11ai)
+# Note: This is an experimental and not yet complete implementation. This
+# should not be enabled for production use.
+#CONFIG_FILS=y
+
+# Support RSN on IBSS networks
+# This is needed to be able to use mode=1 network profile with proto=RSN and
+# key_mgmt=WPA-PSK (i.e., full key management instead of WPA-None).
+#CONFIG_IBSS_RSN=y
+
 # External PMKSA cache control
 # This can be used to enable control interface commands that allow the current
 # PMKSA cache entries to be fetched and new entries to be added.
 #CONFIG_PMKSA_CACHE_EXTERNAL=y
 
+# Mesh Networking (IEEE 802.11s)
+#CONFIG_MESH=y
+
+# Background scanning modules
+# These can be used to request wpa_supplicant to perform background scanning
+# operations for roaming within an ESS (same SSID). See the bgscan parameter in
+# the wpa_supplicant.conf file for more details.
+# Periodic background scans based on signal strength
+#CONFIG_BGSCAN_SIMPLE=y
+# Learn channels used by the network and try to avoid bgscans on other
+# channels (experimental)
+#CONFIG_BGSCAN_LEARN=y
+
 include $(wildcard $(LOCAL_PATH)/android_config_*.inc)
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 608d355..1721d6a 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -168,6 +168,7 @@
 
 			if (mode->vht_capab && ssid->vht) {
 				conf->ieee80211ac = 1;
+				conf->vht_capab |= mode->vht_capab;
 				wpas_conf_ap_vht(wpa_s, conf, mode);
 			}
 		}
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index bdaaa54..58ecf19 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -3748,6 +3748,7 @@
 		config->ctrl_interface = os_strdup(ctrl_interface);
 	if (driver_param)
 		config->driver_param = os_strdup(driver_param);
+	config->gas_rand_addr_lifetime = DEFAULT_RAND_ADDR_LIFETIME;
 
 	return config;
 }
@@ -4456,6 +4457,8 @@
 	{ INT(gas_address3), 0 },
 	{ INT_RANGE(ftm_responder, 0, 1), 0 },
 	{ INT_RANGE(ftm_initiator, 0, 1), 0 },
+	{ INT(gas_rand_addr_lifetime), 0 },
+	{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
 };
 
 #undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 48e64be..2f2bb01 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1328,6 +1328,21 @@
 	 * wpa_supplicant.
 	 */
 	int ftm_initiator;
+
+	/**
+	 * gas_rand_addr_lifetime - Lifetime of random MAC address for ANQP in
+	 *	seconds
+	 */
+	unsigned int gas_rand_addr_lifetime;
+
+	/**
+	 * gas_rand_mac_addr - GAS MAC address policy
+	 *
+	 * 0 = use permanent MAC address
+	 * 1 = use random MAC address
+	 * 2 = like 1, but maintain OUI (with local admin bit set)
+	 */
+	int gas_rand_mac_addr;
 };
 
 
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 920bdc0..84a1ee9 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1413,6 +1413,13 @@
 		fprintf(f, "fst_priority=%d\n", config->fst_priority);
 	if (config->fst_llt)
 		fprintf(f, "fst_llt=%d\n", config->fst_llt);
+
+	if (config->gas_rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME)
+		fprintf(f, "gas_rand_addr_lifetime=%u\n",
+			config->gas_rand_addr_lifetime);
+	if (config->gas_rand_mac_addr)
+		fprintf(f, "gas_rand_mac_addr=%d\n", config->gas_rand_mac_addr);
+
 }
 
 #endif /* CONFIG_NO_CONFIG_WRITE */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index dff53ad..761d917 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -339,6 +339,75 @@
 }
 
 
+static int
+wpas_ctrl_set_relative_rssi(struct wpa_supplicant *wpa_s, const char *cmd)
+{
+	int relative_rssi;
+
+	if (os_strcmp(cmd, "disable") == 0) {
+		wpa_s->srp.relative_rssi_set = 0;
+		return 0;
+	}
+
+	relative_rssi = atoi(cmd);
+	if (relative_rssi < 0 || relative_rssi > 100)
+		return -1;
+	wpa_s->srp.relative_rssi = relative_rssi;
+	wpa_s->srp.relative_rssi_set = 1;
+	return 0;
+}
+
+
+static int wpas_ctrl_set_relative_band_adjust(struct wpa_supplicant *wpa_s,
+					      const char *cmd)
+{
+	char *pos;
+	int adjust_rssi;
+
+	/* <band>:adjust_value */
+	pos = os_strchr(cmd, ':');
+	if (!pos)
+		return -1;
+	pos++;
+	adjust_rssi = atoi(pos);
+	if (adjust_rssi < -100 || adjust_rssi > 100)
+		return -1;
+
+	if (os_strncmp(cmd, "2G", 2) == 0)
+		wpa_s->srp.relative_adjust_band = WPA_SETBAND_2G;
+	else if (os_strncmp(cmd, "5G", 2) == 0)
+		wpa_s->srp.relative_adjust_band = WPA_SETBAND_5G;
+	else
+		return -1;
+
+	wpa_s->srp.relative_adjust_rssi = adjust_rssi;
+
+	return 0;
+}
+
+
+static int wpas_ctrl_iface_set_ric_ies(struct wpa_supplicant *wpa_s,
+				   const char *cmd)
+{
+	struct wpabuf *ric_ies;
+
+	if (*cmd == '\0' || os_strcmp(cmd, "\"\"") == 0) {
+		wpabuf_free(wpa_s->ric_ies);
+		wpa_s->ric_ies = NULL;
+		return 0;
+	}
+
+	ric_ies = wpabuf_parse_bin(cmd);
+	if (!ric_ies)
+		return -1;
+
+	wpabuf_free(wpa_s->ric_ies);
+	wpa_s->ric_ies = ric_ies;
+
+	return 0;
+}
+
+
 static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
 					 char *cmd)
 {
@@ -530,6 +599,12 @@
 		wpa_s->ignore_assoc_disallow = !!atoi(value);
 	} else if (os_strcasecmp(cmd, "reject_btm_req_reason") == 0) {
 		wpa_s->reject_btm_req_reason = atoi(value);
+	} else if (os_strcasecmp(cmd, "get_pref_freq_list_override") == 0) {
+		os_free(wpa_s->get_pref_freq_list_override);
+		if (!value[0])
+			wpa_s->get_pref_freq_list_override = NULL;
+		else
+			wpa_s->get_pref_freq_list_override = os_strdup(value);
 #endif /* CONFIG_TESTING_OPTIONS */
 #ifndef CONFIG_NO_CONFIG_BLOBS
 	} else if (os_strcmp(cmd, "blob") == 0) {
@@ -551,6 +626,12 @@
 		ret = wpas_ctrl_iface_set_lci(wpa_s, value);
 	} else if (os_strcasecmp(cmd, "tdls_trigger_control") == 0) {
 		ret = wpa_drv_set_tdls_mode(wpa_s, atoi(value));
+	} else if (os_strcasecmp(cmd, "relative_rssi") == 0) {
+		ret = wpas_ctrl_set_relative_rssi(wpa_s, value);
+	} else if (os_strcasecmp(cmd, "relative_band_adjust") == 0) {
+		ret = wpas_ctrl_set_relative_band_adjust(wpa_s, value);
+	} else if (os_strcasecmp(cmd, "ric_ies") == 0) {
+		ret = wpas_ctrl_iface_set_ric_ies(wpa_s, value);
 	} else {
 		value[-1] = '=';
 		ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
@@ -6038,10 +6119,24 @@
 }
 
 
+static int wpas_find_p2p_dev_addr_bss(struct wpa_global *global,
+				      const u8 *p2p_dev_addr)
+{
+	struct wpa_supplicant *wpa_s;
+
+	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
+		if (wpa_bss_get_p2p_dev_addr(wpa_s, p2p_dev_addr))
+			return 1;
+	}
+
+	return 0;
+}
+
+
 static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
 			 char *buf, size_t buflen)
 {
-	u8 addr[ETH_ALEN], *addr_ptr;
+	u8 addr[ETH_ALEN], *addr_ptr, group_capab;
 	int next, res;
 	const struct p2p_peer_info *info;
 	char *pos, *end;
@@ -6070,6 +6165,16 @@
 	info = p2p_get_peer_info(wpa_s->global->p2p, addr_ptr, next);
 	if (info == NULL)
 		return -1;
+	group_capab = info->group_capab;
+
+	if (group_capab &&
+	    !wpas_find_p2p_dev_addr_bss(wpa_s->global, info->p2p_device_addr)) {
+		wpa_printf(MSG_DEBUG,
+			   "P2P: Could not find any BSS with p2p_dev_addr "
+			   MACSTR ", hence override group_capab from 0x%x to 0",
+			   MAC2STR(info->p2p_device_addr), group_capab);
+		group_capab = 0;
+	}
 
 	pos = buf;
 	end = buf + buflen;
@@ -6095,7 +6200,7 @@
 			  info->serial_number,
 			  info->config_methods,
 			  info->dev_capab,
-			  info->group_capab,
+			  group_capab,
 			  info->level);
 	if (os_snprintf_error(end - pos, res))
 		return pos - buf;
@@ -6376,6 +6481,20 @@
 		return 0;
 	}
 
+	if (os_strcmp(cmd, "override_pref_op_chan") == 0) {
+		int op_class, chan;
+
+		op_class = atoi(param);
+		param = os_strchr(param, ':');
+		if (!param)
+			return -1;
+		param++;
+		chan = atoi(param);
+		p2p_set_override_pref_op_chan(wpa_s->global->p2p, op_class,
+					      chan);
+		return 0;
+	}
+
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
 		   cmd);
 
@@ -7144,6 +7263,46 @@
 }
 
 
+#ifdef CONFIG_TESTING_OPTIONS
+int wpas_ctrl_iface_get_pref_freq_list_override(struct wpa_supplicant *wpa_s,
+						enum wpa_driver_if_type if_type,
+						unsigned int *num,
+						unsigned int *freq_list)
+{
+	char *pos = wpa_s->get_pref_freq_list_override;
+	char *end;
+	unsigned int count = 0;
+
+	/* Override string format:
+	 *  <if_type1>:<freq1>,<freq2>,... <if_type2>:... */
+
+	while (pos) {
+		if (atoi(pos) == (int) if_type)
+			break;
+		pos = os_strchr(pos, ' ');
+		if (pos)
+			pos++;
+	}
+	if (!pos)
+		return -1;
+	pos = os_strchr(pos, ':');
+	if (!pos)
+		return -1;
+	pos++;
+	end = os_strchr(pos, ' ');
+	while (pos && (!end || pos < end) && count < *num) {
+		freq_list[count++] = atoi(pos);
+		pos = os_strchr(pos, ',');
+		if (pos)
+			pos++;
+	}
+
+	*num = count;
+	return 0;
+}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+
 static int wpas_ctrl_iface_get_pref_freq_list(
 	struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
 {
@@ -7435,6 +7594,8 @@
 	wpa_s->ignore_assoc_disallow = 0;
 	wpa_s->reject_btm_req_reason = 0;
 	wpa_sm_set_test_assoc_ie(wpa_s->wpa, NULL);
+	os_free(wpa_s->get_pref_freq_list_override);
+	wpa_s->get_pref_freq_list_override = NULL;
 #endif /* CONFIG_TESTING_OPTIONS */
 
 	wpa_s->disconnected = 0;
@@ -7457,6 +7618,9 @@
 #ifdef CONFIG_SME
 	wpa_s->sme.last_unprot_disconnect.sec = 0;
 #endif /* CONFIG_SME */
+
+	wpabuf_free(wpa_s->ric_ies);
+	wpa_s->ric_ies = NULL;
 }
 
 
@@ -8045,6 +8209,7 @@
 	struct wpa_scan_res *res;
 	struct os_reltime now;
 	char *pos, *end;
+	int ret = -1;
 
 	if (!param)
 		return -1;
@@ -8072,8 +8237,8 @@
 		res->flags = strtol(pos + 7, NULL, 16);
 
 	pos = os_strstr(param, " bssid=");
-	if (pos)
-		hwaddr_aton(pos + 7, res->bssid);
+	if (pos && hwaddr_aton(pos + 7, res->bssid))
+		goto fail;
 
 	pos = os_strstr(param, " freq=");
 	if (pos)
@@ -8120,8 +8285,8 @@
 		res->parent_tsf = strtoll(pos + 7, NULL, 16);
 
 	pos = os_strstr(param, " tsf_bssid=");
-	if (pos)
-		hwaddr_aton(pos + 11, res->tsf_bssid);
+	if (pos && hwaddr_aton(pos + 11, res->tsf_bssid))
+		goto fail;
 
 	pos = os_strstr(param, " ie=");
 	if (pos) {
@@ -8130,7 +8295,8 @@
 		if (!end)
 			end = pos + os_strlen(pos);
 		res->ie_len = (end - pos) / 2;
-		hexstr2bin(pos, (u8 *) (res + 1), res->ie_len);
+		if (hexstr2bin(pos, (u8 *) (res + 1), res->ie_len))
+			goto fail;
 	}
 
 	pos = os_strstr(param, " beacon_ie=");
@@ -8140,15 +8306,18 @@
 		if (!end)
 			end = pos + os_strlen(pos);
 		res->beacon_ie_len = (end - pos) / 2;
-		hexstr2bin(pos, ((u8 *) (res + 1)) + res->ie_len,
-			   res->beacon_ie_len);
+		if (hexstr2bin(pos, ((u8 *) (res + 1)) + res->ie_len,
+			       res->beacon_ie_len))
+			goto fail;
 	}
 
 	os_get_reltime(&now);
 	wpa_bss_update_scan_res(wpa_s, res, &now);
+	ret = 0;
+fail:
 	os_free(res);
 
-	return 0;
+	return ret;
 }
 
 
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index a6548ba..e6f356b 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -3766,6 +3766,7 @@
 	struct bss_handler_args *args = user_data;
 	struct wpa_bss *res;
 	const char *mode;
+	const u8 *mesh;
 
 	res = get_bss_helper(args, error, __func__);
 	if (!res)
@@ -3784,7 +3785,10 @@
 			break;
 		}
 	} else {
-		if (res->caps & IEEE80211_CAP_IBSS)
+		mesh = wpa_bss_get_ie(res, WLAN_EID_MESH_ID);
+		if (mesh)
+			mode = "mesh";
+		else if (res->caps & IEEE80211_CAP_IBSS)
 			mode = "ad-hoc";
 		else
 			mode = "infrastructure";
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index f0ce4a6..1e37e27 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -1,9 +1,9 @@
 # Example wpa_supplicant build time configuration
 #
 # This file lists the configuration options that are used when building the
-# hostapd binary. All lines starting with # are ignored. Configuration option
-# lines must be commented out complete, if they are not to be included, i.e.,
-# just setting VARIABLE=n is not disabling that variable.
+# wpa_supplicant binary. All lines starting with # are ignored. Configuration
+# option lines must be commented out complete, if they are not to be included,
+# i.e., just setting VARIABLE=n is not disabling that variable.
 #
 # This file is included in Makefile, so variables like CFLAGS and LIBS can also
 # be modified from here. In most cases, these lines should use += in order not
@@ -570,3 +570,13 @@
 
 # Mesh Networking (IEEE 802.11s)
 #CONFIG_MESH=y
+
+# Background scanning modules
+# These can be used to request wpa_supplicant to perform background scanning
+# operations for roaming within an ESS (same SSID). See the bgscan parameter in
+# the wpa_supplicant.conf file for more details.
+# Periodic background scans based on signal strength
+#CONFIG_BGSCAN_SIMPLE=y
+# Learn channels used by the network and try to avoid bgscans on other
+# channels (experimental)
+#CONFIG_BGSCAN_LEARN=y
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 4758c16..0af63c9 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -902,6 +902,11 @@
 					     unsigned int *num,
 					     unsigned int *freq_list)
 {
+#ifdef CONFIG_TESTING_OPTIONS
+	if (wpa_s->get_pref_freq_list_override)
+		return wpas_ctrl_iface_get_pref_freq_list_override(
+			wpa_s, if_type, num, freq_list);
+#endif /* CONFIG_TESTING_OPTIONS */
 	if (!wpa_s->driver->get_pref_freq_list)
 		return -1;
 	return wpa_s->driver->get_pref_freq_list(wpa_s->drv_priv, if_type,
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 76805e0..448615e 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1561,7 +1561,7 @@
 	if (current_bss->est_throughput > selected->est_throughput + 5000) {
 		wpa_dbg(wpa_s, MSG_DEBUG,
 			"Skip roam - Current BSS has better estimated throughput");
-		return 1;
+		return 0;
 	}
 
 	cur_est = current_bss->est_throughput;
@@ -3618,6 +3618,7 @@
 			  union wpa_event_data *data)
 {
 	struct wpa_supplicant *wpa_s = ctx;
+	char buf[100];
 	int resched;
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
@@ -3786,17 +3787,24 @@
 		break;
 #endif /* CONFIG_IBSS_RSN */
 	case EVENT_ASSOC_REJECT:
+		if (data->assoc_reject.timeout_reason)
+			os_snprintf(buf, sizeof(buf), "=%s",
+				    data->assoc_reject.timeout_reason);
+		else
+			buf[0] = '\0';
 		if (data->assoc_reject.bssid)
 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
-				"bssid=" MACSTR	" status_code=%u%s",
+				"bssid=" MACSTR	" status_code=%u%s%s",
 				MAC2STR(data->assoc_reject.bssid),
 				data->assoc_reject.status_code,
-				data->assoc_reject.timed_out ? " timeout" : "");
+				data->assoc_reject.timed_out ? " timeout" : "",
+				buf);
 		else
 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
-				"status_code=%u%s",
+				"status_code=%u%s%s",
 				data->assoc_reject.status_code,
-				data->assoc_reject.timed_out ? " timeout" : "");
+				data->assoc_reject.timed_out ? " timeout" : "",
+				buf);
 		wpa_s->assoc_status_code = data->assoc_reject.status_code;
 		wpas_notify_assoc_status_code(wpa_s);
 		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c
index 1b57d88..db481a5 100644
--- a/wpa_supplicant/gas_query.c
+++ b/wpa_supplicant/gas_query.c
@@ -53,6 +53,7 @@
 		   const struct wpabuf *adv_proto,
 		   const struct wpabuf *resp, u16 status_code);
 	void *ctx;
+	u8 sa[ETH_ALEN];
 };
 
 /**
@@ -63,6 +64,9 @@
 	struct dl_list pending; /* struct gas_query_pending */
 	struct gas_query_pending *current;
 	struct wpa_radio_work *work;
+	struct os_reltime last_mac_addr_rand;
+	int last_rand_sa_type;
+	u8 rand_addr[ETH_ALEN];
 };
 
 
@@ -278,8 +282,9 @@
 	};
 
 	wpa_printf(MSG_DEBUG, "GAS: Send action frame to " MACSTR " len=%u "
-		   "freq=%d prot=%d", MAC2STR(query->addr),
-		   (unsigned int) wpabuf_len(req), query->freq, prot);
+		   "freq=%d prot=%d using src addr " MACSTR,
+		   MAC2STR(query->addr), (unsigned int) wpabuf_len(req),
+		   query->freq, prot, MAC2STR(query->sa));
 	if (prot) {
 		u8 *categ = wpabuf_mhead_u8(req);
 		*categ = WLAN_ACTION_PROTECTED_DUAL;
@@ -295,10 +300,12 @@
 		bssid = query->addr;
 	else
 		bssid = wildcard_bssid;
+
 	res = offchannel_send_action(gas->wpa_s, query->freq, query->addr,
-				     gas->wpa_s->own_addr, bssid,
-				     wpabuf_head(req), wpabuf_len(req),
-				     wait_time, gas_query_tx_status, 0);
+				     query->sa, bssid, wpabuf_head(req),
+				     wpabuf_len(req), wait_time,
+				     gas_query_tx_status, 0);
+
 	if (res == 0)
 		query->offchannel_tx_started = 1;
 	return res;
@@ -725,6 +732,58 @@
 }
 
 
+static int gas_query_set_sa(struct gas_query *gas,
+			    struct gas_query_pending *query)
+{
+	struct wpa_supplicant *wpa_s = gas->wpa_s;
+	struct os_reltime now;
+
+	if (!wpa_s->conf->gas_rand_mac_addr ||
+	    !(wpa_s->current_bss ?
+	      (wpa_s->drv_flags &
+	       WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA_CONNECTED) :
+	      (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MGMT_TX_RANDOM_TA))) {
+		/* Use own MAC address as the transmitter address */
+		os_memcpy(query->sa, wpa_s->own_addr, ETH_ALEN);
+		return 0;
+	}
+
+	os_get_reltime(&now);
+
+	if (wpa_s->conf->gas_rand_mac_addr == gas->last_rand_sa_type &&
+	    gas->last_mac_addr_rand.sec != 0 &&
+	    !os_reltime_expired(&now, &gas->last_mac_addr_rand,
+				wpa_s->conf->gas_rand_addr_lifetime)) {
+		wpa_printf(MSG_DEBUG,
+			   "GAS: Use the previously selected random transmitter address "
+			   MACSTR, MAC2STR(gas->rand_addr));
+		os_memcpy(query->sa, gas->rand_addr, ETH_ALEN);
+		return 0;
+	}
+
+	if (wpa_s->conf->gas_rand_mac_addr == 1 &&
+	    random_mac_addr(gas->rand_addr) < 0) {
+		wpa_printf(MSG_ERROR, "GAS: Failed to get random address");
+		return -1;
+	}
+
+	if (wpa_s->conf->gas_rand_mac_addr == 2 &&
+	    random_mac_addr_keep_oui(gas->rand_addr) < 0) {
+		wpa_printf(MSG_ERROR,
+			   "GAS: Failed to get random address with same OUI");
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "GAS: Use a new random transmitter address "
+		   MACSTR, MAC2STR(gas->rand_addr));
+	os_memcpy(query->sa, gas->rand_addr, ETH_ALEN);
+	os_get_reltime(&gas->last_mac_addr_rand);
+	gas->last_rand_sa_type = wpa_s->conf->gas_rand_mac_addr;
+
+	return 0;
+}
+
+
 /**
  * gas_query_req - Request a GAS query
  * @gas: GAS query data from gas_query_init()
@@ -759,6 +818,10 @@
 		return -1;
 
 	query->gas = gas;
+	if (gas_query_set_sa(gas, query)) {
+		os_free(query);
+		return -1;
+	}
 	os_memcpy(query->addr, dst, ETH_ALEN);
 	query->dialog_token = dialog_token;
 	query->freq = freq;
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 521a692..954061a 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -428,6 +428,8 @@
 	conf.wpa_group = WPA_CIPHER_CCMP;
 	conf.eapol_version = 2;
 	conf.wpa_group_rekey = ssid->group_rekey ? ssid->group_rekey : 600;
+	conf.wpa_group_update_count = 4;
+	conf.wpa_pairwise_update_count = 4;
 
 	ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb, ibss_rsn);
 	if (ibss_rsn->auth_group == NULL) {
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 602ed2e..2ca81a3 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -177,10 +177,9 @@
 	if (!ifmsh->bss)
 		goto out_free;
 
-	ifmsh->bss[0] = bss = os_zalloc(sizeof(struct hostapd_data));
+	ifmsh->bss[0] = bss = hostapd_alloc_bss_data(NULL, NULL, NULL);
 	if (!bss)
 		goto out_free;
-	dl_list_init(&bss->nr_db);
 
 	os_memcpy(bss->own_addr, wpa_s->own_addr, ETH_ALEN);
 	bss->driver = wpa_s->driver;
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 1a0fd5f..f152044 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -684,7 +684,8 @@
 
 	oper = (struct ieee80211_ht_operation *) elems->ht_operation;
 	if (oper &&
-	    !(oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH)) {
+	    !(oper->ht_param & HT_INFO_HT_PARAM_STA_CHNL_WIDTH) &&
+	    sta->ht_capabilities) {
 		wpa_msg(wpa_s, MSG_DEBUG, MACSTR
 			" does not support 40 MHz bandwidth",
 			MAC2STR(sta->addr));
diff --git a/wpa_supplicant/mesh_rsn.c b/wpa_supplicant/mesh_rsn.c
index 33040f3..628382c 100644
--- a/wpa_supplicant/mesh_rsn.c
+++ b/wpa_supplicant/mesh_rsn.c
@@ -158,6 +158,8 @@
 	conf.wpa_group = rsn->group_cipher;
 	conf.eapol_version = 0;
 	conf.wpa_group_rekey = -1;
+	conf.wpa_group_update_count = 4;
+	conf.wpa_pairwise_update_count = 4;
 #ifdef CONFIG_IEEE80211W
 	conf.ieee80211w = ieee80211w;
 	if (ieee80211w != NO_MGMT_FRAME_PROTECTION)
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index a24505f..a341549 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -307,6 +307,11 @@
 		return;
 	}
 
+	if (wpa_s->clear_driver_scan_cache) {
+		wpa_printf(MSG_DEBUG,
+			   "Request driver to clear scan cache due to local BSS flush");
+		params->only_new_results = 1;
+	}
 	ret = wpa_drv_scan(wpa_s, params);
 	if (ret == 0)
 		wpa_s->curr_scan_cookie = params->scan_cookie;
@@ -322,6 +327,7 @@
 	os_get_reltime(&wpa_s->scan_trigger_time);
 	wpa_s->scan_res_handler = wpas_p2p_scan_res_handler;
 	wpa_s->own_scan_requested = 1;
+	wpa_s->clear_driver_scan_cache = 0;
 	wpa_s->p2p_scan_work = work;
 }
 
@@ -5012,6 +5018,12 @@
 	params.extra_ies = wpabuf_head(ies);
 	params.extra_ies_len = wpabuf_len(ies);
 
+	if (wpa_s->clear_driver_scan_cache) {
+		wpa_printf(MSG_DEBUG,
+			   "Request driver to clear scan cache due to local BSS flush");
+		params.only_new_results = 1;
+	}
+
 	/*
 	 * Run a scan to update BSS table and start Provision Discovery once
 	 * the new scan results become available.
@@ -5021,6 +5033,7 @@
 		os_get_reltime(&wpa_s->scan_trigger_time);
 		wpa_s->scan_res_handler = wpas_p2p_scan_res_join;
 		wpa_s->own_scan_requested = 1;
+		wpa_s->clear_driver_scan_cache = 0;
 	}
 
 	wpabuf_free(ies);
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index 36a8336..5be917c 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -1032,6 +1032,7 @@
 	elems_len = len - sizeof(*req);
 	rand_interval = le_to_host16(req->rand_interval);
 
+	os_free(params->freqs);
 	os_memset(params, 0, sizeof(*params));
 
 	data->token = elem_token;
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 16f9c5c..3a100cd 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -1249,6 +1249,26 @@
 }
 
 
+static void
+wpa_scan_set_relative_rssi_params(struct wpa_supplicant *wpa_s,
+				  struct wpa_driver_scan_params *params)
+{
+	if (wpa_s->wpa_state != WPA_COMPLETED ||
+	    !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SCHED_SCAN_RELATIVE_RSSI) ||
+	    wpa_s->srp.relative_rssi_set == 0)
+		return;
+
+	params->relative_rssi_set = 1;
+	params->relative_rssi = wpa_s->srp.relative_rssi;
+
+	if (wpa_s->srp.relative_adjust_rssi == 0)
+		return;
+
+	params->relative_adjust_band = wpa_s->srp.relative_adjust_band;
+	params->relative_adjust_rssi = wpa_s->srp.relative_adjust_rssi;
+}
+
+
 /**
  * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan
  * @wpa_s: Pointer to wpa_supplicant data
@@ -1503,6 +1523,8 @@
 		}
 	}
 
+	wpa_scan_set_relative_rssi_params(wpa_s, scan_params);
+
 	ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params);
 	wpabuf_free(extra_ie);
 	os_free(params.filter_ssids);
@@ -1766,10 +1788,12 @@
  * This doc https://supportforums.cisco.com/docs/DOC-12954 says, "the general
  * rule of thumb is that any SNR above 20 is good." This one
  * http://www.cisco.com/en/US/tech/tk722/tk809/technologies_q_and_a_item09186a00805e9a96.shtml#qa23
- * recommends 25 as a minimum SNR for 54 Mbps data rate. 30 is chosen here as a
- * conservative value.
+ * recommends 25 as a minimum SNR for 54 Mbps data rate. The estimates used in
+ * scan_est_throughput() allow even smaller SNR values for the maximum rates
+ * (21 for 54 Mbps, 22 for VHT80 MCS9, 24 for HT40 and HT20 MCS7). Use 25 as a
+ * somewhat conservative value here.
  */
-#define GREAT_SNR 30
+#define GREAT_SNR 25
 
 #define IS_5GHZ(n) (n > 4000)
 
@@ -1817,10 +1841,12 @@
 	}
 
 	/* if SNR is close, decide by max rate or frequency band */
-	if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
-	    (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
+	if (snr_a && snr_b && abs(snr_b - snr_a) < 7) {
 		if (wa->est_throughput != wb->est_throughput)
 			return wb->est_throughput - wa->est_throughput;
+	}
+	if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) ||
+	    (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) {
 		if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq))
 			return IS_5GHZ(wa->freq) ? -1 : 1;
 	}
@@ -2392,6 +2418,10 @@
 		params->bssid = bssid;
 	}
 
+	params->relative_rssi_set = src->relative_rssi_set;
+	params->relative_rssi = src->relative_rssi;
+	params->relative_adjust_band = src->relative_adjust_band;
+	params->relative_adjust_rssi = src->relative_adjust_rssi;
 	return params;
 
 failed:
@@ -2449,7 +2479,7 @@
 		return 0;
 
 	if ((wpa_s->wpa_state > WPA_SCANNING) &&
-	    (wpa_s->wpa_state <= WPA_COMPLETED)) {
+	    (wpa_s->wpa_state < WPA_COMPLETED)) {
 		wpa_printf(MSG_ERROR, "PNO: In assoc process");
 		return -EAGAIN;
 	}
@@ -2570,6 +2600,8 @@
 		}
 	}
 
+	wpa_scan_set_relative_rssi_params(wpa_s, &params);
+
 	ret = wpa_supplicant_start_sched_scan(wpa_s, &params);
 	os_free(params.filter_ssids);
 	if (ret == 0)
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 744bc7b..beb9d6e 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -891,10 +891,11 @@
 			}
 		}
 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AUTH_REJECT MACSTR
-			" auth_type=%u auth_transaction=%u status_code=%u ie=%s",
+			" auth_type=%u auth_transaction=%u status_code=%u%s%s",
 			MAC2STR(data->auth.peer), data->auth.auth_type,
 			data->auth.auth_transaction, data->auth.status_code,
-			ie_txt);
+			ie_txt ? " ie=" : "",
+			ie_txt ? ie_txt : "");
 		os_free(ie_txt);
 
 		if (data->auth.status_code !=
@@ -932,9 +933,17 @@
 
 #ifdef CONFIG_IEEE80211R
 	if (data->auth.auth_type == WLAN_AUTH_FT) {
+		const u8 *ric_ies = NULL;
+		size_t ric_ies_len = 0;
+
+		if (wpa_s->ric_ies) {
+			ric_ies = wpabuf_head(wpa_s->ric_ies);
+			ric_ies_len = wpabuf_len(wpa_s->ric_ies);
+		}
 		if (wpa_ft_process_response(wpa_s->wpa, data->auth.ies,
 					    data->auth.ies_len, 0,
-					    data->auth.peer, NULL, 0) < 0) {
+					    data->auth.peer,
+					    ric_ies, ric_ies_len) < 0) {
 			wpa_dbg(wpa_s, MSG_DEBUG,
 				"SME: FT Authentication response processing failed");
 			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index 538d5cc..964311c 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -492,6 +492,7 @@
 #ifdef CONFIG_TESTING_OPTIONS
 		"ignore_auth_resp",
 #endif /* CONFIG_TESTING_OPTIONS */
+		"relative_rssi", "relative_band_adjust",
 	};
 	int i, num_fields = ARRAY_SIZE(fields);
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index abb033d..9aaedb3 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -453,6 +453,8 @@
 #ifdef CONFIG_TESTING_OPTIONS
 	l2_packet_deinit(wpa_s->l2_test);
 	wpa_s->l2_test = NULL;
+	os_free(wpa_s->get_pref_freq_list_override);
+	wpa_s->get_pref_freq_list_override = NULL;
 #endif /* CONFIG_TESTING_OPTIONS */
 
 	if (wpa_s->conf != NULL) {
@@ -618,6 +620,9 @@
 #endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
 
 	wpas_flush_fils_hlp_req(wpa_s);
+
+	wpabuf_free(wpa_s->ric_ies);
+	wpa_s->ric_ies = NULL;
 }
 
 
@@ -1869,11 +1874,6 @@
 	u8 channel;
 	int i;
 
-#ifdef CONFIG_HT_OVERRIDES
-	if (ssid->disable_ht)
-		return 0;
-#endif /* CONFIG_HT_OVERRIDES */
-
 	hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
 	if (hw_mode == NUM_HOSTAPD_MODES)
 		return 0;
@@ -4368,6 +4368,20 @@
 }
 
 
+static int radio_work_is_connect(struct wpa_radio_work *work)
+{
+	return os_strcmp(work->type, "sme-connect") == 0 ||
+		os_strcmp(work->type, "connect") == 0;
+}
+
+
+static int radio_work_is_scan(struct wpa_radio_work *work)
+{
+	return os_strcmp(work->type, "scan") == 0 ||
+		os_strcmp(work->type, "p2p-scan") == 0;
+}
+
+
 static struct wpa_radio_work * radio_work_get_next_work(struct wpa_radio *radio)
 {
 	struct wpa_radio_work *active_work = NULL;
@@ -4397,8 +4411,7 @@
 		return NULL;
 	}
 
-	if (os_strcmp(active_work->type, "sme-connect") == 0 ||
-	    os_strcmp(active_work->type, "connect") == 0) {
+	if (radio_work_is_connect(active_work)) {
 		/*
 		 * If the active work is either connect or sme-connect,
 		 * do not parallelize them with other radio works.
@@ -4417,10 +4430,20 @@
 		 * If connect or sme-connect are enqueued, parallelize only
 		 * those operations ahead of them in the queue.
 		 */
-		if (os_strcmp(tmp->type, "connect") == 0 ||
-		    os_strcmp(tmp->type, "sme-connect") == 0)
+		if (radio_work_is_connect(tmp))
 			break;
 
+		/* Serialize parallel scan and p2p_scan operations on the same
+		 * interface since the driver_nl80211 mechanism for tracking
+		 * scan cookies does not yet have support for this. */
+		if (active_work->wpa_s == tmp->wpa_s &&
+		    radio_work_is_scan(active_work) &&
+		    radio_work_is_scan(tmp)) {
+			wpa_dbg(active_work->wpa_s, MSG_DEBUG,
+				"Do not start work '%s' when another work '%s' is already scheduled",
+				tmp->type, active_work->type);
+			continue;
+		}
 		/*
 		 * Check that the radio works are distinct and
 		 * on different bands.
@@ -5325,6 +5348,7 @@
 #ifdef CONFIG_MESH
 	unsigned int mesh_if_created = wpa_s->mesh_if_created;
 	char *ifname = NULL;
+	struct wpa_supplicant *parent = wpa_s->parent;
 #endif /* CONFIG_MESH */
 
 	/* Remove interface from the global list of interfaces */
@@ -5360,7 +5384,7 @@
 
 #ifdef CONFIG_MESH
 	if (mesh_if_created) {
-		wpa_drv_if_remove(wpa_s->parent, WPA_IF_MESH, ifname);
+		wpa_drv_if_remove(parent, WPA_IF_MESH, ifname);
 		os_free(ifname);
 	}
 #endif /* CONFIG_MESH */
@@ -5969,6 +5993,7 @@
 	case WPA_CTRL_REQ_SIM:
 		str_clear_free(eap->external_sim_resp);
 		eap->external_sim_resp = os_strdup(value);
+		eap->pending_req_sim = 0;
 		break;
 	case WPA_CTRL_REQ_PSK_PASSPHRASE:
 		if (wpa_config_set(ssid, "psk", value, 0) < 0)
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index c90fa62..6faa7af 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -422,6 +422,15 @@
 # 2 = like 1, but maintain OUI (with local admin bit set)
 #preassoc_mac_addr=0
 
+# MAC address policy for GAS operations
+# 0 = use permanent MAC address
+# 1 = use random MAC address
+# 2 = like 1, but maintain OUI (with local admin bit set)
+#gas_rand_mac_addr=0
+
+# Lifetime of GAS random MAC address in seconds (default: 60)
+#gas_rand_addr_lifetime=60
+
 # Interworking (IEEE 802.11u)
 
 # Enable Interworking
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 4375523..fa0d2b7 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1061,6 +1061,7 @@
 	struct l2_packet_data *l2_test;
 	unsigned int extra_roc_dur;
 	enum wpa_supplicant_test_failure test_failure;
+	char *get_pref_freq_list_override;
 	unsigned int reject_btm_req_reason;
 	unsigned int p2p_go_csa_on_inv:1;
 	unsigned int ignore_auth_resp:1;
@@ -1112,6 +1113,42 @@
 
 	/* FILS HLP requests (struct fils_hlp_req) */
 	struct dl_list fils_hlp_req;
+
+	struct sched_scan_relative_params {
+		/**
+		 * relative_rssi_set - Enable relatively preferred BSS reporting
+		 *
+		 * 0 = Disable reporting relatively preferred BSSs
+		 * 1 = Enable reporting relatively preferred BSSs
+		 */
+		int relative_rssi_set;
+
+		/**
+		 * relative_rssi - Relative RSSI for reporting better BSSs
+		 *
+		 * Amount of RSSI by which a BSS should be better than the
+		 * current connected BSS so that the new BSS can be reported
+		 * to user space. This applies to sched_scan operations.
+		 */
+		int relative_rssi;
+
+		/**
+		 * relative_adjust_band - Band in which RSSI is to be adjusted
+		 */
+		enum set_band relative_adjust_band;
+
+		/**
+		 * relative_adjust_rssi - RSSI adjustment
+		 *
+		 * An amount of relative_adjust_rssi should be added to the
+		 * BSSs that belong to the relative_adjust_band while comparing
+		 * with other bands for BSS reporting.
+		 */
+		int relative_adjust_rssi;
+	} srp;
+
+	/* RIC elements for FT protocol */
+	struct wpabuf *ric_ies;
 };
 
 
@@ -1368,4 +1405,9 @@
 				     struct wpa_ssid *group,
 				     int only_first_ssid, int debug_print);
 
+int wpas_ctrl_iface_get_pref_freq_list_override(struct wpa_supplicant *wpa_s,
+						enum wpa_driver_if_type if_type,
+						unsigned int *num,
+						unsigned int *freq_list);
+
 #endif /* WPA_SUPPLICANT_I_H */
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 16ffc7f..0d753a9 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -1090,6 +1090,7 @@
 
 
 #ifndef CONFIG_NO_WPA
+
 static void wpa_supplicant_set_rekey_offload(void *ctx,
 					     const u8 *kek, size_t kek_len,
 					     const u8 *kck, size_t kck_len,
@@ -1113,6 +1114,25 @@
 	else
 		return 0;
 }
+
+
+static void wpa_supplicant_fils_hlp_rx(void *ctx, const u8 *dst, const u8 *src,
+				       const u8 *pkt, size_t pkt_len)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	char *hex;
+	size_t hexlen;
+
+	hexlen = pkt_len * 2 + 1;
+	hex = os_malloc(hexlen);
+	if (!hex)
+		return;
+	wpa_snprintf_hex(hex, hexlen, pkt, pkt_len);
+	wpa_msg(wpa_s, MSG_INFO, FILS_HLP_RX "dst=" MACSTR " src=" MACSTR
+		" frame=%s", MAC2STR(dst), MAC2STR(src), hex);
+	os_free(hex);
+}
+
 #endif /* CONFIG_NO_WPA */
 
 
@@ -1162,6 +1182,7 @@
 #endif /* CONFIG_TDLS */
 	ctx->set_rekey_offload = wpa_supplicant_set_rekey_offload;
 	ctx->key_mgmt_set_pmk = wpa_supplicant_key_mgmt_set_pmk;
+	ctx->fils_hlp_rx = wpa_supplicant_fils_hlp_rx;
 
 	wpa_s->wpa = wpa_sm_init(ctx);
 	if (wpa_s->wpa == NULL) {