Эх сурвалжийг харах

qcacmn: CFR: Update RCC specific debug statistics

Move RCC specific debug statistics to Data path
to avoid allocating nbuf for the PPDUs for which
MAC has not sent a Freeze TLV. Instead just update the
debug statistics at an earlier point irrespective of
MAC sending Freeze to PHY, to gather below information:
Status of number of PPDUs being captured by PHY
Status of MAC sending freeze TLV for the PPDUs
Update freeze reason for the number of PPDUs received

Add support to clear debug statistics at user's will.

Change-Id: I8def3ce1f3ecc0b169030704db3fb1fb1c0a20ee
CRs-Fixed: 2609604
Adwait Nayak 5 жил өмнө
parent
commit
48d23f29a1

+ 48 - 0
dp/inc/cdp_txrx_ctrl.h

@@ -889,6 +889,54 @@ void cdp_set_cfr_rcc(ol_txrx_soc_handle soc, uint8_t pdev_id, bool enable)
 
 	return soc->ops->cfr_ops->txrx_set_cfr_rcc(soc, pdev_id, enable);
 }
+
+/**
+ * cdp_get_cfr_dbg_stats() - Get debug statistics for CFR
+ *
+ * @soc: SOC TXRX handle
+ * @pdev_id: ID of the physical device object
+ * @buf: CFR RCC debug statistics buffer
+ *
+ * Return: None
+ */
+static inline void
+cdp_get_cfr_dbg_stats(ol_txrx_soc_handle soc, uint8_t pdev_id,
+		      struct cdp_cfr_rcc_stats *buf)
+{
+	if (!soc || !soc->ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		QDF_BUG(0);
+		return;
+	}
+
+	if (!soc->ops->cfr_ops || !soc->ops->cfr_ops->txrx_get_cfr_dbg_stats)
+		return;
+
+	soc->ops->cfr_ops->txrx_get_cfr_dbg_stats(soc, pdev_id, buf);
+}
+
+/**
+ * cdp_cfr_clr_dbg_stats() - Clear debug statistics for CFR
+ *
+ * @soc: SOC TXRX handle
+ * @pdev_id: ID of the physical device object
+ */
+static inline void
+cdp_cfr_clr_dbg_stats(ol_txrx_soc_handle soc, uint8_t pdev_id)
+{
+	if (!soc || !soc->ops) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
+			  "%s invalid instance", __func__);
+		QDF_BUG(0);
+		return;
+	}
+
+	if (!soc->ops->cfr_ops || !soc->ops->cfr_ops->txrx_clear_cfr_dbg_stats)
+		return;
+
+	soc->ops->cfr_ops->txrx_clear_cfr_dbg_stats(soc, pdev_id);
+}
 #endif
 
 #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH)

+ 7 - 0
dp/inc/cdp_txrx_ops.h

@@ -1599,6 +1599,8 @@ struct cdp_rx_offld_ops {
  * @txrx_cfr_filter: Handler to configure host rx monitor status ring
  * @txrx_get_cfr_rcc: Handler to get CFR mode
  * @txrx_set_cfr_rcc: Handler to enable/disable CFR mode
+ * @txrx_get_cfr_dbg_stats: Handler to get debug statistics for CFR mode
+ * @txrx_clear_cfr_dbg_stats: Handler to clear debug statistics for CFR mode
  */
 struct cdp_cfr_ops {
 	void (*txrx_cfr_filter)(struct cdp_soc_t *soc_hdl,
@@ -1610,6 +1612,11 @@ struct cdp_cfr_ops {
 	void (*txrx_set_cfr_rcc)(struct cdp_soc_t *soc_hdl,
 				 uint8_t pdev_id,
 				 bool enable);
+	void (*txrx_get_cfr_dbg_stats)(struct cdp_soc_t *soc_hdl,
+				       uint8_t pdev_id,
+				       struct cdp_cfr_rcc_stats *buf);
+	void (*txrx_clear_cfr_dbg_stats)(struct cdp_soc_t *soc_hdl,
+					 uint8_t pdev_id);
 };
 #endif
 

+ 77 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -1553,6 +1553,82 @@ struct cdp_htt_rx_pdev_stats {
 #define OFDMA_NUM_RU_SIZE 7
 
 #define OFDMA_NUM_USERS	37
+
+#if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
+/*
+ * mac_freeze_capture_reason - capture reason counters
+ * @FREEZE_REASON_TM: When m_directed_ftm is enabled, this CFR data is
+ * captured for a Timing Measurement (TM) frame.
+ * @FREEZE_REASON_FTM: When m_directed_ftm is enabled, this CFR data is
+ * captured for a Fine Timing Measurement (FTM) frame.
+ * @FREEZE_REASON_ACK_RESP_TO_TM_FTM: When m_all_ftm_ack is enabled, this CFR
+ * data is captured for an ACK received for the FTM/TM frame sent to a station.
+ * @FREEZE_REASON_TA_RA_TYPE_FILTER: When m_ta_ra_filter is enabled, this CFR
+ * data is captured for a PPDU received,since the CFR TA_RA filter is met.
+ * @FREEZE_REASON_NDPA_NDP: When m_ndpa_ndp_directed(or)m_ndpa_ndp_all is
+ * enabled, this CFR data is captured for an NDP frame received.
+ * @FREEZE_REASON_ALL_PACKET: When m_all_packet is enabled, this CFR data is
+ * captured for an incoming PPDU.
+ */
+enum mac_freeze_capture_reason {
+	FREEZE_REASON_TM = 0,
+	FREEZE_REASON_FTM,
+	FREEZE_REASON_ACK_RESP_TO_TM_FTM,
+	FREEZE_REASON_TA_RA_TYPE_FILTER,
+	FREEZE_REASON_NDPA_NDP,
+	FREEZE_REASON_ALL_PACKET,
+	FREEZE_REASON_MAX,
+};
+
+/*
+ * chan_capture_status: capture status counters
+ * @CAPTURE_IDLE: CFR data is not captured, since VCSR setting for CFR/RCC is
+ * not enabled.
+ * @CAPTURE_BUSY: CFR data is not available, since previous channel
+ * upload is in progress
+ * @CAPTURE_ACTIVE: CFR data is captured in HW registers
+ * @CAPTURE_NO_BUFFER: CFR data is not captured, since no buffer is available
+ * in IPC ring to DMA CFR data
+ */
+enum chan_capture_status {
+	CAPTURE_IDLE = 0,
+	CAPTURE_BUSY,
+	CAPTURE_ACTIVE,
+	CAPTURE_NO_BUFFER,
+	CAPTURE_MAX,
+};
+
+/* struct cdp_cfr_rcc_stats - CFR RCC debug statistics
+ * @bb_captured_channel_cnt: No. of PPDUs for which MAC sent Freeze TLV to PHY
+ * @bb_captured_timeout_cnt: No. of PPDUs for which CFR filter criteria matched
+ * but MAC did not send Freeze TLV to PHY as time exceeded freeze tlv delay
+ * count threshold
+ * @rx_loc_info_valid_cnt: No. of PPDUs for which PHY could find a valid buffer
+ * in ucode IPC ring
+ * @chan_capture_status[]: capture status counters
+ *	[0] - No. of PPDUs with capture status CAPTURE_IDLE
+ *	[1] - No. of PPDUs with capture status CAPTURE_BUSY
+ *	[2] - No. of PPDUs with capture status CAPTURE_ACTIVE
+ *	[3] - No. of PPDUs with capture status CAPTURE_NO_BUFFER
+ * @reason_cnt[]: capture reason counters
+ *	[0] - No. PPDUs filtered due to freeze_reason_TM
+ *	[1] - No. PPDUs filtered due to freeze_reason_FTM
+ *	[2] - No. PPDUs filtered due to freeze_reason_ACK_resp_to_TM_FTM
+ *	[3] - No. PPDUs filtered due to freeze_reason_TA_RA_TYPE_FILTER
+ *	[4] - No. PPDUs filtered due to freeze_reason_NDPA_NDP
+ *	[5] - No. PPDUs filtered due to freeze_reason_ALL_PACKET
+ */
+struct cdp_cfr_rcc_stats {
+	uint64_t bb_captured_channel_cnt;
+	uint64_t bb_captured_timeout_cnt;
+	uint64_t rx_loc_info_valid_cnt;
+	uint64_t chan_capture_status[CAPTURE_MAX];
+	uint64_t reason_cnt[FREEZE_REASON_MAX];
+};
+#else
+struct cdp_cfr_rcc_stats {
+};
+#endif
 /* struct cdp_pdev_stats - pdev stats
  * @msdu_not_done: packets dropped because msdu done bit not set
  * @mec:Multicast Echo check
@@ -1649,6 +1725,7 @@ struct cdp_pdev_stats {
 	} ul_ofdma;
 
 	struct cdp_tso_stats tso_stats;
+	struct cdp_cfr_rcc_stats rcc;
 };
 
 #ifdef QCA_ENH_V3_STATS_SUPPORT

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

@@ -180,6 +180,11 @@ static void dp_cfr_filter(struct cdp_soc_t *soc_hdl,
 static bool dp_get_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
 static void dp_set_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 			   bool enable);
+static inline void
+dp_get_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
+		     struct cdp_cfr_rcc_stats *cfr_rcc_stats);
+static inline void
+dp_clear_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
 #endif
 static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc,
 					    enum hal_ring_type ring_type,
@@ -10240,6 +10245,8 @@ static struct cdp_cfr_ops dp_ops_cfr = {
 	.txrx_cfr_filter = dp_cfr_filter,
 	.txrx_get_cfr_rcc = dp_get_cfr_rcc,
 	.txrx_set_cfr_rcc = dp_set_cfr_rcc,
+	.txrx_get_cfr_dbg_stats = dp_get_cfr_dbg_stats,
+	.txrx_clear_cfr_dbg_stats = dp_clear_cfr_dbg_stats,
 };
 #endif
 
@@ -11328,6 +11335,51 @@ void dp_set_cfr_rcc(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, bool enable)
 
 	pdev->cfr_rcc_mode = enable;
 }
+
+/*
+ * dp_get_cfr_dbg_stats - Get the debug statistics for CFR
+ * @soc_hdl: Datapath soc handle
+ * @pdev_id: id of data path pdev handle
+ * @cfr_rcc_stats: CFR RCC debug statistics buffer
+ *
+ * Return: none
+ */
+static inline void
+dp_get_cfr_dbg_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
+		     struct cdp_cfr_rcc_stats *cfr_rcc_stats)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
+
+	if (!pdev) {
+		dp_err("Invalid pdev");
+		return;
+	}
+
+	qdf_mem_copy(cfr_rcc_stats, &pdev->stats.rcc,
+		     sizeof(struct cdp_cfr_rcc_stats));
+}
+
+/*
+ * dp_clear_cfr_dbg_stats - Clear debug statistics for CFR
+ * @soc_hdl: Datapath soc handle
+ * @pdev_id: id of data path pdev handle
+ *
+ * Return: none
+ */
+static void dp_clear_cfr_dbg_stats(struct cdp_soc_t *soc_hdl,
+				   uint8_t pdev_id)
+{
+	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
+	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
+
+	if (!pdev) {
+		dp_err("dp pdev is NULL");
+		return;
+	}
+
+	qdf_mem_zero(&pdev->stats.rcc, sizeof(pdev->stats.rcc));
+}
 #endif
 
 /*

+ 151 - 71
dp/wifi3.0/dp_rx_mon_status.c

@@ -37,7 +37,7 @@
 static inline void
 dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev,
 				 struct hal_rx_ppdu_info *ppdu_info,
-				 qdf_nbuf_t ppdu_nbuf);
+				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu);
 
 #ifdef WLAN_RX_PKT_CAPTURE_ENH
 #include "dp_rx_mon_feature.h"
@@ -152,19 +152,19 @@ dp_rx_inc_rusize_cnt(struct dp_pdev *pdev,
  * dp_rx_populate_cdp_indication_ppdu_user() - Populate per user cdp indication
  * @pdev: pdev ctx
  * @ppdu_info: ppdu info structure from ppdu ring
- * @ppdu_nbuf: qdf nbuf abstraction for linux skb
+ * @cdp_rx_ppdu: Rx PPDU indication structure
  *
  * Return: none
  */
 static inline void
 dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev,
 					struct hal_rx_ppdu_info *ppdu_info,
-					qdf_nbuf_t ppdu_nbuf)
+					struct cdp_rx_indication_ppdu
+					*cdp_rx_ppdu)
 {
 	struct dp_peer *peer;
 	struct dp_soc *soc = pdev->soc;
 	struct dp_ast_entry *ast_entry;
-	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
 	uint32_t ast_index;
 	int i;
 	struct mon_rx_user_status *rx_user_status;
@@ -173,8 +173,6 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev,
 	bool is_data = false;
 	uint32_t num_users;
 
-	cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
-
 	num_users = ppdu_info->com_info.num_users;
 	for (i = 0; i < num_users; i++) {
 		if (i > OFDMA_NUM_USERS)
@@ -291,27 +289,24 @@ dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev,
 }
 
 /**
-* dp_rx_populate_cdp_indication_ppdu() - Populate cdp rx indication structure
-* @pdev: pdev ctx
-* @ppdu_info: ppdu info structure from ppdu ring
-* @ppdu_nbuf: qdf nbuf abstraction for linux skb
-*
-* Return: none
-*/
+ * dp_rx_populate_cdp_indication_ppdu() - Populate cdp rx indication structure
+ * @pdev: pdev ctx
+ * @ppdu_info: ppdu info structure from ppdu ring
+ * @cdp_rx_ppdu: Rx PPDU indication structure
+ *
+ * Return: none
+ */
 static inline void
 dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev,
-	struct hal_rx_ppdu_info *ppdu_info,
-	qdf_nbuf_t ppdu_nbuf)
+				   struct hal_rx_ppdu_info *ppdu_info,
+				   struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
 	struct dp_peer *peer;
 	struct dp_soc *soc = pdev->soc;
 	struct dp_ast_entry *ast_entry;
-	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
 	uint32_t ast_index;
 	uint32_t i;
 
-	cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
-
 	cdp_rx_ppdu->first_data_seq_ctrl =
 		ppdu_info->rx_status.first_data_seq_ctrl;
 	cdp_rx_ppdu->frame_ctrl =
@@ -324,11 +319,11 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev,
 	cdp_rx_ppdu->num_mpdu = ppdu_info->com_info.mpdu_cnt_fcs_ok;
 	/* num msdu is consolidated and added together in num user loop */
 	cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count +
-			cdp_rx_ppdu->udp_msdu_count +
-			cdp_rx_ppdu->other_msdu_count);
+				 cdp_rx_ppdu->udp_msdu_count +
+				 cdp_rx_ppdu->other_msdu_count);
 
 	cdp_rx_ppdu->retries = CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl) ?
-					ppdu_info->com_info.mpdu_cnt_fcs_ok : 0;
+		ppdu_info->com_info.mpdu_cnt_fcs_ok : 0;
 
 	if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1)
 		cdp_rx_ppdu->is_ampdu = 1;
@@ -400,17 +395,17 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev,
 	cdp_rx_ppdu->num_mpdu = 0;
 	cdp_rx_ppdu->num_msdu = 0;
 
-	dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, ppdu_nbuf);
+	dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu);
 
 	return;
 end:
-	dp_rx_populate_cfr_non_assoc_sta(pdev, ppdu_info, ppdu_nbuf);
+	dp_rx_populate_cfr_non_assoc_sta(pdev, ppdu_info, cdp_rx_ppdu);
 }
 #else
 static inline void
 dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev,
-		struct hal_rx_ppdu_info *ppdu_info,
-		qdf_nbuf_t ppdu_nbuf)
+				   struct hal_rx_ppdu_info *ppdu_info,
+				   struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
 }
 #endif
@@ -926,30 +921,24 @@ dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
  * for an UL-MU-PPDU
  * @pdev: pdev ctx
  * @ppdu_info: pointer to ppdu info structure populated from ppdu status TLVs
- * @ppdu_nbuf: qdf nbuf abstraction for linux skb
+ * @cdp_rx_ppdu: Rx PPDU indication structure
  *
  * Return: none
  */
 static inline void
 dp_rx_mon_handle_cfr_mu_info(struct dp_pdev *pdev,
 			     struct hal_rx_ppdu_info *ppdu_info,
-			     qdf_nbuf_t ppdu_nbuf)
+			     struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
 	struct dp_peer *peer;
 	struct dp_soc *soc = pdev->soc;
 	struct dp_ast_entry *ast_entry;
-	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
 	struct mon_rx_user_status *rx_user_status;
 	struct cdp_rx_stats_ppdu_user *rx_stats_peruser;
 	uint32_t num_users;
 	int user_id;
 	uint32_t ast_index;
 
-	if (!ppdu_info->cfr_info.bb_captured_channel)
-		return;
-
-	cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
-
 	qdf_spin_lock_bh(&soc->ast_lock);
 
 	num_users = ppdu_info->com_info.num_users;
@@ -992,19 +981,17 @@ dp_rx_mon_handle_cfr_mu_info(struct dp_pdev *pdev,
  * info
  * @pdev: pdev ctx
  * @ppdu_info: ppdu info structure from ppdu ring
- * @ppdu_nbuf: qdf nbuf abstraction for linux skb
+ * @cdp_rx_ppdu : Rx PPDU indication structure
  *
  * Return: none
  */
 static inline void
 dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev,
 				 struct hal_rx_ppdu_info *ppdu_info,
-				 qdf_nbuf_t ppdu_nbuf)
+				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
-	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
 	int chain;
 
-	cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
 	cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id;
 	cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft;
 	cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type;
@@ -1013,29 +1000,40 @@ dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev,
 	for (chain = 0; chain < MAX_CHAIN; chain++)
 		cdp_rx_ppdu->per_chain_rssi[chain] =
 			ppdu_info->rx_status.rssi[chain];
-	dp_rx_mon_handle_cfr_mu_info(pdev, ppdu_info, ppdu_nbuf);
+	dp_rx_mon_handle_cfr_mu_info(pdev, ppdu_info, cdp_rx_ppdu);
+}
+
+/**
+ * dp_cfr_rcc_mode_status() - Return status of cfr rcc mode
+ * @pdev: pdev ctx
+ *
+ * Return: True or False
+ */
+
+static inline bool
+dp_cfr_rcc_mode_status(struct dp_pdev *pdev)
+{
+	return pdev->cfr_rcc_mode;
 }
 
 /*
  * dp_rx_mon_populate_cfr_info() - Populate cdp ppdu info from hal cfr info
  * @pdev: pdev ctx
  * @ppdu_info: ppdu info structure from ppdu ring
- * @ppdu_nbuf: qdf nbuf abstraction for linux skb
+ * @cdp_rx_ppdu: Rx PPDU indication structure
  *
  * Return: none
  */
 static inline void
 dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev,
 			    struct hal_rx_ppdu_info *ppdu_info,
-			    qdf_nbuf_t ppdu_nbuf)
+			    struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
-	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
 	struct cdp_rx_ppdu_cfr_info *cfr_info;
 
-	if (qdf_unlikely(!pdev->cfr_rcc_mode))
+	if (!dp_cfr_rcc_mode_status(pdev))
 		return;
 
-	cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
 	cfr_info = &cdp_rx_ppdu->cfr_info;
 
 	cfr_info->bb_captured_channel
@@ -1054,6 +1052,37 @@ dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev,
 		= ppdu_info->cfr_info.rtt_che_buffer_pointer_low32;
 }
 
+/**
+ * dp_update_cfr_dbg_stats() - Increment RCC debug statistics
+ * @pdev: pdev structure
+ * @ppdu_info: structure for rx ppdu ring
+ *
+ * Return: none
+ */
+static inline void
+dp_update_cfr_dbg_stats(struct dp_pdev *pdev,
+			struct hal_rx_ppdu_info *ppdu_info)
+{
+	struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info;
+
+	DP_STATS_INC(pdev,
+		     rcc.chan_capture_status[cfr->chan_capture_status], 1);
+	if (cfr->rx_location_info_valid) {
+		DP_STATS_INC(pdev, rcc.rx_loc_info_valid_cnt, 1);
+		if (cfr->bb_captured_channel) {
+			DP_STATS_INC(pdev, rcc.bb_captured_channel_cnt, 1);
+			DP_STATS_INC(pdev,
+				     rcc.reason_cnt[cfr->bb_captured_reason],
+				     1);
+		} else if (cfr->bb_captured_timeout) {
+			DP_STATS_INC(pdev, rcc.bb_captured_timeout_cnt, 1);
+			DP_STATS_INC(pdev,
+				     rcc.reason_cnt[cfr->bb_captured_reason],
+				     1);
+		}
+	}
+}
+
 /*
  * dp_rx_handle_cfr() - Gather cfr info from hal ppdu info
  * @soc: core txrx main context
@@ -1067,9 +1096,10 @@ dp_rx_handle_cfr(struct dp_soc *soc, struct dp_pdev *pdev,
 		 struct hal_rx_ppdu_info *ppdu_info)
 {
 	qdf_nbuf_t ppdu_nbuf;
+	struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
 
-	if (!ppdu_info->cfr_info.bb_captured_channel &&
-	    !ppdu_info->cfr_info.bb_captured_timeout)
+	dp_update_cfr_dbg_stats(pdev, ppdu_info);
+	if (!ppdu_info->cfr_info.bb_captured_channel)
 		return;
 
 	ppdu_nbuf = qdf_nbuf_alloc(soc->osdev,
@@ -1078,8 +1108,10 @@ dp_rx_handle_cfr(struct dp_soc *soc, struct dp_pdev *pdev,
 				   0,
 				   FALSE);
 	if (ppdu_nbuf) {
-		dp_rx_mon_populate_cfr_info(pdev, ppdu_info, ppdu_nbuf);
-		dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, ppdu_nbuf);
+		cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
+
+		dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu);
+		dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, cdp_rx_ppdu);
 		qdf_nbuf_put_tail(ppdu_nbuf,
 				  sizeof(struct cdp_rx_indication_ppdu));
 		dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc,
@@ -1093,40 +1125,62 @@ dp_rx_handle_cfr(struct dp_soc *soc, struct dp_pdev *pdev,
  * non-associated stations
  * @pdev: pdev ctx
  * @ppdu_info: ppdu info structure from ppdu ring
- * @ppdu_nbuf: qdf nbuf abstraction for linux skb
+ * @cdp_rx_ppdu: Rx PPDU indication structure
  *
  * Return: none
  */
 static inline void
 dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev,
 				 struct hal_rx_ppdu_info *ppdu_info,
-				 qdf_nbuf_t ppdu_nbuf)
+				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
-	if (!pdev->cfr_rcc_mode)
+	if (!dp_cfr_rcc_mode_status(pdev))
 		return;
 
 	if (ppdu_info->cfr_info.bb_captured_channel)
-		dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, ppdu_nbuf);
+		dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, cdp_rx_ppdu);
+}
+
+/**
+ * dp_bb_captured_chan_status() - Get the bb_captured_channel status
+ * @ppdu_info: structure for rx ppdu ring
+ *
+ * Return: Success/ Failure
+ */
+
+static inline QDF_STATUS
+dp_bb_captured_chan_status(struct dp_pdev *pdev,
+			   struct hal_rx_ppdu_info *ppdu_info)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+	struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info;
+
+	if (dp_cfr_rcc_mode_status(pdev)) {
+		if (cfr->bb_captured_channel)
+			status = QDF_STATUS_SUCCESS;
+	}
+
+	return status;
 }
 #else
 static inline void
 dp_rx_mon_handle_cfr_mu_info(struct dp_pdev *pdev,
 			     struct hal_rx_ppdu_info *ppdu_info,
-			     qdf_nbuf_t ppdu_nbuf)
+			     struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
 }
 
 static inline void
 dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev,
 				 struct hal_rx_ppdu_info *ppdu_info,
-				 qdf_nbuf_t ppdu_nbuf)
+				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
 }
 
 static inline void
 dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev,
 			    struct hal_rx_ppdu_info *ppdu_info,
-			    qdf_nbuf_t ppdu_nbuf)
+			    struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
 {
 }
 
@@ -1139,8 +1193,27 @@ dp_rx_handle_cfr(struct dp_soc *soc, struct dp_pdev *pdev,
 static inline void
 dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev,
 				 struct hal_rx_ppdu_info *ppdu_info,
-				 qdf_nbuf_t ppdu_nbuf)
+				 struct cdp_rx_indication_ppdu *cdp_rx_ppdu)
+{
+}
+
+static inline void
+dp_update_cfr_dbg_stats(struct dp_pdev *pdev,
+			struct hal_rx_ppdu_info *ppdu_info)
+{
+}
+
+static inline QDF_STATUS
+dp_bb_captured_chan_status(struct dp_pdev *pdev,
+			   struct hal_rx_ppdu_info *ppdu_info)
+{
+	return QDF_STATUS_E_NOSUPPORT;
+}
+
+static inline bool
+dp_cfr_rcc_mode_status(struct dp_pdev *pdev)
 {
+	return false;
 }
 #endif
 
@@ -1190,28 +1263,35 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev,
 		qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex);
 	}
 
-	/* need not generate wdi event when mcopy and
+	/* need not generate wdi event when mcopy, cfr rcc mode and
 	 * enhanced stats are not enabled
 	 */
 	if (!pdev->mcopy_mode && !pdev->enhanced_stats_en &&
-	    !pdev->cfr_rcc_mode)
+	    !dp_cfr_rcc_mode_status(pdev))
 		return;
 
-	if (!pdev->mcopy_mode && !pdev->cfr_rcc_mode) {
-		if (!ppdu_info->rx_status.frame_control_info_valid)
-			return;
+	if (dp_cfr_rcc_mode_status(pdev))
+		dp_update_cfr_dbg_stats(pdev, ppdu_info);
 
-		if (ppdu_info->rx_status.ast_index == HAL_AST_IDX_INVALID)
+	if (!ppdu_info->rx_status.frame_control_info_valid ||
+	    (ppdu_info->rx_status.ast_index == HAL_AST_IDX_INVALID)) {
+		if (!(pdev->mcopy_mode ||
+		      (dp_bb_captured_chan_status(pdev, ppdu_info) ==
+		       QDF_STATUS_SUCCESS)))
 			return;
 	}
+
 	ppdu_nbuf = qdf_nbuf_alloc(soc->osdev,
-			sizeof(struct cdp_rx_indication_ppdu), 0, 0, FALSE);
+				   sizeof(struct cdp_rx_indication_ppdu),
+				   0, 0, FALSE);
 	if (ppdu_nbuf) {
-		dp_rx_mon_populate_cfr_info(pdev, ppdu_info, ppdu_nbuf);
-		dp_rx_populate_cdp_indication_ppdu(pdev, ppdu_info, ppdu_nbuf);
-		qdf_nbuf_put_tail(ppdu_nbuf,
-				sizeof(struct cdp_rx_indication_ppdu));
 		cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
+
+		dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu);
+		dp_rx_populate_cdp_indication_ppdu(pdev,
+						   ppdu_info, cdp_rx_ppdu);
+		qdf_nbuf_put_tail(ppdu_nbuf,
+				  sizeof(struct cdp_rx_indication_ppdu));
 		dp_rx_stats_update(pdev, cdp_rx_ppdu);
 
 		if (cdp_rx_ppdu->peer_id != HTT_INVALID_PEER) {
@@ -1219,10 +1299,10 @@ dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev,
 					     soc, ppdu_nbuf,
 					     cdp_rx_ppdu->peer_id,
 					     WDI_NO_VAL, pdev->pdev_id);
-		} else if (pdev->mcopy_mode || pdev->cfr_rcc_mode) {
+		} else if (pdev->mcopy_mode || dp_cfr_rcc_mode_status(pdev)) {
 			dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc,
-					ppdu_nbuf, HTT_INVALID_PEER,
-					WDI_NO_VAL, pdev->pdev_id);
+					     ppdu_nbuf, HTT_INVALID_PEER,
+					     WDI_NO_VAL, pdev->pdev_id);
 		} else {
 			qdf_nbuf_free(ppdu_nbuf);
 		}
@@ -1412,7 +1492,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
 		nbuf_used = false;
 
 		if ((pdev->monitor_vdev) || (pdev->enhanced_stats_en) ||
-		    pdev->mcopy_mode ||
+		    (pdev->mcopy_mode) || (dp_cfr_rcc_mode_status(pdev)) ||
 		    (rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED)) {
 			do {
 				tlv_status = hal_rx_status_get_tlv_info(rx_tlv,
@@ -1490,7 +1570,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
 			if (pdev->enhanced_stats_en ||
 			    pdev->mcopy_mode || pdev->neighbour_peers_added)
 				dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info);
-			else if (pdev->cfr_rcc_mode)
+			else if (dp_cfr_rcc_mode_status(pdev))
 				dp_rx_handle_cfr(soc, pdev, ppdu_info);
 
 			pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE;