Explorar el Código

qcacmn: Add common framework for mon filters

A framework is added where the filters for every
mode are stored on a radio instance. Whenever a mode comes
up, it stores the filters in the radio and calls a
common API which iterates through all the enabled
mode filters and loops through them to create a
superset of filters which is sent to HTT.

This framework can be extended for new feature addition
which set filters for the monitor status and monitor
destination rings.

Change-Id: I9b739af2086bbe261b65c57af0a5bd867294f30f
CRs-Fixed: 2585872
Aniruddha Paul hace 5 años
padre
commit
f9d2c0f54e

+ 3 - 0
dp/inc/cdp_txrx_ctrl.h

@@ -65,6 +65,8 @@ cdp_mempools_attach(ol_txrx_soc_handle soc)
 	return soc->ops->ctrl_ops->txrx_mempools_attach(soc);
 }
 
+
+#if defined(ATH_SUPPORT_NAC) || defined(ATH_SUPPORT_NAC_RSSI)
 /**
  * @brief update the neighbour peer addresses
  * @details
@@ -95,6 +97,7 @@ cdp_update_filter_neighbour_peers(ol_txrx_soc_handle soc,
 	return soc->ops->ctrl_ops->txrx_update_filter_neighbour_peers
 			(soc, vdev_id, cmd, macaddr);
 }
+#endif /* ATH_SUPPORT_NAC || ATH_SUPPORT_NAC_RSSI*/
 
 /**
  * @brief set the Reo Destination ring for the pdev

+ 4 - 2
dp/inc/cdp_txrx_mon.h

@@ -27,7 +27,8 @@
 #include "cdp_txrx_handle.h"
 
 static inline QDF_STATUS cdp_reset_monitor_mode(ol_txrx_soc_handle soc,
-						uint8_t pdev_id)
+						uint8_t pdev_id,
+						u_int8_t smart_monitor)
 {
 	if (!soc || !soc->ops) {
 		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
@@ -40,7 +41,8 @@ static inline QDF_STATUS cdp_reset_monitor_mode(ol_txrx_soc_handle soc,
 	    !soc->ops->mon_ops->txrx_reset_monitor_mode)
 		return 0;
 
-	return soc->ops->mon_ops->txrx_reset_monitor_mode(soc, pdev_id);
+	return soc->ops->mon_ops->txrx_reset_monitor_mode(soc, pdev_id,
+							  smart_monitor);
 }
 
 /**

+ 2 - 2
dp/inc/cdp_txrx_ops.h

@@ -700,8 +700,8 @@ struct cdp_me_ops {
 
 struct cdp_mon_ops {
 
-	QDF_STATUS (*txrx_reset_monitor_mode)(ol_txrx_soc_handle soc,
-					      uint8_t pdev_id);
+	QDF_STATUS (*txrx_reset_monitor_mode)
+		(ol_txrx_soc_handle soc, uint8_t pdev_id, u_int8_t smart_monitor);
 
 	QDF_STATUS (*txrx_deliver_tx_mgmt)
 		(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, qdf_nbuf_t nbuf);

+ 3 - 1
dp/wifi3.0/dp_htt.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -200,6 +200,8 @@ struct htt_soc {
  * @rx_msdu_end_offset: Offset of rx_msdu_end tlv
  * @rx_msdu_start_offset: Offset of rx_msdu_start tlv
  * @rx_attn_offset: Offset of rx_attention tlv
+ *
+ * NOTE: Do not change the layout of this structure
  */
 struct htt_rx_ring_tlv_filter {
 	u_int32_t mpdu_start:1,

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

@@ -1977,5 +1977,15 @@ QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
 uint16_t dp_get_peer_mac_list(ol_txrx_soc_handle soc, uint8_t vdev_id,
 			      u_int8_t newmac[][QDF_MAC_ADDR_SIZE],
 			      u_int16_t mac_cnt);
+/*
+ * dp_is_hw_dbs_enable() - Procedure to check if DBS is supported
+ * @soc:		DP SoC context
+ * @max_mac_rings:	No of MAC rings
+ *
+ * Return: None
+ */
+void dp_is_hw_dbs_enable(struct dp_soc *soc,
+				int *max_mac_rings);
+
 
 #endif /* #ifndef _DP_INTERNAL_H_ */

+ 203 - 551
dp/wifi3.0/dp_main.c

@@ -49,6 +49,7 @@
 #include "htt_ppdu_stats.h"
 #include "qdf_mem.h"   /* qdf_mem_malloc,free */
 #include "cfg_ucfg_api.h"
+#include "dp_mon_filter.h"
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
 #include "cdp_txrx_flow_ctrl_v2.h"
 #else
@@ -151,8 +152,6 @@ static inline QDF_STATUS dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl,
 					      uint8_t *peer_mac_addr);
 static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
 				       uint8_t *peer_mac, uint32_t bitmap);
-static void dp_ppdu_ring_reset(struct dp_pdev *pdev);
-static void dp_ppdu_ring_cfg(struct dp_pdev *pdev);
 static void dp_vdev_flush_peers(struct cdp_vdev *vdev_handle,
 				bool unmap_only);
 #ifdef ENABLE_VERBOSE_DEBUG
@@ -3551,6 +3550,15 @@ static inline QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
 		goto fail0;
 	}
 
+	pdev->filter = dp_mon_filter_alloc(pdev);
+	if (!pdev->filter) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Memory allocation failed for monitor filters"));
+		qdf_mem_free(pdev);
+		ret = QDF_STATUS_E_NOMEM;
+		goto fail0;
+	}
+
 	/*
 	 * Variable to prevent double pdev deinitialization during
 	 * radio detach execution .i.e. in the absence of any vdev.
@@ -3561,6 +3569,7 @@ static inline QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
 	if (!pdev->invalid_peer) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
 			  FL("Invalid peer memory allocation failed"));
+		dp_mon_filter_dealloc(pdev);
 		qdf_mem_free(pdev);
 		ret = QDF_STATUS_E_NOMEM;
 		goto fail0;
@@ -3574,6 +3583,7 @@ static inline QDF_STATUS dp_pdev_attach_wifi3(struct cdp_soc_t *txrx_soc,
 			FL("pdev cfg_attach failed"));
 
 		qdf_mem_free(pdev->invalid_peer);
+		dp_mon_filter_dealloc(pdev);
 		qdf_mem_free(pdev);
 		ret = QDF_STATUS_E_FAILURE;
 		goto fail0;
@@ -3805,8 +3815,11 @@ fail2:
 fail1:
 	if (pdev->invalid_peer)
 		qdf_mem_free(pdev->invalid_peer);
-	dp_pdev_detach((struct cdp_pdev *)pdev, 0);
 
+	if (pdev->filter)
+		dp_mon_filter_dealloc(pdev);
+
+	dp_pdev_detach((struct cdp_pdev *)pdev, 0);
 fail0:
 	return ret;
 }
@@ -4107,6 +4120,13 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force)
 	wlan_cfg_pdev_detach(pdev->wlan_cfg_ctx);
 	if (pdev->invalid_peer)
 		qdf_mem_free(pdev->invalid_peer);
+
+	/*
+	 * Fee the monitor filter allocated and stored
+	 */
+	if (pdev->filter)
+		dp_mon_filter_dealloc(pdev);
+
 	qdf_mem_free(pdev->dp_txrx_handle);
 	dp_pdev_mem_reset(pdev);
 }
@@ -5948,6 +5968,7 @@ dp_get_pdev_reo_dest(struct cdp_soc_t *txrx_soc, uint8_t pdev_id)
 		return cdp_host_reo_dest_ring_unknown;
 }
 
+#ifdef ATH_SUPPORT_NAC
 /*
  * dp_set_filter_neigh_peers() - set filter neighbour peers for smart mesh
  * @pdev_handle: device object
@@ -5964,7 +5985,15 @@ static int dp_set_filter_neigh_peers(struct dp_pdev *pdev,
 	pdev->filter_neighbour_peers = val;
 	return 0;
 }
+#else
+static int dp_set_filter_neigh_peers(struct dp_pdev *pdev,
+				     bool val)
+{
+	return 0;
+}
+#endif /* ATH_SUPPORT_NAC */
 
+#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
 /*
  * dp_update_filter_neighbour_peers() - set neighbour peers(nac clients)
  * address for smart mesh filtering
@@ -6019,8 +6048,18 @@ static int dp_update_filter_neighbour_peers(struct cdp_soc_t *soc,
 
 		/* first neighbour */
 		if (!pdev->neighbour_peers_added) {
+			QDF_STATUS status = QDF_STATUS_SUCCESS;
+
 			pdev->neighbour_peers_added = true;
-			dp_ppdu_ring_cfg(pdev);
+			dp_mon_filter_setup_smart_monitor(pdev);
+			status = dp_mon_filter_update(pdev);
+			if (status != QDF_STATUS_SUCCESS) {
+				QDF_TRACE(QDF_MODULE_ID_DP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  FL("smart mon filter setup failed"));
+				dp_mon_filter_reset_smart_monitor(pdev);
+				pdev->neighbour_peers_added = false;
+			}
 		}
 		return 1;
 
@@ -6039,15 +6078,20 @@ static int dp_update_filter_neighbour_peers(struct cdp_soc_t *soc,
 		}
 		/* last neighbour deleted */
 		if (TAILQ_EMPTY(&pdev->neighbour_peers_list)) {
+			QDF_STATUS status = QDF_STATUS_SUCCESS;
+
 			pdev->neighbour_peers_added = false;
-			dp_ppdu_ring_cfg(pdev);
+			dp_mon_filter_reset_smart_monitor(pdev);
+			status = dp_mon_filter_update(pdev);
+			if (status != QDF_STATUS_SUCCESS) {
+				QDF_TRACE(QDF_MODULE_ID_DP,
+					  QDF_TRACE_LEVEL_ERROR,
+					  FL("smart mon filter clear failed"));
+			}
+
 		}
 
 		qdf_spin_unlock_bh(&pdev->neighbour_peer_mutex);
-
-		if (!pdev->mcopy_mode && !pdev->neighbour_peers_added &&
-		    !pdev->enhanced_stats_en)
-			dp_ppdu_ring_reset(pdev);
 		return 1;
 
 	}
@@ -6055,6 +6099,7 @@ static int dp_update_filter_neighbour_peers(struct cdp_soc_t *soc,
 fail0:
 	return 0;
 }
+#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
 
 /*
  * dp_get_sec_type() - Get the security type
@@ -6577,6 +6622,8 @@ static inline void
 dp_pdev_disable_mcopy_code(struct dp_pdev *pdev)
 {
 	pdev->mcopy_mode = 0;
+	pdev->monitor_configured = false;
+	pdev->monitor_vdev = NULL;
 	qdf_nbuf_queue_free(&pdev->rx_ppdu_buf_q);
 }
 
@@ -6587,54 +6634,48 @@ dp_pdev_disable_mcopy_code(struct dp_pdev *pdev)
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
+QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
+				 uint8_t pdev_id,
+				 uint8_t special_monitor)
 {
 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
-	struct htt_rx_ring_tlv_filter htt_tlv_filter;
-	int mac_id;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_pdev *pdev =
 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
 						   pdev_id);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	if (!pdev)
 		return QDF_STATUS_E_FAILURE;
 
 	qdf_spin_lock_bh(&pdev->mon_lock);
 
-	qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter));
-
-	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
-		int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id);
-		/*
-		 * Obtain lmac id from pdev to access the ring in soc
-		 * context
-		 */
-		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id);
-		status = dp_monitor_mode_ring_config(soc, mac_for_pdev,
-						     pdev, lmac_id,
-						     htt_tlv_filter);
-
-		if (status != QDF_STATUS_SUCCESS) {
-			dp_err("Failed to send tlv filter for monitor mode rings");
-			qdf_spin_unlock_bh(&pdev->mon_lock);
-			return status;
-		}
+	pdev->monitor_vdev = NULL;
+	pdev->monitor_configured = false;
 
-		htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
-				    soc->rxdma_mon_status_ring[lmac_id]
-				    .hal_srng,
-				    RXDMA_MONITOR_STATUS, RX_DATA_BUFFER_SIZE,
-				    &htt_tlv_filter);
+	/*
+	 * Lite monitor mode, smart monitor mode and monitor
+	 * mode uses this APIs to filter reset and mode disable
+	 */
+	if (pdev->mcopy_mode) {
+#if defined(FEATURE_PERPKT_INFO)
+		dp_pdev_disable_mcopy_code(pdev);
+		dp_mon_filter_reset_mcopy_mode(pdev);
+#endif /* FEATURE_PERPKT_INFO */
+	} else if (special_monitor) {
+#if defined(ATH_SUPPORT_NAC)
+		dp_mon_filter_reset_smart_monitor(pdev);
+#endif /* ATH_SUPPORT_NAC */
+	} else {
+		dp_mon_filter_reset_mon_mode(pdev);
 	}
 
-	pdev->monitor_vdev = NULL;
-	if (pdev->mcopy_mode)
-		dp_pdev_disable_mcopy_code(pdev);
-	pdev->monitor_configured = false;
+	status = dp_mon_filter_update(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to reset monitor filters"));
+	}
 
 	qdf_spin_unlock_bh(&pdev->mon_lock);
-
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -6679,171 +6720,6 @@ static QDF_STATUS dp_get_peer_mac_from_peer_id(struct cdp_soc_t *soc,
 	return QDF_STATUS_E_FAILURE;
 }
 
-/**
- * dp_pdev_configure_monitor_rings() - configure monitor rings
- * @vdev_handle: Datapath VDEV handle
- *
- * Return: QDF_STATUS
- */
-QDF_STATUS dp_pdev_configure_monitor_rings(struct dp_pdev *pdev)
-{
-	struct htt_rx_ring_tlv_filter htt_tlv_filter;
-	struct dp_soc *soc;
-	uint8_t pdev_id;
-	int mac_id;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
-
-	pdev_id = pdev->pdev_id;
-	soc = pdev->soc;
-
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-		"MODE[%x] FP[%02x|%02x|%02x] MO[%02x|%02x|%02x]",
-		pdev->mon_filter_mode, pdev->fp_mgmt_filter,
-		pdev->fp_ctrl_filter, pdev->fp_data_filter,
-		pdev->mo_mgmt_filter, pdev->mo_ctrl_filter,
-		pdev->mo_data_filter);
-
-	qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter));
-
-	htt_tlv_filter.mpdu_start = 1;
-	htt_tlv_filter.msdu_start = 1;
-	htt_tlv_filter.packet = 1;
-	htt_tlv_filter.msdu_end = 1;
-	htt_tlv_filter.mpdu_end = 1;
-	htt_tlv_filter.packet_header = 1;
-	htt_tlv_filter.attention = 1;
-	htt_tlv_filter.ppdu_start = 0;
-	htt_tlv_filter.ppdu_end = 0;
-	htt_tlv_filter.ppdu_end_user_stats = 0;
-	htt_tlv_filter.ppdu_end_user_stats_ext = 0;
-	htt_tlv_filter.ppdu_end_status_done = 0;
-	htt_tlv_filter.header_per_msdu = 1;
-	htt_tlv_filter.enable_fp =
-		(pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0;
-	htt_tlv_filter.enable_md = 0;
-	htt_tlv_filter.enable_mo =
-		(pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0;
-	htt_tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter;
-	htt_tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter;
-
-	if (pdev->mcopy_mode) {
-		htt_tlv_filter.fp_data_filter = 0;
-		htt_tlv_filter.mo_data_filter = 0;
-	} else {
-		htt_tlv_filter.fp_data_filter = pdev->fp_data_filter;
-		htt_tlv_filter.mo_data_filter = pdev->mo_data_filter;
-	}
-	htt_tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter;
-	htt_tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter;
-	htt_tlv_filter.offset_valid = false;
-
-	if ((pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) ||
-	    (pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU_MSDU)) {
-		htt_tlv_filter.fp_mgmt_filter = 0;
-		htt_tlv_filter.fp_ctrl_filter = 0;
-		htt_tlv_filter.fp_data_filter = 0;
-		htt_tlv_filter.mo_mgmt_filter = 0;
-		htt_tlv_filter.mo_ctrl_filter = 0;
-		htt_tlv_filter.mo_data_filter = 0;
-	}
-
-	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
-		int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id);
-		/*
-		 * Obtain lmac id from pdev to access the LMAC ring in soc
-		 * context
-		 */
-		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id);
-
-		status = dp_monitor_mode_ring_config(soc, mac_for_pdev,
-						     pdev, lmac_id,
-						     htt_tlv_filter);
-
-		if (status != QDF_STATUS_SUCCESS) {
-			dp_err("Failed to send tlv filter for monitor mode rings");
-			return status;
-		}
-	}
-
-	qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter));
-
-	htt_tlv_filter.mpdu_start = 1;
-	htt_tlv_filter.msdu_start = 0;
-	htt_tlv_filter.packet = 0;
-	htt_tlv_filter.msdu_end = 0;
-	htt_tlv_filter.mpdu_end = 0;
-	if ((pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) ||
-	    (pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU_MSDU)) {
-		htt_tlv_filter.mpdu_end = 1;
-	}
-	htt_tlv_filter.attention = 0;
-	htt_tlv_filter.ppdu_start = 1;
-	htt_tlv_filter.ppdu_end = 1;
-	htt_tlv_filter.ppdu_end_user_stats = 1;
-	htt_tlv_filter.ppdu_end_user_stats_ext = 1;
-	htt_tlv_filter.ppdu_end_status_done = 1;
-	htt_tlv_filter.enable_fp = 1;
-	htt_tlv_filter.enable_md = 0;
-	htt_tlv_filter.enable_mo = 1;
-	if (pdev->mcopy_mode ||
-	    (pdev->rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED)) {
-		htt_tlv_filter.packet_header = 1;
-		if (pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) {
-			htt_tlv_filter.header_per_msdu = 0;
-			htt_tlv_filter.enable_mo = 0;
-		} else if (pdev->rx_enh_capture_mode ==
-			   CDP_RX_ENH_CAPTURE_MPDU_MSDU) {
-			bool is_rx_mon_proto_flow_tag_enabled =
-			    wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(
-						    soc->wlan_cfg_ctx);
-			htt_tlv_filter.header_per_msdu = 1;
-			htt_tlv_filter.enable_mo = 0;
-			if (pdev->is_rx_enh_capture_trailer_enabled ||
-			    is_rx_mon_proto_flow_tag_enabled)
-				htt_tlv_filter.msdu_end = 1;
-		}
-	}
-
-	htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
-	htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
-	htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL;
-	htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
-	htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
-	htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
-	htt_tlv_filter.offset_valid = false;
-
-	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
-		int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id);
-		/*
-		 * Obtain lmac id from pdev to access the LMAC ring in soc
-		 * context
-		 */
-		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id);
-
-		/*
-		 * If two back to back HTT msg sending happened in
-		 * short time, the second HTT msg source SRNG HP
-		 * writing has chance to fail, this has been confirmed
-		 * by HST HW.
-		 * for monitor mode, here is the last HTT msg for sending.
-		 * if the 2nd HTT msg for monitor status ring sending failed,
-		 * HW won't provide anything into 2nd monitor status ring.
-		 * as a WAR, add some delay before 2nd HTT msg start sending,
-		 * > 2us is required per HST HW, delay 100 us for safe.
-		 */
-		if (mac_id)
-			qdf_udelay(100);
-
-		htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
-				    soc->rxdma_mon_status_ring[lmac_id]
-				    .hal_srng,
-				    RXDMA_MONITOR_STATUS,
-				    RX_DATA_BUFFER_SIZE, &htt_tlv_filter);
-	}
-
-	return status;
-}
-
 /**
  * dp_vdev_set_monitor_mode() - Set DP VDEV to monitor mode
  * @vdev_handle: Datapath VDEV handle
@@ -6859,6 +6735,7 @@ static QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *soc,
 	struct dp_vdev *vdev =
 		dp_get_vdev_from_soc_vdev_id_wifi3((struct dp_soc *)soc,
 						   vdev_id);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	if (!vdev)
 		return QDF_STATUS_E_FAILURE;
@@ -6887,10 +6764,19 @@ static QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *soc,
 	}
 
 	pdev->monitor_configured = true;
-
 	dp_mon_buf_delayed_replenish(pdev);
 
-	return dp_pdev_configure_monitor_rings(pdev);
+	dp_mon_filter_setup_mon_mode(pdev);
+	status = dp_mon_filter_update(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to reset monitor filters"));
+		dp_mon_filter_reset_mon_mode(pdev);
+		pdev->monitor_configured = false;
+		pdev->monitor_vdev = NULL;
+	}
+
+	return status;
 }
 
 /**
@@ -6909,12 +6795,10 @@ dp_pdev_set_advance_monitor_filter(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 	 */
 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
 	struct dp_vdev *vdev;
-	struct htt_rx_ring_tlv_filter htt_tlv_filter;
-	int mac_id;
-	QDF_STATUS status = QDF_STATUS_SUCCESS;
 	struct dp_pdev *pdev =
 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
 						   pdev_id);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
 	if (!pdev)
 		return QDF_STATUS_E_FAILURE;
@@ -6944,131 +6828,15 @@ dp_pdev_set_advance_monitor_filter(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 	pdev->mo_ctrl_filter = filter_val->mo_ctrl;
 	pdev->mo_data_filter = filter_val->mo_data;
 
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
-		"MODE[%x] FP[%02x|%02x|%02x] MO[%02x|%02x|%02x]",
-		pdev->mon_filter_mode, pdev->fp_mgmt_filter,
-		pdev->fp_ctrl_filter, pdev->fp_data_filter,
-		pdev->mo_mgmt_filter, pdev->mo_ctrl_filter,
-		pdev->mo_data_filter);
-
-	qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter));
-
-	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
-		int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id);
-		/*
-		 * Obtain lmac id from pdev to access the LMAC ring in soc
-		 * context
-		 */
-		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id);
-
-		status = dp_monitor_mode_ring_config(soc, mac_for_pdev,
-						     pdev, lmac_id,
-						     htt_tlv_filter);
-
-		if (status != QDF_STATUS_SUCCESS) {
-			dp_err("Failed to send tlv filter for monitor mode rings");
-			return status;
-		}
-
-		htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
-			soc->rxdma_mon_status_ring[lmac_id].hal_srng,
-			RXDMA_MONITOR_STATUS, RX_DATA_BUFFER_SIZE,
-			&htt_tlv_filter);
-	}
-
-	htt_tlv_filter.mpdu_start = 1;
-	htt_tlv_filter.msdu_start = 1;
-	htt_tlv_filter.packet = 1;
-	htt_tlv_filter.msdu_end = 1;
-	htt_tlv_filter.mpdu_end = 1;
-	htt_tlv_filter.packet_header = 1;
-	htt_tlv_filter.attention = 1;
-	htt_tlv_filter.ppdu_start = 0;
-	htt_tlv_filter.ppdu_end = 0;
-	htt_tlv_filter.ppdu_end_user_stats = 0;
-	htt_tlv_filter.ppdu_end_user_stats_ext = 0;
-	htt_tlv_filter.ppdu_end_status_done = 0;
-	htt_tlv_filter.header_per_msdu = 1;
-	htt_tlv_filter.enable_fp =
-		(pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0;
-	htt_tlv_filter.enable_md = 0;
-	htt_tlv_filter.enable_mo =
-		(pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0;
-	htt_tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter;
-	htt_tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter;
-	if (pdev->mcopy_mode)
-		htt_tlv_filter.fp_data_filter = 0;
-	else
-		htt_tlv_filter.fp_data_filter = pdev->fp_data_filter;
-	htt_tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter;
-	htt_tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter;
-	htt_tlv_filter.mo_data_filter = pdev->mo_data_filter;
-	htt_tlv_filter.offset_valid = false;
-
-	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
-		int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev_id);
-		/*
-		 * Obtain lmac id from pdev to access the LMAC ring in soc
-		 * context
-		 */
-		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id);
-
-		status = dp_monitor_mode_ring_config(soc, mac_for_pdev,
-						     pdev, lmac_id,
-						     htt_tlv_filter);
-
-		if (status != QDF_STATUS_SUCCESS) {
-			dp_err("Failed to send tlv filter for monitor mode rings");
-			return status;
-		}
-	}
-
-	qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter));
-
-	htt_tlv_filter.mpdu_start = 1;
-	htt_tlv_filter.msdu_start = 0;
-	htt_tlv_filter.packet = 0;
-	htt_tlv_filter.msdu_end = 0;
-	htt_tlv_filter.mpdu_end = 0;
-	htt_tlv_filter.attention = 0;
-	htt_tlv_filter.ppdu_start = 1;
-	htt_tlv_filter.ppdu_end = 1;
-	htt_tlv_filter.ppdu_end_user_stats = 1;
-	htt_tlv_filter.ppdu_end_user_stats_ext = 1;
-	htt_tlv_filter.ppdu_end_status_done = 1;
-	htt_tlv_filter.enable_fp = 1;
-	htt_tlv_filter.enable_md = 0;
-	htt_tlv_filter.enable_mo = 1;
-	if (pdev->mcopy_mode) {
-		htt_tlv_filter.packet_header = 1;
-	}
-	htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
-	htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
-	htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL;
-	htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
-	htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
-	htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
-	htt_tlv_filter.offset_valid = false;
-
-	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
-		int mac_for_pdev =
-			dp_get_mac_id_for_pdev(mac_id,
-					       pdev->pdev_id);
-		/*
-		 * Obtain lmac id from pdev to access the LMAC ring in soc
-		 * context
-		 */
-		int lmac_id =
-			dp_get_lmac_id_for_pdev_id(soc,
-						   mac_id, pdev->pdev_id);
-
-		htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
-			soc->rxdma_mon_status_ring[lmac_id].hal_srng,
-			RXDMA_MONITOR_STATUS, RX_DATA_BUFFER_SIZE,
-			&htt_tlv_filter);
+	dp_mon_filter_setup_mon_mode(pdev);
+	status = dp_mon_filter_update(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to set filter for advance mon mode"));
+		dp_mon_filter_reset_mon_mode(pdev);
 	}
 
-	return QDF_STATUS_SUCCESS;
+	return status;
 }
 
 /**
@@ -7664,102 +7432,6 @@ dp_print_host_stats(struct dp_vdev *vdev,
 	return 0;
 }
 
-/*
- * dp_ppdu_ring_reset()- Reset PPDU Stats ring
- * @pdev: DP_PDEV handle
- *
- * Return: void
- */
-static void
-dp_ppdu_ring_reset(struct dp_pdev *pdev)
-{
-	struct htt_rx_ring_tlv_filter htt_tlv_filter;
-	int mac_id;
-
-	qdf_mem_zero(&(htt_tlv_filter), sizeof(htt_tlv_filter));
-
-	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
-		int mac_for_pdev =
-			dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id);
-		/*
-		 * Obtain lmac id from pdev to access the LMAC ring in soc
-		 * context
-		 */
-		int lmac_id =
-			dp_get_lmac_id_for_pdev_id(pdev->soc,
-						   mac_id, pdev->pdev_id);
-
-		htt_h2t_rx_ring_cfg(pdev->soc->htt_handle, mac_for_pdev,
-			pdev->soc->rxdma_mon_status_ring[lmac_id].hal_srng,
-			RXDMA_MONITOR_STATUS, RX_DATA_BUFFER_SIZE,
-			&htt_tlv_filter);
-	}
-}
-
-/*
- * dp_ppdu_ring_cfg()- Configure PPDU Stats ring
- * @pdev: DP_PDEV handle
- *
- * Return: void
- */
-static void
-dp_ppdu_ring_cfg(struct dp_pdev *pdev)
-{
-	struct htt_rx_ring_tlv_filter htt_tlv_filter = {0};
-	int mac_id;
-
-	htt_tlv_filter.mpdu_start = 1;
-	htt_tlv_filter.msdu_start = 0;
-	htt_tlv_filter.packet = 0;
-	htt_tlv_filter.msdu_end = 0;
-	htt_tlv_filter.mpdu_end = 0;
-	htt_tlv_filter.attention = 0;
-	htt_tlv_filter.ppdu_start = 1;
-	htt_tlv_filter.ppdu_end = 1;
-	htt_tlv_filter.ppdu_end_user_stats = 1;
-	htt_tlv_filter.ppdu_end_user_stats_ext = 1;
-	htt_tlv_filter.ppdu_end_status_done = 1;
-	htt_tlv_filter.enable_fp = 1;
-	htt_tlv_filter.enable_md = 0;
-	if (pdev->neighbour_peers_added &&
-	    pdev->soc->hw_nac_monitor_support) {
-		htt_tlv_filter.enable_md = 1;
-		htt_tlv_filter.packet_header = 1;
-	}
-	if (pdev->mcopy_mode) {
-		htt_tlv_filter.packet_header = 1;
-		htt_tlv_filter.enable_mo = 1;
-	}
-	htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
-	htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
-	htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL;
-	htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
-	htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
-	htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
-	if (pdev->neighbour_peers_added &&
-	    pdev->soc->hw_nac_monitor_support)
-		htt_tlv_filter.md_data_filter = FILTER_DATA_ALL;
-
-	htt_tlv_filter.offset_valid = false;
-
-	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
-		int mac_for_pdev = dp_get_mac_id_for_pdev(mac_id,
-						pdev->pdev_id);
-		/*
-		 * Obtain lmac id from pdev to access the LMAC ring in soc
-		 * context
-		 */
-		int lmac_id =
-			dp_get_lmac_id_for_pdev_id(pdev->soc,
-						   mac_id, pdev->pdev_id);
-
-		htt_h2t_rx_ring_cfg(pdev->soc->htt_handle, mac_for_pdev,
-			pdev->soc->rxdma_mon_status_ring[lmac_id].hal_srng,
-			RXDMA_MONITOR_STATUS, RX_DATA_BUFFER_SIZE,
-			&htt_tlv_filter);
-	}
-}
-
 /*
  * is_ppdu_txrx_capture_enabled() - API to check both pktlog and debug_sniffer
  *                              modes are enabled or not.
@@ -7865,20 +7537,37 @@ dp_config_debug_sniffer(struct dp_pdev *pdev, int val)
 {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
-	if (pdev->mcopy_mode)
-		dp_reset_monitor_mode((struct cdp_soc_t *)(pdev->soc),
-				      pdev->pdev_id);
+	/*
+	 * Note: The mirror copy mode cannot co-exist with any other
+	 * monitor modes. Hence disabling the filter for this mode will
+	 * reset the monitor destination ring filters.
+	 */
+	if (pdev->mcopy_mode) {
+#ifdef FEATURE_PERPKT_INFO
+		dp_pdev_disable_mcopy_code(pdev);
+		dp_mon_filter_reset_mcopy_mode(pdev);
+		status = dp_mon_filter_update(pdev);
+		if (status != QDF_STATUS_SUCCESS) {
+			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Failed to reset AM copy mode filters"));
+		}
+#endif /* FEATURE_PERPKT_INFO */
+	}
 
 	switch (val) {
 	case 0:
 		pdev->tx_sniffer_enable = 0;
-
 		pdev->monitor_configured = false;
 
+		/*
+		 * We don't need to reset the Rx monitor status ring  or call
+		 * the API dp_ppdu_ring_reset() if all debug sniffer mode is
+		 * disabled. The Rx monitor status ring will be disabled when
+		 * the last mode using the monitor status ring get disabled.
+		 */
 		if (!pdev->pktlog_ppdu_stats && !pdev->enhanced_stats_en &&
 		    !pdev->bpr_enable) {
 			dp_h2t_cfg_stats_msg_send(pdev, 0, pdev->pdev_id);
-			dp_ppdu_ring_reset(pdev);
 		} else if (pdev->enhanced_stats_en && !pdev->bpr_enable) {
 			dp_h2t_cfg_stats_msg_send(pdev,
 				DP_PPDU_STATS_CFG_ENH_STATS, pdev->pdev_id);
@@ -7907,14 +7596,28 @@ dp_config_debug_sniffer(struct dp_pdev *pdev, int val)
 			break;
 		}
 
+#ifdef FEATURE_PERPKT_INFO
 		pdev->mcopy_mode = 1;
-		dp_pdev_configure_monitor_rings(pdev);
-		pdev->monitor_configured = true;
 		pdev->tx_sniffer_enable = 0;
+		pdev->monitor_configured = true;
+
+		/*
+		 * Setup the M copy mode filter.
+		 */
+		dp_mon_filter_setup_mcopy_mode(pdev);
+		status = dp_mon_filter_update(pdev);
+		if (status != QDF_STATUS_SUCCESS) {
+			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+				  FL("Failed to set M_copy mode filters"));
+			dp_mon_filter_reset_mcopy_mode(pdev);
+			dp_pdev_disable_mcopy_code(pdev);
+			return status;
+		}
 
 		if (!pdev->pktlog_ppdu_stats)
 			dp_h2t_cfg_stats_msg_send(pdev,
 				DP_PPDU_STATS_CFG_SNIFFER, pdev->pdev_id);
+#endif /* FEATURE_PERPKT_INFO */
 		break;
 
 	default:
@@ -7925,6 +7628,7 @@ dp_config_debug_sniffer(struct dp_pdev *pdev, int val)
 	return status;
 }
 
+#ifdef FEATURE_PERPKT_INFO
 /*
  * dp_enable_enhanced_stats()- API to enable enhanced statistcs
  * @soc_handle: DP_SOC handle
@@ -7935,9 +7639,11 @@ dp_config_debug_sniffer(struct dp_pdev *pdev, int val)
 static QDF_STATUS
 dp_enable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id)
 {
-	struct dp_pdev *pdev =
-		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
-						   pdev_id);
+	struct dp_pdev *pdev = NULL;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
+						  pdev_id);
 
 	if (!pdev)
 		return QDF_STATUS_E_FAILURE;
@@ -7947,9 +7653,16 @@ dp_enable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id)
 
 	pdev->enhanced_stats_en = 1;
 
-	if (!pdev->mcopy_mode && !pdev->neighbour_peers_added &&
-	    !pdev->monitor_vdev)
-		dp_ppdu_ring_cfg(pdev);
+	dp_mon_filter_setup_enhanced_stats(pdev);
+	status = dp_mon_filter_update(pdev);
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to set enhanced mode filters"));
+		dp_mon_filter_reset_enhanced_stats(pdev);
+		dp_cal_client_timer_stop(pdev->cal_client_ctx);
+		pdev->enhanced_stats_en = 0;
+		return QDF_STATUS_E_FAILURE;
+	}
 
 	if (is_ppdu_txrx_capture_enabled(pdev) && !pdev->bpr_enable) {
 		dp_h2t_cfg_stats_msg_send(pdev, DP_PPDU_STATS_CFG_ENH_STATS, pdev->pdev_id);
@@ -7992,12 +7705,15 @@ dp_disable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id)
 					  pdev->pdev_id);
 	}
 
-	if (!pdev->mcopy_mode && !pdev->neighbour_peers_added &&
-	    !pdev->monitor_vdev)
-		dp_ppdu_ring_reset(pdev);
+	dp_mon_filter_reset_enhanced_stats(pdev);
+	if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
+			  FL("Failed to reset enhanced mode filters"));
+	}
 
 	return QDF_STATUS_SUCCESS;
 }
+#endif /* FEATURE_PERPKT_INFO */
 
 /*
  * dp_get_fw_peer_stats()- function to print peer stats
@@ -10175,8 +9891,10 @@ static struct cdp_ctrl_ops dp_ops_ctrl = {
 	.txrx_get_psoc_param = dp_get_psoc_param,
 	.txrx_set_pdev_reo_dest = dp_set_pdev_reo_dest,
 	.txrx_get_pdev_reo_dest = dp_get_pdev_reo_dest,
+#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
 	.txrx_update_filter_neighbour_peers =
 		dp_update_filter_neighbour_peers,
+#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
 	.txrx_get_sec_type = dp_get_sec_type,
 	.txrx_wdi_event_sub = dp_wdi_event_sub,
 	.txrx_wdi_event_unsub = dp_wdi_event_unsub,
@@ -10234,8 +9952,10 @@ static struct cdp_host_stats_ops dp_ops_host_stats = {
 	.txrx_per_peer_stats = dp_get_host_peer_stats,
 	.get_fw_peer_stats = dp_get_fw_peer_stats,
 	.get_htt_stats = dp_get_htt_stats,
+#ifdef FEATURE_PERPKT_INFO
 	.txrx_enable_enhanced_stats = dp_enable_enhanced_stats,
 	.txrx_disable_enhanced_stats = dp_disable_enhanced_stats,
+#endif /* FEATURE_PERPKT_INFO */
 	.txrx_stats_publish = dp_txrx_stats_publish,
 	.txrx_get_vdev_stats  = dp_txrx_get_vdev_stats,
 	.txrx_get_peer_stats = dp_txrx_get_peer_stats,
@@ -11110,7 +10830,6 @@ void *dp_get_pdev_for_mac_id(struct dp_soc *soc, uint32_t mac_id)
  *
  * Return: None
  */
-static
 void dp_is_hw_dbs_enable(struct dp_soc *soc,
 				int *max_mac_rings)
 {
@@ -11268,7 +10987,6 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 		bool enable)
 {
 	struct dp_soc *soc = NULL;
-	struct htt_rx_ring_tlv_filter htt_tlv_filter = {0};
 	int max_mac_rings = wlan_cfg_get_num_mac_rings
 					(pdev->wlan_cfg_ctx);
 	uint8_t mac_id = 0;
@@ -11289,51 +11007,18 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 				 */
 				return 0;
 			}
+
 			if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_FULL) {
 				pdev->rx_pktlog_mode = DP_RX_PKTLOG_FULL;
-				htt_tlv_filter.mpdu_start = 1;
-				htt_tlv_filter.msdu_start = 1;
-				htt_tlv_filter.msdu_end = 1;
-				htt_tlv_filter.mpdu_end = 1;
-				htt_tlv_filter.packet_header = 1;
-				htt_tlv_filter.attention = 1;
-				htt_tlv_filter.ppdu_start = 1;
-				htt_tlv_filter.ppdu_end = 1;
-				htt_tlv_filter.ppdu_end_user_stats = 1;
-				htt_tlv_filter.ppdu_end_user_stats_ext = 1;
-				htt_tlv_filter.ppdu_end_status_done = 1;
-				htt_tlv_filter.enable_fp = 1;
-				htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
-				htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
-				htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL;
-				htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
-				htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
-				htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
-				htt_tlv_filter.offset_valid = false;
-
-				for (mac_id = 0; mac_id < max_mac_rings;
-								mac_id++) {
-					int pdev_id = pdev->pdev_id;
-					int mac_for_pdev =
-					dp_get_mac_id_for_pdev(mac_id,
-							       pdev_id);
-					/*
-					 * Obtain LMAC id from pdev for
-					 * accessing LMAC ring from SOC
-					 */
-					int lmac_id =
-					dp_get_lmac_id_for_pdev_id(soc,
-								   mac_id,
-								   pdev_id);
-
-					htt_h2t_rx_ring_cfg(soc->htt_handle,
-					mac_for_pdev,
-					soc->rxdma_mon_status_ring[lmac_id]
-					.hal_srng,
-					RXDMA_MONITOR_STATUS,
-					RX_DATA_BUFFER_SIZE,
-					&htt_tlv_filter);
-
+				dp_mon_filter_setup_rx_pkt_log_full(pdev);
+				if (dp_mon_filter_update(pdev) !=
+						QDF_STATUS_SUCCESS) {
+					QDF_TRACE(QDF_MODULE_ID_DP,
+						  QDF_TRACE_LEVEL_ERROR,
+						  FL("Pktlog full filters set failed"));
+					dp_mon_filter_reset_rx_pkt_log_full(pdev);
+					pdev->rx_pktlog_mode = DP_RX_PKTLOG_DISABLED;
+					return 0;
 				}
 
 				if (soc->reap_timer_init)
@@ -11349,47 +11034,21 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 				 */
 				return 0;
 			}
-
 			if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_LITE) {
 				pdev->rx_pktlog_mode = DP_RX_PKTLOG_LITE;
 
-				htt_tlv_filter.ppdu_start = 1;
-				htt_tlv_filter.ppdu_end = 1;
-				htt_tlv_filter.ppdu_end_user_stats = 1;
-				htt_tlv_filter.ppdu_end_user_stats_ext = 1;
-				htt_tlv_filter.ppdu_end_status_done = 1;
-				htt_tlv_filter.mpdu_start = 1;
-				htt_tlv_filter.enable_fp = 1;
-				htt_tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
-				htt_tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
-				htt_tlv_filter.fp_data_filter = FILTER_DATA_ALL;
-				htt_tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
-				htt_tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
-				htt_tlv_filter.mo_data_filter = FILTER_DATA_ALL;
-				htt_tlv_filter.offset_valid = false;
-
-				for (mac_id = 0; mac_id < max_mac_rings;
-								mac_id++) {
-					int pdev_id = pdev->pdev_id;
-					int mac_for_pdev =
-					dp_get_mac_id_for_pdev(mac_id,
-							       pdev_id);
-					/*
-					 * Obtain lmac id from pdev to access
-					 * the LMAC ring in soc context
-					 */
-					int lmac_id =
-					dp_get_lmac_id_for_pdev_id(soc,
-								   mac_id,
-								   pdev_id);
-
-					htt_h2t_rx_ring_cfg(soc->htt_handle,
-					mac_for_pdev,
-					soc->rxdma_mon_status_ring[lmac_id]
-					.hal_srng,
-					RXDMA_MONITOR_STATUS,
-					RX_BUFFER_SIZE_PKTLOG_LITE,
-					&htt_tlv_filter);
+				/*
+				 * Set the packet log lite mode filter.
+				 */
+				dp_mon_filter_setup_rx_pkt_log_lite(pdev);
+				if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
+					QDF_TRACE(QDF_MODULE_ID_DP,
+						  QDF_TRACE_LEVEL_ERROR,
+						  FL("Pktlog lite filters set failed"));
+					dp_mon_filter_reset_rx_pkt_log_lite(pdev);
+					pdev->rx_pktlog_mode =
+						DP_RX_PKTLOG_DISABLED;
+					return 0;
 				}
 
 				if (soc->reap_timer_init)
@@ -11433,29 +11092,22 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 			}
 			if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) {
 				pdev->rx_pktlog_mode = DP_RX_PKTLOG_DISABLED;
+				dp_mon_filter_reset_rx_pkt_log_full(pdev);
+				if (dp_mon_filter_update(pdev) !=
+						QDF_STATUS_SUCCESS) {
+					QDF_TRACE(QDF_MODULE_ID_DP,
+						  QDF_TRACE_LEVEL_ERROR,
+						  FL("Pktlog filters reset failed"));
+					return 0;
+				}
 
-				for (mac_id = 0; mac_id < max_mac_rings;
-								mac_id++) {
-					int pdev_id = pdev->pdev_id;
-					int mac_for_pdev =
-					dp_get_mac_id_for_pdev(mac_id,
-							       pdev_id);
-					/*
-					 * Obtain lmac id from pdev to access
-					 * the LMAC ring in soc context
-					 */
-					int lmac_id =
-					dp_get_lmac_id_for_pdev_id(soc,
-								   mac_id,
-								   pdev_id);
-
-					htt_h2t_rx_ring_cfg(soc->htt_handle,
-					mac_for_pdev,
-					soc->rxdma_mon_status_ring[lmac_id]
-					.hal_srng,
-					RXDMA_MONITOR_STATUS,
-					RX_DATA_BUFFER_SIZE,
-					&htt_tlv_filter);
+				dp_mon_filter_reset_rx_pkt_log_lite(pdev);
+				if (dp_mon_filter_update(pdev) !=
+						QDF_STATUS_SUCCESS) {
+					QDF_TRACE(QDF_MODULE_ID_DP,
+						  QDF_TRACE_LEVEL_ERROR,
+						  FL("Pktlog filters reset failed"));
+					return 0;
 				}
 
 				if (soc->reap_timer_init)

+ 1182 - 0
dp/wifi3.0/dp_mon_filter.c

@@ -0,0 +1,1182 @@
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <hal_api.h>
+#include <wlan_cfg.h>
+#include "dp_types.h"
+#include "dp_internal.h"
+#include "dp_htt.h"
+#include "dp_mon_filter.h"
+
+/**
+ * dp_mon_filter_mode_type_to_str
+ *	Monitor Filter mode to string
+ */
+static int8_t *dp_mon_filter_mode_type_to_str[DP_MON_FILTER_MAX_MODE] = {
+#ifdef FEATURE_PERPKT_INFO
+	"DP MON FILTER ENHACHED STATS MODE",
+	"DP MON FILTER MCOPY MODE",
+#endif /* FEATURE_PERPKT_INFO */
+#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
+	"DP MON FILTER SMART MONITOR MODE",
+#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
+	"DP_MON FILTER MONITOR MODE",
+#ifdef	WLAN_RX_PKT_CAPTURE_ENH
+	"DP MON FILTER RX CAPTURE MODE",
+#endif /* WLAN_RX_PKT_CAPTURE_ENH */
+#ifdef WDI_EVENT_ENABLE
+	"DP MON FILTER PKT LOG FULL MODE",
+	"DP MON FILTER PKT LOG LITE_MODE",
+#endif /* WDI_EVENT_ENABLE */
+};
+
+/**
+ * dp_mon_filter_show_filter() - Show the set filters
+ * @pdev: DP pdev handle
+ * @mode: The filter modes
+ * @tlv_filter: tlv filter
+ */
+static void dp_mon_filter_show_filter(struct dp_pdev *pdev,
+				      enum dp_mon_filter_mode mode,
+				      struct dp_mon_filter *filter)
+{
+	struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter;
+
+	DP_MON_FILTER_PRINT("[%s]: Valid: %d",
+			    dp_mon_filter_mode_type_to_str[mode],
+			    filter->valid);
+	DP_MON_FILTER_PRINT("mpdu_start: %d", tlv_filter->mpdu_start);
+	DP_MON_FILTER_PRINT("msdu_start: %d", tlv_filter->msdu_start);
+	DP_MON_FILTER_PRINT("packet: %d", tlv_filter->packet);
+	DP_MON_FILTER_PRINT("msdu_end: %d", tlv_filter->msdu_end);
+	DP_MON_FILTER_PRINT("mpdu_end: %d", tlv_filter->mpdu_end);
+	DP_MON_FILTER_PRINT("packet_header: %d",
+			    tlv_filter->packet_header);
+	DP_MON_FILTER_PRINT("attention: %d", tlv_filter->attention);
+	DP_MON_FILTER_PRINT("ppdu_start: %d", tlv_filter->ppdu_start);
+	DP_MON_FILTER_PRINT("ppdu_end: %d", tlv_filter->ppdu_end);
+	DP_MON_FILTER_PRINT("ppdu_end_user_stats: %d",
+			    tlv_filter->ppdu_end_user_stats);
+	DP_MON_FILTER_PRINT("ppdu_end_user_stats_ext: %d",
+			    tlv_filter->ppdu_end_user_stats_ext);
+	DP_MON_FILTER_PRINT("ppdu_end_status_done: %d",
+			    tlv_filter->ppdu_end_status_done);
+	DP_MON_FILTER_PRINT("header_per_msdu: %d", tlv_filter->header_per_msdu);
+	DP_MON_FILTER_PRINT("enable_fp: %d", tlv_filter->enable_fp);
+	DP_MON_FILTER_PRINT("enable_md: %d", tlv_filter->enable_md);
+	DP_MON_FILTER_PRINT("enable_mo: %d", tlv_filter->enable_mo);
+	DP_MON_FILTER_PRINT("fp_mgmt_filter: 0x%x", tlv_filter->fp_mgmt_filter);
+	DP_MON_FILTER_PRINT("mo_mgmt_filter: 0x%x", tlv_filter->mo_mgmt_filter);
+	DP_MON_FILTER_PRINT("fp_ctrl_filter: 0x%x", tlv_filter->fp_ctrl_filter);
+	DP_MON_FILTER_PRINT("mo_ctrl_filter: 0x%x", tlv_filter->mo_ctrl_filter);
+	DP_MON_FILTER_PRINT("fp_data_filter: 0x%x", tlv_filter->fp_data_filter);
+	DP_MON_FILTER_PRINT("mo_data_filter: 0x%x", tlv_filter->mo_data_filter);
+	DP_MON_FILTER_PRINT("md_data_filter: 0x%x", tlv_filter->md_data_filter);
+	DP_MON_FILTER_PRINT("md_mgmt_filter: 0x%x", tlv_filter->md_mgmt_filter);
+	DP_MON_FILTER_PRINT("md_ctrl_filter: 0x%x", tlv_filter->md_ctrl_filter);
+}
+
+/**
+ * dp_mon_ht2_rx_ring_cfg() - Send the tlv config to fw for a srng_type
+ * based on target
+ * @soc: DP soc handle
+ * @pdev: DP pdev handle
+ * @srng_type: The srng type for which filter wll be set
+ * @tlv_filter: tlv filter
+ */
+static QDF_STATUS
+dp_mon_ht2_rx_ring_cfg(struct dp_soc *soc,
+		       struct dp_pdev *pdev,
+		       enum dp_mon_filter_srng_type srng_type,
+		       struct htt_rx_ring_tlv_filter *tlv_filter)
+{
+	int mac_id;
+	int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	/*
+	 * Overwrite the max_mac_rings for the status rings.
+	 */
+	if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS)
+		dp_is_hw_dbs_enable(soc, &max_mac_rings);
+
+	QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_INFO,
+			FL("srng type %d Max_mac_rings %d "),
+			srng_type,
+			max_mac_rings);
+
+	/*
+	 * Loop through all MACs per radio and set the filter to the individual
+	 * macs. For MCL
+	 */
+	for (mac_id = 0; mac_id < max_mac_rings; mac_id++) {
+		int mac_for_pdev =
+			dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id);
+		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id);
+		int hal_ring_type, ring_buf_size;
+		hal_ring_handle_t hal_ring_hdl;
+
+		switch (srng_type) {
+		case DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF:
+			hal_ring_hdl = pdev->rx_mac_buf_ring[lmac_id].hal_srng;
+			hal_ring_type = RXDMA_BUF;
+			ring_buf_size = RX_DATA_BUFFER_SIZE;
+			break;
+
+		case DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS:
+			/*
+			 * If two back to back HTT msg sending happened in
+			 * short time, the second HTT msg source SRNG HP
+			 * writing has chance to fail, this has been confirmed
+			 * by HST HW.
+			 * for monitor mode, here is the last HTT msg for sending.
+			 * if the 2nd HTT msg for monitor status ring sending failed,
+			 * HW won't provide anything into 2nd monitor status ring.
+			 * as a WAR, add some delay before 2nd HTT msg start sending,
+			 * > 2us is required per HST HW, delay 100 us for safe.
+			 */
+			if (mac_id)
+				qdf_udelay(100);
+
+			hal_ring_hdl =
+				soc->rxdma_mon_status_ring[lmac_id].hal_srng;
+			hal_ring_type = RXDMA_MONITOR_STATUS;
+			ring_buf_size = RX_DATA_BUFFER_SIZE;
+			break;
+
+		case DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF:
+			hal_ring_hdl =
+				soc->rxdma_mon_buf_ring[lmac_id].hal_srng;
+			hal_ring_type = RXDMA_MONITOR_BUF;
+			ring_buf_size = RX_DATA_BUFFER_SIZE;
+			break;
+
+		default:
+			return QDF_STATUS_E_FAILURE;
+		}
+
+		status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
+					     hal_ring_hdl, hal_ring_type,
+					     ring_buf_size,
+					     tlv_filter);
+		if (status != QDF_STATUS_SUCCESS)
+			return status;
+	}
+
+	return status;
+}
+
+/**
+ * dp_mon_filter_ht2_setup() - Setup the filter for the Target setup
+ * @soc: DP soc handle
+ * @pdev: DP pdev handle
+ * @srng_type: The srng type for which filter wll be set
+ * @tlv_filter: tlv filter
+ */
+static void dp_mon_filter_ht2_setup(struct dp_soc *soc, struct dp_pdev *pdev,
+				    enum dp_mon_filter_srng_type srng_type,
+				    struct dp_mon_filter *filter)
+{
+	int32_t current_mode = 0;
+	struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter;
+
+	/*
+	 * Loop through all the modes.
+	 */
+	for (current_mode = 0; current_mode < DP_MON_FILTER_MAX_MODE;
+						current_mode++) {
+		struct dp_mon_filter *mon_filter =
+			&pdev->filter[current_mode][srng_type];
+		uint32_t src_filter = 0, dst_filter = 0;
+
+		/*
+		 * Check if the correct mode is enabled or not.
+		 */
+		if (!mon_filter->valid)
+			continue;
+
+		filter->valid = true;
+
+		/*
+		 * Set the super bit fields
+		 */
+		src_filter =
+			DP_MON_FILTER_GET(&mon_filter->tlv_filter, FILTER_TLV);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_TLV);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter, FILTER_TLV, dst_filter);
+
+		/*
+		 * Set the filter management filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_FP_MGMT);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_MGMT);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter, FILTER_FP_MGMT, dst_filter);
+
+		/*
+		 * Set the monitor other management filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_MO_MGMT);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_MGMT);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter, FILTER_MO_MGMT, dst_filter);
+
+		/*
+		 * Set the filter pass control filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_FP_CTRL);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_CTRL);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter, FILTER_FP_CTRL, dst_filter);
+
+		/*
+		 * Set the monitor other control filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_MO_CTRL);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_CTRL);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter, FILTER_MO_CTRL, dst_filter);
+
+		/*
+		 * Set the filter pass data filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_FP_DATA);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter,
+					       FILTER_FP_DATA);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter,
+				  FILTER_FP_DATA, dst_filter);
+
+		/*
+		 * Set the monitor other data filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_MO_DATA);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_DATA);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter, FILTER_MO_DATA, dst_filter);
+
+		/*
+		 * Set the monitor direct data filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_MD_DATA);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter,
+					       FILTER_MD_DATA);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter,
+				  FILTER_MD_DATA, dst_filter);
+
+		/*
+		 * Set the monitor direct management filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_MD_MGMT);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_MGMT);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter, FILTER_MD_MGMT, dst_filter);
+
+		/*
+		 * Set the monitor direct management filter.
+		 */
+		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
+					       FILTER_MD_CTRL);
+		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_CTRL);
+		dst_filter |= src_filter;
+		DP_MON_FILTER_SET(tlv_filter, FILTER_MD_CTRL, dst_filter);
+	}
+
+	dp_mon_filter_show_filter(pdev, 0, filter);
+}
+
+/**
+ * dp_mon_filter_reset_mon_srng()
+ * @soc: DP SoC handle
+ * @pdev: DP pdev handle
+ * @mon_srng_type: Monitor srng type
+ */
+static void
+dp_mon_filter_reset_mon_srng(struct dp_soc *soc, struct dp_pdev *pdev,
+			     enum dp_mon_filter_srng_type mon_srng_type)
+{
+	struct htt_rx_ring_tlv_filter tlv_filter = {0};
+
+	if (dp_mon_ht2_rx_ring_cfg(soc, pdev, mon_srng_type,
+				   &tlv_filter) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Monitor destinatin ring filter setting failed"));
+	}
+}
+
+#if defined(FEATURE_PERPKT_INFO) || defined(ATH_SUPPORT_NAC_RSSI) \
+	|| defined(ATH_SUPPORT_NAC) || defined(WLAN_RX_PKT_CAPTURE_ENH)
+/**
+ * dp_mon_filter_check_co_exist() - Check the co-existing of the
+ * enabled modes.
+ * @pdev: DP pdev handle
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS dp_mon_filter_check_co_exist(struct dp_pdev *pdev)
+{
+	/*
+	 * Check if the Rx Enhanced capture mode, monitor mode,
+	 * smart_monitor_mode and mcopy mode can co-exist together.
+	 */
+	if ((pdev->rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED) &&
+	    ((pdev->neighbour_peers_added && pdev->monitor_vdev) ||
+		 pdev->mcopy_mode)) {
+		 QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			   FL("Rx Capture mode can't exist with modes:\n"
+			     "Smart Monitor Mode:%d\n"
+			     "M_Copy Mode:%d"),
+			      pdev->neighbour_peers_added,
+			      pdev->mcopy_mode);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Check if the monitor mode cannot co-exist with any other mode.
+	 */
+	if ((pdev->monitor_vdev && pdev->monitor_configured) &&
+	    (pdev->mcopy_mode || pdev->neighbour_peers_added)) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Monitor mode can't exist with modes\n"
+			     "M_Copy Mode:%d\n"
+			     "Smart Monitor Mode:%d"),
+			      pdev->mcopy_mode,
+			      pdev->neighbour_peers_added);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Check if the smart monitor mode can co-exist with any other mode
+	 */
+	if (pdev->neighbour_peers_added &&
+	    ((pdev->mcopy_mode) || pdev->monitor_configured)) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Smart Monitor mode can't exist with modes\n"
+			     "M_Copy Mode:%d\n"
+			     "Monitor Mode:%d"),
+			      pdev->mcopy_mode,
+			      pdev->monitor_configured);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Check if the m_copy, monitor mode and the smart_monitor_mode
+	 * can co-exist togther.
+	 */
+	if (pdev->mcopy_mode &&
+	    (pdev->monitor_vdev || pdev->neighbour_peers_added)) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("mcopy mode can't exist with modes\n"
+			     "Monitor Mode:%d\n"
+			     "Smart Monitor Mode:%d"),
+			      pdev->monitor_vdev,
+			      pdev->neighbour_peers_added);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Check if the Rx packet log lite or full can co-exist with
+	 * the enable modes.
+	 */
+	if ((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) &&
+	    (pdev->monitor_vdev || pdev->monitor_configured)) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Rx pktlog full/lite can't exist with modes\n"
+			     "Monitor Mode:%d"),
+			      pdev->monitor_configured);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static QDF_STATUS dp_mon_filter_check_co_exist(struct dp_pdev *pdev)
+{
+	/*
+	 * Check if the Rx packet log lite or full can co-exist with
+	 * the enable modes.
+	 */
+	if ((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) &&
+	    (pdev->monitor_vdev || pdev->monitor_configured)) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Rx pktlog full/lite can't exist with modes\n"
+			     "Monitor Mode:%d"),
+			      pdev->monitor_configured);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/**
+ * dp_mon_filter_set_mon_cmn() - Setp the common mon filters
+ * @pdev: DP pdev handle
+ * @filter: DP mon filter
+ *
+ * Return: QDF_STATUS
+ */
+static void dp_mon_filter_set_mon_cmn(struct dp_pdev *pdev,
+				      struct dp_mon_filter *filter)
+{
+	filter->tlv_filter.mpdu_start = 1;
+	filter->tlv_filter.msdu_start = 1;
+	filter->tlv_filter.packet = 1;
+	filter->tlv_filter.msdu_end = 1;
+	filter->tlv_filter.mpdu_end = 1;
+	filter->tlv_filter.packet_header = 1;
+	filter->tlv_filter.attention = 1;
+	filter->tlv_filter.ppdu_start = 0;
+	filter->tlv_filter.ppdu_end = 0;
+	filter->tlv_filter.ppdu_end_user_stats = 0;
+	filter->tlv_filter.ppdu_end_user_stats_ext = 0;
+	filter->tlv_filter.ppdu_end_status_done = 0;
+	filter->tlv_filter.header_per_msdu = 1;
+	filter->tlv_filter.enable_fp =
+		(pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0;
+	filter->tlv_filter.enable_mo =
+		(pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0;
+
+	filter->tlv_filter.fp_mgmt_filter = pdev->fp_mgmt_filter;
+	filter->tlv_filter.fp_ctrl_filter = pdev->fp_ctrl_filter;
+	filter->tlv_filter.fp_data_filter = pdev->fp_data_filter;
+	filter->tlv_filter.mo_mgmt_filter = pdev->mo_mgmt_filter;
+	filter->tlv_filter.mo_ctrl_filter = pdev->mo_ctrl_filter;
+	filter->tlv_filter.mo_data_filter = pdev->mo_data_filter;
+	filter->tlv_filter.offset_valid = false;
+}
+
+/**
+ * dp_mon_filter_set_status_cmn() - Setp the common status filters
+ * @pdev: DP pdev handle
+ * @filter: Dp mon filters
+ *
+ * Return: QDF_STATUS
+ */
+static void dp_mon_filter_set_status_cmn(struct dp_pdev *pdev,
+					 struct dp_mon_filter *filter)
+{
+	filter->tlv_filter.mpdu_start = 1;
+	filter->tlv_filter.msdu_start = 0;
+	filter->tlv_filter.packet = 0;
+	filter->tlv_filter.msdu_end = 0;
+	filter->tlv_filter.mpdu_end = 0;
+	filter->tlv_filter.attention = 0;
+	filter->tlv_filter.ppdu_start = 1;
+	filter->tlv_filter.ppdu_end = 1;
+	filter->tlv_filter.ppdu_end_user_stats = 1;
+	filter->tlv_filter.ppdu_end_user_stats_ext = 1;
+	filter->tlv_filter.ppdu_end_status_done = 1;
+	filter->tlv_filter.enable_fp = 1;
+	filter->tlv_filter.enable_md = 0;
+	filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
+	filter->tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
+	filter->tlv_filter.fp_data_filter = FILTER_DATA_ALL;
+	filter->tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
+	filter->tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
+	filter->tlv_filter.mo_data_filter = FILTER_DATA_ALL;
+	filter->tlv_filter.offset_valid = false;
+}
+
+#ifdef FEATURE_PERPKT_INFO
+/**
+ * dp_mon_filter_setup_enhanced_stats() - Setup the enhanced stats filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_ENHACHED_STATS_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	/* Enabled the filter */
+	filter.valid = true;
+
+	dp_mon_filter_set_status_cmn(pdev, &filter);
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_reset_enhanced_stats() - Reset the enhanced stats filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_ENHACHED_STATS_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_setup_mcopy_mode() - Setup the m_copy mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	struct dp_soc *soc = NULL;
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_MCOPY_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	soc = pdev->soc;
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Soc Context is null"));
+		return;
+	}
+
+	/* Enabled the filter */
+	filter.valid = true;
+	dp_mon_filter_set_mon_cmn(pdev, &filter);
+
+	filter.tlv_filter.fp_data_filter = 0;
+	filter.tlv_filter.mo_data_filter = 0;
+
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+
+	srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ?
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF :
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF);
+	pdev->filter[mode][srng_type] = filter;
+
+	/* Clear the filter as the same filter will be used to set the
+	 * monitor status ring
+	 */
+	qdf_mem_zero(&(filter), sizeof(struct dp_mon_filter));
+
+	/* Enabled the filter */
+	filter.valid = true;
+	dp_mon_filter_set_status_cmn(pdev, &filter);
+
+	/* Setup the filter */
+	filter.tlv_filter.enable_mo = 1;
+	filter.tlv_filter.packet_header = 1;
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+
+	srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_reset_mcopy_mode() - Reset the m_copy mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	struct dp_soc *soc = NULL;
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_MCOPY_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	soc = pdev->soc;
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Soc Context is null"));
+		return;
+	}
+
+	srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ?
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF :
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF);
+	pdev->filter[mode][srng_type] = filter;
+
+	srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	pdev->filter[mode][srng_type] = filter;
+}
+#endif /* FEATURE_PERPKT_INFO */
+
+#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
+/**
+ * dp_mon_filter_setup_smart_monitor() - Setup the smart monitor mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	struct dp_soc *soc = NULL;
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_SMART_MONITOR_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	soc = pdev->soc;
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Soc Context is null"));
+		return;
+	}
+
+	/* Enabled the filter */
+	filter.valid = true;
+	dp_mon_filter_set_status_cmn(pdev, &filter);
+
+	if (soc->hw_nac_monitor_support) {
+		filter.tlv_filter.enable_md = 1;
+		filter.tlv_filter.packet_header = 1;
+		filter.tlv_filter.md_data_filter = FILTER_DATA_ALL;
+	}
+
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_reset_smart_monitor() - Reset the smart monitor mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_SMART_MONITOR_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	pdev->filter[mode][srng_type] = filter;
+}
+#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
+
+#ifdef WLAN_RX_PKT_CAPTURE_ENH
+/**
+ * dp_mon_filter_setup_rx_enh_capture() - Setup the Rx capture mode filters
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	struct dp_soc *soc = NULL;
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_RX_CAPTURE_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	soc = pdev->soc;
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Soc Context is null"));
+		return;
+	}
+
+	/* Enabled the filter */
+	filter.valid = true;
+	dp_mon_filter_set_mon_cmn(pdev, &filter);
+
+	filter.tlv_filter.fp_mgmt_filter = 0;
+	filter.tlv_filter.fp_ctrl_filter = 0;
+	filter.tlv_filter.fp_data_filter = 0;
+	filter.tlv_filter.mo_mgmt_filter = 0;
+	filter.tlv_filter.mo_ctrl_filter = 0;
+	filter.tlv_filter.mo_data_filter = 0;
+
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+
+	srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ?
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF :
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF);
+	pdev->filter[mode][srng_type] = filter;
+
+	/* Clear the filter as the same filter will be used to set the
+	 * monitor status ring
+	 */
+	qdf_mem_zero(&(filter), sizeof(struct dp_mon_filter));
+
+	/* Enabled the filter */
+	filter.valid = true;
+	dp_mon_filter_set_status_cmn(pdev, &filter);
+
+	/* Setup the filter */
+	filter.tlv_filter.mpdu_end = 1;
+	filter.tlv_filter.enable_mo = 1;
+	filter.tlv_filter.packet_header = 1;
+
+	if (pdev->rx_enh_capture_mode == CDP_RX_ENH_CAPTURE_MPDU) {
+		filter.tlv_filter.header_per_msdu = 0;
+		filter.tlv_filter.enable_mo = 0;
+	} else if (pdev->rx_enh_capture_mode ==
+			CDP_RX_ENH_CAPTURE_MPDU_MSDU) {
+		bool is_rx_mon_proto_flow_tag_enabled =
+		wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(soc->wlan_cfg_ctx);
+		filter.tlv_filter.header_per_msdu = 1;
+		filter.tlv_filter.enable_mo = 0;
+		if (pdev->is_rx_enh_capture_trailer_enabled ||
+		    is_rx_mon_proto_flow_tag_enabled)
+			filter.tlv_filter.msdu_end = 1;
+	}
+
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+
+	srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_reset_rx_enh_capture() - Reset the Rx capture mode filters
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	struct dp_soc *soc = NULL;
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_RX_CAPTURE_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	soc = pdev->soc;
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Soc Context is null"));
+		return;
+	}
+
+	srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ?
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF :
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF);
+	pdev->filter[mode][srng_type] = filter;
+
+	srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	pdev->filter[mode][srng_type] = filter;
+}
+#endif /* WLAN_RX_PKT_CAPTURE_ENH */
+
+/**
+ * dp_mon_filter_setup_mon_mode() - Setup the Rx monitor mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_mon_mode(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	struct dp_soc *soc = NULL;
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	soc = pdev->soc;
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Soc Context is null"));
+		return;
+	}
+
+	filter.valid = true;
+	dp_mon_filter_set_mon_cmn(pdev, &filter);
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+
+	srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ?
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF :
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF);
+	pdev->filter[mode][srng_type] = filter;
+
+	/* Clear the filter as the same filter will be used to set the
+	 * monitor status ring
+	 */
+	qdf_mem_zero(&(filter), sizeof(struct dp_mon_filter));
+
+	/* Enabled the filter */
+	filter.valid = true;
+	dp_mon_filter_set_status_cmn(pdev, &filter);
+	filter.tlv_filter.enable_mo = 1;
+
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+
+	/* Store the above filter */
+	srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_reset_mon_mode() - Reset the Rx monitor mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_mon_mode(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	struct dp_soc *soc = NULL;
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	soc = pdev->soc;
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Soc Context is null"));
+		return;
+	}
+
+	srng_type = ((soc->wlan_cfg_ctx->rxdma1_enable) ?
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF :
+			DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF);
+	pdev->filter[mode][srng_type] = filter;
+
+	srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	pdev->filter[mode][srng_type] = filter;
+}
+
+#ifdef WDI_EVENT_ENABLE
+/**
+ * dp_mon_filter_setup_rx_pkt_log_full() - Setup the Rx pktlog full mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_PKT_LOG_FULL_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	/* Enabled the filter */
+	filter.valid = true;
+	dp_mon_filter_set_status_cmn(pdev, &filter);
+
+	/* Setup the filter */
+	filter.tlv_filter.packet_header = 1;
+	filter.tlv_filter.msdu_start = 1;
+	filter.tlv_filter.msdu_end = 1;
+	filter.tlv_filter.mpdu_end = 1;
+	filter.tlv_filter.attention = 1;
+
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_reset_rx_pkt_log_full() - Reset the Rx pktlog full mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_PKT_LOG_FULL_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_setup_rx_pkt_log_lite() - Setup the Rx pktlog lite mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_rx_pkt_log_lite(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_PKT_LOG_LITE_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	/* Enabled the filter */
+	filter.valid = true;
+	dp_mon_filter_set_status_cmn(pdev, &filter);
+
+	dp_mon_filter_show_filter(pdev, mode, &filter);
+	pdev->filter[mode][srng_type] = filter;
+}
+
+/**
+ * dp_mon_filter_reset_rx_pkt_log_lite() - Reset the Rx pktlog lite mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_mode mode = DP_MON_FILTER_PKT_LOG_LITE_MODE;
+	enum dp_mon_filter_srng_type srng_type =
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	pdev->filter[mode][srng_type] = filter;
+}
+#endif /* WDI_EVENT_ENABLE */
+
+/**
+ * dp_mon_filter_update() - Setup the monitor filter setting for a srng
+ * type
+ * @pdev: DP pdev handle
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev)
+{
+	struct dp_soc *soc;
+	bool mon_mode_set = false;
+	struct dp_mon_filter filter = {0};
+	enum dp_mon_filter_srng_type mon_srng_type =
+		DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	soc = pdev->soc;
+	if (!soc) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Soc Context is null"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = dp_mon_filter_check_co_exist(pdev);
+	if (status != QDF_STATUS_SUCCESS)
+		return status;
+
+	/*
+	 * Setup the filters for the monitor destination ring.
+	 */
+	if (!soc->wlan_cfg_ctx->rxdma1_enable)
+		mon_srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF;
+
+	/*
+	 * Setup the filters for the monitor mode.
+	 */
+	qdf_mem_zero(&(filter), sizeof(filter));
+	dp_mon_filter_ht2_setup(soc, pdev, mon_srng_type, &filter);
+
+	mon_mode_set = filter.valid;
+	if (mon_mode_set) {
+		status = dp_mon_ht2_rx_ring_cfg(soc, pdev,
+						mon_srng_type,
+						&filter.tlv_filter);
+	} else {
+		/*
+		 * For WIN case the monitor buffer ring is used and it does need
+		 * reset when monitor mode gets disabled.
+		 */
+		if (soc->wlan_cfg_ctx->rxdma1_enable) {
+			status = dp_mon_ht2_rx_ring_cfg(soc, pdev,
+							mon_srng_type,
+							&filter.tlv_filter);
+		}
+	}
+
+	if (status != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Monitor destination ring filter setting failed"));
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	/*
+	 * Setup the filters for the status ring.
+	 */
+	qdf_mem_zero(&(filter), sizeof(filter));
+	dp_mon_filter_ht2_setup(soc, pdev,
+				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS,
+				&filter);
+
+	/*
+	 * Reset the monitor filters if the all the modes for the status rings
+	 * are disabled. This is done to prevent the HW backpressure from the
+	 * monitor destination ring in case the status ring filters
+	 * are not enabled.
+	 */
+	if (!filter.valid && mon_mode_set)
+		dp_mon_filter_reset_mon_srng(soc, pdev, mon_srng_type);
+
+	if (dp_mon_ht2_rx_ring_cfg(soc, pdev,
+				   DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS,
+				   &filter.tlv_filter) != QDF_STATUS_SUCCESS) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Monitor status ring filter setting failed"));
+		dp_mon_filter_reset_mon_srng(soc, pdev, mon_srng_type);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return status;
+}
+
+/**
+ * dp_mon_filter_dealloc() - Deallocate the filter objects to be stored in
+ * the radio object.
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_dealloc(struct dp_pdev *pdev)
+{
+	enum dp_mon_filter_mode mode;
+	struct dp_mon_filter **mon_filter = NULL;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return;
+	}
+
+	mon_filter = pdev->filter;
+
+	/*
+	 * Check if the monitor filters are already allocated to the pdev.
+	 */
+	if (!mon_filter) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Found NULL memmory for the Monitor filter"));
+		return;
+	}
+
+	/*
+	 * Iterate through the every mode and free the filter object.
+	 */
+	for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) {
+		if (!mon_filter[mode]) {
+			continue;
+		}
+
+		qdf_mem_free(mon_filter[mode]);
+		mon_filter[mode] = NULL;
+	}
+
+	qdf_mem_free(mon_filter);
+	pdev->filter = NULL;
+}
+
+/**
+ * dp_mon_filter_alloc() - Allocate the filter objects to be stored in
+ * the radio object.
+ * @pdev: DP pdev handle
+ */
+struct dp_mon_filter **dp_mon_filter_alloc(struct dp_pdev *pdev)
+{
+	struct dp_mon_filter **mon_filter = NULL;
+	enum dp_mon_filter_mode mode;
+
+	if (!pdev) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("pdev Context is null"));
+		return NULL;
+	}
+
+	mon_filter = (struct dp_mon_filter **)qdf_mem_malloc(
+			(sizeof(struct dp_mon_filter *) *
+			 DP_MON_FILTER_MAX_MODE));
+	if (!mon_filter) {
+		QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_ERROR,
+			  FL("Monitor filter mem allocation failed"));
+		return NULL;
+	}
+
+	qdf_mem_zero(mon_filter,
+		     sizeof(struct dp_mon_filter *) * DP_MON_FILTER_MAX_MODE);
+
+	/*
+	 * Allocate the memory for filters for different srngs for each modes.
+	 */
+	for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) {
+		mon_filter[mode] = qdf_mem_malloc(sizeof(struct dp_mon_filter) *
+						  DP_MON_FILTER_SRNG_TYPE_MAX);
+		/* Assign the mon_filter to the pdev->filter such
+		 * that the dp_mon_filter_dealloc() can free up the filters. */
+		if (!mon_filter[mode]) {
+			pdev->filter = mon_filter;
+			goto fail;
+		}
+	}
+
+	return mon_filter;
+fail:
+	dp_mon_filter_dealloc(pdev);
+	return NULL;
+}

+ 262 - 0
dp/wifi3.0/dp_mon_filter.h

@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DP_MON_FILTER_H_
+#define _DP_MON_FILTER_H_
+
+/**
+ * Accessor Macros to access the software
+ * defined HTT filter htt_rx_ring_tlv_filter.
+ */
+#define DP_MON_FILTER_TLV_OFFSET                      0x00000000
+#define DP_MON_FILTER_TLV_MASK                        0xffffffff
+#define DP_MON_FILTER_TLV_LSB                         0
+
+#define DP_MON_FILTER_FP_MGMT_OFFSET                  0x00000004
+#define DP_MON_FILTER_FP_MGMT_MASK                    0x0000ffff
+#define DP_MON_FILTER_FP_MGMT_LSB                     0
+
+#define DP_MON_FILTER_MO_MGMT_OFFSET                  0x00000004
+#define DP_MON_FILTER_MO_MGMT_MASK                    0xffff0000
+#define DP_MON_FILTER_MO_MGMT_LSB                     16
+
+#define DP_MON_FILTER_FP_CTRL_OFFSET                  0x00000008
+#define DP_MON_FILTER_FP_CTRL_MASK                    0x0000ffff
+#define DP_MON_FILTER_FP_CTRL_LSB                     0
+
+#define DP_MON_FILTER_MO_CTRL_OFFSET                  0x00000008
+#define DP_MON_FILTER_MO_CTRL_MASK                    0xffff0000
+#define DP_MON_FILTER_MO_CTRL_LSB                     16
+
+#define DP_MON_FILTER_FP_DATA_OFFSET                  0x0000000c
+#define DP_MON_FILTER_FP_DATA_MASK                    0x0000ffff
+#define DP_MON_FILTER_FP_DATA_LSB                     0
+
+#define DP_MON_FILTER_MO_DATA_OFFSET                  0x0000000c
+#define DP_MON_FILTER_MO_DATA_MASK                    0xffff0000
+#define DP_MON_FILTER_MO_DATA_LSB                     16
+
+#define DP_MON_FILTER_MD_DATA_OFFSET                  0x00000010
+#define DP_MON_FILTER_MD_DATA_MASK                    0x0000ffff
+#define DP_MON_FILTER_MD_DATA_LSB                     0
+
+#define DP_MON_FILTER_MD_MGMT_OFFSET                  0x00000010
+#define DP_MON_FILTER_MD_MGMT_MASK                    0xffff0000
+#define DP_MON_FILTER_MD_MGMT_LSB                     16
+
+#define DP_MON_FILTER_MD_CTRL_OFFSET                  0x00000014
+#define DP_MON_FILTER_MD_CTRL_MASK                    0x0000ffff
+#define DP_MON_FILTER_MD_CTRL_LSB                     0
+
+#define DP_MON_FILTER_GET(src, field) \
+	((*((uint32_t *)((uint8_t *)(src) + DP_MON_ ## field ## _OFFSET)) & \
+	(DP_MON_ ## field ## _MASK)) >> DP_MON_ ## field ## _LSB) \
+
+#define DP_MON_FILTER_SET(dst, field, value) \
+do { \
+	uint32_t *val = \
+	((uint32_t *)((uint8_t *)(dst) + DP_MON_ ## field ## _OFFSET)); \
+	*val &= ~(DP_MON_ ## field ## _MASK); \
+	*val |= ((value) << DP_MON_ ## field ## _LSB); \
+} while (0)
+
+#define DP_MON_FILTER_PRINT(fmt, args ...) \
+	QDF_TRACE(QDF_MODULE_ID_MON_FILTER, QDF_TRACE_LEVEL_DEBUG, \
+		  fmt, ## args)
+/**
+ * struct dp_mon_filter - Monitor TLV filter
+ * @valid: enable/disable TLV filter
+ * @tlv_filter: Rx ring TLV filter
+ */
+struct dp_mon_filter {
+	bool valid;
+	struct htt_rx_ring_tlv_filter tlv_filter;
+};
+
+/**
+ * enum dp_mon_filter_mode - Different modes for SRNG filters
+ * @DP_MON_FILTER_ENHACHED_STATS_MODE: PPDU enhanced stats mode
+ * @DP_MON_FILTER_SMART_MONITOR_MODE: Smart monitor mode
+ * @DP_MON_FILTER_MCOPY_MODE: AM copy mode
+ * @DP_MON_FILTER_MONITOR_MODE: Monitor mode
+ * @DP_MON_FILTER_RX_CAPTURE_MODE: Rx Capture mode
+ * @DP_MON_FILTER_PKT_LOG_FULL_MODE: Packet log full mode
+ * @DP_MON_FILTER_PKT_LOG_LITE_MODE: Packet log lite mode
+ */
+enum dp_mon_filter_mode {
+#ifdef FEATURE_PERPKT_INFO
+	DP_MON_FILTER_ENHACHED_STATS_MODE,
+	DP_MON_FILTER_MCOPY_MODE,
+#endif /* FEATURE_PERPKT_INFO */
+#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
+	DP_MON_FILTER_SMART_MONITOR_MODE,
+#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
+	DP_MON_FILTER_MONITOR_MODE,
+#ifdef	WLAN_RX_PKT_CAPTURE_ENH
+	DP_MON_FILTER_RX_CAPTURE_MODE,
+#endif /* WLAN_RX_PKT_CAPTURE_ENH */
+
+#ifdef WDI_EVENT_ENABLE
+	DP_MON_FILTER_PKT_LOG_FULL_MODE,
+	DP_MON_FILTER_PKT_LOG_LITE_MODE,
+#endif /* WDI_EVENT_ENABLE */
+	DP_MON_FILTER_MAX_MODE
+};
+
+/**
+ * enum dp_mon_filter_srng_type - Srng types dynamic mode filter
+ * settings.
+ * @DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF: RXDMA srng type
+ * @DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS: RxDMA monitor status srng
+ * @DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF: RxDMA destination srng
+ * @DP_MON_FILTER_SRNG_TYPE_MAX: Srng max type
+ */
+enum dp_mon_filter_srng_type {
+	DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF,
+	DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS,
+	DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF,
+	DP_MON_FILTER_SRNG_TYPE_MAX
+};
+
+/**
+ * enum dp_mon_filter_action - Action for storing the filters
+ * into the radio structure.
+ * @DP_MON_FILTER_CLEAR - Clears the filter for a mode
+ * @DP_MON_FILTER_SET - Set the filtes for a mode
+ */
+enum dp_mon_filter_action {
+	DP_MON_FILTER_CLEAR,
+	DP_MON_FILTER_SET,
+};
+
+#ifdef FEATURE_PERPKT_INFO
+/**
+ * dp_mon_filter_setup_enhanced_stats() - Setup the enhanced stats filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev);
+
+/***
+ * dp_mon_filter_reset_enhanced_stats() - Reset the enhanced stats filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_setup_mcopy_mode() - Setup the m_copy mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_reset_mcopy_mode() - Reset the m_copy mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev);
+#endif /* FEATURE_PERPKT_INFO */
+
+#if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
+/**
+ * dp_mon_filter_setup_smart_monitor() - Setup the smart monitor mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_reset_smart_monitor() - Reset the smart monitor mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev);
+#endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
+
+#ifdef  WLAN_RX_PKT_CAPTURE_ENH
+/**
+ * dp_mon_filter_setup_rx_enh_capture() - Setup the Rx capture mode filters
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_reset_rx_enh_capture() - Reset the Rx capture mode filters
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev);
+#endif /* WLAN_RX_PKT_CAPTURE_ENH */
+
+/**
+ * dp_mon_filter_setup_mon_mode() - Setup the Rx monitor mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_mon_mode(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_reset_mon_mode() - Reset the Rx monitor mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_mon_mode(struct dp_pdev *pdev);
+
+#ifdef WDI_EVENT_ENABLE
+/**
+ * dp_mon_filter_setup_rx_pkt_log_full() - Setup the Rx pktlog full mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_reset_rx_pkt_log_full() - Reset the Rx pktlog full mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_setup_rx_pkt_log_lite() - Setup the Rx pktlog lite mode filter
+ * in the radio object.
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_setup_rx_pkt_log_lite(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_reset_rx_pkt_log_lite() - Reset the Rx pktlog lite mode filter
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev);
+#endif /* WDI_EVENT_ENABLE */
+
+/**
+ * dp_mon_filter_update() - Setup the monitor filter setting for a srng
+ * type
+ * @pdev: DP pdev handle
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_dealloc() - Deallocate the filter objects to be stored in
+ * the radio object.
+ * @pdev: DP pdev handle
+ */
+void dp_mon_filter_dealloc(struct dp_pdev *pdev);
+
+/**
+ * dp_mon_filter_alloc() - Allocate the filter objects to be stored in
+ * the radio object.
+ * @pdev: DP pdev handle
+ */
+struct dp_mon_filter  **dp_mon_filter_alloc(struct dp_pdev *pdev);
+#endif /* #ifndef _DP_MON_FILTER_H_ */

+ 3 - 9
dp/wifi3.0/dp_rx_mon.h

@@ -45,15 +45,9 @@ QDF_STATUS dp_rx_pdev_mon_status_detach(struct dp_pdev *pdev, int mac_id);
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl, uint8_t pdev_id);
-
-/**
- * dp_pdev_configure_monitor_rings() - configure monitor rings
- * @vdev_handle: Datapath VDEV handle
- *
- * Return: QDF_STATUS
- */
-QDF_STATUS dp_pdev_configure_monitor_rings(struct dp_pdev *pdev);
+QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
+				 uint8_t pdev_id,
+				 uint8_t smart_monitor);
 
 /**
  * dp_mon_link_free() - free monitor link desc pool

+ 1 - 0
dp/wifi3.0/dp_tx.c

@@ -3143,6 +3143,7 @@ static inline void dp_tx_sojourn_stats_process(struct dp_pdev *pdev,
 }
 #else
 static inline void dp_tx_sojourn_stats_process(struct dp_pdev *pdev,
+					       struct dp_peer *peer,
 					       uint8_t tid,
 					       uint64_t txdesc_ts,
 					       uint32_t ppdu_id)

+ 3 - 0
dp/wifi3.0/dp_types.h

@@ -134,6 +134,7 @@ union dp_rx_desc_list_elem_t;
 struct cdp_peer_rate_stats_ctx;
 struct cdp_soc_rate_stats_ctx;
 struct dp_rx_fst;
+struct dp_mon_filter;
 
 #define DP_PDEV_ITERATE_VDEV_LIST(_pdev, _vdev) \
 	TAILQ_FOREACH((_vdev), &(_pdev)->vdev_list, vdev_list_elem)
@@ -1774,6 +1775,8 @@ struct dp_pdev {
 #ifdef WLAN_SUPPORT_DATA_STALL
 	data_stall_detect_cb data_stall_detect_callback;
 #endif /* WLAN_SUPPORT_DATA_STALL */
+
+	struct dp_mon_filter **filter;	/* Monitor Filter pointer */
 };
 
 struct dp_peer;