Selaa lähdekoodia

qcacmn: Monitor mode improvements

Move the srng history to hif context.

Process the monitor ring only for the lmac
corresponding to the configured monitor channel.

Add the timer and srng history for monitor mode.

Change-Id: I4e5e49ad5e657b55bfafbb40ef5f59496277cb40
CRs-Fixed: 2690530
Rakesh Pillai 5 vuotta sitten
vanhempi
sitoutus
94c0917f49

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

@@ -359,6 +359,16 @@ static inline void dp_set_peer_isolation(struct dp_peer *peer, bool val)
 }
 #endif /* QCA_SUPPORT_PEER_ISOLATION */
 
+/**
+ * The lmac ID for a particular channel band is fixed.
+ * 2.4GHz band uses lmac_id = 1
+ * 5GHz/6GHz band uses lmac_id=0
+ */
+#define DP_MON_INVALID_LMAC_ID	(-1)
+#define DP_MON_2G_LMAC_ID	1
+#define DP_MON_5G_LMAC_ID	0
+#define DP_MON_6G_LMAC_ID	0
+
 #ifdef FEATURE_TSO_STATS
 /**
  * dp_init_tso_stats() - Clear tso stats
@@ -1737,7 +1747,7 @@ static inline void dp_peer_unref_del_find_by_id(struct dp_peer *peer)
 #ifdef WLAN_FEATURE_DP_EVENT_HISTORY
 /**
  * dp_srng_access_start() - Wrapper function to log access start of a hal ring
- * @int_ctx: pointer to DP interrupt context
+ * @int_ctx: pointer to DP interrupt context. This should not be NULL
  * @soc: DP Soc handle
  * @hal_ring: opaque pointer to the HAL Rx Error Ring, which will be serviced
  *
@@ -1748,7 +1758,7 @@ int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc,
 
 /**
  * dp_srng_access_end() - Wrapper function to log access end of a hal ring
- * @int_ctx: pointer to DP interrupt context
+ * @int_ctx: pointer to DP interrupt context. This should not be NULL
  * @soc: DP Soc handle
  * @hal_ring: opaque pointer to the HAL Rx Error Ring, which will be serviced
  *

+ 125 - 19
dp/wifi3.0/dp_main.c

@@ -427,7 +427,7 @@ static void dp_service_mon_rings(struct  dp_soc *soc, uint32_t quota)
 		pdev = dp_get_pdev_for_lmac_id(soc, ring);
 		if (!pdev)
 			continue;
-		work_done = dp_mon_process(soc, ring, quota);
+		work_done = dp_mon_process(soc, NULL, ring, quota);
 
 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
 			  FL("Reaped %d descs from Monitor rings"),
@@ -593,7 +593,7 @@ static void dp_service_lmac_rings(void *arg)
 
 		rx_refill_buf_ring = &soc->rx_refill_buf_ring[mac_for_pdev];
 
-		dp_mon_process(soc, mac_for_pdev,
+		dp_mon_process(soc, NULL, mac_for_pdev,
 			       QCA_NAPI_BUDGET);
 
 		for (i = 0;
@@ -1572,6 +1572,9 @@ int dp_srng_access_start(struct dp_intr *int_ctx, struct dp_soc *dp_soc,
 	uint32_t hp, tp;
 	uint8_t ring_id;
 
+	if (!int_ctx)
+		return hal_srng_access_start(hal_soc, hal_ring_hdl);
+
 	hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp);
 	ring_id = hal_srng_ring_id_get(hal_ring_hdl);
 
@@ -1588,6 +1591,9 @@ void dp_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *dp_soc,
 	uint32_t hp, tp;
 	uint8_t ring_id;
 
+	if (!int_ctx)
+		return hal_srng_access_end(hal_soc, hal_ring_hdl);
+
 	hal_get_sw_hptp(hal_soc, hal_ring_hdl, &tp, &hp);
 	ring_id = hal_srng_ring_id_get(hal_ring_hdl);
 
@@ -1596,6 +1602,32 @@ void dp_srng_access_end(struct dp_intr *int_ctx, struct dp_soc *dp_soc,
 
 	return hal_srng_access_end(hal_soc, hal_ring_hdl);
 }
+
+static inline void dp_srng_record_timer_entry(struct dp_soc *dp_soc,
+					      uint8_t hist_group_id)
+{
+	hif_record_event(dp_soc->hif_handle, hist_group_id,
+			 0, 0, 0, HIF_EVENT_TIMER_ENTRY);
+}
+
+static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc,
+					     uint8_t hist_group_id)
+{
+	hif_record_event(dp_soc->hif_handle, hist_group_id,
+			 0, 0, 0, HIF_EVENT_TIMER_EXIT);
+}
+#else
+
+static inline void dp_srng_record_timer_entry(struct dp_soc *dp_soc,
+					      uint8_t hist_group_id)
+{
+}
+
+static inline void dp_srng_record_timer_exit(struct dp_soc *dp_soc,
+					     uint8_t hist_group_id)
+{
+}
+
 #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */
 
 /*
@@ -1646,7 +1678,7 @@ static int dp_process_lmac_rings(struct dp_intr *int_ctx, int total_budget)
 		if (!pdev)
 			continue;
 		if (int_ctx->rx_mon_ring_mask & (1 << mac_for_pdev)) {
-			work_done = dp_mon_process(soc, mac_for_pdev,
+			work_done = dp_mon_process(soc, int_ctx, mac_for_pdev,
 						   remaining_quota);
 			if (work_done)
 				intr_stats->num_rx_mon_ring_masks++;
@@ -1830,6 +1862,31 @@ budget_done:
 	return dp_budget - budget;
 }
 
+/**
+ * dp_mon_get_lmac_id_from_ch_band() - get the lmac id corresponding
+ *		to a particular channel band.
+ * @soc: Datapath soc handle
+ * @band: channel band configured
+ *
+ * Returns: lmac id corresponding to the channel band
+ *
+ * Currently the 5GHz/6GHz packets will be captured on lmac id 0
+ * and the 2.4GHz packets are captured on lmac id 1.
+ * This function returns the mapping on the basis of above information.
+ */
+static inline int dp_mon_get_lmac_id_from_ch_band(struct dp_soc *soc,
+						  enum reg_wifi_band band)
+{
+	if (band == REG_BAND_2G)
+		return DP_MON_2G_LMAC_ID;
+	else if (band == REG_BAND_5G)
+		return DP_MON_5G_LMAC_ID;
+	else if (band == REG_BAND_6G)
+		return DP_MON_6G_LMAC_ID;
+
+	return DP_MON_INVALID_LMAC_ID;
+}
+
 /* dp_interrupt_timer()- timer poll for interrupts
  *
  * @arg: SoC Handle
@@ -1840,35 +1897,44 @@ budget_done:
 static void dp_interrupt_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;
-	int i;
+	uint32_t lmac_id;
+	uint8_t dp_intr_id;
 
 	if (!qdf_atomic_read(&soc->cmn_init_done))
 		return;
 
+	if (pdev->mon_chan_band == REG_BAND_UNKNOWN) {
+		qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
+		return;
+	}
+
+	lmac_id = dp_mon_get_lmac_id_from_ch_band(soc, pdev->mon_chan_band);
+	if (qdf_unlikely(lmac_id == DP_MON_INVALID_LMAC_ID)) {
+		qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
+		return;
+	}
+
+	dp_intr_id = soc->mon_intr_id_lmac_map[lmac_id];
+	dp_srng_record_timer_entry(soc, dp_intr_id);
 	start_time = qdf_get_log_timestamp();
 
 	while (yield == DP_TIMER_NO_YIELD) {
-		for (i = 0;
-		     i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) {
-			if (!soc->intr_ctx[i].rx_mon_ring_mask)
-				continue;
-
-			work_done = dp_process_lmac_rings(&soc->intr_ctx[i],
-							  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;
+		work_done = dp_mon_process(soc, &soc->intr_ctx[dp_intr_id],
+					   lmac_id, 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,
@@ -1882,7 +1948,26 @@ budget_done:
 		qdf_timer_mod(&soc->int_timer, 1);
 	else
 		qdf_timer_mod(&soc->int_timer, DP_INTR_POLL_TIMER_MS);
+
+	dp_srng_record_timer_exit(soc, dp_intr_id);
+}
+
+#ifdef WLAN_FEATURE_DP_EVENT_HISTORY
+static inline bool dp_is_mon_mask_valid(struct dp_soc *soc,
+					struct dp_intr *intr_ctx)
+{
+	if (intr_ctx->rx_mon_ring_mask)
+		return true;
+
+	return false;
+}
+#else
+static inline bool dp_is_mon_mask_valid(struct dp_soc *soc,
+					struct dp_intr *intr_ctx)
+{
+	return false;
 }
+#endif
 
 /*
  * dp_soc_attach_poll() - Register handlers for DP interrupts
@@ -1898,7 +1983,10 @@ static QDF_STATUS dp_soc_attach_poll(struct cdp_soc_t *txrx_soc)
 {
 	struct dp_soc *soc = (struct dp_soc *)txrx_soc;
 	int i;
+	int lmac_id = 0;
 
+	qdf_mem_set(&soc->mon_intr_id_lmac_map,
+		    sizeof(soc->mon_intr_id_lmac_map), DP_MON_INVALID_LMAC_ID);
 	soc->intr_mode = DP_INTR_POLL;
 
 	for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) {
@@ -1919,6 +2007,12 @@ static QDF_STATUS dp_soc_attach_poll(struct cdp_soc_t *txrx_soc)
 			wlan_cfg_get_rxdma2host_ring_mask(soc->wlan_cfg_ctx, i);
 		soc->intr_ctx[i].soc = soc;
 		soc->intr_ctx[i].lro_ctx = qdf_lro_init();
+
+		if (dp_is_mon_mask_valid(soc, &soc->intr_ctx[i])) {
+			hif_event_history_init(soc->hif_handle, i);
+			soc->mon_intr_id_lmac_map[lmac_id] = i;
+			lmac_id++;
+		}
 	}
 
 	qdf_timer_init(soc->osdev, &soc->int_timer,
@@ -2153,6 +2247,9 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc)
 	int i = 0;
 	int num_irq = 0;
 
+	qdf_mem_set(&soc->mon_intr_id_lmac_map,
+		    sizeof(soc->mon_intr_id_lmac_map), DP_MON_INVALID_LMAC_ID);
+
 	for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) {
 		int ret = 0;
 
@@ -2209,6 +2306,8 @@ static QDF_STATUS dp_soc_interrupt_attach(struct cdp_soc_t *txrx_soc)
 
 			return QDF_STATUS_E_FAILURE;
 		}
+
+		hif_event_history_init(soc->hif_handle, i);
 		soc->intr_ctx[i].lro_ctx = qdf_lro_init();
 	}
 
@@ -2246,8 +2345,12 @@ static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc)
 		soc->intr_ctx[i].host2rxdma_ring_mask = 0;
 		soc->intr_ctx[i].host2rxdma_mon_ring_mask = 0;
 
+		hif_event_history_deinit(soc->hif_handle, i);
 		qdf_lro_deinit(soc->intr_ctx[i].lro_ctx);
 	}
+
+	qdf_mem_set(&soc->mon_intr_id_lmac_map,
+		    REG_BAND_UNKNOWN * sizeof(int), DP_MON_INVALID_LMAC_ID);
 }
 
 #define AVG_MAX_MPDUS_PER_TID 128
@@ -7886,6 +7989,8 @@ static QDF_STATUS dp_set_pdev_param(struct cdp_soc_t *cdp_soc, uint8_t pdev_id,
 		break;
 	case CDP_MONITOR_FREQUENCY:
 		pdev->mon_chan_freq = val.cdp_pdev_param_mon_freq;
+		pdev->mon_chan_band =
+				wlan_reg_freq_to_band(pdev->mon_chan_freq);
 		break;
 	case CDP_CONFIG_BSS_COLOR:
 		dp_mon_set_bsscolor(pdev, val.cdp_pdev_param_bss_color);
@@ -12397,6 +12502,7 @@ static inline QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc,
 	TAILQ_INIT(&pdev->neighbour_peers_list);
 	pdev->neighbour_peers_added = false;
 	pdev->monitor_configured = false;
+	pdev->mon_chan_band = REG_BAND_UNKNOWN;
 
 	DP_STATS_INIT(pdev);
 

+ 36 - 17
dp/wifi3.0/dp_rx_mon.h

@@ -28,31 +28,34 @@
 
 /*
  * dp_rx_mon_status_process() - Process monitor status ring and
- *>.....TLV in status ring.
+ *			TLV in status ring.
  *
  * @soc: core txrx main context
+ * @int_ctx: interrupt context
  * @mac_id: mac_id which is one of 3 mac_ids
  * @quota: No. of ring entry that can be serviced in one shot.
 
  * Return: uint32_t: No. of ring entry that is processed.
  */
 uint32_t
-dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota);
+dp_rx_mon_status_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+			 uint32_t mac_id, uint32_t quota);
 
 /**
-* dp_rx_mon_dest_process() - Brain of the Rx processing functionality
-*	Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
-* @soc: core txrx main context	164
-* @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced
-* @quota: No. of units (packets) that can be serviced in one shot.
-*
-* This function implements the core of Rx functionality. This is
-* expected to handle only non-error frames.
-*
-* Return: uint32_t: No. of elements processed
-*/
-void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id,
-	uint32_t quota);
+ * dp_rx_mon_dest_process() - Brain of the Rx processing functionality
+ *	Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
+ * @soc: core txrx main contex
+ * @int_ctx: interrupt context
+ * @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced
+ * @quota: No. of units (packets) that can be serviced in one shot.
+ *
+ * This function implements the core of Rx functionality. This is
+ * expected to handle only non-error frames.
+ *
+ * Return: none
+ */
+void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+			    uint32_t mac_id, uint32_t quota);
 
 QDF_STATUS dp_rx_pdev_mon_desc_pool_alloc(struct dp_pdev *pdev);
 QDF_STATUS dp_rx_pdev_mon_buffers_alloc(struct dp_pdev *pdev);
@@ -106,11 +109,13 @@ void dp_full_mon_detach(struct dp_pdev *pdev);
  * full monitor mode
  *
  * @soc: dp soc handle
+ * @int_ctx: interrupt context
  * @mac_id: lmac id
  * @quota: No. of ring entry that can be serviced in one shot.
  */
 
-uint32_t dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota);
+uint32_t dp_rx_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+			   uint32_t mac_id, uint32_t quota);
 
 #else
 /**
@@ -158,7 +163,21 @@ QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
 QDF_STATUS dp_mon_link_free(struct dp_pdev *pdev);
 
 
-uint32_t dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota);
+/**
+ * dp_mon_process() - Main monitor mode processing roution.
+ * @soc: core txrx main context
+ * @int_ctx: interrupt context
+ * @mac_id: mac_id which is one of 3 mac_ids
+ * @quota: No. of status ring entry that can be serviced in one shot.
+ *
+ * This call monitor status ring process then monitor
+ * destination ring process.
+ * Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
+ *
+ * Return: uint32_t: No. of ring entry that is processed.
+ */
+uint32_t dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+			uint32_t mac_id, uint32_t quota);
 QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
 	qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu);
 /*

+ 5 - 15
dp/wifi3.0/dp_rx_mon_dest.c

@@ -996,19 +996,8 @@ mon_deliver_non_std_fail:
 	return QDF_STATUS_E_INVAL;
 }
 
-/**
-* dp_rx_mon_dest_process() - Brain of the Rx processing functionality
-*	Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
-* @soc: core txrx main contex
-* @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced
-* @quota: No. of units (packets) that can be serviced in one shot.
-*
-* This function implements the core of Rx functionality. This is
-* expected to handle only non-error frames.
-*
-* Return: none
-*/
-void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
+void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+			    uint32_t mac_id, uint32_t quota)
 {
 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
 	uint8_t pdev_id;
@@ -1044,7 +1033,7 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
 
 	qdf_spin_lock_bh(&pdev->mon_lock);
 
-	if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_dst_srng))) {
+	if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_dst_srng))) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			"%s %d : HAL Monitor Destination Ring access Failed -- %pK",
 			__func__, __LINE__, mon_dst_srng);
@@ -1114,7 +1103,8 @@ void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
 		rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc,
 			mon_dst_srng);
 	}
-	hal_srng_access_end(hal_soc, mon_dst_srng);
+
+	dp_srng_access_end(int_ctx, soc, mon_dst_srng);
 
 	qdf_spin_unlock_bh(&pdev->mon_lock);
 

+ 31 - 43
dp/wifi3.0/dp_rx_mon_status.c

@@ -57,13 +57,15 @@ dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev,
  * Called from bottom half (tasklet/NET_RX_SOFTIRQ)
  *
  * @soc: datapath soc context
+ * @int_ctx: interrupt context
  * @mac_id: mac_id on which interrupt is received
  * @quota: Number of status ring entry that can be serviced in one shot.
  *
  * @Return: Number of reaped status ring entries
  */
 static inline uint32_t
-dp_rx_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
+dp_rx_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+		  uint32_t mac_id, uint32_t quota)
 {
 	return quota;
 }
@@ -1568,16 +1570,18 @@ dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info)
 #endif
 
 /**
-* dp_rx_mon_status_process_tlv() - Process status TLV in status
-*	buffer on Rx status Queue posted by status SRNG processing.
-* @soc: core txrx main context
-* @mac_id: mac_id which is one of 3 mac_ids _ring
-*
-* Return: none
-*/
+ * dp_rx_mon_status_process_tlv() - Process status TLV in status
+ *	buffer on Rx status Queue posted by status SRNG processing.
+ * @soc: core txrx main context
+ * @int_ctx: interrupt context
+ * @mac_id: mac_id which is one of 3 mac_ids _ring
+ * @quota: amount of work which can be done
+ *
+ * Return: none
+ */
 static inline void
-dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
-	uint32_t quota)
+dp_rx_mon_status_process_tlv(struct dp_soc *soc, struct dp_intr *int_ctx,
+			     uint32_t mac_id, uint32_t quota)
 {
 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
 	struct hal_rx_ppdu_info *ppdu_info;
@@ -1718,7 +1722,8 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
 			}
 
 			if (!soc->full_mon_mode)
-				dp_rx_mon_dest_process(soc, mac_id, quota);
+				dp_rx_mon_dest_process(soc, int_ctx, mac_id,
+						       quota);
 
 			pdev->mon_ppdu_status = DP_PPDU_STATUS_START;
 		}
@@ -1732,16 +1737,16 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
  *	processing when status ring is filled with status TLV.
  *	Allocate a new buffer to status ring if the filled buffer
  *	is posted.
- *
  * @soc: core txrx main context
+ * @int_ctx: interrupt context
  * @mac_id: mac_id which is one of 3 mac_ids
  * @quota: No. of ring entry that can be serviced in one shot.
 
  * Return: uint32_t: No. of ring entry that is processed.
  */
 static inline uint32_t
-dp_rx_mon_status_srng_process(struct dp_soc *soc, uint32_t mac_id,
-	uint32_t quota)
+dp_rx_mon_status_srng_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+			      uint32_t mac_id, uint32_t quota)
 {
 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
 	hal_soc_handle_t hal_soc;
@@ -1771,7 +1776,7 @@ dp_rx_mon_status_srng_process(struct dp_soc *soc, uint32_t mac_id,
 
 	qdf_assert(hal_soc);
 
-	if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_status_srng)))
+	if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_status_srng)))
 		goto done;
 
 	/* mon_status_ring_desc => WBM_BUFFER_RING STRUCT =>
@@ -1911,50 +1916,33 @@ dp_rx_mon_status_srng_process(struct dp_soc *soc, uint32_t mac_id,
 	}
 done:
 
-	hal_srng_access_end(hal_soc, mon_status_srng);
+	dp_srng_access_end(int_ctx, soc, mon_status_srng);
 
 	return work_done;
 
 }
 
-/*
- * dp_rx_mon_status_process() - Process monitor status ring and
- *	TLV in status ring.
- *
- * @soc: core txrx main context
- * @mac_id: mac_id which is one of 3 mac_ids
- * @quota: No. of ring entry that can be serviced in one shot.
-
- * Return: uint32_t: No. of ring entry that is processed.
- */
 uint32_t
-dp_rx_mon_status_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) {
+dp_rx_mon_status_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+			 uint32_t mac_id, uint32_t quota)
+{
 	uint32_t work_done;
 
-	work_done = dp_rx_mon_status_srng_process(soc, mac_id, quota);
+	work_done = dp_rx_mon_status_srng_process(soc, int_ctx, mac_id, quota);
 	quota -= work_done;
-	dp_rx_mon_status_process_tlv(soc, mac_id, quota);
+	dp_rx_mon_status_process_tlv(soc, int_ctx, mac_id, quota);
 
 	return work_done;
 }
 
-/**
- * dp_mon_process() - Main monitor mode processing roution.
- *	This call monitor status ring process then monitor
- *	destination ring process.
- *	Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
- * @soc: core txrx main context
- * @mac_id: mac_id which is one of 3 mac_ids
- * @quota: No. of status ring entry that can be serviced in one shot.
-
- * Return: uint32_t: No. of ring entry that is processed.
- */
 uint32_t
-dp_mon_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota) {
+dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx,
+	       uint32_t mac_id, uint32_t quota)
+{
 	if (qdf_unlikely(soc->full_mon_mode))
-		return dp_rx_mon_process(soc, mac_id, quota);
+		return dp_rx_mon_process(soc, int_ctx, mac_id, quota);
 
-	return dp_rx_mon_status_process(soc, mac_id, quota);
+	return dp_rx_mon_status_process(soc, int_ctx, mac_id, quota);
 }
 
 QDF_STATUS

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

@@ -1102,6 +1102,8 @@ struct dp_soc {
 	/* DP Interrupts */
 	struct dp_intr intr_ctx[WLAN_CFG_INT_NUM_CONTEXTS];
 
+	/* Monitor mode mac id to dp_intr_id map */
+	int mon_intr_id_lmac_map[MAX_NUM_LMAC_HW];
 	/* Rx SW descriptor pool for RXDMA monitor buffer */
 	struct rx_desc_pool rx_desc_mon[MAX_RXDESC_POOLS];
 
@@ -1621,6 +1623,9 @@ struct dp_pdev {
 	/* Monitor mode operation frequency */
 	qdf_freq_t mon_chan_freq;
 
+	/* Monitor mode band */
+	enum reg_wifi_band mon_chan_band;
+
 	/* monitor mode lock */
 	qdf_spinlock_t mon_lock;
 

+ 32 - 0
hif/inc/hif.h

@@ -315,12 +315,16 @@ struct hif_opaque_softc {
 /**
  * enum hif_event_type - Type of DP events to be recorded
  * @HIF_EVENT_IRQ_TRIGGER: IRQ trigger event
+ * @HIF_EVENT_TIMER_ENTRY: Monitor Timer entry event
+ * @HIF_EVENT_TIMER_EXIT: Monitor Timer exit event
  * @HIF_EVENT_BH_SCHED: NAPI POLL scheduled event
  * @HIF_EVENT_SRNG_ACCESS_START: hal ring access start event
  * @HIF_EVENT_SRNG_ACCESS_END: hal ring access end event
  */
 enum hif_event_type {
 	HIF_EVENT_IRQ_TRIGGER,
+	HIF_EVENT_TIMER_ENTRY,
+	HIF_EVENT_TIMER_EXIT,
 	HIF_EVENT_BH_SCHED,
 	HIF_EVENT_SRNG_ACCESS_START,
 	HIF_EVENT_SRNG_ACCESS_END,
@@ -379,6 +383,24 @@ void hif_hist_record_event(struct hif_opaque_softc *hif_ctx,
 			   struct hif_event_record *event,
 			   uint8_t intr_grp_id);
 
+/**
+ * hif_event_history_init() - Initialize SRNG event history buffers
+ * @hif_ctx: HIF opaque context
+ * @id: context group ID for which history is recorded
+ *
+ * Returns: None
+ */
+void hif_event_history_init(struct hif_opaque_softc *hif_ctx, uint8_t id);
+
+/**
+ * hif_event_history_deinit() - De-initialize SRNG event history buffers
+ * @hif_ctx: HIF opaque context
+ * @id: context group ID for which history is recorded
+ *
+ * Returns: None
+ */
+void hif_event_history_deinit(struct hif_opaque_softc *hif_ctx, uint8_t id);
+
 /**
  * hif_record_event() - Wrapper function to form and record DP event
  * @hif_ctx: HIF opaque context
@@ -418,6 +440,16 @@ static inline void hif_record_event(struct hif_opaque_softc *hif_ctx,
 				    enum hif_event_type type)
 {
 }
+
+static inline void hif_event_history_init(struct hif_opaque_softc *hif_ctx,
+					  uint8_t id)
+{
+}
+
+static inline void hif_event_history_deinit(struct hif_opaque_softc *hif_ctx,
+					    uint8_t id)
+{
+}
 #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */
 
 /**

+ 17 - 14
hif/src/hif_exec.c

@@ -47,25 +47,21 @@ void hif_hist_record_event(struct hif_opaque_softc *hif_ctx,
 			   struct hif_event_record *event, uint8_t intr_grp_id)
 {
 	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
-	struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
-	struct hif_exec_context *hif_ext_group;
 	struct hif_event_history *hist_ev;
 	struct hif_event_record *record;
 	int record_index;
 
-	if (!hif_state->hif_num_extgroup)
-		return;
-
 	if (scn->event_disable_mask & BIT(event->type))
 		return;
 
-	if (intr_grp_id >= HIF_NUM_INT_CONTEXTS) {
+	if (qdf_unlikely(intr_grp_id >= HIF_NUM_INT_CONTEXTS)) {
 		hif_err("Invalid interrupt group id %d", intr_grp_id);
 		return;
 	}
 
-	hif_ext_group = hif_state->hif_ext_group[intr_grp_id];
-	hist_ev = hif_ext_group->evt_hist;
+	hist_ev = scn->evt_hist[intr_grp_id];
+	if (qdf_unlikely(!hist_ev))
+		return;
 
 	record_index = hif_get_next_record_index(
 			&hist_ev->index, HIF_EVENT_HIST_MAX);
@@ -80,14 +76,22 @@ void hif_hist_record_event(struct hif_opaque_softc *hif_ctx,
 	record->type = event->type;
 }
 
-static void hif_event_history_init(struct hif_exec_context *hif_ext_grp)
+void hif_event_history_init(struct hif_opaque_softc *hif_ctx, uint8_t id)
 {
-	hif_ext_grp->evt_hist = &hif_event_desc_history[hif_ext_grp->grp_id];
-	qdf_atomic_set(&hif_ext_grp->evt_hist->index, -1);
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+
+	scn->evt_hist[id] = &hif_event_desc_history[id];
+	qdf_atomic_set(&scn->evt_hist[id]->index, -1);
+
+	hif_info("SRNG events history initialized for group: %d", id);
 }
-#else
-static inline void hif_event_history_init(struct hif_exec_context *hif_ext_grp)
+
+void hif_event_history_deinit(struct hif_opaque_softc *hif_ctx, uint8_t id)
 {
+	struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
+
+	scn->evt_hist[id] = NULL;
+	hif_info("SRNG events history de-initialized for group: %d", id);
 }
 #endif /* WLAN_FEATURE_DP_EVENT_HISTORY */
 
@@ -878,7 +882,6 @@ uint32_t hif_register_ext_group(struct hif_opaque_softc *hif_ctx,
 	hif_ext_group->hif = hif_ctx;
 	hif_ext_group->context_name = context_name;
 	hif_ext_group->type = type;
-	hif_event_history_init(hif_ext_group);
 
 	hif_state->hif_num_extgroup++;
 	return QDF_STATUS_SUCCESS;

+ 0 - 2
hif/src/hif_exec.h

@@ -54,7 +54,6 @@ struct hif_execution_ops {
  *					hif_tasklet_exec_context
  *
  * @context: context for the handler function to use.
- * @evt_hist: a pointer to the DP event history
  * @context_name: a pointer to a const string for debugging.
  *		this should help whenever there could be ambiguity
  *		in what type of context the void* context points to
@@ -89,7 +88,6 @@ struct hif_exec_context {
 	const char *context_name;
 	void *context;
 	ext_intr_handler handler;
-	struct hif_event_history *evt_hist;
 
 	bool (*work_complete)(struct hif_exec_context *, int work_done);
 	void (*irq_enable)(struct hif_exec_context *);

+ 4 - 0
hif/src/hif_main.h

@@ -231,6 +231,10 @@ struct hif_softc {
 	/* Handle to pktlog device */
 	void *pktlog_dev;
 #endif
+#ifdef WLAN_FEATURE_DP_EVENT_HISTORY
+	/* Pointer to the srng event history */
+	struct hif_event_history *evt_hist[HIF_NUM_INT_CONTEXTS];
+#endif
 
 /*
  * Note: For MCL, #if defined (HIF_CONFIG_SLUB_DEBUG_ON) needs to be checked