qcacmn: FILS changes for scan path

Add changes to match FILS realm info present in FILS indication IE
with the connection info.

Change-Id: I1ed6081f3320ecee8f86f7d87597b343230923b3
CRs-Fixed: 2093637
diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
index 9cb76ea..da7c4da 100644
--- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
+++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h
@@ -369,6 +369,10 @@
 #define WLAN_AKM_FT_PSK           0x04
 #define WLAN_AKM_SHA256_IEEE8021X 0x05
 #define WLAN_AKM_SHA256_PSK       0x06
+#define WLAN_AKM_FILS_SHA256      0x0E
+#define WLAN_AKM_FILS_SHA384      0x0F
+#define WLAN_AKM_FILS_FT_SHA256   0x10
+#define WLAN_AKM_FILS_FT_SHA384   0x11
 
 #define WLAN_ASE_NONE                    0x00
 #define WLAN_ASE_8021X_UNSPEC            0x01
@@ -610,6 +614,35 @@
 	struct htcap_cmn_ie ie;
 } qdf_packed;
 
+/**
+ * struct fils_indication_ie: FILS indication IE element
+ * @id: id
+ * @len: len
+ * @public_key_identifiers_cnt: public key identifiers count
+ * @realm_identifiers_cnt: realm identifiers count
+ * @is_ip_config_supported: whether ip config is supported in AP
+ * @is_cache_id_present: whether cache identifier is present
+ * @is_hessid_present: whether hessid is present
+ * @is_fils_sk_auth_supported: FILS shared key authentication is supported
+ * @is_fils_sk_auth_pfs_supported: FILS shared key auth with PFS is supported
+ * @is_pk_auth_supported: FILS public key authentication is supported
+ * @reserved: reserved
+ * @variable_data: pointer to data depends on initial variables
+ */
+struct fils_indication_ie {
+	uint8_t id;
+	uint8_t len;
+	uint16_t public_key_identifiers_cnt:3;
+	uint16_t realm_identifiers_cnt:3;
+	uint16_t is_ip_config_supported:1;
+	uint16_t is_cache_id_present:1;
+	uint16_t is_hessid_present:1;
+	uint16_t is_fils_sk_auth_supported:1;
+	uint16_t is_fils_sk_auth_pfs_supported:1;
+	uint16_t is_pk_auth_supported:1;
+	uint16_t reserved:4;
+	uint8_t variable_data[255];
+} qdf_packed;
 
 /**
  * struct wlan_vendor_ie_htcap: vendor private HT Capability IE
diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h
index 0ad8f07..9a37679 100644
--- a/umac/cmn_services/inc/wlan_cmn.h
+++ b/umac/cmn_services/inc/wlan_cmn.h
@@ -282,6 +282,10 @@
  * @WLAN_AUTH_TYPE_CCKM_RSN: CCKM RSN
  * @WLAN_AUTH_TYPE_RSN_PSK_SHA256: SHA256 PSK
  * @WLAN_AUTH_TYPE_RSN_8021X_SHA256: SHA256 Enterprise
+ * @WLAN_AUTH_TYPE_FILS_SHA256: FILS SHA256
+ * @WLAN_AUTH_TYPE_FILS_SHA384: FILS SHA384
+ * @WLAN_AUTH_TYPE_FT_FILS_SHA256: FILS SHA256 for 11r
+ * @WLAN_AUTH_TYPE_FT_FILS_SHA384: FILS SHA384 for 11r
  * @WLAN_NUM_OF_SUPPORT_AUTH_TYPE: Max no of Auth type
  */
 enum wlan_auth_type {
@@ -301,6 +305,11 @@
 	WLAN_AUTH_TYPE_CCKM_RSN,
 	WLAN_AUTH_TYPE_RSN_PSK_SHA256,
 	WLAN_AUTH_TYPE_RSN_8021X_SHA256,
+	WLAN_AUTH_TYPE_FILS_SHA256,
+	WLAN_AUTH_TYPE_FILS_SHA384,
+	WLAN_AUTH_TYPE_FT_FILS_SHA256,
+	WLAN_AUTH_TYPE_FT_FILS_SHA384,
+
 	WLAN_NUM_OF_SUPPORT_AUTH_TYPE,
 };
 
diff --git a/umac/scan/core/src/wlan_scan_cache_db_ops.c b/umac/scan/core/src/wlan_scan_cache_db_ops.c
index c08ea0e..055bd56 100644
--- a/umac/scan/core/src/wlan_scan_cache_db_ops.c
+++ b/umac/scan/core/src/wlan_scan_cache_db_ops.c
@@ -600,6 +600,46 @@
 		 */
 		if (scm_is_cipher_match(rsn.akm_suites,
 		   rsn.akm_suite_count,
+		   WLAN_RSN_SEL(WLAN_AKM_FILS_FT_SHA384))) {
+			if (WLAN_AUTH_TYPE_FT_FILS_SHA384 ==
+			   filter->auth_type[i]) {
+				neg_auth = WLAN_AUTH_TYPE_FT_FILS_SHA384;
+				match = true;
+				break;
+			}
+		}
+		if (scm_is_cipher_match(rsn.akm_suites,
+		   rsn.akm_suite_count,
+		   WLAN_RSN_SEL(WLAN_AKM_FILS_FT_SHA256))) {
+			if (WLAN_AUTH_TYPE_FT_FILS_SHA256 ==
+			   filter->auth_type[i]) {
+				neg_auth = WLAN_AUTH_TYPE_FT_FILS_SHA256;
+				match = true;
+				break;
+			}
+		}
+		if (scm_is_cipher_match(rsn.akm_suites,
+		   rsn.akm_suite_count,
+		   WLAN_RSN_SEL(WLAN_AKM_FILS_SHA384))) {
+			if (WLAN_AUTH_TYPE_FILS_SHA384 ==
+			   filter->auth_type[i]) {
+				neg_auth = WLAN_AUTH_TYPE_FILS_SHA384;
+				match = true;
+				break;
+			}
+		}
+		if (scm_is_cipher_match(rsn.akm_suites,
+		   rsn.akm_suite_count,
+		   WLAN_RSN_SEL(WLAN_AKM_FILS_SHA256))) {
+			if (WLAN_AUTH_TYPE_FILS_SHA256 ==
+			   filter->auth_type[i]) {
+				neg_auth = WLAN_AUTH_TYPE_FILS_SHA256;
+				match = true;
+				break;
+			}
+		}
+		if (scm_is_cipher_match(rsn.akm_suites,
+		   rsn.akm_suite_count,
 		   WLAN_RSN_SEL(WLAN_AKM_FT_IEEE8021X))) {
 			if (WLAN_AUTH_TYPE_FT_RSN ==
 			   filter->auth_type[i]) {
@@ -920,6 +960,51 @@
 }
 
 /**
+ * scm_is_fils_config_match() - Check if FILS config matches
+ * @filter: scan filter
+ * @db_entry: db entry
+ *
+ * Return: true if FILS config matches else false
+ */
+static bool scm_is_fils_config_match(struct scan_filter *filter,
+	struct scan_cache_entry *db_entry)
+{
+	int i;
+	struct fils_indication_ie *indication_ie;
+	uint8_t *data;
+
+	if (!filter->fils_scan_filter.realm_check)
+		return true;
+
+	if (!db_entry->ie_list.fils_indication)
+		return false;
+
+
+	indication_ie =
+		(struct fils_indication_ie *) db_entry->ie_list.fils_indication;
+
+	data = indication_ie->variable_data;
+	if (indication_ie->is_cache_id_present)
+		data += CACHE_IDENTIFIER_LEN;
+
+	if (indication_ie->is_hessid_present)
+		data += HESSID_LEN;
+
+	for (i = 1; i <= indication_ie->realm_identifiers_cnt; i++) {
+		if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm,
+				 data, REAM_HASH_LEN))
+			return true;
+		/* Max realm count reached */
+		if (indication_ie->realm_identifiers_cnt == i)
+			break;
+		else
+			data = data + REAM_HASH_LEN;
+	}
+
+	return false;
+}
+
+/**
  * scm_is_security_match() - Check if security in filter match
  * @filter: scan filter
  * @db_entry: db entry
@@ -1068,6 +1153,10 @@
 	   !db_entry->ie_list.wmeparam)
 		return false;
 
+	/* Match realm */
+	if (!scm_is_fils_config_match(filter, db_entry))
+		return false;
+
 	if (!util_country_code_match(filter->country,
 	   db_entry->ie_list.country))
 		return false;
diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h
index e0c71bf..70e7522 100644
--- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h
+++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h
@@ -337,6 +337,22 @@
 #define WLAN_SCAN_FILTER_NUM_SSID 5
 #define WLAN_SCAN_FILTER_NUM_BSSID 5
 
+#define REAM_HASH_LEN 2
+#define CACHE_IDENTIFIER_LEN 2
+#define HESSID_LEN 6
+
+/**
+ * struct fils_filter_info: FILS info present in scan filter
+ * @realm_check: whether realm check is required
+ * @fils_realm: realm hash value
+ * @security_type: type of security supported
+ */
+struct fils_filter_info {
+	bool realm_check;
+	uint8_t fils_realm[REAM_HASH_LEN];
+	uint8_t security_type;
+};
+
 /**
  * @age_threshold: If set return entry which are newer than the age_threshold
  * @p2p_results: If only p2p entries is required
@@ -368,6 +384,7 @@
  * @enc_type: unicast enc type list
  * @mc_enc_type: multicast cast enc type list
  * @pcl_channel_list: PCL channel list
+ * @fils_scan_filter: FILS info
  */
 struct scan_filter {
 	uint32_t age_threshold;
@@ -397,6 +414,7 @@
 	enum wlan_enc_type enc_type[WLAN_NUM_OF_ENCRYPT_TYPE];
 	enum wlan_enc_type mc_enc_type[WLAN_NUM_OF_ENCRYPT_TYPE];
 	uint8_t pcl_channel_list[QDF_MAX_NUM_CHAN];
+	struct fils_filter_info fils_scan_filter;
 };