qcacmn: Add API to get SNR value from scan entry

Add snr and avg_snr variables to scan entry and populate these variables
while generating the scan entry.
Add API to read avg_snr value from the scan entry.

Change-Id: Ie19d5ad7c8debb35e9d278ec648bd6217b2f4099
CRs-Fixed: 2532369
diff --git a/umac/scan/core/src/wlan_scan_cache_db.c b/umac/scan/core/src/wlan_scan_cache_db.c
index 20bfee9..f343343 100644
--- a/umac/scan/core/src/wlan_scan_cache_db.c
+++ b/umac/scan/core/src/wlan_scan_cache_db.c
@@ -567,29 +567,37 @@
 
 	/* Use old value for rssi if beacon was heard on adjacent channel. */
 	if (scan_params->channel_mismatch) {
+		scan_params->snr = scan_entry->snr;
+		scan_params->avg_snr = scan_entry->avg_snr;
 		scan_params->rssi_raw = scan_entry->rssi_raw;
 		scan_params->avg_rssi = scan_entry->avg_rssi;
 		scan_params->rssi_timestamp =
 			scan_entry->rssi_timestamp;
 	} else {
-		/* If elapsed time since last rssi update for this
+		/* If elapsed time since last rssi and snr update for this
 		 * entry is smaller than a thresold, calculate a
-		 * running average of the RSSI values.
-		 * Otherwise new frames RSSI is more representive
+		 * running average of the RSSI and SNR values.
+		 * Otherwise new frames RSSI and SNR are more representive
 		 * of the signal strength.
 		 */
 		time_gap =
 			scan_params->scan_entry_time -
 			scan_entry->rssi_timestamp;
-		if (time_gap > WLAN_RSSI_AVERAGING_TIME)
+		if (time_gap > WLAN_RSSI_AVERAGING_TIME) {
 			scan_params->avg_rssi =
 				WLAN_RSSI_IN(scan_params->rssi_raw);
+			scan_params->avg_snr =
+				WLAN_SNR_IN(scan_params->snr);
+		}
 		else {
-			/* Copy previous average rssi to new entry */
+			/* Copy previous average rssi and snr to new entry */
+			scan_params->avg_snr = scan_entry->avg_snr;
 			scan_params->avg_rssi = scan_entry->avg_rssi;
 			/* Average with previous samples */
 			WLAN_RSSI_LPF(scan_params->avg_rssi,
-					scan_params->rssi_raw);
+				      scan_params->rssi_raw);
+			WLAN_SNR_LPF(scan_params->avg_snr,
+				     scan_params->snr);
 		}
 
 		scan_params->rssi_timestamp = scan_params->scan_entry_time;
@@ -824,12 +832,13 @@
 			continue;
 		}
 
-		scm_nofl_debug("Received %s from BSSID: %pM tsf_delta = %u Seq Num: %d  ssid:%.*s, rssi: %d frequency %d pdev_id = %d",
+		scm_nofl_debug("Received %s from BSSID: %pM tsf_delta = %u Seq Num: %d  ssid:%.*s, rssi: %d snr = %d frequency %d pdev_id = %d",
 			       (bcn->frm_type == MGMT_SUBTYPE_PROBE_RESP) ?
 			       "Probe Rsp" : "Beacon", scan_entry->bssid.bytes,
 			       scan_entry->tsf_delta, scan_entry->seq_num,
 			       scan_entry->ssid.length, scan_entry->ssid.ssid,
 			       scan_entry->rssi_raw,
+			       scan_entry->snr,
 			       scan_entry->channel.chan_freq,
 			       wlan_objmgr_pdev_get_pdev_id(pdev));
 
diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h
index 171f7f5..74672ad 100644
--- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h
+++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h
@@ -287,8 +287,10 @@
  * @is_hidden_ssid: is AP having hidden ssid.
  * @seq_num: sequence number
  * @phy_mode: Phy mode of the AP
- * @avg_rssi: Average RSSI fof the AP
+ * @avg_rssi: Average RSSI of the AP
  * @rssi_raw: The rssi of the last beacon/probe received
+ * @snr: The snr of the last beacon/probe received
+ * @avg_snr: Average SNR of the AP
  * @bcn_int: Beacon interval of the AP
  * @cap_info: Capability of the AP
  * @tsf_info: TSF info
@@ -329,6 +331,8 @@
 	enum wlan_phymode phy_mode;
 	int32_t avg_rssi;
 	int8_t rssi_raw;
+	uint8_t snr;
+	uint32_t avg_snr;
 	uint16_t bcn_int;
 	union wlan_capability cap_info;
 	union {
diff --git a/umac/scan/dispatcher/inc/wlan_scan_utils_api.h b/umac/scan/dispatcher/inc/wlan_scan_utils_api.h
index 17b284d..301b42e 100644
--- a/umac/scan/dispatcher/inc/wlan_scan_utils_api.h
+++ b/umac/scan/dispatcher/inc/wlan_scan_utils_api.h
@@ -208,7 +208,7 @@
 
 #define WLAN_RSSI_EP_MULTIPLIER (1<<7)  /* pow2 to optimize out * and / */
 
-#define WLAN_RSSI_LPF_LEN       10
+#define WLAN_RSSI_LPF_LEN       0
 #define WLAN_RSSI_DUMMY_MARKER  0x127
 
 #define WLAN_EP_MUL(x, mul) ((x) * (mul))
@@ -231,7 +231,7 @@
 	((x != WLAN_RSSI_DUMMY_MARKER) ? ((((x) << 3) + (y) - (x)) >> 3) : (y))
 
 #define WLAN_RSSI_LPF(x, y) do { \
-	if ((y) >= RSSI_LPF_THRESHOLD) \
+	if ((y) < RSSI_LPF_THRESHOLD) \
 		x = WLAN_LPF_RSSI((x), WLAN_RSSI_IN((y)), WLAN_RSSI_LPF_LEN); \
 	} while (0)
 
@@ -240,6 +240,24 @@
 		x = WLAN_LPF_RSSI((x), WLAN_RSSI_IN((y)), WLAN_RSSI_LPF_LEN); \
 	} while (0)
 
+#define WLAN_SNR_EP_MULTIPLIER BIT(7) /* pow2 to optimize out * and / */
+#define WLAN_SNR_DUMMY_MARKER  0x127
+#define SNR_LPF_THRESHOLD      0
+#define WLAN_SNR_LPF_LEN       10
+
+#define WLAN_SNR_OUT(x) (((x) != WLAN_SNR_DUMMY_MARKER) ?     \
+	(WLAN_EP_RND((x), WLAN_SNR_EP_MULTIPLIER)) :  WLAN_SNR_DUMMY_MARKER)
+
+#define WLAN_SNR_IN(x)         (WLAN_EP_MUL((x), WLAN_SNR_EP_MULTIPLIER))
+
+#define WLAN_LPF_SNR(x, y, len) \
+	((x != WLAN_SNR_DUMMY_MARKER) ? ((((x) << 3) + (y) - (x)) >> 3) : (y))
+
+#define WLAN_SNR_LPF(x, y) do { \
+	if ((y) > SNR_LPF_THRESHOLD) \
+		x = WLAN_LPF_SNR((x), WLAN_SNR_IN((y)), WLAN_SNR_LPF_LEN); \
+	} while (0)
+
 /**
  * util_scan_entry_rssi() - function to read rssi of scan entry
  * @scan_entry: scan entry
@@ -265,6 +283,29 @@
 }
 
 /**
+ * util_scan_entry_snr() - function to read snr of scan entry
+ * @scan_entry: scan entry
+ *
+ * API, function to read snr value of scan entry
+ *
+ * Return: snr
+ */
+static inline uint8_t
+util_scan_entry_snr(struct scan_cache_entry *scan_entry)
+{
+	uint32_t snr = WLAN_SNR_OUT(scan_entry->avg_snr);
+	/*
+	 * An entry is in the BSS list means we've received at least one beacon
+	 * from the corresponding AP, so the snr must be initialized.
+	 *
+	 * If the SNR is not initialized, return 0 (i.e. SNR == Noise Floor).
+	 * Once se_avgsnr field has been initialized, ATH_SNR_OUT always
+	 * returns values that fit in an 8-bit variable.
+	 */
+	return (snr >= WLAN_SNR_DUMMY_MARKER) ? 0 : (uint8_t)snr;
+}
+
+/**
  * util_scan_entry_phymode() - function to read phymode of scan entry
  * @scan_entry: scan entry
  *
diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c
index 9748371..cc5bb96 100644
--- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c
+++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c
@@ -1077,6 +1077,8 @@
 	scan_entry->seq_num =
 		(le16toh(*(uint16_t *)hdr->i_seq) >> WLAN_SEQ_SEQ_SHIFT);
 
+	scan_entry->snr = rx_param->snr;
+	scan_entry->avg_snr = WLAN_SNR_IN(scan_entry->snr);
 	scan_entry->rssi_raw = rx_param->rssi;
 	scan_entry->avg_rssi = WLAN_RSSI_IN(scan_entry->rssi_raw);
 	scan_entry->tsf_delta = rx_param->tsf_delta;