Ver Fonte

qcacld-3.0: Add implementation of get_station_stats

Add changes to support get station stats from within cp_stats
component.

Change-Id: Id685e9d94f185ee562f21d12d118e94a737a6a7e
CRs-Fixed: 2210338
Naveen Rawat há 7 anos atrás
pai
commit
fa2a100bac

+ 77 - 9
core/hdd/src/wlan_hdd_stats.c

@@ -3039,12 +3039,12 @@ static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
 static int
 wlan_hdd_get_sap_stats(struct hdd_adapter *adapter, struct station_info *info)
 {
-	QDF_STATUS status;
+	int ret;
 
-	status = wlan_hdd_get_station_stats(adapter);
-	if (QDF_IS_STATUS_ERROR(status)) {
-		hdd_err("Failed to get SAP stats; status:%d", status);
-		return qdf_status_to_os_return(status);
+	ret = wlan_hdd_get_station_stats(adapter);
+	if (ret) {
+		hdd_err("Failed to get SAP stats; status:%d", ret);
+		return ret;
 	}
 
 	wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
@@ -5711,6 +5711,73 @@ return_cached_results:
 }
 #endif
 
+#ifdef QCA_SUPPORT_CP_STATS
+int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
+{
+	int ret;
+	uint8_t mcs_rate_flags;
+	struct stats_event stats = {0};
+
+	ret =  wlan_cfg80211_mc_cp_stats_get_station_stats(adapter->hdd_vdev,
+							   &stats);
+
+	if (!stats.vdev_summary_stats || !stats.vdev_chain_rssi) {
+		hdd_err("summary_stats: %pK, chain_rssi: %pK",
+			stats.vdev_summary_stats, stats.vdev_chain_rssi);
+		return -EINVAL;
+	}
+
+	/* save summary stats to legacy location */
+	qdf_mem_copy(adapter->hdd_stats.summary_stat.retry_cnt,
+		stats.vdev_summary_stats[0].stats.retry_cnt,
+		sizeof(adapter->hdd_stats.summary_stat.retry_cnt));
+	qdf_mem_copy(adapter->hdd_stats.summary_stat.multiple_retry_cnt,
+		stats.vdev_summary_stats[0].stats.multiple_retry_cnt,
+		sizeof(adapter->hdd_stats.summary_stat.multiple_retry_cnt));
+	qdf_mem_copy(adapter->hdd_stats.summary_stat.tx_frm_cnt,
+		stats.vdev_summary_stats[0].stats.tx_frm_cnt,
+		sizeof(adapter->hdd_stats.summary_stat.tx_frm_cnt));
+	qdf_mem_copy(adapter->hdd_stats.summary_stat.fail_cnt,
+		stats.vdev_summary_stats[0].stats.fail_cnt,
+		sizeof(adapter->hdd_stats.summary_stat.fail_cnt));
+	adapter->hdd_stats.summary_stat.snr =
+		stats.vdev_summary_stats[0].stats.snr;
+	adapter->hdd_stats.summary_stat.rssi =
+		stats.vdev_summary_stats[0].stats.rssi;
+	adapter->hdd_stats.summary_stat.rx_frm_cnt =
+		stats.vdev_summary_stats[0].stats.rx_frm_cnt;
+	adapter->hdd_stats.summary_stat.frm_dup_cnt =
+		stats.vdev_summary_stats[0].stats.frm_dup_cnt;
+	adapter->hdd_stats.summary_stat.rts_fail_cnt =
+		stats.vdev_summary_stats[0].stats.rts_fail_cnt;
+	adapter->hdd_stats.summary_stat.ack_fail_cnt =
+		stats.vdev_summary_stats[0].stats.ack_fail_cnt;
+	adapter->hdd_stats.summary_stat.rts_succ_cnt =
+		stats.vdev_summary_stats[0].stats.rts_succ_cnt;
+	adapter->hdd_stats.summary_stat.rx_discard_cnt =
+		stats.vdev_summary_stats[0].stats.rx_discard_cnt;
+	adapter->hdd_stats.summary_stat.rx_error_cnt =
+		stats.vdev_summary_stats[0].stats.rx_error_cnt;
+
+	/* save class a stats to legacy location */
+	adapter->hdd_stats.class_a_stat.nss =
+		wlan_vdev_mlme_get_nss(adapter->hdd_vdev);
+	adapter->hdd_stats.class_a_stat.tx_rate = stats.tx_rate;
+	adapter->hdd_stats.class_a_stat.tx_rate_flags = stats.tx_rate_flags;
+	adapter->hdd_stats.class_a_stat.mcs_index =
+		sme_get_mcs_idx(stats.tx_rate * 5, stats.tx_rate_flags,
+			adapter->hdd_stats.class_a_stat.nss, &mcs_rate_flags);
+	adapter->hdd_stats.class_a_stat.mcs_rate_flags = mcs_rate_flags;
+
+	/* save per chain rssi to legacy location */
+	qdf_mem_copy(adapter->hdd_stats.per_chain_rssi_stats.rssi,
+		     stats.vdev_chain_rssi[0].chain_rssi,
+		     sizeof(stats.vdev_chain_rssi[0].chain_rssi));
+
+	wlan_cfg80211_mc_cp_stats_put_station_stats(&stats);
+	return ret;
+}
+#else /* QCA_SUPPORT_CP_STATS */
 struct station_stats {
 	tCsrSummaryStatsInfo summary_stats;
 	tCsrGlobalClassAStatsInfo class_a_stats;
@@ -5760,7 +5827,7 @@ static void hdd_get_station_statistics_cb(void *stats, void *context)
 	hdd_request_put(request);
 }
 
-QDF_STATUS wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
+int wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
 {
 	struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
 	QDF_STATUS status;
@@ -5775,13 +5842,13 @@ QDF_STATUS wlan_hdd_get_station_stats(struct hdd_adapter *adapter)
 
 	if (NULL == adapter) {
 		hdd_err("adapter is NULL");
-		return QDF_STATUS_SUCCESS;
+		return 0;
 	}
 
 	request = hdd_request_alloc(&params);
 	if (!request) {
 		hdd_err("Request allocation failure");
-		return QDF_STATUS_E_NOMEM;
+		return -ENOMEM;
 	}
 	cookie = hdd_request_cookie(request);
 
@@ -5822,8 +5889,9 @@ put_request:
 	hdd_request_put(request);
 
 	/* either callback updated adapter stats or it has cached data */
-	return QDF_STATUS_SUCCESS;
+	return 0;
 }
+#endif /* QCA_SUPPORT_CP_STATS */
 
 struct temperature_priv {
 	int temperature;

+ 9 - 2
core/hdd/src/wlan_hdd_stats.h

@@ -409,9 +409,9 @@ QDF_STATUS wlan_hdd_get_class_astats(struct hdd_adapter *adapter);
  * wlan_hdd_get_station_stats() - Get station statistics
  * @adapter: adapter for which statistics are desired
  *
- * Return: QDF_STATUS_SUCCESS if adapter's statistics were updated
+ * Return: status of operation
  */
-QDF_STATUS wlan_hdd_get_station_stats(struct hdd_adapter *adapter);
+int wlan_hdd_get_station_stats(struct hdd_adapter *adapter);
 
 /**
  * wlan_hdd_get_temperature() - get current device temperature
@@ -424,4 +424,11 @@ QDF_STATUS wlan_hdd_get_station_stats(struct hdd_adapter *adapter);
  */
 int wlan_hdd_get_temperature(struct hdd_adapter *adapter, int *temperature);
 
+/**
+ * wlan_hdd_request_station_stats() - Get station statistics
+ * @adapter: adapter for which statistics are desired
+ *
+ * Return: QDF_STATUS_SUCCESS if adapter's statistics were updated
+ */
+int wlan_hdd_request_station_stats(struct hdd_adapter *adapter);
 #endif /* end #if !defined(WLAN_HDD_STATS_H) */

+ 54 - 38
core/hdd/src/wlan_hdd_wext.c

@@ -8343,6 +8343,12 @@ static int iw_set_packet_filter_params(struct net_device *dev,
 }
 #endif
 
+#ifdef QCA_SUPPORT_CP_STATS
+static int hdd_get_wlan_stats(struct hdd_adapter *adapter)
+{
+	return wlan_hdd_get_station_stats(adapter);
+}
+#else /* QCA_SUPPORT_CP_STATS */
 struct hdd_statistics_priv {
 	tCsrSummaryStatsInfo summary_stats;
 	tCsrGlobalClassAStatsInfo class_a_stats;
@@ -8386,56 +8392,28 @@ static void hdd_statistics_cb(void *stats, void *context)
 	hdd_request_put(request);
 }
 
-static int __iw_get_statistics(struct net_device *dev,
-			       struct iw_request_info *info,
-			       union iwreq_data *wrqu, char *extra)
+static int hdd_get_wlan_stats(struct hdd_adapter *adapter)
 {
-
-	QDF_STATUS status;
-	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
-	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	struct hdd_station_ctx *sta_ctx;
-	char *p;
-	int tlen;
-	tCsrSummaryStatsInfo *summary_stats =
-		&(adapter->hdd_stats.summary_stat);
-	tCsrGlobalClassAStatsInfo *class_a_stats =
-		&(adapter->hdd_stats.class_a_stat);
-	tCsrGlobalClassDStatsInfo *class_d_stats =
-		&(adapter->hdd_stats.class_d_stat);
-	int ret;
+	int ret = 0;
 	void *cookie;
+	QDF_STATUS status;
 	struct hdd_request *request;
+	struct hdd_station_ctx *sta_ctx;
 	struct hdd_statistics_priv *priv;
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	static const struct hdd_request_params params = {
 		.priv_size = sizeof(*priv),
 		.timeout_ms = WLAN_WAIT_TIME_STATS,
 	};
 
-	hdd_enter_dev(dev);
-
-	ret = wlan_hdd_validate_context(hdd_ctx);
-	if (0 != ret)
-		return ret;
-
-	ret = hdd_check_private_wext_control(hdd_ctx, info);
-	if (0 != ret)
-		return ret;
-
 	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
-	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
-		wrqu->data.length = 0;
-		return 0;
-	}
-
 	request = hdd_request_alloc(&params);
 	if (!request) {
 		hdd_warn("request allocation failed");
-		goto return_cached_stats;
+		return -EINVAL;
 	}
 
 	cookie = hdd_request_cookie(request);
-
 	status = sme_get_statistics(hdd_ctx->hHal, eCSR_HDD,
 				    SME_SUMMARY_STATS |
 				    SME_GLOBAL_CLASSA_STATS |
@@ -8458,9 +8436,9 @@ static int __iw_get_statistics(struct net_device *dev,
 
 	/* update the adapter cache with the fresh results */
 	priv = hdd_request_priv(request);
-	*summary_stats = priv->summary_stats;
-	*class_a_stats = priv->class_a_stats;
-	*class_d_stats = priv->class_d_stats;
+	adapter->hdd_stats.summary_stat = priv->summary_stats;
+	adapter->hdd_stats.class_a_stat = priv->class_a_stats;
+	adapter->hdd_stats.class_d_stat = priv->class_d_stats;
 
 put_request:
 	/*
@@ -8469,8 +8447,46 @@ put_request:
 	 * regardless we are done with the request.
 	 */
 	hdd_request_put(request);
+	return ret;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
+static int __iw_get_statistics(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	int ret;
+	char *p;
+	int tlen;
+	struct hdd_station_ctx *sta_ctx;
+	tCsrSummaryStatsInfo *summary_stats;
+	tCsrGlobalClassAStatsInfo *class_a_stats;
+	tCsrGlobalClassDStatsInfo *class_d_stats;
+	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+
+	hdd_enter_dev(dev);
+
+	ret = wlan_hdd_validate_context(hdd_ctx);
+	if (0 != ret)
+		return ret;
+
+	ret = hdd_check_private_wext_control(hdd_ctx, info);
+	if (0 != ret)
+		return ret;
+
+	sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+	if (eConnectionState_Associated != sta_ctx->conn_info.connState) {
+		wrqu->data.length = 0;
+		return 0;
+	}
+
+	hdd_get_wlan_stats(adapter);
+
+	summary_stats = &(adapter->hdd_stats.summary_stat);
+	class_a_stats = &(adapter->hdd_stats.class_a_stat);
+	class_d_stats = &(adapter->hdd_stats.class_d_stat);
 
-return_cached_stats:
 	p = extra;
 	tlen = 0;
 

+ 5 - 0
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -3522,6 +3522,7 @@ void lim_process_sme_addts_rsp_timeout(tpAniSirGlobal pMac, uint32_t param)
 			       psessionEntry->transactionId);
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 /**
  * __lim_process_sme_get_statistics_request()
  *
@@ -3558,6 +3559,10 @@ __lim_process_sme_get_statistics_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
 
 	return;
 }
+#else
+static void __lim_process_sme_get_statistics_request(
+			struct sAniSirGlobal *mac_ctx, uint32_t *pMsgBuf) {}
+#endif
 
 #ifdef FEATURE_WLAN_ESE
 /**

+ 20 - 0
core/mac/src/pe/lim/lim_prop_exts_utils.c

@@ -323,6 +323,23 @@ static void lim_check_he_ldpc_cap(tpPESession session,
 		tSirProbeRespBeacon *beacon_struct)
 {}
 #endif
+
+static void lim_objmgr_update_vdev_nss(struct wlan_objmgr_psoc *psoc,
+				       uint8_t vdev_id, uint8_t nss)
+{
+	struct wlan_objmgr_vdev *vdev;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_LEGACY_MAC_ID);
+	if (!vdev) {
+		pe_err("vdev not found for id: %d", vdev_id);
+		return;
+	}
+	wlan_vdev_obj_lock(vdev);
+	wlan_vdev_mlme_set_nss(vdev, nss);
+	wlan_vdev_obj_unlock(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+}
 /**
  * lim_extract_ap_capability() - extract AP's HCF/WME/WSM capability
  * @mac_ctx: Pointer to Global MAC structure
@@ -597,6 +614,9 @@ lim_extract_ap_capability(tpAniSirGlobal mac_ctx, uint8_t *p_ie,
 				&beacon_struct->hs20vendor_ie.hs_id,
 				sizeof(beacon_struct->hs20vendor_ie.hs_id));
 	}
+
+	lim_objmgr_update_vdev_nss(mac_ctx->psoc, session->smeSessionId,
+				   session->nss);
 	qdf_mem_free(beacon_struct);
 	return;
 } /****** end lim_extract_ap_capability() ******/

+ 2 - 0
core/mac/src/pe/lim/lim_send_sme_rsp_messages.c

@@ -1640,6 +1640,7 @@ lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts, uint16_t ai
 	lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT);
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 /**
  * lim_send_sme_pe_statistics_rsp()
  *
@@ -1697,6 +1698,7 @@ lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgType, void *stat
 	return;
 
 } /*** end lim_send_sme_pe_statistics_rsp() ***/
+#endif
 
 #ifdef FEATURE_WLAN_ESE
 /**

+ 6 - 0
core/mac/src/pe/lim/lim_send_sme_rsp_messages.h

@@ -90,8 +90,14 @@ void lim_send_sme_delts_ind(tpAniSirGlobal pMac, tpSirDeltsReqInfo delts,
 			    uint16_t aid, tpPESession);
 void lim_send_sme_stats_rsp(tpAniSirGlobal pMac, uint16_t msgtype, void *stats);
 
+#ifdef QCA_SUPPORT_CP_STATS
+static inline void lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac,
+					uint16_t msgtype, void *stats) {}
+#else
 void lim_send_sme_pe_statistics_rsp(tpAniSirGlobal pMac, uint16_t msgtype,
 				    void *stats);
+#endif /* QCA_SUPPORT_CP_STATS */
+
 #ifdef FEATURE_WLAN_ESE
 void lim_send_sme_pe_ese_tsm_rsp(tpAniSirGlobal pMac, tAniGetTsmStatsRsp *pStats);
 #endif

+ 4 - 0
core/sme/inc/csr_internal.h

@@ -720,6 +720,7 @@ struct csr_linkquality_indinfo {
 	void *context;
 };
 
+#ifndef QCA_SUPPORT_CP_STATS
 struct csr_pestats_reqinfo {
 	tListElem link;         /* list links */
 	uint32_t statsMask;
@@ -747,6 +748,7 @@ struct csr_statsclient_reqinfo {
 struct csr_tlstats_reqinfo {
 	uint8_t numClient;
 };
+#endif /* QCA_SUPPORT_CP_STATS */
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 enum csr_roamoffload_authstatus {
@@ -967,6 +969,7 @@ struct csr_roamstruct {
 	uint32_t numValidChannels;       /* total number of channels in CFG */
 	int32_t sPendingCommands;
 	qdf_mc_timer_t hTimerWaitForKey; /* support timeout for WaitForKey */
+#ifndef QCA_SUPPORT_CP_STATS
 	tCsrSummaryStatsInfo summaryStatsInfo;
 	tCsrGlobalClassAStatsInfo classAStatsInfo;
 	tCsrGlobalClassDStatsInfo classDStatsInfo;
@@ -974,6 +977,7 @@ struct csr_roamstruct {
 	tDblLinkList statsClientReqList;
 	tDblLinkList peStatsReqList;
 	struct csr_tlstats_reqinfo tlStatsReqInfo;
+#endif
 	eCsrRoamLinkQualityInd vccLinkQuality;
 	struct csr_linkquality_indinfo linkQualityIndInfo;
 	tCsrTimerInfo WaitForKeyTimerInfo;

+ 14 - 0
core/sme/inc/sme_api.h

@@ -416,10 +416,12 @@ QDF_STATUS sme_roam_get_pmkid_cache(tHalHandle hHal, uint8_t sessionId,
 		uint32_t *pNum,
 		tPmkidCacheInfo *pPmkidCache);
 QDF_STATUS sme_get_config_param(tHalHandle hHal, tSmeConfigParams *pParam);
+#ifndef QCA_SUPPORT_CP_STATS
 QDF_STATUS sme_get_statistics(tHalHandle hHal,
 		eCsrStatsRequesterType requesterId,
 		uint32_t statsMask, tCsrStatsCallback callback,
 		uint8_t staId, void *pContext, uint8_t sessionId);
+#endif
 QDF_STATUS sme_get_rssi(tHalHandle hHal,
 		tCsrRssiCallback callback,
 		uint8_t staId, struct qdf_mac_addr bssId, int8_t lastRSSI,
@@ -2233,4 +2235,16 @@ bool sme_validate_channel_list(tHalHandle hal,
  */
 void sme_set_amsdu(tHalHandle hal, bool enable);
 
+/**
+ * sme_get_mcs_idx() - gets mcs index
+ * @max_rate: max rate
+ * @rate_flags: rate flags
+ * @nss: number of nss
+ * @mcs_rate_flags: mcs rate flag
+ *
+ * Return: return mcs index
+ */
+uint8_t sme_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
+			uint8_t nss, uint8_t *mcs_rate_flags);
+
 #endif /* #if !defined( __SME_API_H ) */

+ 8 - 0
core/sme/src/common/sme_api.c

@@ -4265,6 +4265,7 @@ QDF_STATUS sme_get_snr(tHalHandle hHal,
 	return status;
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 /*
  * sme_get_statistics() -
  * A wrapper function that client calls to register a callback to get
@@ -4302,6 +4303,7 @@ QDF_STATUS sme_get_statistics(tHalHandle hHal,
 	return status;
 
 }
+#endif
 
 QDF_STATUS sme_get_link_status(tHalHandle hHal,
 			       tCsrLinkStatusCallback callback,
@@ -16117,3 +16119,9 @@ void sme_set_amsdu(tHalHandle hal, bool enable)
 	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
 	mac_ctx->is_usr_cfg_amsdu_enabled = enable;
 }
+
+uint8_t sme_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
+			uint8_t nss, uint8_t *mcs_rate_flags)
+{
+	return wma_get_mcs_idx(max_rate, rate_flags, nss, mcs_rate_flags);
+}

+ 59 - 17
core/sme/src/csr/csr_api_roam.c

@@ -402,19 +402,13 @@ static QDF_STATUS csr_send_mb_set_context_req_msg(tpAniSirGlobal pMac,
 					   uint8_t *pKeyRsc);
 static void csr_roam_link_up(tpAniSirGlobal pMac, struct qdf_mac_addr bssid);
 static void csr_roam_link_down(tpAniSirGlobal pMac, uint32_t sessionId);
+#ifndef QCA_SUPPORT_CP_STATS
 static QDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac,
 					uint32_t statsMask, uint8_t staId,
 					uint8_t sessionId);
 /* pStaEntry is no longer invalid upon the return of this function. */
 static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac,
 							tListElem *pEntry);
-static enum csr_cfgdot11mode
-csr_roam_get_phy_mode_band_for_bss(tpAniSirGlobal pMac,
-				   struct csr_roam_profile *pProfile,
-				   uint8_t operationChn,
-				   enum band_info *pBand);
-static QDF_STATUS csr_roam_get_qos_info_from_bss(
-tpAniSirGlobal pMac, tSirBssDescription *pBssDesc);
 struct csr_statsclient_reqinfo *csr_roam_insert_entry_into_list(
 			tpAniSirGlobal pMac, tDblLinkList *pStaList,
 				struct csr_statsclient_reqinfo *
@@ -430,6 +424,19 @@ tListElem *csr_roam_find_in_pe_stats_req_list(
 	tpAniSirGlobal pMac,
 						uint32_t statsMask);
 static QDF_STATUS csr_roam_dereg_statistics_req(tpAniSirGlobal pMac);
+#else
+static QDF_STATUS csr_roam_dereg_statistics_req(tpAniSirGlobal pMac)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+static enum csr_cfgdot11mode
+csr_roam_get_phy_mode_band_for_bss(tpAniSirGlobal pMac,
+				   struct csr_roam_profile *pProfile,
+				   uint8_t operationChn,
+				   enum band_info *pBand);
+static QDF_STATUS csr_roam_get_qos_info_from_bss(
+tpAniSirGlobal pMac, tSirBssDescription *pBssDesc);
 static uint32_t csr_find_ibss_session(tpAniSirGlobal pMac);
 static uint32_t csr_find_session_by_type(tpAniSirGlobal,
 					enum QDF_OPMODE);
@@ -486,6 +493,32 @@ static void csr_roam_de_init_globals(tpAniSirGlobal pMac)
 	}
 }
 
+#ifdef QCA_SUPPORT_CP_STATS
+static QDF_STATUS csr_open_stats_ll(struct sAniSirGlobal *mac_ctx)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static void csr_close_stats_ll(struct sAniSirGlobal *mac_ctx) {}
+#else
+static QDF_STATUS csr_open_stats_ll(struct sAniSirGlobal *mac_ctx)
+{
+	QDF_STATUS status;
+
+	status = csr_ll_open(mac_ctx->hHdd, &mac_ctx->roam.statsClientReqList);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
+	return csr_ll_open(mac_ctx->hHdd, &mac_ctx->roam.peStatsReqList);
+}
+
+static void csr_close_stats_ll(struct sAniSirGlobal *mac_ctx)
+{
+	csr_ll_close(&mac_ctx->roam.statsClientReqList);
+	csr_ll_close(&mac_ctx->roam.peStatsReqList);
+}
+#endif
+
 QDF_STATUS csr_open(tpAniSirGlobal pMac)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -505,13 +538,8 @@ QDF_STATUS csr_open(tpAniSirGlobal pMac)
 		if (!QDF_IS_STATUS_SUCCESS(status))
 			break;
 		pMac->roam.nextRoamId = 1;      /* Must not be 0 */
-		if (!QDF_IS_STATUS_SUCCESS
-			    (csr_ll_open(pMac->hHdd,
-					 &pMac->roam.statsClientReqList)))
-			break;
-		if (!QDF_IS_STATUS_SUCCESS
-			    (csr_ll_open(pMac->hHdd,
-					 &pMac->roam.peStatsReqList)))
+		status = csr_open_stats_ll(pMac);
+		if (QDF_IS_STATUS_ERROR(status))
 			break;
 		qdf_list_create(&pMac->roam.rssi_disallow_bssid,
 			MAX_RSSI_AVOID_BSSID_LIST);
@@ -601,8 +629,7 @@ QDF_STATUS csr_close(tpAniSirGlobal pMac)
 	csr_assoc_rej_free_rssi_disallow_list(
 		&pMac->roam.rssi_disallow_bssid);
 	csr_scan_close(pMac);
-	csr_ll_close(&pMac->roam.statsClientReqList);
-	csr_ll_close(&pMac->roam.peStatsReqList);
+	csr_close_stats_ll(pMac);
 	/* DeInit Globals */
 	csr_roam_de_init_globals(pMac);
 	return status;
@@ -1108,6 +1135,15 @@ QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef QCA_SUPPORT_CP_STATS
+static void csr_init_tl_stats(struct sAniSirGlobal *mac_ctx) {}
+#else
+static void csr_init_tl_stats(struct sAniSirGlobal *mac_ctx)
+{
+	mac_ctx->roam.tlStatsReqInfo.numClient = 0;
+}
+#endif /* QCA_SUPPORT_CP_STATS */
+
 QDF_STATUS csr_start(tpAniSirGlobal pMac)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -1124,7 +1160,7 @@ QDF_STATUS csr_start(tpAniSirGlobal pMac)
 		pMac->roam.sPendingCommands = 0;
 		for (i = 0; i < CSR_ROAM_SESSION_MAX; i++)
 			status = csr_neighbor_roam_init(pMac, i);
-		pMac->roam.tlStatsReqInfo.numClient = 0;
+		csr_init_tl_stats(pMac);
 		/* init the link quality indication also */
 		pMac->roam.vccLinkQuality = eCSR_ROAM_LINK_QUAL_MIN_IND;
 		if (!QDF_IS_STATUS_SUCCESS(status)) {
@@ -17291,6 +17327,7 @@ static void csr_roam_link_down(tpAniSirGlobal pMac, uint32_t sessionId)
 
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 QDF_STATUS csr_send_mb_stats_req_msg(tpAniSirGlobal pMac, uint32_t statsMask,
 				     uint8_t staId, uint8_t sessionId)
 {
@@ -17574,6 +17611,7 @@ struct csr_statsclient_reqinfo *csr_roam_insert_entry_into_list(
 	}
 	return pNewStaEntry;
 }
+#endif /* QCA_SUPPORT_CP_STATS */
 
 QDF_STATUS csr_get_rssi(tpAniSirGlobal pMac,
 			tCsrRssiCallback callback,
@@ -17664,6 +17702,7 @@ QDF_STATUS csr_get_snr(tpAniSirGlobal pMac,
 	return status;
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 /**
  * csr_deregister_client_request() - deregisters a get stats request
  * @mac_ctx:       mac global context
@@ -17796,6 +17835,7 @@ QDF_STATUS csr_get_statistics(tpAniSirGlobal pMac,
 
 	return QDF_STATUS_SUCCESS;
 }
+#endif /* QCA_SUPPORT_CP_STATS */
 
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 /**
@@ -19630,6 +19670,7 @@ QDF_STATUS csr_roam_offload_scan_rsp_hdlr(tpAniSirGlobal pMac,
 }
 #endif
 
+#ifndef QCA_SUPPORT_CP_STATS
 /* pStaEntry is no longer invalid upon the return of this function. */
 static void csr_roam_remove_stat_list_entry(tpAniSirGlobal pMac,
 						tListElem *pEntry)
@@ -19809,6 +19850,7 @@ static QDF_STATUS csr_roam_dereg_statistics_req(
 	return status;
 
 }
+#endif /* QCA_SUPPORT_CP_STATS */
 
 tSmeCmd *csr_get_command_buffer(tpAniSirGlobal pMac)
 {

+ 7 - 0
core/sme/src/csr/csr_inside_api.h

@@ -308,7 +308,14 @@ QDF_STATUS csr_roam_save_connected_information(tpAniSirGlobal pMac,
 					      tDot11fBeaconIEs *pIes);
 void csr_roam_check_for_link_status_change(tpAniSirGlobal pMac,
 					tSirSmeRsp *pSirMsg);
+
+#ifndef QCA_SUPPORT_CP_STATS
 void csr_roam_stats_rsp_processor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg);
+#else
+static inline void csr_roam_stats_rsp_processor(tpAniSirGlobal pMac,
+						tSirSmeRsp *pSirMsg) {}
+#endif /* QCA_SUPPORT_CP_STATS */
+
 QDF_STATUS csr_roam_issue_start_bss(tpAniSirGlobal pMac, uint32_t sessionId,
 				    struct csr_roamstart_bssparams *pParam,
 				    struct csr_roam_profile *pProfile,

+ 11 - 0
core/wma/inc/wma_api.h

@@ -371,4 +371,15 @@ QDF_STATUS wma_process_dhcp_ind(WMA_HANDLE wma_handle,
  */
 void wma_wmi_stop(void);
 
+/**
+ * wma_get_mcs_idx() - get mcs index
+ * @max_rate: max rate
+ * @rate_flags: rate flags
+ * @nss: nss
+ * @mcs_rate_flag: mcs rate flags
+ *
+ *  Return: mcs index
+ */
+uint8_t wma_get_mcs_idx(uint16_t max_rate, uint8_t rate_flags,
+			uint8_t nss, uint8_t *mcs_rate_flag);
 #endif

+ 8 - 5
core/wma/inc/wma_internal.h

@@ -705,9 +705,8 @@ void wma_set_resume_dtim(tp_wma_handle wma);
  * wma_data.c functions declarations
  */
 
-
-void wma_set_bss_rate_flags(struct wma_txrx_node *iface,
-				   tpAddBssParams add_bss);
+void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id,
+			    tpAddBssParams add_bss);
 
 int32_t wmi_unified_send_txbf(tp_wma_handle wma, tpAddStaParams params);
 
@@ -861,9 +860,13 @@ int32_t wma_txrx_fw_stats_reset(tp_wma_handle wma_handle,
 int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle,
 				    uint8_t vdev_id, uint32_t value);
 
+#ifdef QCA_SUPPORT_CP_STATS
+static inline void wma_get_stats_req(WMA_HANDLE handle,
+				struct sAniGetPEStatsReq *get_stats_param) {}
+#else
 void wma_get_stats_req(WMA_HANDLE handle,
-		       tAniGetPEStatsReq *get_stats_param);
-
+		       struct sAniGetPEStatsReq *get_stats_param);
+#endif
 /*
  * wma_features.c functions declarations
  */

+ 36 - 3
core/wma/src/wma_data.c

@@ -75,6 +75,7 @@
 #include <cdp_txrx_handle.h>
 #include <wlan_pmo_ucfg_api.h>
 #include "wlan_lmac_if_api.h"
+#include <wlan_cp_stats_mc_ucfg_api.h>
 
 struct wma_search_rate {
 	int32_t rate;
@@ -727,6 +728,35 @@ ht_vht_done:
 	return ret;
 }
 
+#ifdef QCA_SUPPORT_CP_STATS
+/**
+ * wma_cp_stats_set_rate_flag() - set rate flags within cp_stats priv object
+ * @wma: wma handle
+ * @vdev_id: vdev id
+ *
+ * Return: none
+ */
+static void wma_cp_stats_set_rate_flag(tp_wma_handle wma, uint8_t vdev_id)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_psoc *psoc = wma->psoc;
+	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_LEGACY_WMA_ID);
+	if (!vdev) {
+		WMA_LOGE("%s, vdev not found for id: %d", __func__,
+			 vdev_id);
+		return;
+	}
+
+	ucfg_mc_cp_stats_set_rate_flags(vdev, iface->rate_flags);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+}
+#else
+static void wma_cp_stats_set_rate_flag(tp_wma_handle wma, uint8_t vdev_id) {}
+#endif
+
 /**
  * wma_set_bss_rate_flags() - set rate flags based on BSS capability
  * @iface: txrx_node ctx
@@ -734,11 +764,12 @@ ht_vht_done:
  *
  * Return: none
  */
-void wma_set_bss_rate_flags(struct wma_txrx_node *iface,
-				   tpAddBssParams add_bss)
+void wma_set_bss_rate_flags(tp_wma_handle wma, uint8_t vdev_id,
+			    tpAddBssParams add_bss)
 {
-	iface->rate_flags = 0;
+	struct wma_txrx_node *iface = &wma->interfaces[vdev_id];
 
+	iface->rate_flags = 0;
 	if (add_bss->vhtCapable) {
 		if (add_bss->ch_width == CH_WIDTH_80P80MHZ)
 			iface->rate_flags |= TX_RATE_VHT80;
@@ -765,6 +796,8 @@ void wma_set_bss_rate_flags(struct wma_txrx_node *iface,
 
 	if (!add_bss->htCapable && !add_bss->vhtCapable)
 		iface->rate_flags = TX_RATE_LEGACY;
+
+	wma_cp_stats_set_rate_flag(wma, vdev_id);
 }
 
 /**

+ 3 - 3
core/wma/src/wma_dev_if.c

@@ -3775,7 +3775,7 @@ static void wma_add_bss_ap_mode(tp_wma_handle wma, tpAddBssParams add_bss)
 	if (SAP_WPS_DISABLED == add_bss->wps_state)
 		pmo_ucfg_disable_wakeup_event(wma->psoc, vdev_id,
 			(1 << WOW_PROBE_REQ_WPS_IE_EVENT));
-	wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss);
+	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
 	status = wma_create_peer(wma, pdev, vdev, add_bss->bssId,
 				 WMI_PEER_TYPE_DEFAULT, vdev_id, false);
 	if (status != QDF_STATUS_SUCCESS) {
@@ -3903,7 +3903,7 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
 		WMA_LOGE("%s: Failed to get pdev", __func__);
 		goto send_fail_resp;
 	}
-	wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss);
+	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
 
 	/* create ibss bss peer */
 	status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr,
@@ -4063,7 +4063,7 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss)
 	vdev_id = add_bss->staContext.smesessionId;
 	iface = &wma->interfaces[vdev_id];
 
-	wma_set_bss_rate_flags(iface, add_bss);
+	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
 	if (add_bss->operMode) {
 		/* Save parameters later needed by WMA_ADD_STA_REQ */
 		if (iface->addBssStaContext)

+ 144 - 0
core/wma/src/wma_mgmt.c

@@ -1016,6 +1016,148 @@ static void wma_mask_tx_ht_rate(tp_wma_handle wma, uint8_t *mcs_set)
 	}
 }
 
+#if SUPPORT_11AX
+/**
+ * wma_fw_to_host_phymode_11ac() - convert fw to host phymode for 11ax phymodes
+ * @wma:     wma handle
+ * @phymode: phymode to convert
+ *
+ * Return: None
+ */
+static enum wlan_phymode wma_fw_to_host_phymode_11ac(WLAN_PHY_MODE phymode)
+{
+	switch (phymode) {
+	default:
+		return WLAN_PHYMODE_AUTO;
+	case MODE_11AX_HE20:
+		return WLAN_PHYMODE_11AC_VHT20;
+	case MODE_11AX_HE40:
+		return WLAN_PHYMODE_11AC_VHT40;
+	case MODE_11AX_HE80:
+		return WLAN_PHYMODE_11AC_VHT80;
+	case MODE_11AX_HE80_80:
+		return WLAN_PHYMODE_11AC_VHT80_80;
+	case MODE_11AX_HE160:
+		return WLAN_PHYMODE_11AC_VHT160;
+	case MODE_11AX_HE20_2G:
+		return WLAN_PHYMODE_11AC_VHT20;
+	case MODE_11AX_HE40_2G:
+		return WLAN_PHYMODE_11AC_VHT40;
+	case MODE_11AX_HE80_2G:
+		return WLAN_PHYMODE_11AC_VHT80;
+	}
+	return WLAN_PHYMODE_AUTO;
+}
+#else
+static enum wlan_phymode wma_fw_to_host_phymode_11ac(WLAN_PHY_MODE phymode)
+{
+	return WLAN_PHYMODE_AUTO;
+}
+#endif
+
+#ifdef CONFIG_160MHZ_SUPPORT
+/**
+ * wma_fw_to_host_phymode_160() - convert fw to host phymode for 160 mhz
+ * phymodes
+ * @wma:     wma handle
+ * @phymode: phymode to convert
+ *
+ * Return: None
+ */
+static enum wlan_phymode wma_fw_to_host_phymode_160(WLAN_PHY_MODE phymode)
+{
+	switch (phymode) {
+	default:
+		return WLAN_PHYMODE_AUTO;
+	case MODE_11AC_VHT80_80:
+		return WLAN_PHYMODE_11AC_VHT80_80;
+	case MODE_11AC_VHT160:
+		return WLAN_PHYMODE_11AC_VHT160;
+	}
+}
+#else
+static enum wlan_phymode wma_fw_to_host_phymode_160(WLAN_PHY_MODE phymode)
+{
+	return WLAN_PHYMODE_AUTO;
+}
+#endif
+/**
+ * wma_fw_to_host_phymode() - convert fw to host phymode
+ * @wma:     wma handle
+ * @phymode: phymode to convert
+ *
+ * Return: None
+ */
+static enum wlan_phymode wma_fw_to_host_phymode(WLAN_PHY_MODE phymode)
+{
+	enum wlan_phymode host_phymode;
+	switch (phymode) {
+	default:
+		host_phymode = wma_fw_to_host_phymode_160(phymode);
+		if (host_phymode != WLAN_PHYMODE_AUTO)
+			return host_phymode;
+		return wma_fw_to_host_phymode_11ac(phymode);
+	case MODE_11A:
+		return WLAN_PHYMODE_11A;
+	case MODE_11G:
+		return WLAN_PHYMODE_11G;
+	case MODE_11B:
+		return WLAN_PHYMODE_11B;
+	case MODE_11GONLY:
+		return WLAN_PHYMODE_11G;
+	case MODE_11NA_HT20:
+		return WLAN_PHYMODE_11NA_HT20;
+	case MODE_11NG_HT20:
+		return WLAN_PHYMODE_11NG_HT20;
+	case MODE_11NA_HT40:
+		return WLAN_PHYMODE_11NA_HT40;
+	case MODE_11NG_HT40:
+		return WLAN_PHYMODE_11NG_HT40;
+	case MODE_11AC_VHT20:
+		return WLAN_PHYMODE_11AC_VHT20;
+	case MODE_11AC_VHT40:
+		return WLAN_PHYMODE_11AC_VHT40;
+	case MODE_11AC_VHT80:
+		return WLAN_PHYMODE_11AC_VHT80;
+	case MODE_11AC_VHT20_2G:
+		return WLAN_PHYMODE_11AC_VHT20;
+	case MODE_11AC_VHT40_2G:
+		return WLAN_PHYMODE_11AC_VHT40;
+	case MODE_11AC_VHT80_2G:
+		return WLAN_PHYMODE_11AC_VHT80;
+	}
+}
+
+/**
+ * wma_objmgr_set_peer_mlme_phymode() - set phymode to peer object
+ * @wma:      wma handle
+ * @mac_addr: mac addr of peer
+ * @phymode:  phymode value to set
+ *
+ * Return: None
+ */
+static void wma_objmgr_set_peer_mlme_phymode(tp_wma_handle wma,
+					     uint8_t *mac_addr,
+					     WLAN_PHY_MODE phymode)
+{
+	uint8_t pdev_id;
+	struct wlan_objmgr_peer *peer;
+	struct wlan_objmgr_psoc *psoc = wma->psoc;
+
+	pdev_id = wlan_objmgr_pdev_get_pdev_id(wma->pdev);
+	peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr,
+				    WLAN_LEGACY_WMA_ID);
+	if (!peer) {
+		WMA_LOGE(FL("peer object null"));
+		return;
+	}
+
+	wlan_peer_obj_lock(peer);
+	wlan_peer_set_phymode(peer, wma_fw_to_host_phymode(phymode));
+	wlan_peer_obj_unlock(peer);
+	wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
+}
+
 /**
  * wmi_unified_send_peer_assoc() - send peer assoc command to fw
  * @wma: wma handle
@@ -1072,6 +1214,8 @@ QDF_STATUS wma_send_peer_assoc(tp_wma_handle wma,
 				   params->htCapable, params->ch_width,
 				   params->vhtCapable, is_he);
 
+	wma_objmgr_set_peer_mlme_phymode(wma, params->staMac, phymode);
+
 	if (wlan_cfg_get_int(wma->mac_context,
 			     WNI_CFG_DISABLE_ABG_RATE_FOR_TX_DATA,
 			     &disable_abg_rate) != eSIR_SUCCESS)

+ 1 - 1
core/wma/src/wma_nan_datapath.c

@@ -65,7 +65,7 @@ void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss)
 		goto send_fail_resp;
 	}
 
-	wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss);
+	wma_set_bss_rate_flags(wma, vdev_id, add_bss);
 
 	peer = cdp_peer_find_by_addr(soc,
 			pdev,

+ 12 - 12
core/wma/src/wma_utils.c

@@ -183,17 +183,8 @@ static inline uint16_t wma_mcs_rate_match(uint16_t match_rate, bool *is_sgi,
 		return 0;
 }
 
-/**
- * wma_get_mcs_idx() - get mcs index
- * @maxRate: max rate
- * @rate_flags: rate flags
- * @nss: number of nss
- * @mcsRateFlag: mcs rate flag
- *
- * Return: return mcs index
- */
-static uint8_t wma_get_mcs_idx(uint16_t maxRate, uint8_t rate_flags,
-			       uint8_t nss, uint8_t *mcsRateFlag)
+uint8_t wma_get_mcs_idx(uint16_t maxRate, uint8_t rate_flags,
+			uint8_t nss, uint8_t *mcsRateFlag)
 {
 	uint8_t  index = 0;
 	uint16_t match_rate = 0;
@@ -287,6 +278,7 @@ rate_found:
 	return match_rate ? index : INVALID_MCS_IDX;
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 /**
  * wma_peek_vdev_req() - peek what request message is queued for response.
  *			 the function does not delete the node after found
@@ -332,6 +324,7 @@ static struct wma_target_req *wma_peek_vdev_req(tp_wma_handle wma,
 		 vdev_id, type, req_msg->msg_type);
 	return req_msg;
 }
+#endif /* QCA_SUPPORT_CP_STATS */
 
 void wma_lost_link_info_handler(tp_wma_handle wma, uint32_t vdev_id,
 					int32_t rssi)
@@ -2377,6 +2370,7 @@ void wma_config_stats_ext_threshold(tp_wma_handle wma,
 
 #endif /* WLAN_FEATURE_LINK_LAYER_STATS */
 
+#ifndef QCA_SUPPORT_CP_STATS
 /**
  * wma_update_pdev_stats() - update pdev stats
  * @wma: wma handle
@@ -2678,6 +2672,7 @@ static void wma_update_peer_stats(tp_wma_handle wma,
 		}
 	}
 }
+#endif /* WMA_GET_STATISTICS_RSP */
 
 /**
  * wma_post_link_status() - post link status to SME
@@ -2704,6 +2699,7 @@ void wma_post_link_status(tAniGetLinkStatus *pGetLinkStatus,
 	}
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 /**
  * wma_update_per_chain_rssi_stats() - to store per chain rssi stats
  * @wma: wma handle
@@ -2803,7 +2799,7 @@ static void wma_update_rssi_stats(tp_wma_handle wma,
 		}
 	}
 }
-
+#endif /* QCA_SUPPORT_CP_STATS */
 
 /**
  * wma_link_status_event_handler() - link status event handler
@@ -2910,6 +2906,7 @@ int wma_rso_cmd_status_event_handler(wmi_roam_event_fixed_param *wmi_event)
 	return 0;
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 /**
  * wma_handle_sta_peer_info() - handle peer information in
  * peer stats
@@ -3199,6 +3196,7 @@ int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info,
 
 	return 0;
 }
+#endif /* QCA_SUPPORT_CP_STATS */
 
 /**
  * wma_fill_peer_info() - fill SIR peer info from WMI peer info struct
@@ -3836,6 +3834,7 @@ int32_t wma_set_txrx_fw_stats_level(tp_wma_handle wma_handle,
 	return 0;
 }
 
+#ifndef QCA_SUPPORT_CP_STATS
 /**
  * wma_get_stats_rsp_buf() - fill get stats response buffer
  * @get_stats_param: get stats parameters
@@ -3957,6 +3956,7 @@ end:
 	qdf_mem_free(get_stats_param);
 	WMA_LOGD("%s: Exit", __func__);
 }
+#endif /* QCA_SUPPORT_CP_STATS */
 
 /**
  * wma_get_cca_stats() - send request to fw to get CCA