Browse Source

qcacmn: Add host support for db2dbm RSSI changes

Add host support for db2dbm RSSI changes. Firmware
indicates this capability when underlying hardware
has RSSI reporting feature. Based on this capability
host will know if firmware sends SNR or RSSI. If no
capablity is present then host will convert SNR to
rssi using a fixed offset of -96. If capability is
present host will directly use the rssi as it is.

Change-Id: I9058f16c6280d466feb96cf88a8a0d8cd7b02032
CRs-Fixed: 2364025
Yeshwanth Sriram Guntuka 6 years ago
parent
commit
c4a14ea149

+ 2 - 2
os_if/linux/scan/inc/wlan_cfg80211_scan.h

@@ -138,7 +138,7 @@ struct scan_params {
  * @frame_len: frame length
  * @rssi: signal strength in mBm (100*dBm)
  * @boottime_ns: timestamp (CLOCK_BOOTTIME) when the information was received.
- * @per_chain_snr: per chain snr received
+ * @per_chain_rssi: per chain rssi received
  */
 struct wlan_cfg80211_inform_bss {
 	struct ieee80211_channel *chan;
@@ -146,7 +146,7 @@ struct wlan_cfg80211_inform_bss {
 	size_t frame_len;
 	int rssi;
 	uint64_t boottime_ns;
-	uint8_t per_chain_snr[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
+	uint8_t per_chain_rssi[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
 };
 
 

+ 4 - 6
os_if/linux/scan/src/wlan_cfg80211_scan.c

@@ -1648,12 +1648,10 @@ static void wlan_fill_per_chain_rssi(struct cfg80211_inform_bss *data,
 		return;
 	}
 	for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) {
-		if (!bss->per_chain_snr[i] ||
-		    (bss->per_chain_snr[i] == WLAN_INVALID_PER_CHAIN_RSSI))
+		if (!bss->per_chain_rssi[i] ||
+		    (bss->per_chain_rssi[i] == WLAN_INVALID_PER_CHAIN_RSSI))
 			continue;
-		/* Add noise margin to SNR to convert it to RSSI */
-		data->chain_signal[i] = bss->per_chain_snr[i] +
-					WLAN_NOISE_FLOOR_DBM_DEFAULT;
+		data->chain_signal[i] = bss->per_chain_rssi[i];
 		data->chains |= BIT(i);
 	}
 }
@@ -1760,7 +1758,7 @@ void wlan_cfg80211_inform_bss_frame(struct wlan_objmgr_pdev *pdev,
 
 	bss_data.boottime_ns = scan_params->boottime_ns;
 
-	qdf_mem_copy(bss_data.per_chain_snr, scan_params->per_chain_snr,
+	qdf_mem_copy(bss_data.per_chain_rssi, scan_params->per_chain_rssi,
 		     WLAN_MGMT_TXRX_HOST_MAX_ANTENNA);
 
 	cfg80211_debug("BSSID: %pM Channel:%d RSSI:%d", bss_data.mgmt->bssid,

+ 24 - 36
target_if/cp_stats/src/target_if_mc_cp_stats.c

@@ -33,11 +33,7 @@
 #include <wlan_osif_priv.h>
 #include <wlan_cp_stats_utils_api.h>
 #include <wlan_cp_stats_mc_tgt_api.h>
-
-#define TGT_INVALID_SNR         (0)
-#define TGT_NOISE_FLOOR_DBM     (-96)
-#define TGT_MAX_SNR             (TGT_NOISE_FLOOR_DBM * (-1))
-#define TGT_IS_VALID_SNR(x)     ((x) >= 0 && (x) < TGT_MAX_SNR)
+#include "../../../umac/cmn_services/utils/inc/wlan_utility.h"
 
 static void target_if_cp_stats_free_stats_event(struct stats_event *ev)
 {
@@ -99,6 +95,7 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats(
 	uint32_t i;
 	QDF_STATUS status;
 	wmi_host_peer_stats peer_stats;
+	bool db2dbm_enabled;
 
 	ev->num_peer_stats = stats_param->num_peer_stats;
 	if (!ev->num_peer_stats)
@@ -111,6 +108,8 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats(
 		return QDF_STATUS_E_NOMEM;
 	}
 
+	db2dbm_enabled = wmi_service_enabled(wmi_hdl,
+					     wmi_service_hw_db2dbm_support);
 	for (i = 0; i < ev->num_peer_stats; i++) {
 		status = wmi_extract_peer_stats(wmi_hdl, data, i, &peer_stats);
 		if (QDF_IS_STATUS_ERROR(status)) {
@@ -121,8 +120,11 @@ static QDF_STATUS target_if_cp_stats_extract_peer_stats(
 						ev->peer_stats[i].peer_macaddr);
 		ev->peer_stats[i].tx_rate = peer_stats.peer_tx_rate;
 		ev->peer_stats[i].rx_rate = peer_stats.peer_rx_rate;
-		ev->peer_stats[i].peer_rssi = peer_stats.peer_rssi +
-						TGT_NOISE_FLOOR_DBM;
+		if (db2dbm_enabled)
+			ev->peer_stats[i].peer_rssi = peer_stats.peer_rssi;
+		else
+			ev->peer_stats[i].peer_rssi = peer_stats.peer_rssi +
+							TGT_NOISE_FLOOR_DBM;
 	}
 
 	return QDF_STATUS_SUCCESS;
@@ -164,6 +166,7 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_summary_stats(
 	QDF_STATUS status;
 	int32_t bcn_snr, dat_snr;
 	wmi_host_vdev_stats vdev_stats;
+	bool db2dbm_enabled;
 
 	ev->num_summary_stats = stats_param->num_vdev_stats;
 	if (!ev->num_summary_stats)
@@ -177,6 +180,8 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_summary_stats(
 		return QDF_STATUS_E_NOMEM;
 	}
 
+	db2dbm_enabled = wmi_service_enabled(wmi_hdl,
+					     wmi_service_hw_db2dbm_support);
 	for (i = 0; i < ev->num_summary_stats; i++) {
 		status = wmi_extract_vdev_stats(wmi_hdl, data, i, &vdev_stats);
 		if (QDF_IS_STATUS_ERROR(status))
@@ -208,18 +213,11 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_summary_stats(
 		ev->vdev_summary_stats[i].stats.rts_fail_cnt =
 						vdev_stats.rts_fail_cnt;
 		/* Update SNR and RSSI in SummaryStats */
-		if (TGT_IS_VALID_SNR(bcn_snr)) {
-			ev->vdev_summary_stats[i].stats.snr = bcn_snr;
-			ev->vdev_summary_stats[i].stats.rssi =
-						bcn_snr + TGT_NOISE_FLOOR_DBM;
-		} else if (TGT_IS_VALID_SNR(dat_snr)) {
-			ev->vdev_summary_stats[i].stats.snr = dat_snr;
-			ev->vdev_summary_stats[i].stats.rssi =
-						dat_snr + TGT_NOISE_FLOOR_DBM;
-		} else {
-			ev->vdev_summary_stats[i].stats.snr = TGT_INVALID_SNR;
-			ev->vdev_summary_stats[i].stats.rssi = 0;
-		}
+		wlan_util_stats_get_rssi(db2dbm_enabled, bcn_snr, dat_snr,
+					 &ev->vdev_summary_stats[i].stats.rssi);
+		ev->vdev_summary_stats[i].stats.snr =
+				ev->vdev_summary_stats[i].stats.rssi -
+				TGT_NOISE_FLOOR_DBM;
 	}
 
 	return QDF_STATUS_SUCCESS;
@@ -235,6 +233,7 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_chain_rssi_stats(
 	QDF_STATUS status;
 	int32_t bcn_snr, dat_snr;
 	struct wmi_host_per_chain_rssi_stats rssi_stats;
+	bool db2dbm_enabled;
 
 	ev->num_chain_rssi_stats = stats_param->num_rssi_stats;
 	if (!ev->num_chain_rssi_stats)
@@ -246,7 +245,8 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_chain_rssi_stats(
 		cp_stats_err("malloc failed");
 		return QDF_STATUS_E_NOMEM;
 	}
-
+	db2dbm_enabled = wmi_service_enabled(wmi_hdl,
+					     wmi_service_hw_db2dbm_support);
 	for (i = 0; i < ev->num_chain_rssi_stats; i++) {
 		status = wmi_extract_per_chain_rssi_stats(wmi_hdl, data, i,
 							  &rssi_stats);
@@ -258,27 +258,15 @@ static QDF_STATUS target_if_cp_stats_extract_vdev_chain_rssi_stats(
 			bcn_snr = rssi_stats.rssi_avg_beacon[j];
 			cp_stats_err("Chain %d SNR bcn: %d data: %d", j,
 				     bcn_snr, dat_snr);
-			if (TGT_IS_VALID_SNR(bcn_snr))
-				ev->vdev_chain_rssi[i].chain_rssi[j] = bcn_snr;
-			else if (TGT_IS_VALID_SNR(dat_snr))
-				ev->vdev_chain_rssi[i].chain_rssi[j] = dat_snr;
-			else
-				/*
-				 * Firmware sends invalid snr till it sees
-				 * Beacon/Data after connection since after
-				 * vdev up fw resets the snr to invalid. In this
-				 * duartion Host will return an invalid rssi
-				 * value.
-				 */
-				ev->vdev_chain_rssi[i].chain_rssi[j] =
-							TGT_INVALID_SNR;
 			/*
 			 * Get the absolute rssi value from the current rssi
 			 * value the snr value is hardcoded into 0 in the
 			 * qcacld-new/CORE stack
 			 */
-			ev->vdev_chain_rssi[i].chain_rssi[j] +=
-							TGT_NOISE_FLOOR_DBM;
+			wlan_util_stats_get_rssi(db2dbm_enabled, bcn_snr,
+						 dat_snr,
+						 &ev->vdev_chain_rssi[i].
+						 chain_rssi[j]);
 		}
 	}
 

+ 3 - 0
target_if/init_deinit/src/init_cmd_api.c

@@ -495,4 +495,7 @@ void init_deinit_prepare_send_init_cmd(
 	/* Set Max scans allowed */
 	target_if_scan_set_max_active_scans(psoc,
 					    WLAN_MAX_ACTIVE_SCANS_ALLOWED);
+
+	if (wmi_service_enabled(wmi_handle, wmi_service_hw_db2dbm_support))
+		wlan_psoc_nif_fw_ext_cap_set(psoc, WLAN_SOC_CEXT_HW_DB2DBM);
 }

+ 2 - 1
umac/cmn_services/mgmt_txrx/dispatcher/inc/wlan_mgmt_txrx_utils_api.h

@@ -652,7 +652,8 @@ enum mgmt_frame_type {
 };
 
 #define WLAN_MGMT_TXRX_HOST_MAX_ANTENNA          4
-#define WLAN_INVALID_PER_CHAIN_RSSI             0x80
+#define WLAN_INVALID_PER_CHAIN_RSSI             0xFF
+#define WLAN_INVALID_PER_CHAIN_SNR              0x80
 #define WLAN_NOISE_FLOOR_DBM_DEFAULT            -96
 /**
  * struct mgmt_rx_event_params - host mgmt header params

+ 2 - 0
umac/cmn_services/obj_mgr/inc/wlan_objmgr_psoc_obj.h

@@ -125,6 +125,8 @@
 #define WLAN_SOC_CEXT_TWT_REQUESTER    0x00002000
 	/* TWT Responder capable */
 #define WLAN_SOC_CEXT_TWT_RESPONDER    0x00004000
+	/* HW DB2DBM CAPABLE */
+#define WLAN_SOC_CEXT_HW_DB2DBM        0x00008000
 
 /* feature_flags */
 	/* CONF: ATH FF enabled */

+ 24 - 0
umac/cmn_services/utils/inc/wlan_utility.h

@@ -28,6 +28,12 @@
 #include <wlan_objmgr_pdev_obj.h>
 #include <wlan_objmgr_vdev_obj.h>
 
+#define TGT_INVALID_SNR         (0)
+#define TGT_MAX_SNR             (TGT_NOISE_FLOOR_DBM * (-1))
+#define TGT_NOISE_FLOOR_DBM     (-96)
+#define TGT_IS_VALID_SNR(x)     ((x) >= 0 && (x) < TGT_MAX_SNR)
+#define TGT_IS_VALID_RSSI(x)    ((x) != 0xFF)
+
 /**
  * struct wlan_find_vdev_filter - find vdev filter object. this can be extended
  * @ifname:           interface name of vdev
@@ -261,4 +267,22 @@ QDF_STATUS wlan_pdev_chan_change_pending_vdevs(struct wlan_objmgr_pdev *pdev,
  */
 QDF_STATUS wlan_chan_eq(struct wlan_channel *chan1, struct wlan_channel *chan2);
 
+/**
+ * wlan_util_stats_get_rssi() - API to get rssi in dbm
+ * @db2dbm_enabled: If db2dbm capability is enabled
+ * @bcn_snr: beacon snr
+ * @dat_snr: data snr
+ * @rssi: rssi
+ *
+ * This function gets the rssi based on db2dbm support. If this feature is
+ * present in hw then it means firmware directly sends rssi and no converstion
+ * is required. If this capablity is not present then host needs to convert
+ * snr to rssi
+ *
+ * Return: None
+ */
+void
+wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr,
+			 int8_t *rssi);
+
 #endif /* _WLAN_UTILITY_H_ */

+ 26 - 0
umac/cmn_services/utils/src/wlan_utility.c

@@ -463,3 +463,29 @@ QDF_STATUS wlan_util_pdev_vdevs_deschan_match(struct wlan_objmgr_pdev *pdev,
 	return QDF_STATUS_E_FAILURE;
 }
 #endif
+
+void
+wlan_util_stats_get_rssi(bool db2dbm_enabled, int32_t bcn_snr, int32_t dat_snr,
+			 int8_t *rssi)
+{
+	uint32_t snr;
+
+	if (db2dbm_enabled) {
+		if (TGT_IS_VALID_RSSI(bcn_snr))
+			*rssi = bcn_snr;
+		else if (TGT_IS_VALID_RSSI(dat_snr))
+			*rssi = dat_snr;
+		else
+			*rssi = TGT_NOISE_FLOOR_DBM;
+	} else {
+		if (TGT_IS_VALID_SNR(bcn_snr))
+			snr = bcn_snr;
+		else if (TGT_IS_VALID_SNR(dat_snr))
+			snr = dat_snr;
+		else
+			snr = TGT_INVALID_SNR;
+
+		/* Get the absolute rssi value from the current rssi value */
+		*rssi = snr + TGT_NOISE_FLOOR_DBM;
+	}
+}

+ 2 - 2
umac/cp_stats/dispatcher/inc/wlan_cp_stats_mc_defs.h

@@ -204,7 +204,7 @@ struct pdev_mc_cp_stats {
  */
 struct summary_stats {
 	uint32_t snr;
-	uint32_t rssi;
+	int8_t rssi;
 	uint32_t retry_cnt[4];
 	uint32_t multiple_retry_cnt[4];
 	uint32_t tx_frm_cnt[4];
@@ -244,7 +244,7 @@ struct vdev_mc_cp_stats {
 struct peer_mc_cp_stats {
 	uint32_t tx_rate;
 	uint32_t rx_rate;
-	uint32_t peer_rssi;
+	int8_t peer_rssi;
 	uint8_t peer_macaddr[WLAN_MACADDR_LEN];
 };
 

+ 2 - 2
umac/scan/dispatcher/inc/wlan_scan_public_structs.h

@@ -296,7 +296,7 @@ struct security_info {
  * @tsf_delta: TSF delta
  * @bss_score: bss score calculated on basis of RSSI/caps etc.
  * @neg_sec_info: negotiated security info
- * @per_chain_snr: per chain SNR value received.
+ * @per_chain_rssi: per chain RSSI value received.
  * boottime_ns: boottime in ns.
  * @rrm_parent_tsf: RRM parent tsf
  * @mlme_info: Mlme info, this will be updated by MLME for the scan entry
@@ -334,7 +334,7 @@ struct scan_cache_entry {
 	uint32_t tsf_delta;
 	uint32_t bss_score;
 	struct security_info neg_sec_info;
-	uint8_t per_chain_snr[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
+	uint8_t per_chain_rssi[WLAN_MGMT_TXRX_HOST_MAX_ANTENNA];
 	uint64_t boottime_ns;
 	uint32_t rrm_parent_tsf;
 	struct element_info alt_wcn_ie;

+ 15 - 1
umac/scan/dispatcher/src/wlan_scan_utils_api.c

@@ -985,6 +985,7 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev,
 	struct scan_cache_entry *scan_entry;
 	struct qbss_load_ie *qbss_load;
 	struct scan_cache_node *scan_node;
+	uint8_t i;
 
 	scan_entry = qdf_mem_malloc_atomic(sizeof(*scan_entry));
 	if (!scan_entry) {
@@ -1020,9 +1021,22 @@ util_scan_gen_scan_entry(struct wlan_objmgr_pdev *pdev,
 	scan_entry->tsf_delta = rx_param->tsf_delta;
 
 	/* Copy per chain rssi to scan entry */
-	qdf_mem_copy(scan_entry->per_chain_snr, rx_param->rssi_ctl,
+	qdf_mem_copy(scan_entry->per_chain_rssi, rx_param->rssi_ctl,
 		     WLAN_MGMT_TXRX_HOST_MAX_ANTENNA);
 
+	if (!wlan_psoc_nif_fw_ext_cap_get(wlan_pdev_get_psoc(pdev),
+					  WLAN_SOC_CEXT_HW_DB2DBM)) {
+		for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++) {
+			if (scan_entry->per_chain_rssi[i] !=
+			    WLAN_INVALID_PER_CHAIN_SNR)
+				scan_entry->per_chain_rssi[i] +=
+						WLAN_NOISE_FLOOR_DBM_DEFAULT;
+			else
+				scan_entry->per_chain_rssi[i] =
+						WLAN_INVALID_PER_CHAIN_RSSI;
+		}
+	}
+
 	/* store jiffies */
 	scan_entry->rrm_parent_tsf = (uint32_t)qdf_system_ticks();
 

+ 2 - 1
wmi/inc/wmi_unified_param.h

@@ -4569,7 +4569,7 @@ struct wmi_host_per_chain_rssi_stats {
  */
 typedef struct {
 	wmi_host_mac_addr peer_macaddr;
-	uint32_t  peer_rssi;
+	int8_t  peer_rssi;
 	uint32_t  peer_rssi_seq_num;
 	uint32_t  peer_tx_rate;
 	uint32_t  peer_rx_rate;
@@ -5274,6 +5274,7 @@ typedef enum {
 	wmi_service_nan_sap_support,
 	wmi_service_ndi_sap_support,
 	wmi_service_nan_disable_support,
+	wmi_service_hw_db2dbm_support,
 	wmi_services_max,
 } wmi_conv_service_ids;
 #define WMI_SERVICE_UNAVAILABLE 0xFFFF

+ 2 - 0
wmi/src/wmi_unified_tlv.c

@@ -11974,6 +11974,8 @@ static void populate_tlv_service(uint32_t *wmi_service)
 	wmi_service[wmi_service_ndi_sap_support] = WMI_SERVICE_NDI_SAP_SUPPORT;
 	wmi_service[wmi_service_nan_disable_support] =
 			WMI_SERVICE_NAN_DISABLE_SUPPORT;
+	wmi_service[wmi_service_hw_db2dbm_support] =
+			WMI_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT;
 }
 #ifndef CONFIG_MCL