Browse Source

qcacld-3.0: Optionally report raw rssi value to supplicant

qcacld-2.0 to qcacld-3.0 propagation

Add raw rssi in the beacon header from WMI to beacon descriptor.
Pass it up to SME and report it to supplicant through a call to
wlan_hdd_cfg80211_inform_bss_frame().
It can be enabled as a .ini configuration parameter "gInformBssRssiRaw".
Default is 1, it will report raw rssi by default.
Roaming decisions are based on rssi field of beacon descriptor,
its interpretation and usage are unchanged.

CRs-Fixed: 815344
Change-Id: I6dacdc0b333c093d16a74f8cf36471dfc183ce56
Deepak Dhamdhere 9 years ago
parent
commit
68929ec509

+ 23 - 1
core/cds/src/i_cds_packet.h

@@ -42,8 +42,29 @@
    Include Files
    ------------------------------------------------------------------------*/
 #include "cdf_types.h"
-/*
+/**
  * Rx Packet Struct
+ * Buffer for the packet received from WMA has pointers to 802.11
+ * frame fields and additional information based on the type of frame.
+ * @channel: Channel number
+ * @snr: Signal to noise ratio
+ * @rssi: Received signal strength indicator, normalized to -96 dBm as
+ *        normal noise floor by adding -96 to snr. All the configured
+ *        thresholds in the driver assume that noise floor is -96 dBm.
+ * @timestamp: System timestamp when frame was received. Set to jiffies.
+ * @mpdu_hdr_ptr: Pointer to beginning of 802.11 MPDU
+ * @mpdu_data_ptr: Pointer to beginning of payload
+ * @mpdu_len: Length of 802.11 MPDU
+ * @mpdu_hdr_len: Length of 802.11 MPDU header
+ * @mpdu_data_len: Length of 802.11 MPDU payload
+ * @offloadScanLearn: Bit set to 1 for beacons received during roaming scan
+ * @roamCandidateInd: Bit set to 1 when roaming candidate is found by fw
+ * @scan: Bit set to 1 if packet received during scanning
+ * @scan_src: Source of scan
+ * @dpuFeedback: DPU feedback for frame
+ * @sessionId: PE session
+ * @tsf_delta: Delta between tsf in frame and local value of tsf
+ * @rssi_raw: rssi based on actual noise floor in hardware.
  */
 typedef struct {
 	uint8_t channel;
@@ -62,6 +83,7 @@ typedef struct {
 	uint8_t dpuFeedback;
 	uint8_t sessionId;
 	uint32_t tsf_delta;
+	uint32_t rssi_raw;
 } t_packetmeta, *tp_packetmeta;
 
 /* implementation specific cds packet type */

+ 10 - 1
core/hdd/inc/wlan_hdd_cfg.h

@@ -2853,6 +2853,14 @@ enum dot11p_mode {
 #define CFG_ENABLE_LFR_SUBNET_MAX          (1)
 #define CFG_ENABLE_LFR_SUBNET_DEFAULT      (1)
 #endif /* FEATURE_LFR_SUBNET_DETECTION */
+/* Option to report rssi in cfg80211_inform_bss_frame()
+ * 0 = use rssi value based on noise floor = -96 dBm
+ * 1 = use rssi value based on actual noise floor in hardware
+ */
+#define CFG_INFORM_BSS_RSSI_RAW_NAME               "gInformBssRssiRaw"
+#define CFG_INFORM_BSS_RSSI_RAW_MIN                (0)
+#define CFG_INFORM_BSS_RSSI_RAW_MAX                (1)
+#define CFG_INFORM_BSS_RSSI_RAW_DEFAULT            (1)
 
 /*---------------------------------------------------------------------------
    Type declarations
@@ -3441,6 +3449,7 @@ struct hdd_config {
 #ifdef FEATURE_LFR_SUBNET_DETECTION
 	bool enable_lfr_subnet_detection;
 #endif
+	uint8_t inform_bss_rssi_raw;
 };
 
 #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var))
@@ -3530,7 +3539,7 @@ typedef enum {
 typedef struct tREG_TABLE_ENTRY {
 
 	char *RegName;          /* variable name in the qcom_cfg.ini file */
-	WLAN_PARAMETER_TYPE RegType;    /* variable type in the hdd_config_t structure */
+	WLAN_PARAMETER_TYPE RegType;    /* variable type in hdd_config struct */
 	unsigned long Flags;    /* Specify optional parms and if RangeCheck is performed */
 	unsigned short VarOffset;       /* offset to field from the base address of the structure */
 	unsigned short VarSize; /* size (in bytes) of the field */

+ 7 - 0
core/hdd/src/wlan_hdd_cfg.c

@@ -3666,6 +3666,13 @@ REG_TABLE_ENTRY g_registry_table[] = {
 		     CFG_ENABLE_LFR_SUBNET_MIN,
 		     CFG_ENABLE_LFR_SUBNET_MAX),
 #endif
+
+	REG_VARIABLE(CFG_INFORM_BSS_RSSI_RAW_NAME, WLAN_PARAM_Integer,
+		struct hdd_config, inform_bss_rssi_raw,
+		VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		CFG_INFORM_BSS_RSSI_RAW_DEFAULT,
+		CFG_INFORM_BSS_RSSI_RAW_MIN,
+		CFG_INFORM_BSS_RSSI_RAW_MAX),
 };
 
 

+ 10 - 1
core/hdd/src/wlan_hdd_cfg80211.c

@@ -7307,6 +7307,7 @@ wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter,
 #ifdef CONFIG_CNSS
 	struct timespec ts;
 #endif
+	struct hdd_config *cfg_param;
 
 	ENTER();
 
@@ -7315,6 +7316,7 @@ wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter,
 	if (0 != status)
 		return NULL;
 
+	cfg_param = pHddCtx->config;
 	mgmt = kzalloc((sizeof(struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
 	if (!mgmt) {
 		hddLog(LOGE, FL("memory allocation failed"));
@@ -7408,8 +7410,15 @@ wlan_hdd_cfg80211_inform_bss_frame(hdd_adapter_t *pAdapter,
 		return NULL;
 	}
 
+	/* Based on .ini configuration, raw rssi can be reported for bss.
+	 * Raw rssi is typically used for estimating power.
+	 */
+
+	rssi = (cfg_param->inform_bss_rssi_raw) ? bss_desc->rssi_raw :
+			bss_desc->rssi;
+
 	/* Supplicant takes the signal strength in terms of mBm(100*dBm) */
-	rssi = (CDF_MIN((bss_desc->rssi + bss_desc->sinr), 0)) * 100;
+	rssi = CDF_MIN(rssi, 0) * 100;
 
 	hddLog(LOG1, FL("BSSID: " MAC_ADDRESS_STR " Channel:%d RSSI:%d"),
 	       MAC_ADDR_ARRAY(mgmt->bssid), chan->center_freq,

+ 1 - 1
core/mac/inc/sir_api.h

@@ -625,8 +625,8 @@ typedef struct sSirBssDescription {
 	uint16_t beaconInterval;
 	uint16_t capabilityInfo;
 	tSirNwType nwType;      /* Indicates 11a/b/g */
-	uint8_t reserved_padding0;
 	int8_t rssi;
+	int8_t rssi_raw;
 	int8_t sinr;
 	/* channelId what peer sent in beacon/probersp. */
 	uint8_t channelId;

+ 2 - 2
core/mac/src/pe/lim/lim_process_action_frame.c

@@ -1895,7 +1895,7 @@ void lim_process_action_frame(tpAniSirGlobal mac_ctx,
 		case SIR_MAC_WNM_BSS_TM_RESPONSE:
 		case SIR_MAC_WNM_NOTIF_REQUEST:
 		case SIR_MAC_WNM_NOTIF_RESPONSE:
-			rssi = WMA_GET_RX_RSSI_DB(rx_pkt_info);
+			rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
 			mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
 			/* Forward to the SME to HDD to wpa_supplicant */
 			lim_send_sme_mgmt_frame_ind(mac_ctx,
@@ -2056,7 +2056,7 @@ void lim_process_action_frame(tpAniSirGlobal mac_ctx,
 
 			mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
 			frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
-			rssi = WMA_GET_RX_RSSI_DB(rx_pkt_info);
+			rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
 			CDF_TRACE(CDF_MODULE_ID_PE, CDF_TRACE_LEVEL_INFO,
 				  ("Public Action TDLS Discovery RSP .."));
 			lim_send_sme_mgmt_frame_ind(mac_ctx,

+ 1 - 1
core/mac/src/pe/lim/lim_process_assoc_rsp_frame.c

@@ -611,7 +611,7 @@ lim_process_assoc_rsp_frame(tpAniSirGlobal mac_ctx,
 		"and mlmstate: %d RSSI %d from " MAC_ADDRESS_STR), subtype,
 		session_entry->peSessionId, GET_LIM_SYSTEM_ROLE(session_entry),
 		session_entry->limMlmState,
-		(uint) abs((int8_t) WMA_GET_RX_RSSI_DB(rx_pkt_info)),
+		(uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info)),
 		MAC_ADDR_ARRAY(hdr->sa));
 
 	beacon = cdf_mem_malloc(sizeof(tSchBeaconStruct));

+ 2 - 2
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -190,7 +190,7 @@ lim_process_auth_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
 		   "Frame Received: BSSID: " MAC_ADDRESS_STR " (RSSI %d)"),
 		psessionEntry->peSessionId, GET_LIM_SYSTEM_ROLE(psessionEntry),
 		psessionEntry->limMlmState, MAC_ADDR_ARRAY(pHdr->bssId),
-		(uint) abs((int8_t) WMA_GET_RX_RSSI_DB(pRxPacketInfo)));
+		(uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo)));
 
 	pBody = WMA_GET_RX_MPDU_DATA(pRxPacketInfo);
 
@@ -1775,7 +1775,7 @@ tSirRetStatus lim_process_auth_frame_no_session(tpAniSirGlobal pMac, uint8_t *pB
 	lim_log(pMac, LOG1,
 		FL("Auth Frame Received: BSSID " MAC_ADDRESS_STR " (RSSI %d)"),
 		MAC_ADDR_ARRAY(pHdr->bssId),
-		(uint) abs((int8_t) WMA_GET_RX_RSSI_DB(pBd)));
+		(uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(pBd)));
 
 	/* Auth frame has come on a new BSS, however, we need to find the session
 	 * from where the auth-req was sent to the new AP

+ 2 - 2
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -352,7 +352,7 @@ __lim_pno_match_fwd_bcn_probepsp(tpAniSirGlobal pmac, uint8_t *rx_pkt_info,
 		result->ap[i].capability =
 			lim_get_u16((uint8_t *) &frame->capabilityInfo);
 		result->ap[i].channel = WMA_GET_RX_CH(rx_pkt_info);
-		result->ap[i].rssi = WMA_GET_RX_RSSI_DB(rx_pkt_info);
+		result->ap[i].rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
 		result->ap[i].rtt = 0;
 		result->ap[i].rtt_sd = 0;
 		result->ap[i].ieLength = ie_len;
@@ -403,7 +403,7 @@ __lim_ext_scan_forward_bcn_probe_rsp(tpAniSirGlobal pmac, uint8_t *rx_pkt_info,
 	result->ap.capability =
 			lim_get_u16((uint8_t *) &frame->capabilityInfo);
 	result->ap.channel = WMA_GET_RX_CH(rx_pkt_info);
-	result->ap.rssi = WMA_GET_RX_RSSI_DB(rx_pkt_info);
+	result->ap.rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info);
 	result->ap.rtt = 0;
 	result->ap.rtt_sd = 0;
 	result->ap.ieLength = ie_len;

+ 3 - 2
core/mac/src/pe/lim/lim_process_probe_rsp_frame.c

@@ -129,7 +129,7 @@ lim_process_probe_rsp_frame(tpAniSirGlobal mac_ctx, uint8_t *rx_Packet_info,
 		FL("Probe Resp Frame Received: BSSID "
 		MAC_ADDRESS_STR " (RSSI %d)"),
 		MAC_ADDR_ARRAY(header->bssId),
-		(uint) abs((int8_t)WMA_GET_RX_RSSI_DB(rx_Packet_info)));
+		(uint) abs((int8_t)WMA_GET_RX_RSSI_NORMALIZED(rx_Packet_info)));
 	/* Get pointer to Probe Response frame body */
 	body = WMA_GET_RX_MPDU_DATA(rx_Packet_info);
 		/* Enforce Mandatory IEs */
@@ -349,7 +349,8 @@ lim_process_probe_rsp_frame_no_session(tpAniSirGlobal mac_ctx,
 		  FL("Probe Resp Frame Received: BSSID "
 		  MAC_ADDRESS_STR " (RSSI %d)"),
 		  MAC_ADDR_ARRAY(header->bssId),
-		  (uint) abs((int8_t)WMA_GET_RX_RSSI_DB(rx_packet_info)));
+		  (uint) abs((int8_t)WMA_GET_RX_RSSI_NORMALIZED(
+					rx_packet_info)));
 	/*
 	 * Get pointer to Probe Response frame body
 	 */

+ 6 - 1
core/mac/src/pe/lim/lim_scan_result_utils.c

@@ -177,10 +177,15 @@ lim_collect_bss_description(tpAniSirGlobal pMac,
 	sir_dump_buf(pMac, SIR_LIM_MODULE_ID, LOG4,
 		(uint8_t *) pRxPacketInfo, 36);
 
-	pBssDescr->rssi = (int8_t) WMA_GET_RX_RSSI_DB(pRxPacketInfo);
+	pBssDescr->rssi = (int8_t) WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo);
+	pBssDescr->rssi_raw = (int8_t) WMA_GET_RX_RSSI_RAW(pRxPacketInfo);
 
 	/* SINR no longer reported by HW */
 	pBssDescr->sinr = 0;
+	lim_log(pMac, LOG3,
+		FL(MAC_ADDRESS_STR " rssi: normalized = %d, absolute = %d"),
+		MAC_ADDR_ARRAY(pHdr->bssId), pBssDescr->rssi,
+		pBssDescr->rssi_raw);
 
 	pBssDescr->nReceivedTime = (uint32_t) cdf_mc_timer_get_system_ticks();
 	pBssDescr->tsf_delta = WMA_GET_RX_TSF_DELTA(pRxPacketInfo);

+ 1 - 1
core/mac/src/pe/rrm/rrm_api.c

@@ -306,7 +306,7 @@ rrm_process_link_measurement_request(tpAniSirGlobal pMac,
 	LinkReport.dialogToken = pLinkReq->DialogToken.token;
 	LinkReport.rxAntenna = 0;
 	LinkReport.txAntenna = 0;
-	currentRSSI = WMA_GET_RX_RSSI_DB(pRxPacketInfo);
+	currentRSSI = WMA_GET_RX_RSSI_RAW(pRxPacketInfo);
 
 	lim_log(pMac, LOG1, "Received Link report frame with %d", currentRSSI);
 

+ 18 - 12
core/sme/src/csr/csr_api_scan.c

@@ -2506,7 +2506,6 @@ bool csr_remove_dup_bss_description(tpAniSirGlobal pMac,
 	tListElem *pEntry;
 	tCsrScanResult *scan_entry;
 	bool fRC = false;
-	int8_t scan_entry_rssi = 0;
 
 	/*
 	 * Walk through all the chained BssDescriptions. If we find a chained
@@ -2526,17 +2525,24 @@ bool csr_remove_dup_bss_description(tpAniSirGlobal pMac,
 		if (csr_is_duplicate_bss_description(pMac,
 			&scan_entry->Result.BssDescriptor,
 			bss_dscp, pIes, fForced)) {
-			/*
-			 * Following is mathematically a = (aX + b(100-X))/100
-			 * where:
-			 * a = bss_dscp->rssi, b = scan_entry_rssi
-			 * and X = CSR_SCAN_RESULT_RSSI_WEIGHT
-			 */
-			scan_entry_rssi = scan_entry->Result.BssDescriptor.rssi;
-			bss_dscp->rssi = (int8_t) ((((int32_t) bss_dscp->rssi *
-						CSR_SCAN_RESULT_RSSI_WEIGHT) +
-				((int32_t) scan_entry_rssi *
-				 (100 - CSR_SCAN_RESULT_RSSI_WEIGHT))) / 100);
+			int32_t rssi_new, rssi_old;
+
+			rssi_new = (int32_t) bss_dscp->rssi;
+			rssi_old = (int32_t) scan_entry->
+					Result.BssDescriptor.rssi;
+			rssi_new = ((rssi_new * CSR_SCAN_RESULT_RSSI_WEIGHT) +
+				rssi_old *
+				(100 - CSR_SCAN_RESULT_RSSI_WEIGHT)) / 100;
+			bss_dscp->rssi = (int8_t) rssi_new;
+
+			rssi_new = (int32_t) bss_dscp->rssi_raw;
+			rssi_old = (int32_t) scan_entry->
+					Result.BssDescriptor.rssi_raw;
+			rssi_new = ((rssi_new * CSR_SCAN_RESULT_RSSI_WEIGHT) +
+				rssi_old *
+				(100 - CSR_SCAN_RESULT_RSSI_WEIGHT)) / 100;
+			bss_dscp->rssi_raw = (int8_t) rssi_new;
+
 			/* Remove the old entry from the list */
 			if (csr_ll_remove_entry
 				    (&pMac->scan.scanResultList, pEntry,

+ 8 - 3
core/wma/inc/wma_types.h

@@ -123,9 +123,14 @@
 
 #define WMA_GET_RX_RFBAND(pRxMeta) 0
 
-#define WMA_MAX_TXPOWER_INVALID		127
-#define WMA_GET_RX_RSSI_DB(pRxMeta) \
-	(((t_packetmeta *)pRxMeta)->rssi)
+#define WMA_MAX_TXPOWER_INVALID        127
+/* rssi value normalized to noise floor of -96 dBm */
+#define WMA_GET_RX_RSSI_NORMALIZED(pRxMeta) \
+		       (((t_packetmeta *)pRxMeta)->rssi)
+
+/* raw rssi based on actual noise floor in hardware */
+#define WMA_GET_RX_RSSI_RAW(pRxMeta) \
+		       (((t_packetmeta *)pRxMeta)->rssi_raw)
 
 /* WMA Messages */
 #define WMA_MSG_TYPES_BEGIN            SIR_HAL_MSG_TYPES_BEGIN

+ 19 - 3
core/wma/src/wma_mgmt.c

@@ -3191,10 +3191,21 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data,
 	 */
 	rx_pkt->pkt_meta.channel = hdr->channel;
 	rx_pkt->pkt_meta.scan_src = hdr->flags;
-	/*Get the absolute rssi value from the current rssi value
-	 *the sinr value is hardcoded into 0 in the core stack*/
-	rx_pkt->pkt_meta.rssi = hdr->snr + WMA_TGT_NOISE_FLOOR_DBM;
+
+	/*
+	 * Get the rssi value from the current snr value
+	 * using standard noise floor of -96.
+	 */
+	rx_pkt->pkt_meta.rssi = hdr->snr + WMA_NOISE_FLOOR_DBM_DEFAULT;
 	rx_pkt->pkt_meta.snr = hdr->snr;
+
+	/* If absolute rssi is available from firmware, use it */
+	if (hdr->rssi != 0)
+		rx_pkt->pkt_meta.rssi_raw = hdr->rssi;
+	else
+		rx_pkt->pkt_meta.rssi_raw = rx_pkt->pkt_meta.rssi;
+
+
 	/*
 	 * FIXME: Assigning the local timestamp as hw timestamp is not
 	 * available. Need to see if pe/lim really uses this data.
@@ -3253,6 +3264,11 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data,
 	cdf_mem_copy(wh, param_tlvs->bufp, hdr->buf_len);
 #endif
 
+	WMA_LOGD(
+		FL("BSSID: "MAC_ADDRESS_STR" snr = %d, rssi = %d, rssi_raw = %d"),
+			MAC_ADDR_ARRAY(wh->i_addr3),
+			hdr->snr, rx_pkt->pkt_meta.rssi,
+			rx_pkt->pkt_meta.rssi_raw);
 	if (!wma_handle->mgmt_rx) {
 		WMA_LOGE("Not registered for Mgmt rx, dropping the frame");
 		cds_pkt_return_packet(rx_pkt);