浏览代码

qcacmn: refine the APIs for reap timer of monitor status ring

Since more than one components depend on reap timer of
monitor status ring, add bitmap to record the trigger
sources of the timer and refine the APIs/calling functions
accordingly.

With this change:
When a new start request comes, if the source is
CDP_MON_REAP_SOURCE_ANY, skip bit set, and start timer
if any bit has been set in the bitmap; while for the
other sources, set the bit and start timer if the bitmap
is empty before that.

When a new stop request comes, if the source is
CDP_MON_REAP_SOURCE_ANY, skip bit clear, and stop timer
if any bit has been set in the bitmap; while for the
other sources, clear the bit and stop timer if the bitmap
is empty after that.

Change-Id: Idaa7837c4b93b247ff2236aa5072d309fa9548c2
CRs-Fixed: 3190347
Yu Wang 3 年之前
父节点
当前提交
a9461beb20

+ 7 - 6
dp/inc/cdp_txrx_cmn.h

@@ -2835,24 +2835,25 @@ void cdp_set_rtpm_tput_policy_requirement(ol_txrx_soc_handle soc,
  * @pdev_id: id of objmgr pdev
  * @enable: enable/disable reap timer of monitor status ring
  *
- * Return: none
+ * Return: true if timer start/stop is performed, false otherwise.
  */
-static inline void
-cdp_enable_mon_reap_timer(ol_txrx_soc_handle soc, uint8_t pdev_id,
+static inline bool
+cdp_enable_mon_reap_timer(ol_txrx_soc_handle soc,
+			  enum cdp_mon_reap_source source,
 			  bool enable)
 {
 	if (!soc || !soc->ops) {
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL,
 			  "%s invalid instance", __func__);
 		QDF_BUG(0);
-		return;
+		return false;
 	}
 
 	if (!soc->ops->mon_ops ||
 	    !soc->ops->mon_ops->txrx_enable_mon_reap_timer)
-		return;
+		return false;
 
-	return soc->ops->mon_ops->txrx_enable_mon_reap_timer(soc, pdev_id,
+	return soc->ops->mon_ops->txrx_enable_mon_reap_timer(soc, source,
 							     enable);
 }
 #endif /* _CDP_TXRX_CMN_H_ */

+ 19 - 0
dp/inc/cdp_txrx_mon_struct.h

@@ -545,4 +545,23 @@ struct cdp_rssi_db2dbm_param_dp {
 	struct cdp_rssi_temp_off_param_dp temp_off_param;
 	struct cdp_rssi_dbm_conv_param_dp rssi_dbm_param;
 };
+
+/*
+ * enum cdp_mon_reap_source: trigger source of the reap timer of
+ * monitor status ring
+ * @CDP_MON_REAP_SOURCE_PKTLOG: pktlog
+ * @CDP_MON_REAP_SOURCE_CFR: CFR
+ * @CDP_MON_REAP_SOURCE_EMESH: easy mesh
+ * @CDP_MON_REAP_SOURCE_NUM: total number of the sources
+ * @CDP_MON_REAP_SOURCE_ANY: any of the sources
+ */
+enum cdp_mon_reap_source {
+	CDP_MON_REAP_SOURCE_PKTLOG,
+	CDP_MON_REAP_SOURCE_CFR,
+	CDP_MON_REAP_SOURCE_EMESH,
+
+	/* keep last */
+	CDP_MON_REAP_SOURCE_NUM,
+	CDP_MON_REAP_SOURCE_ANY,
+};
 #endif

+ 3 - 3
dp/inc/cdp_txrx_ops.h

@@ -969,9 +969,9 @@ struct cdp_mon_ops {
 					 struct cdp_pdev_mon_stats *stats);
 
 	/* Configure monitor status srng reap timer */
-	 void (*txrx_enable_mon_reap_timer)(struct cdp_soc_t *soc_hdl,
-					    uint8_t pdev_id,
-					    bool enable);
+	bool (*txrx_enable_mon_reap_timer)(struct cdp_soc_t *soc_hdl,
+					   enum cdp_mon_reap_source source,
+					   bool enable);
 
 #ifdef QCA_SUPPORT_LITE_MONITOR
 	/* set lite monitor config */

+ 5 - 2
dp/wifi3.0/dp_internal.h

@@ -493,12 +493,15 @@ void dp_monitor_reap_timer_deinit(struct dp_soc *soc)
 }
 
 static inline
-void dp_monitor_reap_timer_start(struct dp_soc *soc)
+bool dp_monitor_reap_timer_start(struct dp_soc *soc,
+				 enum cdp_mon_reap_source source)
 {
+	return false;
 }
 
 static inline
-bool dp_monitor_reap_timer_stop(struct dp_soc *soc)
+bool dp_monitor_reap_timer_stop(struct dp_soc *soc,
+				enum cdp_mon_reap_source source)
 {
 	return false;
 }

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

@@ -13548,7 +13548,7 @@ static QDF_STATUS dp_bus_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
 		qdf_timer_stop(&soc->int_timer);
 
 	/* Stop monitor reap timer and reap any pending frames in ring */
-	dp_monitor_pktlog_reap_pending_frames(pdev);
+	dp_monitor_reap_timer_suspend(soc);
 
 	dp_suspend_fse_cache_flush(soc);
 
@@ -13570,7 +13570,7 @@ static QDF_STATUS dp_bus_resume(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
 		qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
 
 	/* Start monitor reap timer */
-	dp_monitor_pktlog_start_reap_timer(pdev);
+	dp_monitor_reap_timer_start(soc, CDP_MON_REAP_SOURCE_ANY);
 
 	dp_resume_fse_cache_flush(soc);
 
@@ -13602,7 +13602,7 @@ static void dp_process_wow_ack_rsp(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
 	 * response from FW reap mon status ring to make sure no packets pending
 	 * in the ring.
 	 */
-	dp_monitor_pktlog_reap_pending_frames(pdev);
+	dp_monitor_reap_timer_suspend(soc);
 }
 
 /**
@@ -13624,7 +13624,7 @@ static void dp_process_target_suspend_req(struct cdp_soc_t *soc_hdl,
 	}
 
 	/* Stop monitor reap timer and reap any pending frames in ring */
-	dp_monitor_pktlog_reap_pending_frames(pdev);
+	dp_monitor_reap_timer_suspend(soc);
 }
 
 static struct cdp_bus_ops dp_ops_bus = {

+ 71 - 16
dp/wifi3.0/monitor/1.0/dp_mon_1.0.c

@@ -564,10 +564,13 @@ 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;
+	qdf_spinlock_create(&mon_soc->reap_timer_lock);
+	qdf_timer_init(soc->osdev, &mon_soc->mon_reap_timer,
+		       dp_mon_reap_timer_handler, (void *)soc,
+		       QDF_TIMER_TYPE_WAKE_APPS);
+	qdf_mem_zero(mon_soc->mon_reap_src_bitmap,
+		     sizeof(mon_soc->mon_reap_src_bitmap));
+	mon_soc->reap_timer_init = 1;
 }
 #else
 static void dp_mon_reap_timer_init(struct dp_soc *soc)
@@ -579,29 +582,81 @@ static void dp_mon_reap_timer_deinit(struct dp_soc *soc)
 {
 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
         if (mon_soc->reap_timer_init) {
-                qdf_timer_free(&mon_soc->mon_reap_timer);
-                mon_soc->reap_timer_init = 0;
+		mon_soc->reap_timer_init = 0;
+		qdf_timer_free(&mon_soc->mon_reap_timer);
+		qdf_spinlock_destroy(&mon_soc->reap_timer_lock);
         }
 }
 
-static void dp_mon_reap_timer_start(struct dp_soc *soc)
+/**
+ * dp_mon_reap_timer_start() - start reap timer of monitor status ring
+ * @soc: point to soc
+ * @source: trigger source
+ *
+ * If the source is CDP_MON_REAP_SOURCE_ANY, skip bit set, and start timer
+ * if any bit has been set in the bitmap; while for the other sources, set
+ * the bit and start timer if the bitmap is empty before that.
+ *
+ * Return: true if timer-start is performed, false otherwise.
+ */
+static bool
+dp_mon_reap_timer_start(struct dp_soc *soc, enum cdp_mon_reap_source source)
 {
 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
-        if (mon_soc->reap_timer_init) {
-                qdf_timer_mod(&mon_soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
-        }
+	bool do_start;
+
+	if (!mon_soc->reap_timer_init)
+		return false;
+
+	qdf_spin_lock_bh(&mon_soc->reap_timer_lock);
+	do_start = qdf_bitmap_empty(mon_soc->mon_reap_src_bitmap,
+				    CDP_MON_REAP_SOURCE_NUM);
+	if (source == CDP_MON_REAP_SOURCE_ANY)
+		do_start = !do_start;
+	else
+		qdf_set_bit(source, mon_soc->mon_reap_src_bitmap);
+	qdf_spin_unlock_bh(&mon_soc->reap_timer_lock);
+
+	if (do_start)
+		qdf_timer_mod(&mon_soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
 
+	return do_start;
 }
 
-static bool dp_mon_reap_timer_stop(struct dp_soc *soc)
+/**
+ * dp_mon_reap_timer_stop() - stop reap timer of monitor status ring
+ * @soc: point to soc
+ * @source: trigger source
+ *
+ * If the source is CDP_MON_REAP_SOURCE_ANY, skip bit clear, and stop timer
+ * if any bit has been set in the bitmap; while for the other sources, clear
+ * the bit and stop the timer if the bitmap is empty after that.
+ *
+ * Return: true if timer-stop is performed, false otherwise.
+ */
+static bool
+dp_mon_reap_timer_stop(struct dp_soc *soc, enum cdp_mon_reap_source source)
 {
 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
-        if (mon_soc->reap_timer_init) {
-                qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
-                return true;
-        }
+	bool do_stop;
+
+	if (!mon_soc->reap_timer_init)
+		return false;
+
+	qdf_spin_lock_bh(&mon_soc->reap_timer_lock);
+	if (source != CDP_MON_REAP_SOURCE_ANY)
+		qdf_clear_bit(source, mon_soc->mon_reap_src_bitmap);
+
+	do_stop = qdf_bitmap_empty(mon_soc->mon_reap_src_bitmap,
+				   CDP_MON_REAP_SOURCE_NUM);
+	if (source == CDP_MON_REAP_SOURCE_ANY)
+		do_stop = !do_stop;
+	qdf_spin_unlock_bh(&mon_soc->reap_timer_lock);
+
+	if (do_stop)
+		qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
 
-        return false;
+	return do_stop;
 }
 
 static void dp_mon_vdev_timer_init(struct dp_soc *soc)

+ 1 - 1
dp/wifi3.0/monitor/2.0/dp_mon_2.0.c

@@ -1577,7 +1577,7 @@ struct cdp_mon_ops dp_ops_mon_2_0 = {
 	.config_full_mon_mode = NULL,
 	.soc_config_full_mon_mode = NULL,
 	.get_mon_pdev_rx_stats = dp_pdev_get_rx_mon_stats,
-	.txrx_enable_mon_reap_timer = dp_enable_mon_reap_timer,
+	.txrx_enable_mon_reap_timer = NULL,
 #ifdef QCA_SUPPORT_LITE_MONITOR
 	.txrx_set_lite_mon_config = dp_lite_mon_set_config,
 	.txrx_get_lite_mon_config = dp_lite_mon_get_config,

+ 85 - 117
dp/wifi3.0/monitor/dp_mon.c

@@ -925,7 +925,7 @@ dp_set_bpr_enable(struct dp_pdev *pdev, int val)
 static bool
 dp_set_hybrid_pktlog_enable(struct dp_pdev *pdev,
 			    struct dp_mon_pdev *mon_pdev,
-			    struct dp_mon_soc *mon_soc)
+			    struct dp_soc *soc)
 {
 	if (mon_pdev->mvdev) {
 		/* Nothing needs to be done if monitor mode is
@@ -947,10 +947,7 @@ dp_set_hybrid_pktlog_enable(struct dp_pdev *pdev,
 			return false;
 		}
 
-		if (mon_soc->reap_timer_init &&
-		    !dp_mon_is_enable_reap_timer_non_pkt(pdev))
-			qdf_timer_mod(&mon_soc->mon_reap_timer,
-				      DP_INTR_POLL_TIMER_MS);
+		dp_monitor_reap_timer_start(soc, CDP_MON_REAP_SOURCE_PKTLOG);
 	}
 
 	return true;
@@ -970,7 +967,7 @@ dp_set_hybrid_pktlog_disable(struct dp_mon_pdev *mon_pdev)
 static bool
 dp_set_hybrid_pktlog_enable(struct dp_pdev *pdev,
 			    struct dp_mon_pdev *mon_pdev,
-			    struct dp_mon_soc *mon_soc)
+			    struct dp_soc *soc)
 {
 	dp_cdp_err("Hybrid mode is supported only on beryllium");
 	return true;
@@ -1011,23 +1008,22 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 				return 0;
 			}
 
-			if (mon_pdev->rx_pktlog_mode != DP_RX_PKTLOG_FULL) {
-				mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_FULL;
-				dp_mon_filter_setup_rx_pkt_log_full(pdev);
-				if (dp_mon_filter_update(pdev) !=
-						QDF_STATUS_SUCCESS) {
-					dp_cdp_err("%pK: Pktlog full filters set failed", soc);
-					dp_mon_filter_reset_rx_pkt_log_full(pdev);
-					mon_pdev->rx_pktlog_mode =
-							DP_RX_PKTLOG_DISABLED;
-					return 0;
-				}
+			if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_FULL)
+				break;
 
-				if (mon_soc->reap_timer_init &&
-				    (!dp_mon_is_enable_reap_timer_non_pkt(pdev)))
-					qdf_timer_mod(&mon_soc->mon_reap_timer,
-						      DP_INTR_POLL_TIMER_MS);
+			mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_FULL;
+			dp_mon_filter_setup_rx_pkt_log_full(pdev);
+			if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
+				dp_cdp_err("%pK: Pktlog full filters set failed",
+					   soc);
+				dp_mon_filter_reset_rx_pkt_log_full(pdev);
+				mon_pdev->rx_pktlog_mode =
+					DP_RX_PKTLOG_DISABLED;
+				return 0;
 			}
+
+			dp_monitor_reap_timer_start(soc,
+						    CDP_MON_REAP_SOURCE_PKTLOG);
 			break;
 
 		case WDI_EVENT_LITE_RX:
@@ -1038,29 +1034,28 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 				mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_LITE;
 				return 0;
 			}
-			if (mon_pdev->rx_pktlog_mode != DP_RX_PKTLOG_LITE) {
-				mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_LITE;
 
-				/*
-				 * 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) {
-					dp_cdp_err("%pK: Pktlog lite filters set failed", soc);
-					dp_mon_filter_reset_rx_pkt_log_lite(pdev);
-					mon_pdev->rx_pktlog_mode =
-						DP_RX_PKTLOG_DISABLED;
-					return 0;
-				}
+			if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_LITE)
+				break;
 
-				if (mon_soc->reap_timer_init &&
-				    (!dp_mon_is_enable_reap_timer_non_pkt(pdev)))
-					qdf_timer_mod(&mon_soc->mon_reap_timer,
-						      DP_INTR_POLL_TIMER_MS);
+			mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_LITE;
+
+			/*
+			 * 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) {
+				dp_cdp_err("%pK: Pktlog lite filters set failed",
+					   soc);
+				dp_mon_filter_reset_rx_pkt_log_lite(pdev);
+				mon_pdev->rx_pktlog_mode =
+					DP_RX_PKTLOG_DISABLED;
+				return 0;
 			}
-			break;
 
+			dp_monitor_reap_timer_start(soc,
+						    CDP_MON_REAP_SOURCE_PKTLOG);
+			break;
 		case WDI_EVENT_LITE_T2H:
 			for (mac_id = 0; mac_id < max_mac_rings; mac_id++) {
 				int mac_for_pdev = dp_get_mac_id_for_pdev(
@@ -1082,37 +1077,36 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 				mon_pdev->rx_pktlog_cbf = true;
 				return 0;
 			}
-			if (!mon_pdev->rx_pktlog_cbf) {
-				mon_pdev->rx_pktlog_cbf = true;
-				mon_pdev->monitor_configured = true;
-				if (mon_ops->mon_vdev_set_monitor_mode_buf_rings)
-					mon_ops->mon_vdev_set_monitor_mode_buf_rings(pdev);
-				/*
-				 * Set the packet log lite mode filter.
-				 */
-				qdf_info("Non mon mode: Enable destination ring");
-
-				dp_mon_filter_setup_rx_pkt_log_cbf(pdev);
-				if (dp_mon_filter_update(pdev) !=
-				    QDF_STATUS_SUCCESS) {
-					dp_mon_err("Pktlog set CBF filters failed");
-					dp_mon_filter_reset_rx_pktlog_cbf(pdev);
-					mon_pdev->rx_pktlog_mode =
-						DP_RX_PKTLOG_DISABLED;
-					mon_pdev->monitor_configured = false;
-					return 0;
-				}
 
-				if (mon_soc->reap_timer_init &&
-				    !dp_mon_is_enable_reap_timer_non_pkt(pdev))
-					qdf_timer_mod(&mon_soc->mon_reap_timer,
-						      DP_INTR_POLL_TIMER_MS);
+			if (mon_pdev->rx_pktlog_cbf)
+				break;
+
+			mon_pdev->rx_pktlog_cbf = true;
+			mon_pdev->monitor_configured = true;
+			if (mon_ops->mon_vdev_set_monitor_mode_buf_rings)
+				mon_ops->mon_vdev_set_monitor_mode_buf_rings(
+					pdev);
+
+			/*
+			 * Set the packet log lite mode filter.
+			 */
+			qdf_info("Non mon mode: Enable destination ring");
+
+			dp_mon_filter_setup_rx_pkt_log_cbf(pdev);
+			if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
+				dp_mon_err("Pktlog set CBF filters failed");
+				dp_mon_filter_reset_rx_pktlog_cbf(pdev);
+				mon_pdev->rx_pktlog_mode =
+					DP_RX_PKTLOG_DISABLED;
+				mon_pdev->monitor_configured = false;
+				return 0;
 			}
-			break;
 
+			dp_monitor_reap_timer_start(soc,
+						    CDP_MON_REAP_SOURCE_PKTLOG);
+			break;
 		case WDI_EVENT_HYBRID_TX:
-			if (!dp_set_hybrid_pktlog_enable(pdev,
-							 mon_pdev, mon_soc))
+			if (!dp_set_hybrid_pktlog_enable(pdev, mon_pdev, soc))
 				return 0;
 			break;
 
@@ -1132,27 +1126,27 @@ int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
 						DP_RX_PKTLOG_DISABLED;
 				return 0;
 			}
-			if (mon_pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) {
-				mon_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) {
-					dp_cdp_err("%pK: Pktlog filters reset failed", soc);
-					return 0;
-				}
 
-				dp_mon_filter_reset_rx_pkt_log_lite(pdev);
-				if (dp_mon_filter_update(pdev) !=
-						QDF_STATUS_SUCCESS) {
-					dp_cdp_err("%pK: Pktlog filters reset failed", soc);
-					return 0;
-				}
+			if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_DISABLED)
+				break;
 
-				if (mon_soc->reap_timer_init &&
-				    (!dp_mon_is_enable_reap_timer_non_pkt(pdev)))
-					qdf_timer_stop(&mon_soc->mon_reap_timer);
+			mon_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) {
+				dp_cdp_err("%pK: Pktlog filters reset failed",
+					   soc);
+				return 0;
 			}
+
+			dp_mon_filter_reset_rx_pkt_log_lite(pdev);
+			if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
+				dp_cdp_err("%pK: Pktlog filters reset failed",
+					   soc);
+				return 0;
+			}
+
+			dp_monitor_reap_timer_stop(soc,
+						   CDP_MON_REAP_SOURCE_PKTLOG);
 			break;
 		case WDI_EVENT_LITE_T2H:
 			/*
@@ -1215,12 +1209,7 @@ void dp_pktlogmod_exit(struct dp_pdev *pdev)
 		return;
 	}
 
-	/* stop mon_reap_timer if it has been started */
-	if (mon_pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED &&
-	    mon_soc->reap_timer_init &&
-	    (!dp_mon_is_enable_reap_timer_non_pkt(pdev)))
-		qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
-
+	dp_monitor_reap_timer_stop(soc, CDP_MON_REAP_SOURCE_PKTLOG);
 	pktlogmod_exit(scn);
 	mon_pdev->pkt_log_init = false;
 }
@@ -1628,38 +1617,17 @@ static void dp_cfr_filter(struct cdp_soc_t *soc_hdl,
 }
 #endif
 
-void
-dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
+bool
+dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl,
+			 enum cdp_mon_reap_source source,
 			 bool enable)
 {
 	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;
-	struct dp_mon_pdev *mon_pdev;
-
-	pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
-	if (!pdev) {
-		dp_mon_err("pdev is NULL");
-		return;
-	}
-
-	mon_pdev = pdev->monitor_pdev;
-	mon_pdev->enable_reap_timer_non_pkt = enable;
-	if (mon_pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) {
-		dp_mon_debug("pktlog enabled %d", mon_pdev->rx_pktlog_mode);
-		return;
-	}
-
-	if (!mon_soc->reap_timer_init) {
-		dp_mon_err("reap timer not init");
-		return;
-	}
 
 	if (enable)
-		qdf_timer_mod(&mon_soc->mon_reap_timer,
-			      DP_INTR_POLL_TIMER_MS);
+		return dp_monitor_reap_timer_start(soc, source);
 	else
-		qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
+		return dp_monitor_reap_timer_stop(soc, source);
 }
 
 #if defined(DP_CON_MON)

+ 43 - 62
dp/wifi3.0/monitor/dp_mon.h

@@ -665,8 +665,10 @@ struct dp_mon_ops {
 	bool (*mon_vdev_timer_stop)(struct dp_soc *soc);
 	void (*mon_vdev_timer_deinit)(struct dp_soc *soc);
 	void (*mon_reap_timer_init)(struct dp_soc *soc);
-	void (*mon_reap_timer_start)(struct dp_soc *soc);
-	bool (*mon_reap_timer_stop)(struct dp_soc *soc);
+	bool (*mon_reap_timer_start)(struct dp_soc *soc,
+				     enum cdp_mon_reap_source source);
+	bool (*mon_reap_timer_stop)(struct dp_soc *soc,
+				    enum cdp_mon_reap_source source);
 	void (*mon_reap_timer_deinit)(struct dp_soc *soc);
 #ifdef QCA_MCOPY_SUPPORT
 	QDF_STATUS (*mon_mcopy_check_deliver)(struct dp_pdev *pdev,
@@ -806,6 +808,11 @@ struct dp_mon_soc {
 	qdf_timer_t mon_reap_timer;
 	uint8_t reap_timer_init;
 
+	qdf_spinlock_t reap_timer_lock;
+
+	/* Bitmap to record trigger sources of the reap timer */
+	qdf_bitmap(mon_reap_src_bitmap, CDP_MON_REAP_SOURCE_NUM);
+
 	qdf_timer_t mon_vdev_timer;
 	uint8_t mon_vdev_timer_state;
 
@@ -987,7 +994,6 @@ struct  dp_mon_pdev {
 	bool tx_sniffer_enable;
 	/* mirror copy mode */
 	enum m_copy_mode mcopy_mode;
-	bool enable_reap_timer_non_pkt;
 	bool bpr_enable;
 	/* Pdev level flag to check peer based pktlog enabled or
 	 * disabled
@@ -1291,21 +1297,6 @@ static inline bool dp_soc_is_full_mon_enable(struct dp_pdev *pdev)
 		pdev->monitor_pdev->monitor_configured) ? true : false;
 }
 
-/*
- * dp_mon_is_enable_reap_timer_non_pkt() - check if mon reap timer is
- * enabled by non-pkt log or not
- * @pdev: point to dp pdev
- *
- * Return: true if mon reap timer is enabled by non-pkt log
- */
-static inline bool dp_mon_is_enable_reap_timer_non_pkt(struct dp_pdev *pdev)
-{
-	if (qdf_unlikely(!pdev || !pdev->monitor_pdev))
-		return false;
-
-	return pdev->monitor_pdev->enable_reap_timer_non_pkt;
-}
-
 /*
  * dp_monitor_is_enable_mcopy_mode() - check if mcopy mode is enabled
  * @pdev: point to dp pdev
@@ -3328,28 +3319,44 @@ void dp_monitor_reap_timer_deinit(struct dp_soc *soc)
 	monitor_ops->mon_reap_timer_deinit(soc);
 }
 
-static inline
-void dp_monitor_reap_timer_start(struct dp_soc *soc)
+/**
+ * dp_monitor_reap_timer_start() - start reap timer of monitor status ring
+ * @soc: point to soc
+ * @source: trigger source
+ *
+ * Return: true if timer-start is performed, false otherwise.
+ */
+static inline bool
+dp_monitor_reap_timer_start(struct dp_soc *soc,
+			    enum cdp_mon_reap_source source)
 {
 	struct dp_mon_ops *monitor_ops;
 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
 
 	if (!mon_soc) {
 		dp_mon_debug("monitor soc is NULL");
-		return;
+		return false;
 	}
 
 	monitor_ops = mon_soc->mon_ops;
 	if (!monitor_ops || !monitor_ops->mon_reap_timer_start) {
 		dp_mon_debug("callback not registered");
-		return;
+		return false;
 	}
 
-	monitor_ops->mon_reap_timer_start(soc);
+	return monitor_ops->mon_reap_timer_start(soc, source);
 }
 
-static inline
-bool dp_monitor_reap_timer_stop(struct dp_soc *soc)
+/**
+ * dp_monitor_reap_timer_stop() - stop reap timer of monitor status ring
+ * @soc: point to soc
+ * @source: trigger source
+ *
+ * Return: true if timer-stop is performed, false otherwise.
+ */
+static inline bool
+dp_monitor_reap_timer_stop(struct dp_soc *soc,
+			   enum cdp_mon_reap_source source)
 {
 	struct dp_mon_ops *monitor_ops;
 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
@@ -3365,7 +3372,7 @@ bool dp_monitor_reap_timer_stop(struct dp_soc *soc)
 		return false;
 	}
 
-	return monitor_ops->mon_reap_timer_stop(soc);
+	return monitor_ops->mon_reap_timer_stop(soc, source);
 }
 
 static inline
@@ -3539,45 +3546,19 @@ static inline void dp_monitor_vdev_delete(struct dp_soc *soc,
 
 #ifdef DP_POWER_SAVE
 /*
- * dp_monitor_pktlog_reap_pending_frames() - reap pending frames
+ * dp_monitor_reap_timer_suspend() - Stop monitor reap timer
+ * and reap any pending frames in ring
  * @pdev: point to dp pdev
  *
  * Return: void
  */
-static inline void dp_monitor_pktlog_reap_pending_frames(struct dp_pdev *pdev)
+static inline void
+dp_monitor_reap_timer_suspend(struct dp_soc *soc)
 {
-	struct dp_soc *soc;
-
-	if (qdf_unlikely(!pdev || !pdev->monitor_pdev))
-		return;
-
-	soc = pdev->soc;
-
-	if (((pdev->monitor_pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) ||
-	     dp_mon_is_enable_reap_timer_non_pkt(pdev))) {
-		if (dp_monitor_reap_timer_stop(soc))
-			dp_monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
-	}
+	if (dp_monitor_reap_timer_stop(soc, CDP_MON_REAP_SOURCE_ANY))
+		dp_monitor_service_mon_rings(soc, DP_MON_REAP_BUDGET);
 }
 
-/*
- * dp_monitor_pktlog_start_reap_timer() - start reap timer
- * @pdev: point to dp pdev
- *
- * Return: void
- */
-static inline void dp_monitor_pktlog_start_reap_timer(struct dp_pdev *pdev)
-{
-	struct dp_soc *soc;
-
-	if (qdf_unlikely(!pdev || !pdev->monitor_pdev))
-		return;
-
-	soc = pdev->soc;
-	if (((pdev->monitor_pdev->rx_pktlog_mode != DP_RX_PKTLOG_DISABLED) ||
-	     dp_mon_is_enable_reap_timer_non_pkt(pdev)))
-		dp_monitor_reap_timer_start(soc);
-}
 #endif
 
 /*
@@ -3993,13 +3974,13 @@ QDF_STATUS dp_pdev_get_rx_mon_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 /*
  * dp_enable_mon_reap_timer() - enable/disable reap timer
  * @soc_hdl: Datapath soc handle
- * @pdev_id: id of objmgr pdev
+ * @source: trigger source of the timer
  * @enable: Enable/Disable reap timer of monitor status ring
  *
- * Return: none
+ * Return: true if a timer-start/stop is performed, false otherwise.
  */
-void dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
-			      bool enable);
+bool dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl,
+			      enum cdp_mon_reap_source source, bool enable);
 
 /*
  * dp_monitor_lite_mon_disable_rx() - disables rx lite mon

+ 2 - 1
target_if/cfr/src/target_if_cfr_6490.c

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -101,7 +102,7 @@ target_if_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev,
 	g_cfr_subscribe.callback = target_cfr_callback;
 	g_cfr_subscribe.context = pdev;
 	cdp_set_cfr_rcc(soc, 0, is_subscribe);
-	cdp_enable_mon_reap_timer(soc, 0, is_subscribe);
+	cdp_enable_mon_reap_timer(soc, CDP_MON_REAP_SOURCE_CFR, is_subscribe);
 	if (is_subscribe) {
 		if (cdp_wdi_event_sub(soc, 0, &g_cfr_subscribe,
 				      WDI_EVENT_RX_PPDU_DESC)) {