Cumulative patch from commit 0ad3b9c402ee92863b720bc01f882ebcb1bd42c8

0ad3b9c Use wpa_radio data for get_shared_radio_freqs()
1b544ff Use wpa_radio data for wpas_wpa_is_in_progress()
5b81927 Use wpa_radio data for wpas_p2p_search_delay()
c67e7e2 Use wpa_radio data for channel list updates
f88f19b Use wpa_radio data for scan result updates
202dec2 Add shared per-radio structure for wpa_supplicant
73c00fd Move wpa_supplicant driver initialization into a helper function
7feff06 Add CONFIG_CODE_COVERAGE=y option for gcov
d9c753b EAP server: Handle EAP method initialization failures more cleanly
59d3438 EAP server: Initialize TLS context based on private_key
6b417a1 Reject TLS-based EAP server method if TLS context not initialized
158b090 nl80211: Fix regression in P2P group interface removal
6f72577 P2P: Handle INTERFACE_DISABLED event on a P2P GO interface
336167c AP: Fix inactivity STA timer trigger for driver offload case
1245503 Restore scan_req if sta scan is rescheduled in the scan results event
bdec7ee D-Bus: Add support to set pkcs11_{engine,module}_path
80ed037 Clear beacon_data before usage

Change-Id: I1a87557ad09419b88b993ba13f58359121e3543b
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index b9481f6..4d9eea8 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1203,6 +1203,7 @@
 		if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
 			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
 				"stopped scan processing");
+			wpa_s->scan_req = wpa_s->last_scan_req;
 			wpa_s->sta_scan_pending = 1;
 			wpa_supplicant_req_scan(wpa_s, 5, 0);
 			return -1;
@@ -1392,7 +1393,6 @@
 static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 					      union wpa_event_data *data)
 {
-	const char *rn, *rn2;
 	struct wpa_supplicant *ifs;
 
 	if (_wpa_supplicant_event_scan_results(wpa_s, data, 1) != 0) {
@@ -1407,25 +1407,12 @@
 	}
 
 	/*
-	 * Check other interfaces to see if they have the same radio-name. If
+	 * Check other interfaces to see if they share the same radio. If
 	 * so, they get updated with this same scan info.
 	 */
-	if (!wpa_s->driver->get_radio_name)
-		return;
-
-	rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
-	if (rn == NULL || rn[0] == '\0')
-		return;
-
-	wpa_dbg(wpa_s, MSG_DEBUG, "Checking for other virtual interfaces "
-		"sharing same radio (%s) in event_scan_results", rn);
-
-	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
-		if (ifs == wpa_s || !ifs->driver->get_radio_name)
-			continue;
-
-		rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
-		if (rn2 && os_strcmp(rn, rn2) == 0) {
+	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
+			 radio_list) {
+		if (ifs != wpa_s) {
 			wpa_printf(MSG_DEBUG, "%s: Updating scan results from "
 				   "sibling", ifs->ifname);
 			_wpa_supplicant_event_scan_results(ifs, data, 0);
@@ -2670,7 +2657,6 @@
 
 static void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s)
 {
-	const char *rn, *rn2;
 	struct wpa_supplicant *ifs;
 
 	if (wpa_s->drv_priv == NULL)
@@ -2685,25 +2671,12 @@
 #endif /* CONFIG_P2P */
 
 	/*
-	 * Check other interfaces to see if they have the same radio-name. If
+	 * Check other interfaces to see if they share the same radio. If
 	 * so, they get updated with this same hw mode info.
 	 */
-	if (!wpa_s->driver->get_radio_name)
-		return;
-
-	rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
-	if (rn == NULL || rn[0] == '\0')
-		return;
-
-	wpa_dbg(wpa_s, MSG_DEBUG, "Checking for other virtual interfaces "
-		"sharing same radio (%s) in event_channel_list_change", rn);
-
-	for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
-		if (ifs == wpa_s || !ifs->driver->get_radio_name)
-			continue;
-
-		rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
-		if (rn2 && os_strcmp(rn, rn2) == 0) {
+	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
+			 radio_list) {
+		if (ifs != wpa_s) {
 			wpa_printf(MSG_DEBUG, "%s: Updating hw mode",
 				   ifs->ifname);
 			free_hw_features(ifs);
@@ -3199,6 +3172,20 @@
 		break;
 	case EVENT_INTERFACE_DISABLED:
 		wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled");
+#ifdef CONFIG_P2P
+		if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
+		    (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group &&
+		     wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)) {
+			/*
+			 * The interface was externally disabled. Remove
+			 * it assuming an external entity will start a
+			 * new session if needed.
+			 */
+			wpas_p2p_disconnect(wpa_s);
+			break;
+		}
+#endif /* CONFIG_P2P */
+
 		wpa_supplicant_mark_disassoc(wpa_s);
 		wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
 		break;