浏览代码

qcacmn: Scan radio special vap stats support

-Add flag to inidicate special vap configuration
-Add frame type counters while processing tlv
 WIFIRX_MPDU_START_E
-Add function to update special vap rx stats
-Add dp pdev param to enable/disable special vap
 stats reset
-Add function to reset special vap stats
-Add fucntion to get special vap stats
-Add CDP function to retreive special vap stats

Change-Id: Ia5de6743e472dc86c9e66b9e789c909a57025e35
CRs-Fixed: 3005425
Jeevan Kukkalli 3 年之前
父节点
当前提交
1665e7c8e5

+ 23 - 0
dp/inc/cdp_txrx_cmn_struct.h

@@ -1115,6 +1115,7 @@ enum cdp_peer_param_type {
  * @CDP_CONFIG_BSS_COLOR: configure bss color
  * @CDP_SET_ATF_STATS_ENABLE: set ATF stats flag
  * @CDP_CONFIG_SPECIAL_VAP: Configure Special vap
+ * @CDP_RESET_SPCL_VAP_STATS_ENABLE: Enable spcl vap stats reset
  */
 enum cdp_pdev_param_type {
 	CDP_CONFIG_DEBUG_SNIFFER,
@@ -1146,6 +1147,7 @@ enum cdp_pdev_param_type {
 	CDP_CONFIG_BSS_COLOR,
 	CDP_SET_ATF_STATS_ENABLE,
 	CDP_CONFIG_SPECIAL_VAP,
+	CDP_RESET_SPCL_VAP_STATS_ENABLE,
 };
 
 /*
@@ -1279,6 +1281,7 @@ typedef union cdp_config_param_t {
 	uint32_t cdp_pdev_param_tx_pending;
 	bool cdp_pdev_param_atf_stats_enable;
 	bool cdp_pdev_param_config_special_vap;
+	bool cdp_pdev_param_reset_spcl_vap_stats_enable;
 
 	/* psoc params */
 	bool cdp_psoc_param_en_rate_stats;
@@ -2567,4 +2570,24 @@ struct cdp_rx_flow_info {
 	struct cdp_rx_flow_tuple_info flow_tuple_info;
 	uint16_t fse_metadata;
 };
+
+/**
+ * cdp_spcl_vap_stats - Special vap statistics info
+ * @rx_ok_pkts: rx fcs ok pkts count
+ * @rx_ok_bytes: rx fcs ok bytes count
+ * @rx_err_pkts: rx fcs err pkts count
+ * @rx_err_bytes: rx fcs err bytes count
+ * @rx_mgmt_pkts: rx mgmt pkts count
+ * @rx_ctrl_pkts: rx ctrl pkts count
+ * @rx_data_pkts: rx data pkts count
+ */
+struct cdp_spcl_vap_stats {
+	uint64_t rx_ok_pkts;
+	uint64_t rx_ok_bytes;
+	uint64_t rx_err_pkts;
+	uint64_t rx_err_bytes;
+	uint64_t rx_mgmt_pkts;
+	uint64_t rx_ctrl_pkts;
+	uint64_t rx_data_pkts;
+};
 #endif

+ 19 - 0
dp/inc/cdp_txrx_host_stats.h

@@ -733,4 +733,23 @@ cdp_host_get_radio_stats(ol_txrx_soc_handle soc,
 	return soc->ops->host_stats_ops->txrx_get_radio_stats(soc, pdev_id,
 							      buf);
 }
+
+static inline int
+cdp_get_spcl_vap_stats(ol_txrx_soc_handle soc,
+		       uint8_t vdev_id,
+		       struct cdp_spcl_vap_stats *stats)
+{
+	if (!soc || !soc->ops) {
+		dp_cdp_debug("Invalid Instance");
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!soc->ops->host_stats_ops ||
+	    !soc->ops->host_stats_ops->txrx_get_spcl_vap_stats)
+		return QDF_STATUS_E_FAILURE;
+
+	return soc->ops->host_stats_ops->txrx_get_spcl_vap_stats(soc, vdev_id,
+								 stats);
+}
 #endif /* _CDP_TXRX_HOST_STATS_H_ */

+ 4 - 0
dp/inc/cdp_txrx_ops.h

@@ -986,6 +986,10 @@ struct cdp_host_stats_ops {
 				  uint8_t *peer_mac, void *stats,
 				  uint32_t last_tx_rate_mcs,
 				  uint32_t stats_id);
+
+	QDF_STATUS
+	(*txrx_get_spcl_vap_stats)(struct cdp_soc_t *soc, uint8_t vdev_id,
+				   struct cdp_spcl_vap_stats *stats);
 };
 
 struct cdp_wds_ops {

+ 11 - 0
dp/wifi3.0/dp_internal.h

@@ -590,6 +590,17 @@ static inline bool monitor_is_enable_enhanced_stats(struct dp_pdev *pdev)
 {
 	return false;
 }
+
+static inline
+void dp_monitor_pdev_config_spcl_vap(struct dp_pdev *pdev)
+{
+}
+
+static inline
+void dp_monitor_pdev_reset_spcl_vap_stats_enable(struct dp_pdev *pdev,
+						 bool val)
+{
+}
 #endif
 
 #define DP_MAX_TIMER_EXEC_TIME_TICKS \

+ 6 - 0
dp/wifi3.0/dp_main.c

@@ -8528,8 +8528,14 @@ static QDF_STATUS dp_set_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id,
 					val.cdp_pdev_param_atf_stats_enable);
 		break;
 	case CDP_CONFIG_SPECIAL_VAP:
+		dp_monitor_pdev_config_spcl_vap(pdev,
+					val.cdp_pdev_param_config_special_vap);
 		monitor_vdev_set_monitor_mode_buf_rings(pdev);
 		break;
+	case CDP_RESET_SPCL_VAP_STATS_ENABLE:
+		dp_monitor_pdev_reset_spcl_vap_stats_enable(pdev,
+				val.cdp_pdev_param_reset_spcl_vap_stats_enable);
+		break;
 	default:
 		return QDF_STATUS_E_INVAL;
 	}

+ 48 - 0
dp/wifi3.0/monitor/dp_mon.c

@@ -610,6 +610,25 @@ dp_deliver_tx_mgmt(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, qdf_nbuf_t nbuf)
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * dp_reset_spcl_vap_stats() - reset spcl vap rx stats
+ * @vdev: Datapath VDEV handle
+ *
+ * Return: void
+ */
+static inline void
+dp_reset_spcl_vap_stats(struct dp_vdev *vdev)
+{
+	struct dp_mon_vdev *mon_vdev;
+
+	mon_vdev = vdev->monitor_vdev;
+	if (!mon_vdev)
+		return;
+
+	qdf_mem_zero(&mon_vdev->spcl_vap_stats,
+		     sizeof(mon_vdev->spcl_vap_stats));
+}
+
 /**
  * dp_vdev_set_monitor_mode() - Set DP VDEV to monitor mode
  * @vdev_handle: Datapath VDEV handle
@@ -657,6 +676,10 @@ static QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *dp_soc,
 		goto fail;
 	}
 
+	if (mon_pdev->spcl_vap_configured &&
+	    mon_pdev->reset_spcl_vap_stats_enable)
+		dp_reset_spcl_vap_stats(vdev);
+
 	/*Check if current pdev's monitor_vdev exists */
 	if (mon_pdev->monitor_configured) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
@@ -5251,6 +5274,29 @@ static void  dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl)
 }
 #endif
 
+static QDF_STATUS
+dp_get_spcl_vap_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
+		      struct cdp_spcl_vap_stats *stats)
+{
+	struct dp_mon_vdev *mon_vdev = NULL;
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
+						     DP_MOD_ID_CDP);
+
+	if (!vdev || !stats)
+		return QDF_STATUS_E_INVAL;
+
+	mon_vdev = vdev->monitor_vdev;
+	if (!mon_vdev)
+		return QDF_STATUS_E_INVAL;
+
+	qdf_mem_copy(stats, &mon_vdev->spcl_vap_stats,
+		     sizeof(struct cdp_spcl_vap_stats));
+
+	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
+	return QDF_STATUS_SUCCESS;
+}
+
 QDF_STATUS dp_mon_soc_cfg_init(struct dp_soc *soc)
 {
 	int target_type;
@@ -5670,6 +5716,8 @@ void dp_mon_cdp_ops_register(struct dp_soc *soc)
 #ifdef WDI_EVENT_ENABLE
 	ops->ctrl_ops->txrx_get_pldev = dp_get_pldev;
 #endif
+	ops->host_stats_ops->txrx_get_spcl_vap_stats =
+					dp_get_spcl_vap_stats;
 	return;
 }
 

+ 24 - 0
dp/wifi3.0/monitor/dp_mon.h

@@ -351,11 +351,16 @@ struct  dp_mon_pdev {
 
 	qdf_nbuf_t mcopy_status_nbuf;
 	bool is_dp_mon_pdev_initialized;
+	/* indicates if spcl vap is configured */
+	bool spcl_vap_configured;
+	/* enable spcl vap stats reset on ch change */
+	bool reset_spcl_vap_stats_enable;
 };
 
 struct  dp_mon_vdev {
 	/* callback to hand rx monitor 802.11 MPDU to the OS shim */
 	ol_txrx_rx_mon_fp osif_rx_mon;
+	struct cdp_spcl_vap_stats spcl_vap_stats;
 };
 
 struct dp_mon_peer {
@@ -2261,6 +2266,25 @@ void monitor_pdev_set_mon_vdev(struct dp_vdev *vdev)
 	mon_pdev->mvdev = vdev;
 }
 
+static inline
+void dp_monitor_pdev_config_spcl_vap(struct dp_pdev *pdev, bool val)
+{
+	if (!pdev || !pdev->monitor_pdev)
+		return;
+
+	pdev->monitor_pdev->spcl_vap_configured = val;
+}
+
+static inline
+void dp_monitor_pdev_reset_spcl_vap_stats_enable(struct dp_pdev *pdev,
+						 bool val)
+{
+	if (!pdev || !pdev->monitor_pdev)
+		return;
+
+	pdev->monitor_pdev->reset_spcl_vap_stats_enable = val;
+}
+
 QDF_STATUS dp_mon_soc_attach(struct dp_soc *soc);
 QDF_STATUS dp_mon_soc_detach(struct dp_soc *soc);
 QDF_STATUS dp_mon_pdev_attach(struct dp_pdev *pdev);

+ 50 - 0
dp/wifi3.0/monitor/dp_rx_mon_status.c

@@ -1730,6 +1730,51 @@ dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info)
 }
 #endif
 
+/**
+ * dp_rx_mon_update_spcl_vap_stats() - Update special vap stats
+ * @pdev: dp pdev context
+ * @ppdu_info: ppdu info structure from ppdu ring
+ *
+ * Return: none
+ */
+static inline void
+dp_rx_mon_update_spcl_vap_stats(struct dp_pdev *pdev,
+				struct hal_rx_ppdu_info *ppdu_info)
+{
+	struct mon_rx_user_status *rx_user_status = NULL;
+	struct dp_mon_pdev *mon_pdev = NULL;
+	struct dp_mon_vdev *mon_vdev = NULL;
+	uint32_t num_users = 0;
+	uint32_t user = 0;
+
+	mon_pdev = pdev->monitor_pdev;
+	if (!mon_pdev || !mon_pdev->mvdev)
+		return;
+
+	mon_vdev = mon_pdev->mvdev->monitor_vdev;
+	if (!mon_vdev)
+		return;
+
+	num_users = ppdu_info->com_info.num_users;
+	for (user = 0; user < num_users; user++) {
+		rx_user_status =  &ppdu_info->rx_user_status[user];
+		mon_vdev->spcl_vap_stats.rx_ok_pkts +=
+				rx_user_status->mpdu_cnt_fcs_ok;
+		mon_vdev->spcl_vap_stats.rx_ok_bytes +=
+				rx_user_status->mpdu_ok_byte_count;
+		mon_vdev->spcl_vap_stats.rx_err_pkts +=
+				rx_user_status->mpdu_cnt_fcs_err;
+		mon_vdev->spcl_vap_stats.rx_err_bytes +=
+				rx_user_status->mpdu_err_byte_count;
+	}
+	mon_vdev->spcl_vap_stats.rx_mgmt_pkts +=
+				ppdu_info->frm_type_info.rx_mgmt_cnt;
+	mon_vdev->spcl_vap_stats.rx_ctrl_pkts +=
+				ppdu_info->frm_type_info.rx_ctrl_cnt;
+	mon_vdev->spcl_vap_stats.rx_data_pkts +=
+				ppdu_info->frm_type_info.rx_data_cnt;
+}
+
 /**
  * dp_rx_mon_status_process_tlv() - Process status TLV in status
  *	buffer on Rx status Queue posted by status SRNG processing.
@@ -1873,6 +1918,11 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, struct dp_intr *int_ctx,
 
 			mon_pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE;
 
+			/* Collect spcl vap stats if configured */
+			if (mon_pdev->spcl_vap_configured)
+				dp_rx_mon_update_spcl_vap_stats(pdev,
+								ppdu_info);
+
 			/*
 			* if chan_num is not fetched correctly from ppdu RX TLV,
 			 * get it from pdev saved.

+ 15 - 0
hal/wifi3.0/hal_api_mon.h

@@ -162,6 +162,13 @@
 /* Max pilot count */
 #define HAL_RX_MAX_SU_EVM_COUNT 32
 
+#define HAL_RX_FRAMECTRL_TYPE_MASK 0x0C
+#define HAL_RX_GET_FRAME_CTRL_TYPE(fc)\
+		(((fc) & HAL_RX_FRAMECTRL_TYPE_MASK) >> 2)
+#define HAL_RX_FRAME_CTRL_TYPE_MGMT 0x0
+#define HAL_RX_FRAME_CTRL_TYPE_CTRL 0x1
+#define HAL_RX_FRAME_CTRL_TYPE_DATA 0x2
+
 /**
  * struct hal_rx_mon_desc_info () - HAL Rx Monitor descriptor info
  *
@@ -656,6 +663,12 @@ struct mon_rx_user_info {
 	uint8_t qos_control_info_valid;
 };
 
+struct hal_rx_frm_type_info {
+	uint32_t rx_mgmt_cnt;
+	uint32_t rx_ctrl_cnt;
+	uint32_t rx_data_cnt;
+};
+
 struct hal_rx_ppdu_info {
 	struct hal_rx_ppdu_common_info com_info;
 	struct mon_rx_status rx_status;
@@ -693,6 +706,8 @@ struct hal_rx_ppdu_info {
 	 * and for CFR correlation as well
 	 */
 	struct hal_rx_ppdu_cfr_info cfr_info;
+	/* per frame type counts */
+	struct hal_rx_frm_type_info frm_type_info;
 };
 
 static inline uint32_t

+ 15 - 0
hal/wifi3.0/li/hal_li_generic_api.h

@@ -1494,6 +1494,21 @@ hal_rx_status_get_tlv_info_generic_li(void *rx_tlv_hdr, void *ppduinfo,
 		uint8_t *rx_mpdu_start = (uint8_t *)rx_tlv;
 		uint32_t ppdu_id = HAL_RX_GET_PPDU_ID(rx_mpdu_start);
 		uint8_t filter_category = 0;
+		uint16_t frame_ctrl;
+		uint8_t fc_type;
+
+		if (HAL_RX_GET_FC_VALID(rx_mpdu_start)) {
+			frame_ctrl = HAL_RX_GET(rx_mpdu_start,
+						RX_MPDU_INFO_14,
+						MPDU_FRAME_CONTROL_FIELD);
+			fc_type = HAL_RX_GET_FRAME_CTRL_TYPE(frame_ctrl);
+			if (fc_type == HAL_RX_FRAME_CTRL_TYPE_MGMT)
+				ppdu_info->frm_type_info.rx_mgmt_cnt++;
+			else if (fc_type == HAL_RX_FRAME_CTRL_TYPE_CTRL)
+				ppdu_info->frm_type_info.rx_ctrl_cnt++;
+			else if (fc_type == HAL_RX_FRAME_CTRL_TYPE_DATA)
+				ppdu_info->frm_type_info.rx_data_cnt++;
+		}
 
 		ppdu_info->nac_info.fc_valid =
 				HAL_RX_GET_FC_VALID(rx_mpdu_start);