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;