Browse Source

qcacmn: Enable interrupt based processing in monitor mode

Enable the interrupt based processing in monitor mode
for WCN7850, by enabling MSI interrupts for rxdma
monitor destination ring.

Change-Id: Ia3c4456d28ed58c8ef49a7aa8e711076fbdf9415
CRs-Fixed: 3094129
Rakesh Pillai 3 năm trước cách đây
mục cha
commit
615c512921
4 tập tin đã thay đổi với 106 bổ sung14 xóa
  1. 8 0
      dp/wifi3.0/dp_internal.h
  2. 81 13
      dp/wifi3.0/dp_main.c
  3. 12 0
      dp/wifi3.0/monitor/dp_mon.h
  4. 5 1
      wlan_cfg/wlan_cfg.c

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

@@ -2859,6 +2859,14 @@ static inline QDF_STATUS dp_runtime_init(struct dp_soc *soc)
 }
 #endif
 
+static inline enum QDF_GLOBAL_MODE dp_soc_get_con_mode(struct dp_soc *soc)
+{
+	if (soc->cdp_soc.ol_ops->get_con_mode)
+		return soc->cdp_soc.ol_ops->get_con_mode();
+
+	return QDF_GLOBAL_MAX_MODE;
+}
+
 /*
  * dp_pdev_bkp_stats_detach() - detach resources for back pressure stats
  *				processing

+ 81 - 13
dp/wifi3.0/dp_main.c

@@ -403,6 +403,8 @@ const int dp_stats_mapping_table[][STATS_TYPE_MAX] = {
 
 /* MCL specific functions */
 #if defined(DP_CON_MON)
+
+#ifdef DP_CON_MON_MSI_ENABLED
 /**
  * dp_soc_get_mon_mask_for_interrupt_mode() - get mon mode mask for intr mode
  * @soc: pointer to dp_soc handle
@@ -418,11 +420,33 @@ const int dp_stats_mapping_table[][STATS_TYPE_MAX] = {
  *
  * Return: 0
  */
-static inline
-uint32_t dp_soc_get_mon_mask_for_interrupt_mode(struct dp_soc *soc, int intr_ctx_num)
+static inline uint32_t
+dp_soc_get_mon_mask_for_interrupt_mode(struct dp_soc *soc, int intr_ctx_num)
+{
+	return wlan_cfg_get_rx_mon_ring_mask(soc->wlan_cfg_ctx, intr_ctx_num);
+}
+#else
+/**
+ * dp_soc_get_mon_mask_for_interrupt_mode() - get mon mode mask for intr mode
+ * @soc: pointer to dp_soc handle
+ * @intr_ctx_num: interrupt context number for which mon mask is needed
+ *
+ * For MCL, monitor mode rings are being processed in timer contexts (polled).
+ * This function is returning 0, since in interrupt mode(softirq based RX),
+ * we donot want to process monitor mode rings in a softirq.
+ *
+ * So, in case packet log is enabled for SAP/STA/P2P modes,
+ * regular interrupt processing will not process monitor mode rings. It would be
+ * done in a separate timer context.
+ *
+ * Return: 0
+ */
+static inline uint32_t
+dp_soc_get_mon_mask_for_interrupt_mode(struct dp_soc *soc, int intr_ctx_num)
 {
 	return 0;
 }
+#endif
 
 /**
  * dp_get_num_rx_contexts() - get number of RX contexts
@@ -2023,7 +2047,7 @@ qdf_export_symbol(dp_srng_free);
  *
  * Return: True if msi cfg should be skipped for srng type else false
  */
-static inline bool dp_skip_msi_cfg(int ring_type)
+static inline bool dp_skip_msi_cfg(struct dp_soc *soc, int ring_type)
 {
 	if (ring_type == RXDMA_MONITOR_STATUS)
 		return true;
@@ -2031,11 +2055,26 @@ static inline bool dp_skip_msi_cfg(int ring_type)
 	return false;
 }
 #else
-static inline bool dp_skip_msi_cfg(int ring_type)
+#ifdef DP_CON_MON_MSI_ENABLED
+static inline bool dp_skip_msi_cfg(struct dp_soc *soc, int ring_type)
 {
+	if (soc->cdp_soc.ol_ops->get_con_mode &&
+	    soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_MONITOR_MODE) {
+		if (ring_type == REO_DST)
+			return true;
+	} else if (ring_type == RXDMA_MONITOR_STATUS) {
+		return true;
+	}
+
 	return false;
 }
-#endif
+#else
+static inline bool dp_skip_msi_cfg(struct dp_soc *soc, int ring_type)
+{
+	return false;
+}
+#endif /* DP_CON_MON_MSI_ENABLED */
+#endif /* DISABLE_MON_RING_MSI_CFG */
 
 /*
  * dp_srng_init() - Initialize SRNG
@@ -2074,7 +2113,7 @@ QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng,
 		(void *)ring_params.ring_base_paddr,
 		ring_params.num_entries);
 
-	if (soc->intr_mode == DP_INTR_MSI && !dp_skip_msi_cfg(ring_type)) {
+	if (soc->intr_mode == DP_INTR_MSI && !dp_skip_msi_cfg(soc, ring_type)) {
 		dp_srng_msi_setup(soc, &ring_params, ring_type, ring_num);
 		dp_verbose_debug("Using MSI for ring_type: %d, ring_num %d",
 				 ring_type, ring_num);
@@ -2278,6 +2317,30 @@ dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
 
 qdf_export_symbol(dp_should_timer_irq_yield);
 
+#ifdef DP_CON_MON_MSI_ENABLED
+static int dp_process_rxdma_dst_ring(struct dp_soc *soc,
+				     struct dp_intr *int_ctx,
+				     int mac_for_pdev,
+				     int total_budget)
+{
+	if (dp_soc_get_con_mode(soc) == QDF_GLOBAL_MONITOR_MODE)
+		return dp_monitor_process(soc, int_ctx, mac_for_pdev,
+					  total_budget);
+	else
+		return dp_rxdma_err_process(int_ctx, soc, mac_for_pdev,
+					    total_budget);
+}
+#else
+static int dp_process_rxdma_dst_ring(struct dp_soc *soc,
+				     struct dp_intr *int_ctx,
+				     int mac_for_pdev,
+				     int total_budget)
+{
+	return dp_rxdma_err_process(int_ctx, soc, mac_for_pdev,
+				    total_budget);
+}
+#endif
+
 /**
  * dp_process_lmac_rings() - Process LMAC rings
  * @int_ctx: interrupt context
@@ -2328,9 +2391,9 @@ static int dp_process_lmac_rings(struct dp_intr *int_ctx, int total_budget)
 
 		if (int_ctx->rxdma2host_ring_mask &
 				(1 << mac_for_pdev)) {
-			work_done = dp_rxdma_err_process(int_ctx, soc,
-							 mac_for_pdev,
-							 remaining_quota);
+			work_done = dp_process_rxdma_dst_ring(soc, int_ctx,
+							      mac_for_pdev,
+							      remaining_quota);
 			if (work_done)
 				intr_stats->num_rxdma2host_ring_masks++;
 			budget -=  work_done;
@@ -2743,7 +2806,8 @@ static void dp_soc_set_interrupt_mode(struct dp_soc *soc)
 	soc->intr_mode = DP_INTR_INTEGRATED;
 
 	if (!(soc->wlan_cfg_ctx->napi_enabled) ||
-	    (soc->cdp_soc.ol_ops->get_con_mode &&
+	    (dp_is_monitor_mode_using_poll(soc) &&
+	     soc->cdp_soc.ol_ops->get_con_mode &&
 	     soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_MONITOR_MODE)) {
 		soc->intr_mode = DP_INTR_POLL;
 	} else {
@@ -2774,7 +2838,8 @@ static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc)
 	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
 
 	if (!(soc->wlan_cfg_ctx->napi_enabled) ||
-	    (soc->cdp_soc.ol_ops->get_con_mode &&
+	    (dp_is_monitor_mode_using_poll(soc) &&
+	     soc->cdp_soc.ol_ops->get_con_mode &&
 	     soc->cdp_soc.ol_ops->get_con_mode() ==
 	     QDF_GLOBAL_MONITOR_MODE)) {
 		dp_info("Poll mode");
@@ -6199,8 +6264,10 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
 		if ((pdev->vdev_count == 0) ||
 		    (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 &&
+	} else if (dp_soc_get_con_mode(soc) == QDF_GLOBAL_MISSION_MODE &&
+		   soc->intr_mode == DP_INTR_MSI &&
 		   wlan_op_mode_monitor == vdev->opmode) {
+		/* Timer to reap status ring in mission mode */
 		dp_monitor_vdev_timer_start(soc);
 	}
 
@@ -14160,7 +14227,8 @@ static void dp_soc_cfg_init(struct dp_soc *soc)
 			for (int_ctx = 0; int_ctx < WLAN_CFG_INT_NUM_CONTEXTS;
 			     int_ctx++) {
 				soc->wlan_cfg_ctx->int_rx_ring_mask[int_ctx] = 0;
-				soc->wlan_cfg_ctx->int_rxdma2host_ring_mask[int_ctx] = 0;
+				if (dp_is_monitor_mode_using_poll(soc))
+					soc->wlan_cfg_ctx->int_rxdma2host_ring_mask[int_ctx] = 0;
 			}
 		}
 

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

@@ -60,6 +60,18 @@ dp_process_ppdu_stats_update_failed_bitmap(struct dp_pdev *pdev,
 }
 #endif
 
+#ifdef DP_CON_MON_MSI_ENABLED
+static inline bool dp_is_monitor_mode_using_poll(struct dp_soc *soc)
+{
+	return false;
+}
+#else
+static inline bool dp_is_monitor_mode_using_poll(struct dp_soc *soc)
+{
+	return true;
+}
+#endif
+
 /*
  * dp_mon_soc_attach() - DP monitor soc attach
  * @soc: Datapath SOC handle

+ 5 - 1
wlan_cfg/wlan_cfg.c

@@ -1516,7 +1516,11 @@ void wlan_cfg_fill_interrupt_mask(struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx,
 							reo_status_ring_mask_msi[i];
 		if (is_monitor_mode) {
 			wlan_cfg_ctx->int_rx_ring_mask[i] = 0;
-			wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = 0;
+			if (interrupt_mode == DP_INTR_POLL)
+				wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = 0;
+			else
+				wlan_cfg_ctx->int_rxdma2host_ring_mask[i] =
+						rxdma2host_ring_mask_msi[i];
 		} else {
 			wlan_cfg_ctx->int_rx_ring_mask[i] =
 							rx_ring_mask_msi[i];