Accumulative patch from commit 565110cd554801fa301c55010b3e9e14f43d7973

nl80211: Include interface name in more debug prints
Convert WPS NFC python scripts from using wpactrl to wpaspy
wpa_supplicant: Fix lookup of cached PMKSA
Add capability flag for IBSS and add get_capability modes
hostapd: Fix client reassociation after disconnect due to ACK failure
Fix build with CONFIG_NO_CONFIG_BLOBS
Fix build without CONFIG_CTRL_IFACE or CONFIG_NO_STDOUT_DEBUG
libtommath: Avoid a compiler warning on unused variable
libtommath: Condition fast_s_mp_mul_digs() on LTM_FAST
P2P: Remove persistent group peer if it rejects invitation
P2P: Allow shared interface channel preference to be ignored
P2P: Fix shared frequency preference for concurrent operations
P2P: Use best-overall channel in p2p_reselect_channel()
P2P: Allow all channels for multi-channel concurrency (no negotiation)
TDLS: Disable link to existing peer with lower address
Fix compiler warning when CONFIG_IEEE80211R is not included
WPS NFC: Fix build without CONFIG_WPS_ER
FT: Add support for IEEE 802.11r with driver-based SME

Change-Id: I1d5ced870c33d5cb73ecc6f04e272a3cf50f344a
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 704e531..2b5e5bd 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -3490,7 +3490,8 @@
 				"P2P: Invitation Request retry limit reached");
 			if (p2p->cfg->invitation_result)
 				p2p->cfg->invitation_result(
-					p2p->cfg->cb_ctx, -1, NULL, NULL);
+					p2p->cfg->cb_ctx, -1, NULL, NULL,
+					p2p->invite_peer->info.p2p_device_addr);
 		}
 		p2p_set_state(p2p, P2P_IDLE);
 	}
@@ -4319,6 +4320,14 @@
 }
 
 
+void p2p_set_own_freq_preference(struct p2p_data *p2p, int freq)
+{
+	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Own frequency preference: "
+		"%d MHz", freq);
+	p2p->own_freq_preference = freq;
+}
+
+
 const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p)
 {
 	if (p2p == NULL || p2p->go_neg_peer == NULL)
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 4f9b75d..28a0a1d 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -743,6 +743,7 @@
 	 * @status: Negotiation result (Status Code)
 	 * @bssid: P2P Group BSSID or %NULL if not received
 	 * @channels: Available operating channels for the group
+	 * @addr: Peer address
 	 *
 	 * This callback is used to indicate result of an Invitation procedure
 	 * started with a call to p2p_invite(). The indicated status code is
@@ -751,7 +752,8 @@
 	 * local failure in transmitting the Invitation Request.
 	 */
 	void (*invitation_result)(void *ctx, int status, const u8 *bssid,
-				  const struct p2p_channels *channels);
+				  const struct p2p_channels *channels,
+				  const u8 *addr);
 
 	/**
 	 * go_connected - Check whether we are connected to a GO
@@ -1658,6 +1660,17 @@
 void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5,
 			   int freq_overall);
 
+/**
+ * p2p_set_own_freq_preference - Set own preference for channel
+ * @p2p: P2P module context from p2p_init()
+ * @freq: Frequency (MHz) of the preferred channel or 0 if no preference
+ *
+ * This function can be used to set a preference on the operating channel based
+ * on frequencies used on the other virtual interfaces that share the same
+ * radio. If non-zero, this is used to try to avoid multi-channel concurrency.
+ */
+void p2p_set_own_freq_preference(struct p2p_data *p2p, int freq);
+
 const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p);
 
 /**
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 61153d4..c143ef4 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -350,14 +350,36 @@
 	u8 op_reg_class, op_channel;
 	unsigned int i;
 
-	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Selected operating "
-		"channel (reg_class %u channel %u) not acceptable to the "
-		"peer", p2p->op_reg_class, p2p->op_channel);
+	if (p2p->own_freq_preference > 0 &&
+	    p2p_freq_to_channel(p2p->cfg->country, p2p->own_freq_preference,
+				&op_reg_class, &op_channel) == 0 &&
+	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
+		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick own channel "
+			"preference (reg_class %u channel %u) from "
+			"intersection", op_reg_class, op_channel);
+		p2p->op_reg_class = op_reg_class;
+		p2p->op_channel = op_channel;
+		return;
+	}
+
+	if (p2p->best_freq_overall > 0 &&
+	    p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_overall,
+				&op_reg_class, &op_channel) == 0 &&
+	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
+		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick best overall "
+			"channel (reg_class %u channel %u) from intersection",
+			op_reg_class, op_channel);
+		p2p->op_reg_class = op_reg_class;
+		p2p->op_channel = op_channel;
+		return;
+	}
 
 	/* First, try to pick the best channel from another band */
 	freq = p2p_channel_to_freq(p2p->cfg->country, p2p->op_reg_class,
 				   p2p->op_channel);
 	if (freq >= 2400 && freq < 2500 && p2p->best_freq_5 > 0 &&
+	    !p2p_channels_includes(intersection, p2p->op_reg_class,
+				   p2p->op_channel) &&
 	    p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_5,
 				&op_reg_class, &op_channel) == 0 &&
 	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
@@ -370,6 +392,8 @@
 	}
 
 	if (freq >= 4900 && freq < 6000 && p2p->best_freq_24 > 0 &&
+	    !p2p_channels_includes(intersection, p2p->op_reg_class,
+				   p2p->op_channel) &&
 	    p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_24,
 				&op_reg_class, &op_channel) == 0 &&
 	    p2p_channels_includes(intersection, op_reg_class, op_channel)) {
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 5286b02..d5ce52f 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -430,6 +430,7 @@
 	int best_freq_24;
 	int best_freq_5;
 	int best_freq_overall;
+	int own_freq_preference;
 
 	/**
 	 * wps_vendor_ext - WPS Vendor Extensions to add
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index 43d9475..2ed9730 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -466,7 +466,7 @@
 
 	if (p2p->cfg->invitation_result)
 		p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status,
-					    msg.group_bssid, channels);
+					    msg.group_bssid, channels, sa);
 
 	p2p_parse_free(&msg);