Accumulative patch from commit 1075b2957169d8f9d6dddd7679339c751dc9515b

1075b29 P2P: Report group formation failure on error to start GO mode
b62b29e Do not block on ctrl_iface monitor events
eb7ddbf WPS: Stop SSDP service before freeing the pending entries
98cbc0a Remove forgotten Xcode defines
0b9d3b2 Interworking: Relax 3GPP info PLMN matching for MNC
c7a67a7 WPS: Disconnect when removing existing WPS network block
fe65847 EAP-EKE: Add server implementation
7e7610d EAP-EKE: Add peer implementation
489202d EAP-SAKE: Use configured server identity
a607b42 EAP-PSK: Use configured server identity
15b042b EAP-MSCHAPv2: Use configured server identity
162865b EAP-IKEv2 server: Use configured server identity
8f89d82 EAP-GPSK server: Use configured server identity
67fe933 Add server identity configuration for EAP server
06aeff5 dbus: Register the AutoScan method call at the right place
78f79fe P2P: Do not add ctrl interface for P2P_DEVICE (p2p-dev-*)
1c42b42 P2P: Fix TDLS and l2_packet init without P2P Device interface
9e6a321 Fix non-P2P build after the P2P_DEVICE changes
d53d259 Fix build with older OpenSSL versions
54d4ba4 nl80211: Silence a compiler warning with older gcc versions
2e5ba4b P2P: Derive group interface name bit more sensibly
c68f620 P2P: Create P2P Device interface if supported
851b0c5 nl80211: Do not indicate P2P_DEVICE support by default
bb4028f P2P: Ignore p2p_no_group_iface when driver advertizes P2P_DEVICE support
7940c79 nl80211: Use wdev id when cancelling wait for frame using P2P_DEVICE
f608081 nl80211: Verify P2P GO/client address with all interface addresses
5fbcb45 nl80211: Fix determining phy name for P2P Device
27ce1d6 nl80211: Fix nl80211_get_wiphy_index() for P2P Device
080585c Add support for OCSP stapling to validate server certificate
72950ed P2P: Remove a call to wpas_p2p_deinit_global()
ab7a1ad nl80211: Fix P2P group interface creating using P2P Device
fa93de4 nl80211: Use wdev_id in nl80211_create_iface_once()
fdc554b nl80211: Use wdev id to obtain P2P Device scan results
597b94f nl80211: Add .get_mac_addr() callback for P2P Device
8e12685 nl80211: Rework setting interface mode
91724d6 nl80211: Introduce i802_set_iface_flags()
eb4582f nl80211: Remove P2P Device interface upon .deinit()
f632e48 nl80211: Fix P2P Device interface initialization
e472e1b nl80211: Handle creation of P2P Device interface
01517c8 nl80211: Allow Android P2P functionality
6bae92e nl80211: Add support for P2P Device in add interface
d6dcfcd nl80211: Add a handler to create_interface
d3aaef8 nl80211: Hold wdev identification for P2P Device
7aad838 nl80211: Identify if nl80211 is capable of P2P Device abstraction
6a71413 nl80211: Rename is_p2p_interface
8393e1a nl80211: Print interface name on set_key()
80ebfd9 VLAN: Avoid access to non-existing interfaces
4345fe9 bridge: Track inter-BSS usage
459eee9 bridge: Use safe default bridge interface
2aaeedf bridge: Give bridge name in per-bss configuration
8a901d7 D-Bus: Emit signal when a station is authorized or deauthorized
9578329 Add AVG_RSSI report in signal_poll
2cc8d8f Add bandwidth and center freq info to signal_poll
1e0e943 Remove 802.11b rates only in case of P2P group operation
2090a0b nl80211: Add prints for kernel events
8743676 TDLS: Validate ext_supp_rates in copy_supp_rates
85b4eac P2P: Do not reply to 802.11b-only Probe Request frames as GO
ec7b97a Interworking: Add support for using eap_proxy offload
4331263 Fix session timeout after ANQP dummy STA entry with SME-in-driver
56cb4e1 wpadebug: Add option to ignore SSL errors
aa20e1a Remove CONFIG_NO_WPA2 build parameter
5d5c4ee Remove compiler warnings with CONFIG_NO_SCAN_PROCESSING
9aaa695 Remove compiler warnings if TDLS is enabled without WPA2
84ae1d4 Fix WNM build without WPA2
c33d5eb Fix build without WPA2 or EAP
1aef400 IBSS RSN: Implement disconnect() callback using sta_deauth()

Change-Id: I4593be5b1478f6532da917423b1d2afa95fb8020
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index a0c97f0..8515b5a 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -236,7 +236,7 @@
 NEED_MD5=y
 NEED_RC4=y
 else
-L_CFLAGS += -DCONFIG_NO_WPA -DCONFIG_NO_WPA2
+L_CFLAGS += -DCONFIG_NO_WPA
 endif
 
 ifdef CONFIG_IBSS_RSN
@@ -286,10 +286,6 @@
 NEED_GAS=y
 endif
 
-ifdef CONFIG_NO_WPA2
-L_CFLAGS += -DCONFIG_NO_WPA2
-endif
-
 include $(LOCAL_PATH)/src/drivers/drivers.mk
 
 ifdef CONFIG_AP
@@ -601,6 +597,22 @@
 NEED_SHA256=y
 endif
 
+ifdef CONFIG_EAP_EKE
+# EAP-EKE
+ifeq ($(CONFIG_EAP_EKE), dyn)
+L_CFLAGS += -DEAP_EKE_DYNAMIC
+EAPDYN += src/eap_peer/eap_eke.so
+else
+L_CFLAGS += -DEAP_EKE
+OBJS += src/eap_peer/eap_eke.c src/eap_common/eap_eke_common.c
+OBJS_h += src/eap_server/eap_server_eke.c
+endif
+CONFIG_IEEE8021X_EAPOL=y
+NEED_DH_GROUPS=y
+NEED_DH_GROUPS_ALL=y
+NEED_SHA256=y
+endif
+
 ifdef CONFIG_WPS
 ifdef CONFIG_WPS2
 L_CFLAGS += -DCONFIG_WPS2
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 0634219..5698619 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -215,7 +215,7 @@
 NEED_MD5=y
 NEED_RC4=y
 else
-CFLAGS += -DCONFIG_NO_WPA -DCONFIG_NO_WPA2
+CFLAGS += -DCONFIG_NO_WPA
 endif
 
 ifdef CONFIG_IBSS_RSN
@@ -265,10 +265,6 @@
 NEED_GAS=y
 endif
 
-ifdef CONFIG_NO_WPA2
-CFLAGS += -DCONFIG_NO_WPA2
-endif
-
 include ../src/drivers/drivers.mak
 ifdef CONFIG_AP
 OBJS_d += $(DRV_BOTH_OBJS)
@@ -579,6 +575,22 @@
 NEED_SHA256=y
 endif
 
+ifdef CONFIG_EAP_EKE
+# EAP-EKE
+ifeq ($(CONFIG_EAP_EKE), dyn)
+CFLAGS += -DEAP_EKE_DYNAMIC
+EAPDYN += ../src/eap_peer/eap_eke.so
+else
+CFLAGS += -DEAP_EKE
+OBJS += ../src/eap_peer/eap_eke.o ../src/eap_common/eap_eke_common.o
+OBJS_h += ../src/eap_server/eap_server_eke.o
+endif
+CONFIG_IEEE8021X_EAPOL=y
+NEED_DH_GROUPS=y
+NEED_DH_GROUPS_ALL=y
+NEED_SHA256=y
+endif
+
 ifdef CONFIG_WPS
 ifdef CONFIG_WPS2
 CFLAGS += -DCONFIG_WPS2
@@ -1581,6 +1593,10 @@
 	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
 		-Deap_peer_ikev2_register=eap_peer_method_dynamic_init
 
+eap_eke.so: ../src/eap_peer/eap_eke.c ../src/eap_common/eap_eke_common.c
+	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-Deap_peer_eke_register=eap_peer_method_dynamic_init
+
 %.so: %.c
 	$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $< \
 		-D$(*F:eap_%=eap_peer_%)_register=eap_peer_method_dynamic_init
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index 331940c..8b3d6b4 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -262,11 +262,6 @@
 # 35-50 kB in code size.
 #CONFIG_NO_WPA=y
 
-# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
-# save about 1 kB in code size when building only WPA-Personal (no EAP support)
-# or 6 kB if building for WPA-Enterprise.
-#CONFIG_NO_WPA2=y
-
 # Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
 # This option can be used to reduce code size by removing support for
 # converting ASCII passphrases into PSK. If this functionality is removed, the
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index d9e1f82..c48a286 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -124,7 +124,9 @@
 #endif /* CONFIG_IEEE80211N */
 
 #ifdef CONFIG_P2P
-	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
+	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
+	    (ssid->mode == WPAS_MODE_P2P_GO ||
+	     ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
 		/* Remove 802.11b rates from supported and basic rate sets */
 		int *list = os_malloc(4 * sizeof(int));
 		if (list) {
@@ -492,6 +494,11 @@
 
 	if (wpa_drv_associate(wpa_s, &params) < 0) {
 		wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
+#ifdef CONFIG_P2P
+		if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION &&
+		    wpa_s->global->p2p_group_formation == wpa_s)
+			wpas_p2p_group_formation_failed(wpa_s->parent);
+#endif /* CONFIG_P2P */
 		return -1;
 	}
 
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 7a860b6..a35be51 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1522,6 +1522,7 @@
 	{ INT(eap_workaround) },
 	{ STRe(pac_file) },
 	{ INTe(fragment_size) },
+	{ INTe(ocsp) },
 #endif /* IEEE8021X_EAPOL */
 	{ INT_RANGE(mode, 0, 4) },
 	{ INT_RANGE(proactive_key_caching, 0, 1) },
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index a354a11..a24abaf 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -5018,23 +5018,76 @@
 #endif /* CONFIG_WNM */
 
 
+/* Get string representation of channel width */
+static const char * channel_width_name(enum chan_width width)
+{
+	switch (width) {
+	case CHAN_WIDTH_20_NOHT:
+		return "20 MHz (no HT)";
+	case CHAN_WIDTH_20:
+		return "20 MHz";
+	case CHAN_WIDTH_40:
+		return "40 MHz";
+	case CHAN_WIDTH_80:
+		return "80 MHz";
+	case CHAN_WIDTH_80P80:
+		return "80+80 MHz";
+	case CHAN_WIDTH_160:
+		return "160 MHz";
+	default:
+		return "unknown";
+	}
+}
+
+
 static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
 				      size_t buflen)
 {
 	struct wpa_signal_info si;
 	int ret;
+	char *pos, *end;
 
 	ret = wpa_drv_signal_poll(wpa_s, &si);
 	if (ret)
 		return -1;
 
-	ret = os_snprintf(buf, buflen, "RSSI=%d\nLINKSPEED=%d\n"
+	pos = buf;
+	end = buf + buflen;
+
+	ret = os_snprintf(pos, end - pos, "RSSI=%d\nLINKSPEED=%d\n"
 			  "NOISE=%d\nFREQUENCY=%u\n",
 			  si.current_signal, si.current_txrate / 1000,
 			  si.current_noise, si.frequency);
-	if (ret < 0 || (unsigned int) ret > buflen)
+	if (ret < 0 || ret > end - pos)
 		return -1;
-	return ret;
+	pos += ret;
+
+	if (si.chanwidth != CHAN_WIDTH_UNKNOWN) {
+		ret = os_snprintf(pos, end - pos, "WIDTH=%s\n",
+				  channel_width_name(si.chanwidth));
+		if (ret < 0 || ret > end - pos)
+			return -1;
+		pos += ret;
+	}
+
+	if (si.center_frq1 > 0 && si.center_frq2 > 0) {
+		ret = os_snprintf(pos, end - pos,
+				  "CENTER_FRQ1=%d\nCENTER_FRQ2=%d\n",
+				  si.center_frq1, si.center_frq2);
+		if (ret < 0 || ret > end - pos)
+			return -1;
+		pos += ret;
+	}
+
+	if (si.avg_signal) {
+		ret = os_snprintf(pos, end - pos,
+				  "AVG_RSSI=%d\n", si.avg_signal);
+		if (ret < 0 || ret >= end - pos)
+			return -1;
+		pos += ret;
+	}
+
+	return pos - buf;
 }
 
 
diff --git a/wpa_supplicant/ctrl_iface_unix.c b/wpa_supplicant/ctrl_iface_unix.c
index 1b4b9b0..fc0d649 100644
--- a/wpa_supplicant/ctrl_iface_unix.c
+++ b/wpa_supplicant/ctrl_iface_unix.c
@@ -602,7 +602,7 @@
 				    offsetof(struct sockaddr_un, sun_path));
 			msg.msg_name = (void *) &dst->addr;
 			msg.msg_namelen = dst->addrlen;
-			if (sendmsg(sock, &msg, 0) < 0) {
+			if (sendmsg(sock, &msg, MSG_DONTWAIT) < 0) {
 				int _errno = errno;
 				wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
 					   "%d - %s",
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index e9bd51f..ddd2c82 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -869,6 +869,76 @@
 }
 
 
+/**
+ * wpas_dbus_signal_sta - Send a station related event signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @sta: station mac address
+ * @sig_name: signal name - StaAuthorized or StaDeauthorized
+ *
+ * Notify listeners about event related with station
+ */
+static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
+				 const u8 *sta, const char *sig_name)
+{
+	struct wpas_dbus_priv *iface;
+	DBusMessage *msg;
+	char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
+	char *dev_mac;
+
+	os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
+	dev_mac = sta_mac;
+
+	iface = wpa_s->global->dbus;
+
+	/* Do nothing if the control interface is not turned on */
+	if (iface == NULL)
+		return;
+
+	msg = dbus_message_new_signal(wpa_s->dbus_new_path,
+				      WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
+	if (msg == NULL)
+		return;
+
+	if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
+				     DBUS_TYPE_INVALID))
+		dbus_connection_send(iface->con, msg, NULL);
+	else
+		wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
+	dbus_message_unref(msg);
+
+	wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
+		   sta_mac, sig_name);
+}
+
+
+/**
+ * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @sta: station mac address
+ *
+ * Notify listeners a new station has been authorized
+ */
+void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
+				     const u8 *sta)
+{
+	wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
+}
+
+
+/**
+ * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
+ * @wpa_s: %wpa_supplicant network interface data
+ * @sta: station mac address
+ *
+ * Notify listeners a station has been deauthorized
+ */
+void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
+				       const u8 *sta)
+{
+	wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
+}
+
+
 #ifdef CONFIG_P2P
 
 /**
@@ -1920,15 +1990,6 @@
 		  END_ARGS
 	  }
 	},
-#ifdef CONFIG_AUTOSCAN
-	{ "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
-	  (WPADBusMethodHandler) &wpas_dbus_handler_autoscan,
-	  {
-		  { "arg", "s", ARG_IN },
-		  END_ARGS
-	  }
-	},
-#endif /* CONFIG_AUTOSCAN */
 	{ NULL, NULL, NULL, { END_ARGS } }
 };
 
@@ -2666,6 +2727,15 @@
 		  END_ARGS
 	  }
 	},
+#ifdef CONFIG_AUTOSCAN
+	{ "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) &wpas_dbus_handler_autoscan,
+	  {
+		  { "arg", "s", ARG_IN },
+		  END_ARGS
+	  }
+	},
+#endif /* CONFIG_AUTOSCAN */
 	{ NULL, NULL, NULL, { END_ARGS } }
 };
 
@@ -3017,6 +3087,18 @@
 		  END_ARGS
 	  }
 	},
+	{ "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "name", "s", ARG_OUT },
+		  END_ARGS
+	  }
+	},
+	{ "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  {
+		  { "name", "s", ARG_OUT },
+		  END_ARGS
+	  }
+	},
 	{ NULL, NULL, { END_ARGS } }
 };
 
diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h
index 363a7e5..61c480a 100644
--- a/wpa_supplicant/dbus/dbus_new.h
+++ b/wpa_supplicant/dbus/dbus_new.h
@@ -222,6 +222,10 @@
 			   const u8 *ie, size_t ie_len, u32 ssi_signal);
 void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
 				 const char *status, const char *parameter);
+void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
+				     const u8 *sta);
+void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
+				       const u8 *sta);
 
 #else /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
@@ -493,6 +497,18 @@
 {
 }
 
+static inline
+void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
+				     const u8 *sta)
+{
+}
+
+static inline
+void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
+				       const u8 *sta)
+{
+}
+
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
 #endif /* CTRL_IFACE_DBUS_H_NEW */
diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig
index 5663a5f..aa6005f 100644
--- a/wpa_supplicant/defconfig
+++ b/wpa_supplicant/defconfig
@@ -210,6 +210,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
@@ -261,11 +264,6 @@
 # 35-50 kB in code size.
 #CONFIG_NO_WPA=y
 
-# Remove WPA2 support. This allows WPA to be used, but removes WPA2 code to
-# save about 1 kB in code size when building only WPA-Personal (no EAP support)
-# or 6 kB if building for WPA-Enterprise.
-#CONFIG_NO_WPA2=y
-
 # Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
 # This option can be used to reduce code size by removing support for
 # converting ASCII passphrases into PSK. If this functionality is removed, the
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 6bab19c..9922e07 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -129,6 +129,16 @@
 	return -1;
 }
 
+static inline int wpa_drv_sta_deauth(struct wpa_supplicant *wpa_s,
+				     const u8 *addr, int reason_code)
+{
+	if (wpa_s->driver->sta_deauth) {
+		return wpa_s->driver->sta_deauth(wpa_s->drv_priv, NULL, addr,
+						 reason_code);
+	}
+	return -1;
+}
+
 static inline int wpa_drv_deauthenticate(struct wpa_supplicant *wpa_s,
 					 const u8 *addr, int reason_code)
 {
diff --git a/wpa_supplicant/eap_register.c b/wpa_supplicant/eap_register.c
index d1eb4ff..6cd2fc5 100644
--- a/wpa_supplicant/eap_register.c
+++ b/wpa_supplicant/eap_register.c
@@ -135,6 +135,11 @@
 		ret = eap_peer_pwd_register();
 #endif /* EAP_PWD */
 
+#ifdef EAP_EKE
+	if (ret == 0)
+		ret = eap_peer_eke_register();
+#endif /* EAP_EKE */
+
 #ifdef EAP_SERVER_IDENTITY
 	if (ret == 0)
 		ret = eap_server_identity_register();
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 60e71b6..d39216f 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -44,8 +44,10 @@
 #include "interworking.h"
 
 
+#ifndef CONFIG_NO_SCAN_PROCESSING
 static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
 					      int new_scan);
+#endif /* CONFIG_NO_SCAN_PROCESSING */
 
 
 static int wpas_temp_disabled(struct wpa_supplicant *wpa_s,
@@ -1957,7 +1959,9 @@
 	int authenticating;
 	u8 prev_pending_bssid[ETH_ALEN];
 	struct wpa_bss *fast_reconnect = NULL;
+#ifndef CONFIG_NO_SCAN_PROCESSING
 	struct wpa_ssid *fast_reconnect_ssid = NULL;
+#endif /* CONFIG_NO_SCAN_PROCESSING */
 	struct wpa_ssid *last_ssid;
 
 	authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
@@ -1998,7 +2002,9 @@
 			 * time for some common cases.
 			 */
 			fast_reconnect = wpa_s->current_bss;
+#ifndef CONFIG_NO_SCAN_PROCESSING
 			fast_reconnect_ssid = wpa_s->current_ssid;
+#endif /* CONFIG_NO_SCAN_PROCESSING */
 		} else if (wpa_s->wpa_state >= WPA_ASSOCIATING)
 #ifdef ANDROID
 			wpa_supplicant_req_scan(wpa_s, 0, 500000);
diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c
index 046f181..687c042 100644
--- a/wpa_supplicant/ibss_rsn.c
+++ b/wpa_supplicant/ibss_rsn.c
@@ -296,6 +296,13 @@
 }
 
 
+static void ibss_rsn_disconnect(void *ctx, const u8 *addr, u16 reason)
+{
+	struct ibss_rsn *ibss_rsn = ctx;
+	wpa_drv_sta_deauth(ibss_rsn->wpa_s, addr, reason);
+}
+
+
 static int auth_for_each_sta(void *ctx, int (*cb)(struct wpa_state_machine *sm,
 						  void *ctx),
 			     void *cb_ctx)
@@ -386,6 +393,7 @@
 	cb.get_psk = auth_get_psk;
 	cb.set_key = auth_set_key;
 	cb.for_each_sta = auth_for_each_sta;
+	cb.disconnect = ibss_rsn_disconnect;
 
 	ibss_rsn->auth_group = wpa_init(own_addr, &conf, &cb);
 	if (ibss_rsn->auth_group == NULL) {
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index e35628b..36f75a1 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -599,19 +599,29 @@
 
 static int plmn_id_match(struct wpabuf *anqp, const char *imsi, int mnc_len)
 {
-	u8 plmn[3];
+	u8 plmn[3], plmn2[3];
 	const u8 *pos, *end;
 	u8 udhl;
 
-	/* See Annex A of 3GPP TS 24.234 v8.1.0 for description */
+	/*
+	 * See Annex A of 3GPP TS 24.234 v8.1.0 for description. The network
+	 * operator is allowed to include only two digits of the MNC, so allow
+	 * matches based on both two and three digit MNC assumptions. Since some
+	 * SIM/USIM cards may not expose MNC length conveniently, we may be
+	 * provided the default MNC length 3 here and as such, checking with MNC
+	 * length 2 is justifiable even though 3GPP TS 24.234 does not mention
+	 * that case. Anyway, MCC/MNC pair where both 2 and 3 digit MNC is used
+	 * with otherwise matching values would not be good idea in general, so
+	 * this should not result in selecting incorrect networks.
+	 */
+	/* Match with 3 digit MNC */
 	plmn[0] = (imsi[0] - '0') | ((imsi[1] - '0') << 4);
-	plmn[1] = imsi[2] - '0';
-	/* default to MNC length 3 if unknown */
-	if (mnc_len != 2)
-		plmn[1] |= (imsi[5] - '0') << 4;
-	else
-		plmn[1] |= 0xf0;
+	plmn[1] = (imsi[2] - '0') | ((imsi[5] - '0') << 4);
 	plmn[2] = (imsi[3] - '0') | ((imsi[4] - '0') << 4);
+	/* Match with 2 digit MNC */
+	plmn2[0] = (imsi[0] - '0') | ((imsi[1] - '0') << 4);
+	plmn2[1] = (imsi[2] - '0') | 0xf0;
+	plmn2[2] = (imsi[3] - '0') | ((imsi[4] - '0') << 4);
 
 	if (anqp == NULL)
 		return 0;
@@ -631,6 +641,10 @@
 	}
 	end = pos + udhl;
 
+	wpa_printf(MSG_DEBUG, "Interworking: Matching against MCC/MNC alternatives: %02x:%02x:%02x or %02x:%02x:%02x (IMSI %s, MNC length %d)",
+		   plmn[0], plmn[1], plmn[2], plmn2[0], plmn2[1], plmn2[2],
+		   imsi, mnc_len);
+
 	while (pos + 2 <= end) {
 		u8 iei, len;
 		const u8 *l_end;
@@ -643,14 +657,20 @@
 		if (iei == 0 && len > 0) {
 			/* PLMN List */
 			u8 num, i;
+			wpa_hexdump(MSG_DEBUG, "Interworking: PLMN List information element",
+				    pos, len);
 			num = *pos++;
 			for (i = 0; i < num; i++) {
-				if (pos + 3 > end)
+				if (pos + 3 > l_end)
 					break;
-				if (os_memcmp(pos, plmn, 3) == 0)
+				if (os_memcmp(pos, plmn, 3) == 0 ||
+				    os_memcmp(pos, plmn2, 3) == 0)
 					return 1; /* Found matching PLMN */
 				pos += 3;
 			}
+		} else {
+			wpa_hexdump(MSG_DEBUG, "Interworking: Unrecognized 3GPP information element",
+				    pos, len);
 		}
 
 		pos = l_end;
@@ -1337,6 +1357,8 @@
 		char *sep;
 		const char *imsi;
 		int mnc_len;
+		char imsi_buf[16];
+		size_t msin_len;
 
 #ifdef PCSC_FUNCS
 		if (cred->pcsc && wpa_s->conf->pcsc_reader && wpa_s->scard &&
@@ -1346,6 +1368,13 @@
 			goto compare;
 		}
 #endif /* PCSC_FUNCS */
+#ifdef CONFIG_EAP_PROXY
+		if (cred->pcsc && wpa_s->mnc_len > 0 && wpa_s->imsi[0]) {
+			imsi = wpa_s->imsi;
+			mnc_len = wpa_s->mnc_len;
+			goto compare;
+		}
+#endif /* CONFIG_EAP_PROXY */
 
 		if (cred->imsi == NULL || !cred->imsi[0] ||
 		    cred->milenage == NULL || !cred->milenage[0])
@@ -1356,11 +1385,18 @@
 		    (sep - cred->imsi != 5 && sep - cred->imsi != 6))
 			continue;
 		mnc_len = sep - cred->imsi - 3;
-		imsi = cred->imsi;
+		os_memcpy(imsi_buf, cred->imsi, 3 + mnc_len);
+		sep++;
+		msin_len = os_strlen(cred->imsi);
+		if (3 + mnc_len + msin_len >= sizeof(imsi_buf) - 1)
+			msin_len = sizeof(imsi_buf) - 3 - mnc_len - 1;
+		os_memcpy(&imsi_buf[3 + mnc_len], sep, msin_len);
+		imsi_buf[3 + mnc_len + msin_len] = '\0';
+		imsi = imsi_buf;
 
-#ifdef PCSC_FUNCS
+#if defined(PCSC_FUNCS) || defined(CONFIG_EAP_PROXY)
 	compare:
-#endif /* PCSC_FUNCS */
+#endif /* PCSC_FUNCS || CONFIG_EAP_PROXY */
 		wpa_printf(MSG_DEBUG, "Interworking: Parsing 3GPP info from "
 			   MACSTR, MAC2STR(bss->bssid));
 		ret = plmn_id_match(bss->anqp->anqp_3gpp, imsi, mnc_len);
diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c
index 1b3364c..39b837e 100644
--- a/wpa_supplicant/main.c
+++ b/wpa_supplicant/main.c
@@ -14,6 +14,7 @@
 #include "common.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
+#include "p2p_supplicant.h"
 
 extern struct wpa_driver_ops *wpa_drivers[];
 
@@ -289,6 +290,8 @@
 	}
 
 	for (i = 0; exitcode == 0 && i < iface_count; i++) {
+		struct wpa_supplicant *wpa_s;
+
 		if ((ifaces[i].confname == NULL &&
 		     ifaces[i].ctrl_interface == NULL) ||
 		    ifaces[i].ifname == NULL) {
@@ -299,8 +302,18 @@
 			exitcode = -1;
 			break;
 		}
-		if (wpa_supplicant_add_iface(global, &ifaces[i]) == NULL)
+		wpa_s = wpa_supplicant_add_iface(global, &ifaces[i]);
+		if (wpa_s == NULL) {
 			exitcode = -1;
+			break;
+		}
+#ifdef CONFIG_P2P
+		if (wpa_s->global->p2p == NULL &&
+		    (wpa_s->drv_flags &
+		     WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
+		    wpas_p2p_add_p2pdev_interface(wpa_s) < 0)
+			exitcode = -1;
+#endif /* CONFIG_P2P */
 	}
 
 	if (exitcode == 0)
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 3ed826d..f2cbdd7 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -551,6 +551,9 @@
 	 */
 	wpas_dbus_signal_p2p_peer_joined(wpa_s, sta);
 #endif /* CONFIG_P2P */
+
+	/* Notify listeners a new station has been authorized */
+	wpas_dbus_signal_sta_authorized(wpa_s, sta);
 }
 
 
@@ -570,6 +573,9 @@
 	 */
 	wpas_dbus_signal_p2p_peer_disconnected(wpa_s, sta);
 #endif /* CONFIG_P2P */
+
+	/* Notify listeners a station has been deauthorized */
+	wpas_dbus_signal_sta_deauthorized(wpa_s, sta);
 }
 
 
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index f9193ae..37f5ad3 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -65,6 +65,8 @@
 #define P2P_CONCURRENT_SEARCH_DELAY 500
 #endif /* P2P_CONCURRENT_SEARCH_DELAY */
 
+#define P2P_MGMT_DEVICE_PREFIX		"p2p-dev-"
+
 enum p2p_group_removal_reason {
 	P2P_GROUP_REMOVAL_UNKNOWN,
 	P2P_GROUP_REMOVAL_SILENT,
@@ -1013,6 +1015,26 @@
 }
 
 
+static void wpas_p2p_get_group_ifname(struct wpa_supplicant *wpa_s,
+				      char *ifname, size_t len)
+{
+	char *ifname_ptr = wpa_s->ifname;
+
+	if (os_strncmp(wpa_s->ifname, P2P_MGMT_DEVICE_PREFIX,
+		       os_strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+		ifname_ptr = os_strrchr(wpa_s->ifname, '-') + 1;
+	}
+
+	os_snprintf(ifname, len, "p2p-%s-%d", ifname_ptr, wpa_s->p2p_group_idx);
+	if (os_strlen(ifname) >= IFNAMSIZ &&
+	    os_strlen(wpa_s->ifname) < IFNAMSIZ) {
+		/* Try to avoid going over the IFNAMSIZ length limit */
+		os_snprintf(ifname, sizeof(ifname), "p2p-%d",
+			    wpa_s->p2p_group_idx);
+	}
+}
+
+
 static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
 					enum wpa_driver_if_type type)
 {
@@ -1030,14 +1052,7 @@
 		return 0;
 	}
 
-	os_snprintf(ifname, sizeof(ifname), "p2p-%s-%d", wpa_s->ifname,
-		    wpa_s->p2p_group_idx);
-	if (os_strlen(ifname) >= IFNAMSIZ &&
-	    os_strlen(wpa_s->ifname) < IFNAMSIZ) {
-		/* Try to avoid going over the IFNAMSIZ length limit */
-		os_snprintf(ifname, sizeof(ifname), "p2p-%d",
-			    wpa_s->p2p_group_idx);
-	}
+	wpas_p2p_get_group_ifname(wpa_s, ifname, sizeof(ifname));
 	force_ifname[0] = '\0';
 
 	wpa_printf(MSG_DEBUG, "P2P: Create a new interface %s for the group",
@@ -1107,7 +1122,13 @@
 	os_memset(&iface, 0, sizeof(iface));
 	iface.ifname = wpa_s->pending_interface_name;
 	iface.driver = wpa_s->driver->name;
-	iface.ctrl_interface = wpa_s->conf->ctrl_interface;
+	if (wpa_s->conf->ctrl_interface == NULL &&
+	    wpa_s->parent != wpa_s &&
+	    wpa_s->p2p_mgmt &&
+	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE))
+		iface.ctrl_interface = wpa_s->parent->conf->ctrl_interface;
+	else
+		iface.ctrl_interface = wpa_s->conf->ctrl_interface;
 	iface.driver_param = wpa_s->conf->driver_param;
 	group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
 	if (group_wpa_s == NULL) {
@@ -1132,6 +1153,14 @@
 {
 	struct wpa_supplicant *wpa_s = eloop_ctx;
 	wpa_printf(MSG_DEBUG, "P2P: Group Formation timed out");
+	wpas_p2p_group_formation_failed(wpa_s);
+}
+
+
+void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s)
+{
+	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
+			     wpa_s->parent, NULL);
 	if (wpa_s->global->p2p)
 		p2p_group_formation_failed(wpa_s->global->p2p);
 	else if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)
@@ -3048,6 +3077,45 @@
 }
 
 
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_interface iface;
+	struct wpa_supplicant *p2pdev_wpa_s;
+	char ifname[100];
+	char force_name[100];
+	int ret;
+
+	os_snprintf(ifname, sizeof(ifname), P2P_MGMT_DEVICE_PREFIX "%s",
+		    wpa_s->ifname);
+	force_name[0] = '\0';
+	wpa_s->pending_interface_type = WPA_IF_P2P_DEVICE;
+	ret = wpa_drv_if_add(wpa_s, WPA_IF_P2P_DEVICE, ifname, NULL, NULL,
+			     force_name, wpa_s->pending_interface_addr, NULL);
+	if (ret < 0) {
+		wpa_printf(MSG_DEBUG, "P2P: Failed to create P2P Device interface");
+		return ret;
+	}
+	os_strlcpy(wpa_s->pending_interface_name, ifname,
+		   sizeof(wpa_s->pending_interface_name));
+
+	os_memset(&iface, 0, sizeof(iface));
+	iface.p2p_mgmt = 1;
+	iface.ifname = wpa_s->pending_interface_name;
+	iface.driver = wpa_s->driver->name;
+	iface.driver_param = wpa_s->conf->driver_param;
+	iface.confname = wpa_s->confname;
+	p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface);
+	if (!p2pdev_wpa_s) {
+		wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface");
+		return -1;
+	}
+	p2pdev_wpa_s->parent = wpa_s;
+
+	wpa_s->pending_interface_name[0] = '\0';
+	return 0;
+}
+
+
 /**
  * wpas_p2p_init - Initialize P2P module for %wpa_supplicant
  * @global: Pointer to global data from wpa_supplicant_init()
@@ -3312,7 +3380,8 @@
 
 static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s)
 {
-	if (wpa_s->conf->p2p_no_group_iface)
+	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
+	    wpa_s->conf->p2p_no_group_iface)
 		return 0; /* separate interface disabled per configuration */
 	if (wpa_s->drv_flags &
 	    (WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
@@ -5595,14 +5664,7 @@
 		   "session overlap");
 	if (wpa_s != wpa_s->parent)
 		wpa_msg_ctrl(wpa_s->parent, MSG_INFO, WPS_EVENT_OVERLAP);
-
-	if (wpa_s->global->p2p)
-		p2p_group_formation_failed(wpa_s->global->p2p);
-
-	eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
-			     wpa_s->parent, NULL);
-
-	wpas_group_formation_completed(wpa_s, 0);
+	wpas_p2p_group_formation_failed(wpa_s);
 	return 1;
 }
 
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 04ba9b2..3ca6222 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -14,10 +14,12 @@
 enum p2p_send_action_result;
 struct p2p_peer_info;
 struct p2p_channels;
+struct wps_event_fail;
 
 int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s);
 void wpas_p2p_deinit(struct wpa_supplicant *wpa_s);
 void wpas_p2p_deinit_global(struct wpa_global *global);
+int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s);
 int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 		     const char *pin, enum p2p_wps_method wps_method,
 		     int persistent_group, int auto_join, int join,
@@ -76,6 +78,7 @@
 void wpas_dev_found(void *ctx, const u8 *addr,
 		    const struct p2p_peer_info *info,
 		    int new_device);
+void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s);
 void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res);
 void wpas_go_neg_req_rx(void *ctx, const u8 *src, u16 dev_passwd_id);
 void wpas_prov_disc_req(void *ctx, const u8 *peer, u16 config_methods,
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 27791b3..f6b881b 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -17,6 +17,7 @@
 #include "crypto/sha1.h"
 #include "eapol_supp/eapol_supp_sm.h"
 #include "eap_peer/eap.h"
+#include "eap_peer/eap_proxy.h"
 #include "eap_server/eap_methods.h"
 #include "rsn_supp/wpa.h"
 #include "eloop.h"
@@ -2348,7 +2349,10 @@
 		const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
 		if (addr)
 			os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
-	} else if (!(wpa_s->drv_flags &
+	} else if ((!wpa_s->p2p_mgmt ||
+		    !(wpa_s->drv_flags &
+		      WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
+		   !(wpa_s->drv_flags &
 		     WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
 		l2_packet_deinit(wpa_s->l2);
 		wpa_s->l2 = l2_packet_init(wpa_s->ifname,
@@ -2368,10 +2372,6 @@
 		return -1;
 	}
 
-	wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
-		MAC2STR(wpa_s->own_addr));
-	wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
-
 	return 0;
 }
 
@@ -2417,6 +2417,10 @@
 	if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
 		return -1;
 
+	wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
+		MAC2STR(wpa_s->own_addr));
+	wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
+
 	if (wpa_s->bridge_ifname[0]) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
 			"interface '%s'", wpa_s->bridge_ifname);
@@ -2855,6 +2859,11 @@
 			wpa_s->conf->driver_param =
 				os_strdup(iface->driver_param);
 		}
+
+		if (iface->p2p_mgmt && !iface->ctrl_interface) {
+			os_free(wpa_s->conf->ctrl_interface);
+			wpa_s->conf->ctrl_interface = NULL;
+		}
 	} else
 		wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
 						     iface->driver_param);
@@ -2980,11 +2989,24 @@
 	if (wpa_s->max_remain_on_chan == 0)
 		wpa_s->max_remain_on_chan = 1000;
 
+	/*
+	 * Only take p2p_mgmt parameters when P2P Device is supported.
+	 * Doing it here as it determines whether l2_packet_init() will be done
+	 * during wpa_supplicant_driver_init().
+	 */
+	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
+		wpa_s->p2p_mgmt = iface->p2p_mgmt;
+	else
+		iface->p2p_mgmt = 1;
+
 	if (wpa_supplicant_driver_init(wpa_s) < 0)
 		return -1;
 
 #ifdef CONFIG_TDLS
-	if (wpa_tdls_init(wpa_s->wpa))
+	if ((!iface->p2p_mgmt ||
+	     !(wpa_s->drv_flags &
+	       WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
+	    wpa_tdls_init(wpa_s->wpa))
 		return -1;
 #endif /* CONFIG_TDLS */
 
@@ -3022,7 +3044,7 @@
 	}
 
 #ifdef CONFIG_P2P
-	if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
+	if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
 		wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
 		return -1;
 	}
@@ -3031,6 +3053,20 @@
 	if (wpa_bss_init(wpa_s) < 0)
 		return -1;
 
+#ifdef CONFIG_EAP_PROXY
+{
+	size_t len;
+	wpa_s->mnc_len = eap_proxy_get_imsi(wpa_s->imsi, &len);
+	if (wpa_s->mnc_len > 0) {
+		wpa_s->imsi[len] = '\0';
+		wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
+			   wpa_s->imsi, wpa_s->mnc_len);
+	} else {
+		wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
+	}
+}
+#endif /* CONFIG_EAP_PROXY */
+
 	if (pcsc_reader_init(wpa_s) < 0)
 		return -1;
 
@@ -3422,9 +3458,6 @@
 #ifdef CONFIG_WIFI_DISPLAY
 	wifi_display_deinit(global);
 #endif /* CONFIG_WIFI_DISPLAY */
-#ifdef CONFIG_P2P
-	wpas_p2p_deinit_global(global);
-#endif /* CONFIG_P2P */
 
 	while (global->ifaces)
 		wpa_supplicant_remove_iface(global, global->ifaces, 1);
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 8e21a3a..d73d371 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -815,6 +815,11 @@
 #	interface used for EAPOL. The default value is suitable for most
 #	cases.
 #
+# ocsp: Whether to use/require OCSP to check server certificate
+#	0 = do not use OCSP stapling (TLS certificate status extension)
+#	1 = try to use OCSP stapling, but not require response
+#	2 = require valid OCSP stapling response
+#
 # EAP-FAST variables:
 # pac_file: File path for the PAC entries. wpa_supplicant will need to be able
 #	to create this file and write updates to it when PAC is being
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index c971ae4..9240863 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -104,6 +104,15 @@
 	 * receiving of EAPOL frames from an additional interface.
 	 */
 	const char *bridge_ifname;
+
+	/**
+	 * p2p_mgmt - Interface used for P2P management (P2P Device operations)
+	 *
+	 * Indicates whether wpas_p2p_init() must be called for this interface.
+	 * This is used only when the driver supports a dedicated P2P Device
+	 * interface that is not a network interface.
+	 */
+	int p2p_mgmt;
 };
 
 /**
@@ -407,10 +416,8 @@
 			     * previous association event */
 
 	struct scard_data *scard;
-#ifdef PCSC_FUNCS
 	char imsi[20];
 	int mnc_len;
-#endif /* PCSC_FUNCS */
 
 	unsigned char last_eapol_src[ETH_ALEN];
 
@@ -568,6 +575,8 @@
 	unsigned int roc_waiting_drv_freq;
 	int action_tx_wait_time;
 
+	int p2p_mgmt;
+
 #ifdef CONFIG_P2P
 	struct p2p_go_neg_results *go_params;
 	int create_p2p_iface;
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 40720c5..61a42bd 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -513,8 +513,6 @@
 }
 #endif /* CONFIG_IEEE80211R */
 
-#endif /* CONFIG_NO_WPA */
-
 
 #ifdef CONFIG_TDLS
 
@@ -596,6 +594,8 @@
 
 #endif /* CONFIG_TDLS */
 
+#endif /* CONFIG_NO_WPA */
+
 
 enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
 {
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index d73e023..8e0207c 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -868,9 +868,8 @@
 	while (ssid) {
 		if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
 			if (ssid == wpa_s->current_ssid) {
-				wpa_s->current_ssid = NULL;
-				if (ssid != NULL)
-					wpas_notify_network_changed(wpa_s);
+				wpa_supplicant_deauthenticate(
+					wpa_s, WLAN_REASON_DEAUTH_LEAVING);
 			}
 			id = ssid->id;
 			remove_ssid = ssid;