Browse Source

qcacmn: Monitor vdev and peer attach/detach

PATCH[5/7]:
This patch consists following changes:
 -Monitor vdev context allocation while vdev attach and free
  while vdev delete
 -Monitor peer context allocation while peer create and free while
  peer delete
 -Move monitor vdev timer function to monitor file
 -Move monitor reap timer handler function to monitor file
 -Move monitor timer related variables to monitor file
 -Add timer init/deinit and start/stop in monitor file.

Change-Id: I9c7910671d3678c53ca9ec44a57bc10e892008d9
CRs-Fixed: 2983994
aloksing 4 năm trước cách đây
mục cha
commit
c4796962ca

+ 0 - 14
dp/wifi3.0/dp_htt.h

@@ -454,20 +454,6 @@ struct htt_stats_context {
 	uint32_t msg_len;
 };
 
-int
-dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap);
-
-/**
- * dp_ppdu_desc_user_stats_update(): Function to update TX user stats
- * @pdev: DP pdev handle
- * @ppdu_info: per PPDU TLV descriptor
- *
- * return: void
- */
-void
-dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
-			       struct ppdu_info *ppdu_info);
-
 /**
  * dp_htt_rx_flow_fst_setup(): Send HTT Rx FST setup message to FW
  * @pdev: DP pdev handle

+ 82 - 7
dp/wifi3.0/dp_internal.h

@@ -192,6 +192,28 @@ static inline QDF_STATUS monitor_pdev_detach(struct dp_pdev *pdev)
 	return QDF_STATUS_SUCCESS;
 }
 
+static inline QDF_STATUS monitor_vdev_attach(struct dp_vdev *vdev)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS monitor_vdev_detach(struct dp_vdev *vdev)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS monitor_peer_attach(struct dp_soc *soc,
+					     struct dp_peer *peer)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
+static inline QDF_STATUS monitor_peer_detach(struct dp_soc *soc,
+					     struct dp_peer *peer)
+{
+	return QDF_STATUS_E_FAILURE;
+}
+
 static inline QDF_STATUS monitor_pdev_init(struct dp_pdev *pdev)
 {
 	return QDF_STATUS_SUCCESS;
@@ -387,6 +409,48 @@ static inline QDF_STATUS monitor_filter_neighbour_peer(struct dp_pdev *pdev,
 static inline void monitor_print_pdev_tx_capture_stats(struct dp_pdev *pdev)
 {
 }
+
+static inline
+void monitor_reap_timer_init(struct dp_soc *soc)
+{
+}
+
+static inline
+void monitor_reap_timer_deinit(struct dp_soc *soc)
+{
+}
+
+static inline
+void monitor_reap_timer_start(struct dp_soc *soc)
+{
+}
+
+static inline
+bool monitor_reap_timer_stop(struct dp_soc *soc)
+{
+	return false;
+}
+
+static inline
+void monitor_vdev_timer_init(struct dp_soc *soc)
+{
+}
+
+static inline
+void monitor_vdev_timer_deinit(struct dp_soc *soc)
+{
+}
+
+static inline
+void monitor_vdev_timer_start(struct dp_soc *soc)
+{
+}
+
+static inline
+bool monitor_vdev_timer_stop(struct dp_soc *soc)
+{
+	return false;
+}
 #endif
 
 #ifndef WIFI_MONITOR_SUPPORT
@@ -400,6 +464,24 @@ static inline bool dp_is_enable_reap_timer_non_pkt(struct dp_pdev *pdev)
 {
 	return false;
 }
+
+static inline void monitor_vdev_register_osif(struct dp_vdev *vdev,
+					      struct ol_txrx_ops *txrx_ops)
+{
+}
+
+static inline bool monitor_is_vdev_timer_running(struct dp_soc *soc)
+{
+	return false;
+}
+
+static inline void monitor_vdev_delete(struct dp_soc *soc, struct dp_vdev *vdev)
+{
+}
+
+static inline void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
+{
+}
 #endif
 
 #define DP_MAX_TIMER_EXEC_TIME_TICKS \
@@ -1300,13 +1382,6 @@ void dp_peer_find_id_to_obj_remove(struct dp_soc *soc,
 				   uint16_t peer_id);
 void dp_vdev_unref_delete(struct dp_soc *soc, struct dp_vdev *vdev,
 			  enum dp_mod_id mod_id);
-/*
- * dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
- * @peer: Datapath peer
- *
- * return: void
- */
-void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer);
 
 /*
  * dp_peer_ppdu_delayed_ba_cleanup() free ppdu allocated in peer

+ 33 - 149
dp/wifi3.0/dp_main.c

@@ -275,9 +275,6 @@ static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc,
 /* Threshold for peer's cached buf queue beyond which frames are dropped */
 #define DP_RX_CACHED_BUFQ_THRESH 64
 
-/* Budget to reap monitor status ring */
-#define DP_MON_REAP_BUDGET 1024
-
 /**
  * default_dscp_tid_map - Default DSCP-TID mapping
  *
@@ -418,23 +415,6 @@ uint32_t dp_soc_get_mon_mask_for_interrupt_mode(struct dp_soc *soc, int intr_ctx
 	return 0;
 }
 
-/*
- * dp_mon_reap_timer_handler()- timer to reap monitor rings
- * reqd as we are not getting ppdu end interrupts
- * @arg: SoC Handle
- *
- * Return:
- *
- */
-static void dp_mon_reap_timer_handler(void *arg)
-{
-	struct dp_soc *soc = (struct dp_soc *)arg;
-
-	monitor_service_mon_rings(soc, QCA_NAPI_BUDGET);
-
-	qdf_timer_mod(&soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
-}
-
 /**
  * dp_get_num_rx_contexts() - get number of RX contexts
  * @soc_hdl: cdp opaque soc handle
@@ -2212,7 +2192,7 @@ static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc,
  *
  * Return: enum with yield code
  */
-static enum timer_yield_status
+enum timer_yield_status
 dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
 			  uint64_t start_time)
 {
@@ -2227,6 +2207,8 @@ dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
 	return DP_TIMER_NO_YIELD;
 }
 
+qdf_export_symbol(dp_should_timer_irq_yield);
+
 /**
  * dp_process_lmac_rings() - Process LMAC rings
  * @int_ctx: interrupt context
@@ -2447,7 +2429,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
 			int_ctx->intr_stats.num_reo_status_ring_masks++;
 	}
 
-	if (qdf_unlikely(!(soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING))) {
+	if (qdf_unlikely(!monitor_is_vdev_timer_running(soc))) {
 		work_done = dp_process_lmac_rings(int_ctx, remaining_quota);
 		if (work_done) {
 			budget -=  work_done;
@@ -2488,7 +2470,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
 			int_ctx->intr_stats.num_reo_status_ring_masks++;
 	}
 
-	if (qdf_unlikely(!(soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING))) {
+	if (qdf_unlikely(!monitor_is_vdev_timer_running(soc))) {
 		work_done = dp_process_lmac_rings(int_ctx, remaining_quota);
 		if (work_done) {
 			budget -=  work_done;
@@ -2507,70 +2489,6 @@ budget_done:
 
 #endif /* QCA_HOST_MODE_WIFI_DISABLED */
 
-/* dp_mon_vdev_timer()- timer poll for interrupts
- *
- * @arg: SoC Handle
- *
- * Return:
- *
- */
-static void dp_mon_vdev_timer(void *arg)
-{
-	struct dp_soc *soc = (struct dp_soc *)arg;
-	struct dp_pdev *pdev = soc->pdev_list[0];
-	enum timer_yield_status yield = DP_TIMER_NO_YIELD;
-	uint32_t work_done  = 0, total_work_done = 0;
-	int budget = 0xffff;
-	uint32_t remaining_quota = budget;
-	uint64_t start_time;
-	uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
-	uint32_t lmac_iter;
-	int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
-
-	if (!qdf_atomic_read(&soc->cmn_init_done))
-		return;
-
-	if (pdev->mon_chan_band != REG_BAND_UNKNOWN)
-		lmac_id = pdev->ch_band_lmac_id_mapping[pdev->mon_chan_band];
-
-	start_time = qdf_get_log_timestamp();
-	dp_is_hw_dbs_enable(soc, &max_mac_rings);
-
-	while (yield == DP_TIMER_NO_YIELD) {
-		for (lmac_iter = 0; lmac_iter < max_mac_rings; lmac_iter++) {
-			if (lmac_iter == lmac_id)
-				work_done = monitor_process(
-						    soc, NULL,
-						    lmac_iter, remaining_quota);
-			else
-				work_done =
-					monitor_drop_packets_for_mac(pdev,
-							lmac_iter,
-							remaining_quota);
-			if (work_done) {
-				budget -=  work_done;
-				if (budget <= 0) {
-					yield = DP_TIMER_WORK_EXHAUST;
-					goto budget_done;
-				}
-				remaining_quota = budget;
-				total_work_done += work_done;
-			}
-		}
-
-		yield = dp_should_timer_irq_yield(soc, total_work_done,
-						  start_time);
-		total_work_done = 0;
-	}
-
-budget_done:
-	if (yield == DP_TIMER_WORK_EXHAUST ||
-	    yield == DP_TIMER_TIME_EXHAUST)
-		qdf_timer_mod(&soc->mon_vdev_timer, 1);
-	else
-		qdf_timer_mod(&soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
-}
-
 /* dp_interrupt_timer()- timer poll for interrupts
  *
  * @arg: SoC Handle
@@ -4932,10 +4850,7 @@ static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev)
 		dp_srng_free(soc, &pdev->rx_mac_buf_ring[i]);
 	}
 
-	if (soc->reap_timer_init) {
-		qdf_timer_free(&soc->mon_reap_timer);
-		soc->reap_timer_init = 0;
-	}
+	monitor_reap_timer_deinit(soc);
 }
 #else
 static void dp_rxdma_ring_cleanup(struct dp_soc *soc, struct dp_pdev *pdev)
@@ -5396,15 +5311,12 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
 	dp_soc_tx_history_detach(soc);
 	dp_soc_rx_history_detach(soc);
 
+	monitor_vdev_timer_deinit(soc);
+
 	if (!dp_monitor_modularized_enable()) {
 		dp_mon_soc_detach_wrapper(soc);
 	}
 
-	if (soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
-		qdf_timer_free(&soc->mon_vdev_timer);
-		soc->mon_vdev_timer_state = 0;
-	}
-
 	qdf_mem_free(soc);
 }
 
@@ -5523,14 +5435,8 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc)
 	 * Timer to reap rxdma status rings.
 	 * Needed until we enable ppdu end interrupts
 	 */
-	qdf_timer_init(soc->osdev, &soc->mon_reap_timer,
-		       dp_mon_reap_timer_handler, (void *)soc,
-		       QDF_TIMER_TYPE_WAKE_APPS);
-	soc->reap_timer_init = 1;
-	qdf_timer_init(soc->osdev, &soc->mon_vdev_timer,
-		       dp_mon_vdev_timer, (void *)soc,
-		       QDF_TIMER_TYPE_WAKE_APPS);
-	soc->mon_vdev_timer_state |= MON_VDEV_TIMER_INIT;
+	monitor_reap_timer_init(soc);
+	monitor_vdev_timer_init(soc);
 	return status;
 }
 #else
@@ -5554,24 +5460,13 @@ static QDF_STATUS dp_rxdma_ring_config(struct dp_soc *soc)
 		htt_srng_setup(soc->htt_handle, mac_for_pdev,
 			       soc->rx_refill_buf_ring[lmac_id].
 			       hal_srng, RXDMA_BUF);
-#ifndef DISABLE_MON_CONFIG
-
-		if (soc->wlan_cfg_ctx->rxdma1_enable &&
-		    wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) {
-			htt_srng_setup(soc->htt_handle, mac_for_pdev,
-				       soc->rxdma_mon_buf_ring[lmac_id].hal_srng,
-				       RXDMA_MONITOR_BUF);
-			htt_srng_setup(soc->htt_handle, mac_for_pdev,
-				       soc->rxdma_mon_dst_ring[lmac_id].hal_srng,
-				       RXDMA_MONITOR_DST);
-			htt_srng_setup(soc->htt_handle, mac_for_pdev,
-				       soc->rxdma_mon_desc_ring[lmac_id].hal_srng,
-				       RXDMA_MONITOR_DESC);
+		if (wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) {
+			/* Configure monitor mode rings */
+			monitor_htt_srng_setup(soc, pdev,
+					       lmac_id,
+					       mac_for_pdev);
 		}
-		htt_srng_setup(soc->htt_handle, mac_for_pdev,
-			       soc->rxdma_mon_status_ring[lmac_id].hal_srng,
-			       RXDMA_MONITOR_STATUS);
-#endif
+
 		htt_srng_setup(soc->htt_handle, mac_for_pdev,
 			       soc->rxdma_err_dst_ring[lmac_id].hal_srng,
 			       RXDMA_DST);
@@ -5904,7 +5799,6 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
 	vdev->osif_rx = NULL;
 	vdev->osif_rsim_rx_decap = NULL;
 	vdev->osif_get_key = NULL;
-	vdev->osif_rx_mon = NULL;
 	vdev->osif_tx_free_ext = NULL;
 	vdev->osif_vdev = NULL;
 
@@ -5942,16 +5836,14 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
 		    (wlan_op_mode_monitor == vdev->opmode))
 			qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
 	} else if (soc->intr_mode == DP_INTR_MSI &&
-		   wlan_op_mode_monitor == vdev->opmode &&
-		   soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
-		qdf_timer_mod(&soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
-		soc->mon_vdev_timer_state |= MON_VDEV_TIMER_RUNNING;
+		   wlan_op_mode_monitor == vdev->opmode) {
+		monitor_vdev_timer_start(soc);
 	}
 
 	dp_vdev_id_map_tbl_add(soc, vdev, vdev_id);
 
 	if (wlan_op_mode_monitor == vdev->opmode) {
-		monitor_vdev_set_monitor_mode_buf_rings(pdev);
+		monitor_vdev_attach(vdev);
 		pdev->monitor_vdev = vdev;
 		return QDF_STATUS_SUCCESS;
 	}
@@ -6070,7 +5962,7 @@ static QDF_STATUS dp_vdev_register_wifi3(struct cdp_soc_t *soc_hdl,
 	vdev->osif_fisa_rx = txrx_ops->rx.osif_fisa_rx;
 	vdev->osif_fisa_flush = txrx_ops->rx.osif_fisa_flush;
 	vdev->osif_get_key = txrx_ops->get_key;
-	vdev->osif_rx_mon = txrx_ops->rx.mon;
+	monitor_vdev_register_osif(vdev, txrx_ops);
 	vdev->osif_tx_free_ext = txrx_ops->tx.tx_free_ext;
 	vdev->tx_comp = txrx_ops->tx.tx_comp;
 	vdev->stats_cb = txrx_ops->rx.stats_rx;
@@ -6540,6 +6432,7 @@ dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 			QDF_STATUS_SUCCESS)
 		dp_warn("peer ext_stats ctx alloc failed");
 
+	monitor_peer_attach(soc, peer);
 	/*
 	 * In tx_monitor mode, filter may be set for unassociated peer
 	 * when unassociated peer get associated peer need to
@@ -7189,18 +7082,11 @@ void dp_vdev_unref_delete(struct dp_soc *soc, struct dp_vdev *vdev,
 		vdev, QDF_MAC_ADDR_REF(vdev->mac_addr.raw));
 
 	if (wlan_op_mode_monitor == vdev->opmode) {
-		if (soc->intr_mode == DP_INTR_POLL) {
-			qdf_timer_sync_cancel(&soc->int_timer);
-			monitor_flush_rings(soc);
-		} else if (soc->intr_mode == DP_INTR_MSI &&
-			soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING) {
-			qdf_timer_sync_cancel(&soc->mon_vdev_timer);
-			monitor_flush_rings(soc);
-			soc->mon_vdev_timer_state &= ~MON_VDEV_TIMER_RUNNING;
-		}
+		monitor_vdev_delete(soc, vdev);
 		pdev->monitor_vdev = NULL;
 		goto free_vdev;
 	}
+
 	/* all peers are gone, go ahead and delete it */
 	dp_tx_flow_pool_unmap_handler(pdev, vdev_id,
 			FLOW_TYPE_VDEV, vdev_id);
@@ -7299,6 +7185,8 @@ void dp_peer_unref_delete(struct dp_peer *peer, enum dp_mod_id mod_id)
 		wlan_minidump_remove(peer, sizeof(*peer), soc->ctrl_psoc,
 				     WLAN_MD_DP_PEER, "dp_peer");
 
+		monitor_peer_detach(soc, peer);
+
 		qdf_spin_lock_bh(&soc->inactive_peer_list_lock);
 		TAILQ_FOREACH(tmp_peer, &soc->inactive_peer_list,
 			      inactive_list_elem) {
@@ -11446,10 +11334,9 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
 
 	/* Stop monitor reap timer and reap any pending frames in ring */
 	if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) ||
-	     dp_is_enable_reap_timer_non_pkt(pdev)) &&
-	    soc->reap_timer_init) {
-		qdf_timer_sync_cancel(&soc->mon_reap_timer);
-		monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
+	     dp_is_enable_reap_timer_non_pkt(pdev))) {
+		if (monitor_reap_timer_stop(soc))
+			monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
 	}
 
 	dp_suspend_fse_cache_flush(soc);
@@ -11472,10 +11359,8 @@ static QDF_STATUS dp_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
 
 	/* Start monitor reap timer */
 	if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) ||
-	     dp_is_enable_reap_timer_non_pkt(pdev)) &&
-	    soc->reap_timer_init)
-		qdf_timer_mod(&soc->mon_reap_timer,
-			      DP_INTR_POLL_TIMER_MS);
+	     dp_is_enable_reap_timer_non_pkt(pdev)))
+		monitor_reap_timer_start(soc);
 
 	dp_resume_fse_cache_flush(soc);
 
@@ -11531,10 +11416,9 @@ static void dp_process_target_suspend_req(struct cdp_soc_t *soc_hdl,
 
 	/* Stop monitor reap timer and reap any pending frames in ring */
 	if (((pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) ||
-	     dp_is_enable_reap_timer_non_pkt(pdev)) &&
-	    soc->reap_timer_init) {
-		qdf_timer_sync_cancel(&soc->mon_reap_timer);
-		monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
+	    dp_is_enable_reap_timer_non_pkt(pdev))) {
+		if (monitor_reap_timer_stop(soc))
+			monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
 	}
 }
 

+ 0 - 26
dp/wifi3.0/dp_peer.c

@@ -3311,32 +3311,6 @@ void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
 #endif
 }
 
-#ifdef FEATURE_PERPKT_INFO
-/*
- * dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
- * @peer: Datapath peer
- *
- * return: void
- */
-void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
-{
-	qdf_mem_zero(&peer->delayed_ba_ppdu_stats,
-		     sizeof(struct cdp_delayed_tx_completion_ppdu_user));
-	peer->last_delayed_ba = false;
-	peer->last_delayed_ba_ppduid = 0;
-}
-#else
-/*
- * dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
- * @peer: Datapath peer
- *
- * return: void
- */
-void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
-{
-}
-#endif
-
 /*
  * dp_peer_cleanup() – Cleanup peer information
  * @vdev: Datapath vdev

+ 6 - 18
dp/wifi3.0/dp_types.h

@@ -1917,16 +1917,11 @@ struct dp_soc {
 	bool pending_ageout;
 	uint32_t max_ast_ageout_count;
 
-	/*interrupt timer*/
-	qdf_timer_t mon_reap_timer;
-	uint8_t reap_timer_init;
 	qdf_timer_t lmac_reap_timer;
 	uint8_t lmac_timer_init;
 	qdf_timer_t int_timer;
 	uint8_t intr_mode;
 	uint8_t lmac_polled_mode;
-	qdf_timer_t mon_vdev_timer;
-	uint8_t mon_vdev_timer_state;
 
 	qdf_list_t reo_desc_freelist;
 	qdf_spinlock_t reo_desc_freelist_lock;
@@ -2902,9 +2897,6 @@ struct dp_vdev {
 	/* proxy arp function */
 	ol_txrx_proxy_arp_fp osif_proxy_arp;
 
-	/* callback to hand rx monitor 802.11 MPDU to the OS shim */
-	ol_txrx_rx_mon_fp osif_rx_mon;
-
 	ol_txrx_mcast_me_fp me_convert;
 
 	/* completion function used by this vdev*/
@@ -3040,6 +3032,9 @@ struct dp_vdev {
 		uint8_t latency_tid;
 	} mesh_tid_latency_config;
 #endif
+#ifdef WIFI_MONITOR_SUPPORT
+	struct dp_mon_vdev *monitor_vdev;
+#endif
 
 #ifdef WLAN_FEATURE_TSF_UPLINK_DELAY
 	/* Indicate if uplink delay report is enabled or not */
@@ -3225,8 +3220,6 @@ struct dp_peer {
 
 	/* TID structures */
 	struct dp_rx_tid rx_tid[DP_MAX_TIDS];
-	struct dp_peer_tx_capture tx_capture;
-
 
 	/* TBD: No transmit TID state required? */
 
@@ -3303,14 +3296,6 @@ struct dp_peer {
 	qdf_atomic_t flush_in_progress;
 	struct dp_peer_cached_bufq bufq_info;
 #endif
-#ifdef FEATURE_PERPKT_INFO
-	/* delayed ba ppdu stats handling */
-	struct cdp_delayed_tx_completion_ppdu_user delayed_ba_ppdu_stats;
-	/* delayed ba flag */
-	bool last_delayed_ba;
-	/* delayed ba ppdu id */
-	uint32_t last_delayed_ba_ppduid;
-#endif
 #ifdef QCA_PEER_MULTIQ_SUPPORT
 	struct dp_peer_ast_params peer_ast_flowq_idx[DP_PEER_AST_FLOWQ_MAX];
 #endif
@@ -3337,6 +3322,9 @@ struct dp_peer {
 #ifdef WLAN_SUPPORT_MESH_LATENCY
 	struct dp_peer_mesh_latency_parameter mesh_latency_params[DP_MAX_TIDS];
 #endif
+#ifdef WIFI_MONITOR_SUPPORT
+	struct dp_mon_peer *monitor_peer;
+#endif
 };
 
 /*

+ 316 - 74
dp/wifi3.0/monitor/dp_mon.c

@@ -58,8 +58,12 @@ QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng,
 void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng,
 		    int ring_type, int ring_num);
 
-QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
-					  uint8_t delayed_replenish);
+enum timer_yield_status
+dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
+			  uint64_t start_time);
+
+static QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
+						 uint8_t delayed_replenish);
 
 #ifndef WLAN_TX_PKT_CAPTURE_ENH
 static inline void
@@ -1017,11 +1021,12 @@ dp_peer_copy_delay_stats(struct dp_peer *peer,
 {
 	struct dp_pdev *pdev;
 	struct dp_vdev *vdev;
+	struct dp_mon_peer *mon_peer = peer->monitor_peer;
 
-	if (peer->last_delayed_ba) {
+	if (mon_peer->last_delayed_ba) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			  "BA not yet recv for prev delayed ppdu[%d] - cur ppdu[%d]",
-			  peer->last_delayed_ba_ppduid, cur_ppdu_id);
+			  mon_peer->last_delayed_ba_ppduid, cur_ppdu_id);
 		vdev = peer->vdev;
 		if (vdev) {
 			pdev = vdev->pdev;
@@ -1029,30 +1034,32 @@ dp_peer_copy_delay_stats(struct dp_peer *peer,
 		}
 	}
 
-	peer->delayed_ba_ppdu_stats.ltf_size = ppdu->ltf_size;
-	peer->delayed_ba_ppdu_stats.stbc = ppdu->stbc;
-	peer->delayed_ba_ppdu_stats.he_re = ppdu->he_re;
-	peer->delayed_ba_ppdu_stats.txbf = ppdu->txbf;
-	peer->delayed_ba_ppdu_stats.bw = ppdu->bw;
-	peer->delayed_ba_ppdu_stats.nss = ppdu->nss;
-	peer->delayed_ba_ppdu_stats.gi = ppdu->gi;
-	peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
-	peer->delayed_ba_ppdu_stats.ldpc = ppdu->ldpc;
-	peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
-	peer->delayed_ba_ppdu_stats.mpdu_tried_ucast = ppdu->mpdu_tried_ucast;
-	peer->delayed_ba_ppdu_stats.mpdu_tried_mcast = ppdu->mpdu_tried_mcast;
-	peer->delayed_ba_ppdu_stats.frame_ctrl = ppdu->frame_ctrl;
-	peer->delayed_ba_ppdu_stats.qos_ctrl = ppdu->qos_ctrl;
-	peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
-
-	peer->delayed_ba_ppdu_stats.ru_start = ppdu->ru_start;
-	peer->delayed_ba_ppdu_stats.ru_tones = ppdu->ru_tones;
-	peer->delayed_ba_ppdu_stats.is_mcast = ppdu->is_mcast;
-
-	peer->delayed_ba_ppdu_stats.user_pos = ppdu->user_pos;
-	peer->delayed_ba_ppdu_stats.mu_group_id = ppdu->mu_group_id;
-
-	peer->last_delayed_ba = true;
+	mon_peer->delayed_ba_ppdu_stats.ltf_size = ppdu->ltf_size;
+	mon_peer->delayed_ba_ppdu_stats.stbc = ppdu->stbc;
+	mon_peer->delayed_ba_ppdu_stats.he_re = ppdu->he_re;
+	mon_peer->delayed_ba_ppdu_stats.txbf = ppdu->txbf;
+	mon_peer->delayed_ba_ppdu_stats.bw = ppdu->bw;
+	mon_peer->delayed_ba_ppdu_stats.nss = ppdu->nss;
+	mon_peer->delayed_ba_ppdu_stats.gi = ppdu->gi;
+	mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
+	mon_peer->delayed_ba_ppdu_stats.ldpc = ppdu->ldpc;
+	mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
+	mon_peer->delayed_ba_ppdu_stats.mpdu_tried_ucast =
+					ppdu->mpdu_tried_ucast;
+	mon_peer->delayed_ba_ppdu_stats.mpdu_tried_mcast =
+					ppdu->mpdu_tried_mcast;
+	mon_peer->delayed_ba_ppdu_stats.frame_ctrl = ppdu->frame_ctrl;
+	mon_peer->delayed_ba_ppdu_stats.qos_ctrl = ppdu->qos_ctrl;
+	mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
+
+	mon_peer->delayed_ba_ppdu_stats.ru_start = ppdu->ru_start;
+	mon_peer->delayed_ba_ppdu_stats.ru_tones = ppdu->ru_tones;
+	mon_peer->delayed_ba_ppdu_stats.is_mcast = ppdu->is_mcast;
+
+	mon_peer->delayed_ba_ppdu_stats.user_pos = ppdu->user_pos;
+	mon_peer->delayed_ba_ppdu_stats.mu_group_id = ppdu->mu_group_id;
+
+	mon_peer->last_delayed_ba = true;
 
 	ppdu->debug_copied = true;
 }
@@ -1074,30 +1081,34 @@ static void
 dp_peer_copy_stats_to_bar(struct dp_peer *peer,
 			  struct cdp_tx_completion_ppdu_user *ppdu)
 {
-	ppdu->ltf_size = peer->delayed_ba_ppdu_stats.ltf_size;
-	ppdu->stbc = peer->delayed_ba_ppdu_stats.stbc;
-	ppdu->he_re = peer->delayed_ba_ppdu_stats.he_re;
-	ppdu->txbf = peer->delayed_ba_ppdu_stats.txbf;
-	ppdu->bw = peer->delayed_ba_ppdu_stats.bw;
-	ppdu->nss = peer->delayed_ba_ppdu_stats.nss;
-	ppdu->gi = peer->delayed_ba_ppdu_stats.gi;
-	ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm;
-	ppdu->ldpc = peer->delayed_ba_ppdu_stats.ldpc;
-	ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm;
-	ppdu->mpdu_tried_ucast = peer->delayed_ba_ppdu_stats.mpdu_tried_ucast;
-	ppdu->mpdu_tried_mcast = peer->delayed_ba_ppdu_stats.mpdu_tried_mcast;
-	ppdu->frame_ctrl = peer->delayed_ba_ppdu_stats.frame_ctrl;
-	ppdu->qos_ctrl = peer->delayed_ba_ppdu_stats.qos_ctrl;
-	ppdu->dcm = peer->delayed_ba_ppdu_stats.dcm;
-
-	ppdu->ru_start = peer->delayed_ba_ppdu_stats.ru_start;
-	ppdu->ru_tones = peer->delayed_ba_ppdu_stats.ru_tones;
-	ppdu->is_mcast = peer->delayed_ba_ppdu_stats.is_mcast;
-
-	ppdu->user_pos = peer->delayed_ba_ppdu_stats.user_pos;
-	ppdu->mu_group_id = peer->delayed_ba_ppdu_stats.mu_group_id;
-
-	peer->last_delayed_ba = false;
+	struct dp_mon_peer *mon_peer = peer->monitor_peer;
+
+	ppdu->ltf_size = mon_peer->delayed_ba_ppdu_stats.ltf_size;
+	ppdu->stbc = mon_peer->delayed_ba_ppdu_stats.stbc;
+	ppdu->he_re = mon_peer->delayed_ba_ppdu_stats.he_re;
+	ppdu->txbf = mon_peer->delayed_ba_ppdu_stats.txbf;
+	ppdu->bw = mon_peer->delayed_ba_ppdu_stats.bw;
+	ppdu->nss = mon_peer->delayed_ba_ppdu_stats.nss;
+	ppdu->gi = mon_peer->delayed_ba_ppdu_stats.gi;
+	ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
+	ppdu->ldpc = mon_peer->delayed_ba_ppdu_stats.ldpc;
+	ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
+	ppdu->mpdu_tried_ucast =
+			mon_peer->delayed_ba_ppdu_stats.mpdu_tried_ucast;
+	ppdu->mpdu_tried_mcast =
+			mon_peer->delayed_ba_ppdu_stats.mpdu_tried_mcast;
+	ppdu->frame_ctrl = mon_peer->delayed_ba_ppdu_stats.frame_ctrl;
+	ppdu->qos_ctrl = mon_peer->delayed_ba_ppdu_stats.qos_ctrl;
+	ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
+
+	ppdu->ru_start = mon_peer->delayed_ba_ppdu_stats.ru_start;
+	ppdu->ru_tones = mon_peer->delayed_ba_ppdu_stats.ru_tones;
+	ppdu->is_mcast = mon_peer->delayed_ba_ppdu_stats.is_mcast;
+
+	ppdu->user_pos = mon_peer->delayed_ba_ppdu_stats.user_pos;
+	ppdu->mu_group_id = mon_peer->delayed_ba_ppdu_stats.mu_group_id;
+
+	mon_peer->last_delayed_ba = false;
 
 	ppdu->debug_copied = true;
 }
@@ -2272,7 +2283,7 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
 			if (!peer)
 				continue;
 
-			delay_ppdu = &peer->delayed_ba_ppdu_stats;
+			delay_ppdu = &peer->monitor_peer->delayed_ba_ppdu_stats;
 			start_tsf = ppdu_desc->ppdu_start_timestamp;
 			end_tsf = ppdu_desc->ppdu_end_timestamp;
 			/**
@@ -2282,12 +2293,13 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
 				dp_peer_copy_delay_stats(peer,
 							 &ppdu_desc->user[i],
 							 ppdu_id);
-				peer->last_delayed_ba_ppduid = ppdu_id;
+				peer->monitor_peer->last_delayed_ba_ppduid =
+									ppdu_id;
 				delay_ppdu->ppdu_start_timestamp = start_tsf;
 				delay_ppdu->ppdu_end_timestamp = end_tsf;
 			}
 			ppdu_desc->user[i].peer_last_delayed_ba =
-				peer->last_delayed_ba;
+				peer->monitor_peer->last_delayed_ba;
 
 			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 
@@ -2334,20 +2346,20 @@ dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
 				continue;
 			}
 
-			delay_ppdu = &peer->delayed_ba_ppdu_stats;
+			delay_ppdu = &peer->monitor_peer->delayed_ba_ppdu_stats;
 			start_tsf = delay_ppdu->ppdu_start_timestamp;
 			end_tsf = delay_ppdu->ppdu_end_timestamp;
 
-			if (peer->last_delayed_ba) {
+			if (peer->monitor_peer->last_delayed_ba) {
 				dp_peer_copy_stats_to_bar(peer,
 							  &ppdu_desc->user[i]);
 				ppdu_desc->ppdu_id =
-					peer->last_delayed_ba_ppduid;
+					peer->monitor_peer->last_delayed_ba_ppduid;
 				ppdu_desc->ppdu_start_timestamp = start_tsf;
 				ppdu_desc->ppdu_end_timestamp = end_tsf;
 			}
 			ppdu_desc->user[i].peer_last_delayed_ba =
-				peer->last_delayed_ba;
+				peer->monitor_peer->last_delayed_ba;
 			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
 		}
 	}
@@ -3572,8 +3584,10 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 	int max_mac_rings = wlan_cfg_get_num_mac_rings
 					(pdev->wlan_cfg_ctx);
 	uint8_t mac_id = 0;
+	struct dp_mon_soc *mon_soc;
 
 	soc = pdev->soc;
+	mon_soc = soc->monitor_soc;
 	dp_is_hw_dbs_enable(soc, &max_mac_rings);
 
 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
@@ -3603,9 +3617,9 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 					return 0;
 				}
 
-				if (soc->reap_timer_init &&
+				if (mon_soc->reap_timer_init &&
 				    (!dp_is_enable_reap_timer_non_pkt(pdev)))
-					qdf_timer_mod(&soc->mon_reap_timer,
+					qdf_timer_mod(&mon_soc->mon_reap_timer,
 						      DP_INTR_POLL_TIMER_MS);
 			}
 			break;
@@ -3634,9 +3648,9 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 					return 0;
 				}
 
-				if (soc->reap_timer_init &&
+				if (mon_soc->reap_timer_init &&
 				    (!dp_is_enable_reap_timer_non_pkt(pdev)))
-					qdf_timer_mod(&soc->mon_reap_timer,
+					qdf_timer_mod(&mon_soc->mon_reap_timer,
 						      DP_INTR_POLL_TIMER_MS);
 			}
 			break;
@@ -3682,9 +3696,9 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 					return 0;
 				}
 
-				if (soc->reap_timer_init &&
+				if (mon_soc->reap_timer_init &&
 				    !dp_is_enable_reap_timer_non_pkt(pdev))
-					qdf_timer_mod(&soc->mon_reap_timer,
+					qdf_timer_mod(&mon_soc->mon_reap_timer,
 						      DP_INTR_POLL_TIMER_MS);
 			}
 			break;
@@ -3720,9 +3734,9 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 					return 0;
 				}
 
-				if (soc->reap_timer_init &&
+				if (mon_soc->reap_timer_init &&
 				    (!dp_is_enable_reap_timer_non_pkt(pdev)))
-					qdf_timer_stop(&soc->mon_reap_timer);
+					qdf_timer_stop(&mon_soc->mon_reap_timer);
 			}
 			break;
 		case WDI_EVENT_LITE_T2H:
@@ -3781,6 +3795,7 @@ static void dp_pktlogmod_exit(struct dp_pdev *pdev)
 {
 	struct dp_soc *soc = pdev->soc;
 	struct hif_opaque_softc *scn = soc->hif_handle;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
 
 	if (!scn) {
 		dp_err("Invalid hif(scn) handle");
@@ -3789,8 +3804,9 @@ static void dp_pktlogmod_exit(struct dp_pdev *pdev)
 
 	/* stop mon_reap_timer if it has been started */
 	if (pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED &&
-	    soc->reap_timer_init && (!dp_is_enable_reap_timer_non_pkt(pdev)))
-		qdf_timer_sync_cancel(&soc->mon_reap_timer);
+	    mon_soc->reap_timer_init &&
+	    (!dp_is_enable_reap_timer_non_pkt(pdev)))
+		qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
 
 	pktlogmod_exit(scn);
 	pdev->pkt_log_init = false;
@@ -4183,6 +4199,7 @@ dp_enable_mon_reap_timer(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 = NULL;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
 
 	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
 	if (!pdev) {
@@ -4196,16 +4213,16 @@ dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 		return;
 	}
 
-	if (!soc->reap_timer_init) {
+	if (!mon_soc->reap_timer_init) {
 		dp_err("reap timer not init");
 		return;
 	}
 
 	if (enable)
-		qdf_timer_mod(&soc->mon_reap_timer,
+		qdf_timer_mod(&mon_soc->mon_reap_timer,
 			      DP_INTR_POLL_TIMER_MS);
 	else
-		qdf_timer_sync_cancel(&soc->mon_reap_timer);
+		qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
 }
 #endif
 
@@ -4488,8 +4505,8 @@ dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc,
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
-					  uint8_t delayed_replenish)
+static QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
+						 uint8_t delayed_replenish)
 {
 	struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
 	uint32_t mac_id;
@@ -4564,6 +4581,168 @@ fail0:
 	return QDF_STATUS_E_FAILURE;
 }
 
+/* dp_mon_vdev_timer()- timer poll for interrupts
+ *
+ * @arg: SoC Handle
+ *
+ * Return:
+ *
+ */
+static void dp_mon_vdev_timer(void *arg)
+{
+	struct dp_soc *soc = (struct dp_soc *)arg;
+	struct dp_pdev *pdev = soc->pdev_list[0];
+	enum timer_yield_status yield = DP_TIMER_NO_YIELD;
+	uint32_t work_done  = 0, total_work_done = 0;
+	int budget = 0xffff;
+	uint32_t remaining_quota = budget;
+	uint64_t start_time;
+	uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
+	uint32_t lmac_iter;
+	int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!qdf_atomic_read(&soc->cmn_init_done))
+		return;
+
+	if (pdev->mon_chan_band != REG_BAND_UNKNOWN)
+		lmac_id = pdev->ch_band_lmac_id_mapping[pdev->mon_chan_band];
+
+	start_time = qdf_get_log_timestamp();
+	dp_is_hw_dbs_enable(soc, &max_mac_rings);
+
+	while (yield == DP_TIMER_NO_YIELD) {
+		for (lmac_iter = 0; lmac_iter < max_mac_rings; lmac_iter++) {
+			if (lmac_iter == lmac_id)
+				work_done = monitor_process(soc, NULL,
+							    lmac_iter,
+							    remaining_quota);
+			else
+				work_done =
+					monitor_drop_packets_for_mac(pdev,
+								     lmac_iter,
+								     remaining_quota);
+			if (work_done) {
+				budget -=  work_done;
+				if (budget <= 0) {
+					yield = DP_TIMER_WORK_EXHAUST;
+					goto budget_done;
+				}
+				remaining_quota = budget;
+				total_work_done += work_done;
+			}
+		}
+
+		yield = dp_should_timer_irq_yield(soc, total_work_done,
+						  start_time);
+		total_work_done = 0;
+	}
+
+budget_done:
+	if (yield == DP_TIMER_WORK_EXHAUST ||
+	    yield == DP_TIMER_TIME_EXHAUST)
+		qdf_timer_mod(&mon_soc->mon_vdev_timer, 1);
+	else
+		qdf_timer_mod(&mon_soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
+}
+
+/* MCL specific functions */
+#if defined(DP_CON_MON)
+/*
+ * dp_mon_reap_timer_handler()- timer to reap monitor rings
+ * reqd as we are not getting ppdu end interrupts
+ * @arg: SoC Handle
+ *
+ * Return:
+ *
+ */
+static void dp_mon_reap_timer_handler(void *arg)
+{
+	struct dp_soc *soc = (struct dp_soc *)arg;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	dp_service_mon_rings(soc, QCA_NAPI_BUDGET);
+	qdf_timer_mod(&mon_soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
+}
+#endif
+
+#ifdef QCA_HOST2FW_RXBUF_RING
+static void dp_mon_reap_timer_init(struct dp_soc *soc)
+{
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	qdf_timer_init(soc->osdev, &mon_soc->mon_reap_timer,
+		       dp_mon_reap_timer_handler, (void *)soc,
+		       QDF_TIMER_TYPE_WAKE_APPS);
+	mon_soc->reap_timer_init = 1;
+}
+#else
+static void dp_mon_reap_timer_init(struct dp_soc *soc)
+{
+}
+#endif
+
+static void dp_mon_reap_timer_deinit(struct dp_mon_soc *mon_soc)
+{
+	if (mon_soc->reap_timer_init) {
+		qdf_timer_free(&mon_soc->mon_reap_timer);
+		mon_soc->reap_timer_init = 0;
+	}
+}
+
+static void dp_mon_reap_timer_start(struct dp_mon_soc *mon_soc)
+{
+	if (mon_soc->reap_timer_init)
+		qdf_timer_mod(&mon_soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
+}
+
+static bool dp_mon_reap_timer_stop(struct dp_mon_soc *mon_soc)
+{
+	if (mon_soc->reap_timer_init) {
+		qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
+		return true;
+	}
+
+	return false;
+}
+
+static void dp_mon_vdev_timer_init(struct dp_soc *soc)
+{
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	qdf_timer_init(soc->osdev, &mon_soc->mon_vdev_timer,
+		       dp_mon_vdev_timer, (void *)soc,
+		       QDF_TIMER_TYPE_WAKE_APPS);
+	mon_soc->mon_vdev_timer_state |= MON_VDEV_TIMER_INIT;
+}
+
+static void dp_mon_vdev_timer_deinit(struct dp_mon_soc *mon_soc)
+{
+	if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
+		qdf_timer_free(&mon_soc->mon_vdev_timer);
+		mon_soc->mon_vdev_timer_state = 0;
+	}
+}
+
+static void dp_mon_vdev_timer_start(struct dp_mon_soc *mon_soc)
+{
+	if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
+		qdf_timer_mod(&mon_soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
+		mon_soc->mon_vdev_timer_state |= MON_VDEV_TIMER_RUNNING;
+	}
+}
+
+static bool dp_mon_vdev_timer_stop(struct dp_mon_soc *mon_soc)
+{
+	if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING) {
+		qdf_timer_sync_cancel(&mon_soc->mon_vdev_timer);
+		mon_soc->mon_vdev_timer_state &= ~MON_VDEV_TIMER_RUNNING;
+		return true;
+	}
+
+	return false;
+}
+
 QDF_STATUS dp_mon_soc_cfg_init(struct dp_soc *soc)
 {
 	int target_type;
@@ -4746,12 +4925,67 @@ QDF_STATUS dp_mon_pdev_deinit(struct dp_pdev *pdev)
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS dp_mon_vdev_attach(struct dp_vdev *vdev)
+{
+	struct dp_mon_vdev *mon_vdev;
+	struct dp_pdev *pdev = vdev->pdev;
+
+	mon_vdev = (struct dp_mon_vdev *)qdf_mem_malloc(sizeof(*mon_vdev));
+	if (!mon_vdev) {
+		mon_init_err("%pK: Monitor vdev allocation failed", vdev);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	vdev->monitor_vdev = mon_vdev;
+	dp_vdev_set_monitor_mode_buf_rings(pdev);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS dp_mon_vdev_detach(struct dp_vdev *vdev)
+{
+	struct dp_mon_vdev *mon_vdev = vdev->monitor_vdev;
+
+	qdf_mem_free(mon_vdev);
+	vdev->monitor_vdev = NULL;
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS dp_mon_peer_attach(struct dp_peer *peer)
+{
+	struct dp_mon_peer *mon_peer;
+
+	mon_peer = (struct dp_mon_peer *)qdf_mem_malloc(sizeof(*mon_peer));
+	if (!mon_peer) {
+		mon_init_err("%pK: MONITOR peer allocation failed", peer);
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	peer->monitor_peer = mon_peer;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS dp_mon_peer_detach(struct dp_peer *peer)
+{
+	struct dp_mon_peer *mon_peer = peer->monitor_peer;
+
+	qdf_mem_free(mon_peer);
+	peer->monitor_peer = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 static struct dp_mon_ops monitor_ops = {
 	.mon_soc_cfg_init = dp_mon_soc_cfg_init,
 	.mon_pdev_attach = dp_mon_pdev_attach,
 	.mon_pdev_detach = dp_mon_pdev_detach,
 	.mon_pdev_init = dp_mon_pdev_init,
 	.mon_pdev_deinit = dp_mon_pdev_deinit,
+	.mon_vdev_attach = dp_mon_vdev_attach,
+	.mon_vdev_detach = dp_mon_vdev_detach,
+	.mon_peer_attach = dp_mon_peer_attach,
+	.mon_peer_detach = dp_mon_peer_detach,
 	.mon_config_debug_sniffer = dp_config_debug_sniffer,
 	.mon_flush_rings = dp_flush_monitor_rings,
 #if !defined(DISABLE_MON_CONFIG)
@@ -4812,6 +5046,14 @@ static struct dp_mon_ops monitor_ops = {
 #ifdef FEATURE_NAC_RSSI
 	.mon_filter_neighbour_peer = dp_filter_neighbour_peer,
 #endif
+	.mon_vdev_timer_init = dp_mon_vdev_timer_init,
+	.mon_vdev_timer_start = dp_mon_vdev_timer_start,
+	.mon_vdev_timer_stop = dp_mon_vdev_timer_stop,
+	.mon_vdev_timer_deinit = dp_mon_vdev_timer_deinit,
+	.mon_reap_timer_init = dp_mon_reap_timer_init,
+	.mon_reap_timer_start = dp_mon_reap_timer_start,
+	.mon_reap_timer_stop = dp_mon_reap_timer_stop,
+	.mon_reap_timer_deinit = dp_mon_reap_timer_deinit,
 };
 
 static struct cdp_mon_ops dp_ops_mon = {

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

@@ -13,13 +13,26 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#define DP_INTR_POLL_TIMER_MS	5
+
+#define MON_VDEV_TIMER_INIT 0x1
+#define MON_VDEV_TIMER_RUNNING 0x2
+
+/* Budget to reap monitor status ring */
+#define DP_MON_REAP_BUDGET 1024
+
 #define mon_rx_warn(params...) QDF_TRACE_WARN(QDF_MODULE_ID_DP_RX, params)
+
 struct dp_mon_ops {
 	QDF_STATUS (*mon_soc_cfg_init)(struct dp_soc *soc);
 	QDF_STATUS (*mon_pdev_attach)(struct dp_pdev *pdev);
 	QDF_STATUS (*mon_pdev_detach)(struct dp_pdev *pdev);
 	QDF_STATUS (*mon_pdev_init)(struct dp_pdev *pdev);
 	QDF_STATUS (*mon_pdev_deinit)(struct dp_pdev *pdev);
+	QDF_STATUS (*mon_vdev_attach)(struct dp_vdev *vdev);
+	QDF_STATUS (*mon_vdev_detach)(struct dp_vdev *vdev);
+	QDF_STATUS (*mon_peer_attach)(struct dp_peer *peer);
+	QDF_STATUS (*mon_peer_detach)(struct dp_peer *peer);
 	QDF_STATUS (*mon_config_debug_sniffer)(struct dp_pdev *pdev, int val);
 	void (*mon_flush_rings)(struct dp_soc *soc);
 #if !defined(DISABLE_MON_CONFIG)
@@ -100,12 +113,27 @@ struct dp_mon_ops {
 	QDF_STATUS (*mon_filter_neighbour_peer)(struct dp_pdev *pdev,
 						uint8_t *rx_pkt_hdr);
 #endif
+	void (*mon_vdev_timer_init)(struct dp_soc *soc);
+	void (*mon_vdev_timer_start)(struct dp_mon_soc *mon_soc);
+	bool (*mon_vdev_timer_stop)(struct dp_mon_soc *mon_soc);
+	void (*mon_vdev_timer_deinit)(struct dp_mon_soc *mon_soc);
+	void (*mon_reap_timer_init)(struct dp_soc *soc);
+	void (*mon_reap_timer_start)(struct dp_mon_soc *mon_soc);
+	bool (*mon_reap_timer_stop)(struct dp_mon_soc *mon_soc);
+	void (*mon_reap_timer_deinit)(struct dp_mon_soc *mon_soc);
 };
 
 struct dp_mon_soc {
 	/* Holds all monitor related fields extracted from dp_soc */
 	/* Holds pointer to monitor ops */
 
+	/*interrupt timer*/
+	qdf_timer_t mon_reap_timer;
+	uint8_t reap_timer_init;
+
+	qdf_timer_t mon_vdev_timer;
+	uint8_t mon_vdev_timer_state;
+
 	struct dp_mon_ops *mon_ops;
 };
 
@@ -113,9 +141,20 @@ struct  dp_mon_pdev {
 };
 
 struct  dp_mon_vdev {
+	/* callback to hand rx monitor 802.11 MPDU to the OS shim */
+	ol_txrx_rx_mon_fp osif_rx_mon;
 };
 
 struct dp_mon_peer {
+	struct dp_peer_tx_capture tx_capture;
+#ifdef FEATURE_PERPKT_INFO
+	/* delayed ba ppdu stats handling */
+	struct cdp_delayed_tx_completion_ppdu_user delayed_ba_ppdu_stats;
+	/* delayed ba flag */
+	bool last_delayed_ba;
+	/* delayed ba ppdu id */
+	uint32_t last_delayed_ba_ppduid;
+#endif
 };
 
 #ifdef FEATURE_PERPKT_INFO
@@ -227,6 +266,19 @@ extern uint8_t
 dp_cpu_ring_map[DP_NSS_CPU_RING_MAP_MAX][WLAN_CFG_INT_NUM_CONTEXTS_MAX];
 #endif
 
+int
+dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap);
+/**
+ * dp_ppdu_desc_user_stats_update(): Function to update TX user stats
+ * @pdev: DP pdev handle
+ * @ppdu_info: per PPDU TLV descriptor
+ *
+ * return: void
+ */
+void
+dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
+			       struct ppdu_info *ppdu_info);
+
 #ifdef WDI_EVENT_ENABLE
 void dp_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn);
 #else
@@ -324,6 +376,58 @@ static inline QDF_STATUS monitor_drop_inv_peer_pkts(struct dp_vdev *vdev,
 }
 #endif
 
+#ifdef FEATURE_PERPKT_INFO
+/*
+ * dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
+ * @peer: Datapath peer
+ *
+ * return: void
+ */
+static inline void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
+{
+	struct dp_mon_peer *mon_peer = peer->monitor_peer;
+
+	if (!mon_peer)
+		return;
+
+	qdf_mem_zero(&mon_peer->delayed_ba_ppdu_stats,
+		     sizeof(struct cdp_delayed_tx_completion_ppdu_user));
+	mon_peer->last_delayed_ba = false;
+	mon_peer->last_delayed_ba_ppduid = 0;
+}
+#else
+/*
+ * dp_peer_ppdu_delayed_ba_init() Initialize ppdu in peer
+ * @peer: Datapath peer
+ *
+ * return: void
+ */
+static inline void dp_peer_ppdu_delayed_ba_init(struct dp_peer *peer)
+{
+}
+#endif
+
+static inline void monitor_vdev_register_osif(struct dp_vdev *vdev,
+					      struct ol_txrx_ops *txrx_ops)
+{
+	if (!vdev->monitor_vdev)
+		return;
+
+	vdev->monitor_vdev->osif_rx_mon = txrx_ops->rx.mon;
+}
+
+static inline bool monitor_is_vdev_timer_running(struct dp_soc *soc)
+{
+	struct dp_mon_soc *mon_soc;
+
+	if (!soc || !soc->monitor_soc)
+		return false;
+
+	mon_soc = soc->monitor_soc;
+
+	return mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING;
+}
+
 static inline QDF_STATUS monitor_pdev_attach(struct dp_pdev *pdev)
 {
 	struct dp_mon_ops *monitor_ops;
@@ -368,6 +472,76 @@ static inline QDF_STATUS monitor_pdev_detach(struct dp_pdev *pdev)
 	return monitor_ops->mon_pdev_detach(pdev);
 }
 
+static inline QDF_STATUS monitor_vdev_attach(struct dp_vdev *vdev)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = vdev->pdev->soc->monitor_soc;
+
+	if (!mon_soc)
+		return QDF_STATUS_E_FAILURE;
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_vdev_attach) {
+		qdf_err("callback not registered");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return monitor_ops->mon_vdev_attach(vdev);
+}
+
+static inline QDF_STATUS monitor_vdev_detach(struct dp_vdev *vdev)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = vdev->pdev->soc->monitor_soc;
+
+	if (!mon_soc)
+		return QDF_STATUS_E_FAILURE;
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_vdev_detach) {
+		qdf_err("callback not registered");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return monitor_ops->mon_vdev_detach(vdev);
+}
+
+static inline QDF_STATUS monitor_peer_attach(struct dp_soc *soc,
+					     struct dp_peer *peer)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc)
+		return QDF_STATUS_E_FAILURE;
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_peer_attach) {
+		qdf_print("callback not registered");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return monitor_ops->mon_peer_attach(peer);
+}
+
+static inline QDF_STATUS monitor_peer_detach(struct dp_soc *soc,
+					     struct dp_peer *peer)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc)
+		return QDF_STATUS_E_FAILURE;
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_peer_detach) {
+		qdf_print("callback not registered");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	return monitor_ops->mon_peer_detach(peer);
+}
+
 static inline QDF_STATUS monitor_pdev_init(struct dp_pdev *pdev)
 {
 	struct dp_mon_ops *monitor_ops;
@@ -1221,3 +1395,177 @@ static inline QDF_STATUS monitor_filter_neighbour_peer(struct dp_pdev *pdev,
 	return monitor_ops->mon_filter_neighbour_peer(pdev, rx_pkt_hdr);
 }
 #endif
+
+static inline
+void monitor_reap_timer_init(struct dp_soc *soc)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc) {
+		qdf_err("monitor soc is NULL");
+		return;
+	}
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_reap_timer_init) {
+		qdf_err("callback not registered");
+		return;
+	}
+
+	monitor_ops->mon_reap_timer_init(soc);
+}
+
+static inline
+void monitor_reap_timer_deinit(struct dp_soc *soc)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc) {
+		qdf_err("monitor soc is NULL");
+		return;
+	}
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_reap_timer_deinit) {
+		qdf_err("callback not registered");
+		return;
+	}
+
+	monitor_ops->mon_reap_timer_deinit(mon_soc);
+}
+
+static inline
+void monitor_reap_timer_start(struct dp_soc *soc)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc) {
+		qdf_err("monitor soc is NULL");
+		return;
+	}
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_reap_timer_start) {
+		qdf_err("callback not registered");
+		return;
+	}
+
+	monitor_ops->mon_reap_timer_start(mon_soc);
+}
+
+static inline
+bool monitor_reap_timer_stop(struct dp_soc *soc)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc) {
+		qdf_err("monitor soc is NULL");
+		return false;
+	}
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_reap_timer_stop) {
+		qdf_err("callback not registered");
+		return false;
+	}
+
+	monitor_ops->mon_reap_timer_stop(mon_soc);
+}
+
+static inline
+void monitor_vdev_timer_init(struct dp_soc *soc)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc) {
+		qdf_err("monitor soc is NULL");
+		return;
+	}
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_vdev_timer_init) {
+		qdf_err("callback not registered");
+		return;
+	}
+
+	monitor_ops->mon_vdev_timer_init(soc);
+}
+
+static inline
+void monitor_vdev_timer_deinit(struct dp_soc *soc)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc) {
+		qdf_err("monitor soc is NULL");
+		return;
+	}
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_vdev_timer_deinit) {
+		qdf_err("callback not registered");
+		return;
+	}
+
+	monitor_ops->mon_vdev_timer_deinit(mon_soc);
+}
+
+static inline
+void monitor_vdev_timer_start(struct dp_soc *soc)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc) {
+		qdf_err("monitor soc is NULL");
+		return;
+	}
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_vdev_timer_start) {
+		qdf_err("callback not registered");
+		return;
+	}
+
+	monitor_ops->mon_vdev_timer_start(mon_soc);
+}
+
+static inline
+bool monitor_vdev_timer_stop(struct dp_soc *soc)
+{
+	struct dp_mon_ops *monitor_ops;
+	struct dp_mon_soc *mon_soc = soc->monitor_soc;
+
+	if (!mon_soc) {
+		qdf_err("monitor soc is NULL");
+		return false;
+	}
+
+	monitor_ops = mon_soc->mon_ops;
+	if (!monitor_ops || !monitor_ops->mon_vdev_timer_stop) {
+		qdf_err("callback not registered");
+		return false;
+	}
+
+	return monitor_ops->mon_vdev_timer_stop(mon_soc);
+}
+
+static inline void monitor_vdev_delete(struct dp_soc *soc, struct dp_vdev *vdev)
+{
+	if (soc->intr_mode == DP_INTR_POLL) {
+		qdf_timer_sync_cancel(&soc->int_timer);
+		monitor_flush_rings(soc);
+	} else if (soc->intr_mode == DP_INTR_MSI) {
+		if (monitor_vdev_timer_stop(soc))
+			monitor_flush_rings(soc);
+	}
+
+	monitor_vdev_detach(vdev);
+}
+

+ 14 - 4
dp/wifi3.0/monitor/dp_rx_mon_dest.c

@@ -25,6 +25,8 @@
 #include "qdf_trace.h"
 #include "qdf_nbuf.h"
 #include "hal_api_mon.h"
+#include "dp_htt.h"
+#include "dp_mon.h"
 #include "dp_rx_mon.h"
 #include "wlan_cfg.h"
 #include "dp_internal.h"
@@ -1489,11 +1491,13 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
 	struct cdp_mon_status *rs = &pdev->rx_mon_recv_status;
 	qdf_nbuf_t mon_skb, skb_next;
 	qdf_nbuf_t mon_mpdu = NULL;
+	struct dp_vdev *vdev;
 
 	if (!pdev || (!pdev->monitor_vdev && !pdev->mcopy_mode &&
 		      !pdev->rx_pktlog_cbf))
 		goto mon_deliver_fail;
 
+	vdev = pdev->monitor_vdev;
 	/* restitch mon MPDU for delivery via monitor interface */
 	mon_mpdu = dp_rx_mon_restitch_mpdu(soc, mac_id, head_msdu,
 					   tail_msdu, rs);
@@ -1513,7 +1517,7 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
 		return dp_send_mgmt_packet_to_stack(soc, mon_mpdu, pdev);
 
 	if (mon_mpdu && pdev->monitor_vdev && pdev->monitor_vdev->osif_vdev &&
-	    pdev->monitor_vdev->osif_rx_mon) {
+	    vdev->monitor_vdev->osif_rx_mon) {
 		pdev->ppdu_info.rx_status.ppdu_id =
 			pdev->ppdu_info.com_info.ppdu_id;
 		pdev->ppdu_info.rx_status.device_id = soc->device_id;
@@ -1532,7 +1536,7 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
 		}
 
 		dp_rx_mon_update_pf_tag_to_buf_headroom(soc, mon_mpdu);
-		pdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
+		vdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
 						mon_mpdu,
 						&pdev->ppdu_info.rx_status);
 	} else {
@@ -1575,13 +1579,19 @@ QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc,
 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
 	ol_txrx_rx_mon_fp osif_rx_mon;
 	qdf_nbuf_t dummy_msdu;
+	struct dp_vdev *vdev;
 
 	/* Sanity checking */
-	if (!pdev || !pdev->monitor_vdev || !pdev->monitor_vdev->osif_rx_mon)
+	if (!pdev || !pdev->monitor_vdev)
+		goto mon_deliver_non_std_fail;
+
+	vdev = pdev->monitor_vdev;
+
+	if (!vdev->monitor_vdev->osif_rx_mon)
 		goto mon_deliver_non_std_fail;
 
 	/* Generate a dummy skb_buff */
-	osif_rx_mon = pdev->monitor_vdev->osif_rx_mon;
+	osif_rx_mon = vdev->monitor_vdev->osif_rx_mon;
 	dummy_msdu = qdf_nbuf_alloc(soc->osdev, MAX_MONITOR_HEADER,
 				    MAX_MONITOR_HEADER, 4, FALSE);
 	if (!dummy_msdu)

+ 5 - 1
dp/wifi3.0/monitor/dp_rx_mon_status.c

@@ -1092,6 +1092,7 @@ dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
 			      qdf_nbuf_t nbuf)
 {
 	uint8_t size = 0;
+	struct dp_vdev *vdev;
 
 	if (!pdev->monitor_vdev) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
@@ -1099,6 +1100,9 @@ dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
 			  __func__, __LINE__);
 		return 1;
 	}
+
+	vdev = pdev->monitor_vdev;
+
 	if (!ppdu_info->msdu_info.first_msdu_payload) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			  "[%s]:[%d] First msdu payload not present",
@@ -1127,7 +1131,7 @@ dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev,
 		return 1;
 	}
 
-	pdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
+	vdev->monitor_vdev->osif_rx_mon(pdev->monitor_vdev->osif_vdev,
 					nbuf, NULL);
 	pdev->ppdu_info.rx_status.monitor_direct_used = 0;
 	return 0;