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/src/p2p/p2p.c b/src/p2p/p2p.c
index 65dd1a3..14d6279 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -3034,6 +3034,8 @@
 	p2p->ssid_set = 0;
 	p2ps_prov_free(p2p);
 	p2p_reset_pending_pd(p2p);
+	p2p->override_pref_op_class = 0;
+	p2p->override_pref_channel = 0;
 }
 
 
@@ -5522,6 +5524,14 @@
 }
 
 
+void p2p_set_override_pref_op_chan(struct p2p_data *p2p, u8 op_class,
+				   u8 chan)
+{
+	p2p->override_pref_op_class = op_class;
+	p2p->override_pref_channel = chan;
+}
+
+
 struct wpabuf * p2p_build_probe_resp_template(struct p2p_data *p2p,
 					      unsigned int freq)
 {
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 7b18dcf..70d3a90 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -2373,6 +2373,8 @@
 void p2p_set_own_pref_freq_list(struct p2p_data *p2p,
 				const unsigned int *pref_freq_list,
 				unsigned int size);
+void p2p_set_override_pref_op_chan(struct p2p_data *p2p, u8 op_class,
+				   u8 chan);
 
 /**
  * p2p_group_get_common_freqs - Get the group common frequencies
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 9f0b3f3..65ab4b8 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -315,7 +315,12 @@
 			       group_capab);
 	p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker);
 	p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
-	if (peer && peer->go_state == REMOTE_GO && !p2p->num_pref_freq) {
+	if (p2p->override_pref_op_class) {
+		p2p_dbg(p2p, "Override operating channel preference");
+		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
+					      p2p->override_pref_op_class,
+					      p2p->override_pref_channel);
+	} else if (peer && peer->go_state == REMOTE_GO && !p2p->num_pref_freq) {
 		p2p_dbg(p2p, "Omit Operating Channel attribute");
 	} else {
 		p2p_buf_add_operating_channel(buf, p2p->cfg->country,
@@ -562,26 +567,11 @@
 	 * also supported by the peer device.
 	 */
 	for (i = 0; i < size && !found; i++) {
-		/*
-		 * Make sure that the common frequency is:
-		 * 1. Supported by peer
-		 * 2. Allowed for P2P use.
-		 */
+		/* Make sure that the common frequency is supported by peer. */
 		oper_freq = freq_list[i];
 		if (p2p_freq_to_channel(oper_freq, &op_class,
-					&op_channel) < 0) {
-			p2p_dbg(p2p, "Unsupported frequency %u MHz", oper_freq);
-			continue;
-		}
-		if (!p2p_channels_includes(&p2p->cfg->channels,
-					   op_class, op_channel) &&
-		    (go || !p2p_channels_includes(&p2p->cfg->cli_channels,
-						  op_class, op_channel))) {
-			p2p_dbg(p2p,
-				"Freq %u MHz (oper_class %u channel %u) not allowed for P2P",
-				oper_freq, op_class, op_channel);
-			break;
-		}
+					&op_channel) < 0)
+			continue; /* cannot happen due to earlier check */
 		for (j = 0; j < msg->channel_list_len; j++) {
 
 			if (op_channel != msg->channel_list[j])
@@ -602,8 +592,7 @@
 			oper_freq);
 	} else {
 		p2p_dbg(p2p,
-			"None of our preferred channels are supported by peer!. Use: %d MHz for oper_channel",
-			dev->oper_freq);
+			"None of our preferred channels are supported by peer!");
 	}
 }
 
@@ -629,29 +618,9 @@
 				msg->pref_freq_list[2 * j + 1]);
 			if (freq_list[i] != oper_freq)
 				continue;
-
-			/*
-			 * Make sure that the found frequency is:
-			 * 1. Supported
-			 * 2. Allowed for P2P use.
-			 */
 			if (p2p_freq_to_channel(oper_freq, &op_class,
-						&op_channel) < 0) {
-				p2p_dbg(p2p, "Unsupported frequency %u MHz",
-					oper_freq);
-				continue;
-			}
-
-			if (!p2p_channels_includes(&p2p->cfg->channels,
-						   op_class, op_channel) &&
-			    (go ||
-			     !p2p_channels_includes(&p2p->cfg->cli_channels,
-						    op_class, op_channel))) {
-				p2p_dbg(p2p,
-					"Freq %u MHz (oper_class %u channel %u) not allowed for P2P",
-					oper_freq, op_class, op_channel);
-				break;
-			}
+						&op_channel) < 0)
+				continue; /* cannot happen */
 			p2p->op_reg_class = op_class;
 			p2p->op_channel = op_channel;
 			os_memcpy(&p2p->channels, &p2p->cfg->channels,
@@ -666,9 +635,7 @@
 			"Freq %d MHz is a common preferred channel for both peer and local, use it as operating channel",
 			oper_freq);
 	} else {
-		p2p_dbg(p2p,
-			"No common preferred channels found! Use: %d MHz for oper_channel",
-			dev->oper_freq);
+		p2p_dbg(p2p, "No common preferred channels found!");
 	}
 }
 
@@ -679,6 +646,8 @@
 	unsigned int freq_list[P2P_MAX_PREF_CHANNELS], size;
 	unsigned int i;
 	u8 op_class, op_channel;
+	char txt[100], *pos, *end;
+	int res;
 
 	/*
 	 * Use the preferred channel list from the driver only if there is no
@@ -694,6 +663,39 @@
 	if (p2p->cfg->get_pref_freq_list(p2p->cfg->cb_ctx, go, &size,
 					 freq_list))
 		return;
+	/* Filter out frequencies that are not acceptable for P2P use */
+	i = 0;
+	while (i < size) {
+		if (p2p_freq_to_channel(freq_list[i], &op_class,
+					&op_channel) < 0 ||
+		    (!p2p_channels_includes(&p2p->cfg->channels,
+					    op_class, op_channel) &&
+		     (go || !p2p_channels_includes(&p2p->cfg->cli_channels,
+						   op_class, op_channel)))) {
+			p2p_dbg(p2p,
+				"Ignore local driver frequency preference %u MHz since it is not acceptable for P2P use (go=%d)",
+				freq_list[i], go);
+			if (size - i - 1 > 0)
+				os_memmove(&freq_list[i], &freq_list[i + 1], size - i - 1);
+			size--;
+			continue;
+		}
+
+		/* Preferred frequency is acceptable for P2P use */
+		i++;
+	}
+
+	pos = txt;
+	end = pos + sizeof(txt);
+	for (i = 0; i < size; i++) {
+		res = os_snprintf(pos, end - pos, " %u", freq_list[i]);
+		if (os_snprintf_error(end - pos, res))
+			break;
+		pos += res;
+	}
+	*pos = '\0';
+	p2p_dbg(p2p, "Local driver frequency preference (size=%u):%s",
+		size, txt);
 
 	/*
 	 * Check if peer's preference of operating channel is in
@@ -703,20 +705,14 @@
 		if (freq_list[i] == (unsigned int) dev->oper_freq)
 			break;
 	}
-	if (i != size) {
+	if (i != size &&
+	    p2p_freq_to_channel(freq_list[i], &op_class, &op_channel) == 0) {
 		/* Peer operating channel preference matches our preference */
-		if (p2p_freq_to_channel(freq_list[i], &op_class, &op_channel) <
-		    0) {
-			p2p_dbg(p2p,
-				"Peer operating channel preference is unsupported frequency %u MHz",
-				freq_list[i]);
-		} else {
-			p2p->op_reg_class = op_class;
-			p2p->op_channel = op_channel;
-			os_memcpy(&p2p->channels, &p2p->cfg->channels,
-				  sizeof(struct p2p_channels));
-			return;
-		}
+		p2p->op_reg_class = op_class;
+		p2p->op_channel = op_channel;
+		os_memcpy(&p2p->channels, &p2p->cfg->channels,
+			  sizeof(struct p2p_channels));
+		return;
 	}
 
 	p2p_dbg(p2p,
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 47524d4..ce69932 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -553,6 +553,10 @@
 
 	unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS];
 	unsigned int num_pref_freq;
+
+	/* Override option for preferred operating channel in GO Negotiation */
+	u8 override_pref_op_class;
+	u8 override_pref_channel;
 };
 
 /**