xref: /wlan-driver/qca-wifi-host-cmn/dp/wifi3.0/monitor/2.0/dp_tx_mon_2.0.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for any
6*5113495bSYour Name  * purpose with or without fee is hereby granted, provided that the above
7*5113495bSYour Name  * copyright notice and this permission notice appear in all copies.
8*5113495bSYour Name  *
9*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*5113495bSYour Name  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*5113495bSYour Name  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*5113495bSYour Name  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*5113495bSYour Name  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*5113495bSYour Name  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*5113495bSYour Name  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*5113495bSYour Name  */
17*5113495bSYour Name 
18*5113495bSYour Name #include "qdf_types.h"
19*5113495bSYour Name #include "hal_be_hw_headers.h"
20*5113495bSYour Name #include "dp_types.h"
21*5113495bSYour Name #include "hal_be_tx.h"
22*5113495bSYour Name #include "hal_api.h"
23*5113495bSYour Name #include "qdf_trace.h"
24*5113495bSYour Name #include "hal_be_api_mon.h"
25*5113495bSYour Name #include "dp_internal.h"
26*5113495bSYour Name #include "qdf_mem.h"   /* qdf_mem_malloc,free */
27*5113495bSYour Name #include "dp_mon.h"
28*5113495bSYour Name #include <dp_mon_2.0.h>
29*5113495bSYour Name #include <dp_tx_mon_2.0.h>
30*5113495bSYour Name #include <dp_be.h>
31*5113495bSYour Name #include <hal_be_api_mon.h>
32*5113495bSYour Name #include <dp_mon_filter_2.0.h>
33*5113495bSYour Name #include "dp_ratetable.h"
34*5113495bSYour Name #ifdef QCA_SUPPORT_LITE_MONITOR
35*5113495bSYour Name #include "dp_lite_mon.h"
36*5113495bSYour Name #endif
37*5113495bSYour Name 
38*5113495bSYour Name #define MAX_TX_MONITOR_STUCK 50
39*5113495bSYour Name 
40*5113495bSYour Name #ifdef TXMON_DEBUG
41*5113495bSYour Name /*
42*5113495bSYour Name  * dp_tx_mon_debug_statu() - API to display tx monitor status
43*5113495bSYour Name  * @tx_mon_be - pointer to dp_pdev_tx_monitor_be
44*5113495bSYour Name  * @work_done - tx monitor work done
45*5113495bSYour Name  *
46*5113495bSYour Name  * Return: void
47*5113495bSYour Name  */
48*5113495bSYour Name static inline void
dp_tx_mon_debug_status(struct dp_pdev_tx_monitor_be * tx_mon_be,uint32_t work_done)49*5113495bSYour Name dp_tx_mon_debug_status(struct dp_pdev_tx_monitor_be *tx_mon_be,
50*5113495bSYour Name 		       uint32_t work_done)
51*5113495bSYour Name {
52*5113495bSYour Name 	if (tx_mon_be->mode && !work_done)
53*5113495bSYour Name 		tx_mon_be->stats.tx_mon_stuck++;
54*5113495bSYour Name 	else if (tx_mon_be->mode && work_done)
55*5113495bSYour Name 		tx_mon_be->stats.tx_mon_stuck = 0;
56*5113495bSYour Name 
57*5113495bSYour Name 	if (tx_mon_be->stats.tx_mon_stuck > MAX_TX_MONITOR_STUCK) {
58*5113495bSYour Name 		dp_mon_warn("Tx monitor block got stuck!!!!!");
59*5113495bSYour Name 		tx_mon_be->stats.tx_mon_stuck = 0;
60*5113495bSYour Name 		tx_mon_be->stats.total_tx_mon_stuck++;
61*5113495bSYour Name 	}
62*5113495bSYour Name 
63*5113495bSYour Name 	dp_mon_debug_rl("tx_ppdu_info[%u :D %u] STATUS[R %llu: F %llu] PKT_BUF[R %llu: F %llu : P %llu : S %llu]",
64*5113495bSYour Name 			tx_mon_be->tx_ppdu_info_list_depth,
65*5113495bSYour Name 			tx_mon_be->defer_ppdu_info_list_depth,
66*5113495bSYour Name 			tx_mon_be->stats.status_buf_recv,
67*5113495bSYour Name 			tx_mon_be->stats.status_buf_free,
68*5113495bSYour Name 			tx_mon_be->stats.pkt_buf_recv,
69*5113495bSYour Name 			tx_mon_be->stats.pkt_buf_free,
70*5113495bSYour Name 			tx_mon_be->stats.pkt_buf_processed,
71*5113495bSYour Name 			tx_mon_be->stats.pkt_buf_to_stack);
72*5113495bSYour Name }
73*5113495bSYour Name 
74*5113495bSYour Name #else
75*5113495bSYour Name /*
76*5113495bSYour Name  * dp_tx_mon_debug_statu() - API to display tx monitor status
77*5113495bSYour Name  * @tx_mon_be - pointer to dp_pdev_tx_monitor_be
78*5113495bSYour Name  * @work_done - tx monitor work done
79*5113495bSYour Name  *
80*5113495bSYour Name  * Return: void
81*5113495bSYour Name  */
82*5113495bSYour Name static inline void
dp_tx_mon_debug_status(struct dp_pdev_tx_monitor_be * tx_mon_be,uint32_t work_done)83*5113495bSYour Name dp_tx_mon_debug_status(struct dp_pdev_tx_monitor_be *tx_mon_be,
84*5113495bSYour Name 		       uint32_t work_done)
85*5113495bSYour Name {
86*5113495bSYour Name 	if (tx_mon_be->mode && !work_done)
87*5113495bSYour Name 		tx_mon_be->stats.tx_mon_stuck++;
88*5113495bSYour Name 	else if (tx_mon_be->mode && work_done)
89*5113495bSYour Name 		tx_mon_be->stats.tx_mon_stuck = 0;
90*5113495bSYour Name 
91*5113495bSYour Name 	if (tx_mon_be->stats.tx_mon_stuck > MAX_TX_MONITOR_STUCK) {
92*5113495bSYour Name 		dp_mon_warn("Tx monitor block got stuck!!!!!");
93*5113495bSYour Name 		tx_mon_be->stats.tx_mon_stuck = 0;
94*5113495bSYour Name 		tx_mon_be->stats.total_tx_mon_stuck++;
95*5113495bSYour Name 	}
96*5113495bSYour Name }
97*5113495bSYour Name #endif
98*5113495bSYour Name 
99*5113495bSYour Name static inline uint32_t
dp_tx_mon_srng_process_2_0(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)100*5113495bSYour Name dp_tx_mon_srng_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
101*5113495bSYour Name 			   uint32_t mac_id, uint32_t quota)
102*5113495bSYour Name {
103*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
104*5113495bSYour Name 	void *tx_mon_dst_ring_desc;
105*5113495bSYour Name 	hal_soc_handle_t hal_soc;
106*5113495bSYour Name 	void *mon_dst_srng;
107*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
108*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be;
109*5113495bSYour Name 	uint32_t work_done = 0;
110*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
111*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
112*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be = NULL;
113*5113495bSYour Name 	struct dp_mon_desc_pool *tx_mon_desc_pool = &mon_soc_be->tx_desc_mon;
114*5113495bSYour Name 	struct dp_tx_mon_desc_list mon_desc_list;
115*5113495bSYour Name 	uint32_t replenish_cnt = 0;
116*5113495bSYour Name 
117*5113495bSYour Name 	if (!pdev) {
118*5113495bSYour Name 		dp_mon_err("%pK: pdev is null for mac_id = %d", soc, mac_id);
119*5113495bSYour Name 		return work_done;
120*5113495bSYour Name 	}
121*5113495bSYour Name 
122*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
123*5113495bSYour Name 	mon_dst_srng = mon_soc_be->tx_mon_dst_ring[mac_id].hal_srng;
124*5113495bSYour Name 
125*5113495bSYour Name 	if (!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)) {
126*5113495bSYour Name 		dp_mon_err("%pK: : HAL Monitor Destination Ring Init Failed -- %pK",
127*5113495bSYour Name 			   soc, mon_dst_srng);
128*5113495bSYour Name 		return work_done;
129*5113495bSYour Name 	}
130*5113495bSYour Name 
131*5113495bSYour Name 	mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
132*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev_be))
133*5113495bSYour Name 		return work_done;
134*5113495bSYour Name 
135*5113495bSYour Name 	tx_mon_be = &mon_pdev_be->tx_monitor_be;
136*5113495bSYour Name 	hal_soc = soc->hal_soc;
137*5113495bSYour Name 
138*5113495bSYour Name 	qdf_assert((hal_soc && pdev));
139*5113495bSYour Name 
140*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
141*5113495bSYour Name 	mon_desc_list.desc_list = NULL;
142*5113495bSYour Name 	mon_desc_list.tail = NULL;
143*5113495bSYour Name 	mon_desc_list.tx_mon_reap_cnt = 0;
144*5113495bSYour Name 
145*5113495bSYour Name 	if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_dst_srng))) {
146*5113495bSYour Name 		dp_mon_err("%s %d : HAL Mon Dest Ring access Failed -- %pK",
147*5113495bSYour Name 			   __func__, __LINE__, mon_dst_srng);
148*5113495bSYour Name 		qdf_spin_unlock_bh(&mon_pdev->mon_lock);
149*5113495bSYour Name 		return work_done;
150*5113495bSYour Name 	}
151*5113495bSYour Name 
152*5113495bSYour Name 	while (qdf_likely((tx_mon_dst_ring_desc =
153*5113495bSYour Name 		(void *)hal_srng_dst_peek(hal_soc, mon_dst_srng))
154*5113495bSYour Name 				&& quota--)) {
155*5113495bSYour Name 		struct hal_mon_desc hal_mon_tx_desc = {0};
156*5113495bSYour Name 		struct dp_mon_desc *mon_desc = NULL;
157*5113495bSYour Name 		qdf_frag_t status_frag = NULL;
158*5113495bSYour Name 		uint32_t end_offset = 0;
159*5113495bSYour Name 
160*5113495bSYour Name 		hal_be_get_mon_dest_status(soc->hal_soc,
161*5113495bSYour Name 					   tx_mon_dst_ring_desc,
162*5113495bSYour Name 					   &hal_mon_tx_desc);
163*5113495bSYour Name 
164*5113495bSYour Name 		if (hal_mon_tx_desc.empty_descriptor) {
165*5113495bSYour Name 			/* update stats counter */
166*5113495bSYour Name 			dp_mon_debug("P_ID:%d INIT:%d E_DESC:%d R_ID:%d L_CNT:%d  DROP[PPDU:%d MPDU:%d TLV:%d] E_O_PPDU:%d",
167*5113495bSYour Name 				    hal_mon_tx_desc.ppdu_id,
168*5113495bSYour Name 				    hal_mon_tx_desc.initiator,
169*5113495bSYour Name 				    hal_mon_tx_desc.empty_descriptor,
170*5113495bSYour Name 				    hal_mon_tx_desc.ring_id,
171*5113495bSYour Name 				    hal_mon_tx_desc.looping_count,
172*5113495bSYour Name 				    hal_mon_tx_desc.ppdu_drop_count,
173*5113495bSYour Name 				    hal_mon_tx_desc.mpdu_drop_count,
174*5113495bSYour Name 				    hal_mon_tx_desc.tlv_drop_count,
175*5113495bSYour Name 				    hal_mon_tx_desc.end_of_ppdu_dropped);
176*5113495bSYour Name 
177*5113495bSYour Name 			tx_mon_be->stats.ppdu_drop_cnt +=
178*5113495bSYour Name 				hal_mon_tx_desc.ppdu_drop_count;
179*5113495bSYour Name 			tx_mon_be->stats.mpdu_drop_cnt +=
180*5113495bSYour Name 				hal_mon_tx_desc.mpdu_drop_count;
181*5113495bSYour Name 			tx_mon_be->stats.tlv_drop_cnt +=
182*5113495bSYour Name 				hal_mon_tx_desc.tlv_drop_count;
183*5113495bSYour Name 			work_done++;
184*5113495bSYour Name 			hal_srng_dst_get_next(hal_soc, mon_dst_srng);
185*5113495bSYour Name 			continue;
186*5113495bSYour Name 		}
187*5113495bSYour Name 
188*5113495bSYour Name 		dp_mon_debug("P_ID:%d INIT:%d E_DESC:%d R_ID:%d L_CNT:%d BUF_ADDR: 0x%llx E_OFF: %d E_REA: %d",
189*5113495bSYour Name 			    hal_mon_tx_desc.ppdu_id,
190*5113495bSYour Name 			    hal_mon_tx_desc.initiator,
191*5113495bSYour Name 			    hal_mon_tx_desc.empty_descriptor,
192*5113495bSYour Name 			    hal_mon_tx_desc.ring_id,
193*5113495bSYour Name 			    hal_mon_tx_desc.looping_count,
194*5113495bSYour Name 			    hal_mon_tx_desc.buf_addr,
195*5113495bSYour Name 			    hal_mon_tx_desc.end_offset,
196*5113495bSYour Name 			    hal_mon_tx_desc.end_reason);
197*5113495bSYour Name 
198*5113495bSYour Name 		mon_desc = (struct dp_mon_desc *)(uintptr_t)(hal_mon_tx_desc.buf_addr);
199*5113495bSYour Name 		qdf_assert_always(mon_desc);
200*5113495bSYour Name 
201*5113495bSYour Name 		if (!mon_desc->unmapped) {
202*5113495bSYour Name 			qdf_mem_unmap_page(soc->osdev, mon_desc->paddr,
203*5113495bSYour Name 					   DP_MON_DATA_BUFFER_SIZE,
204*5113495bSYour Name 					   QDF_DMA_FROM_DEVICE);
205*5113495bSYour Name 			mon_desc->unmapped = 1;
206*5113495bSYour Name 		}
207*5113495bSYour Name 
208*5113495bSYour Name 		if (mon_desc->magic != DP_MON_DESC_MAGIC) {
209*5113495bSYour Name 			dp_mon_err("Invalid monitor descriptor");
210*5113495bSYour Name 			qdf_assert_always(0);
211*5113495bSYour Name 		}
212*5113495bSYour Name 
213*5113495bSYour Name 		end_offset = hal_mon_tx_desc.end_offset;
214*5113495bSYour Name 
215*5113495bSYour Name 		status_frag = (qdf_frag_t)(mon_desc->buf_addr);
216*5113495bSYour Name 		mon_desc->buf_addr = NULL;
217*5113495bSYour Name 		/* increment reap count */
218*5113495bSYour Name 		++mon_desc_list.tx_mon_reap_cnt;
219*5113495bSYour Name 
220*5113495bSYour Name 		/* add the mon_desc to free list */
221*5113495bSYour Name 		dp_mon_add_to_free_desc_list(&mon_desc_list.desc_list,
222*5113495bSYour Name 					     &mon_desc_list.tail, mon_desc);
223*5113495bSYour Name 
224*5113495bSYour Name 
225*5113495bSYour Name 		if (qdf_unlikely(!status_frag)) {
226*5113495bSYour Name 			dp_mon_debug("P_ID:%d INIT:%d E_DESC:%d R_ID:%d L_CNT:%d BUF_ADDR: 0x%llx E_OFF: %d E_REA: %d",
227*5113495bSYour Name 				     hal_mon_tx_desc.ppdu_id,
228*5113495bSYour Name 				     hal_mon_tx_desc.initiator,
229*5113495bSYour Name 				     hal_mon_tx_desc.empty_descriptor,
230*5113495bSYour Name 				     hal_mon_tx_desc.ring_id,
231*5113495bSYour Name 				     hal_mon_tx_desc.looping_count,
232*5113495bSYour Name 				     hal_mon_tx_desc.buf_addr,
233*5113495bSYour Name 				     hal_mon_tx_desc.end_offset,
234*5113495bSYour Name 				     hal_mon_tx_desc.end_reason);
235*5113495bSYour Name 
236*5113495bSYour Name 			work_done++;
237*5113495bSYour Name 			hal_srng_dst_get_next(hal_soc, mon_dst_srng);
238*5113495bSYour Name 			continue;
239*5113495bSYour Name 		}
240*5113495bSYour Name 
241*5113495bSYour Name 		tx_mon_be->stats.status_buf_recv++;
242*5113495bSYour Name 
243*5113495bSYour Name 		if ((hal_mon_tx_desc.end_reason == HAL_MON_FLUSH_DETECTED) ||
244*5113495bSYour Name 		    (hal_mon_tx_desc.end_reason == HAL_MON_PPDU_TRUNCATED)) {
245*5113495bSYour Name 			tx_mon_be->be_ppdu_id = hal_mon_tx_desc.ppdu_id;
246*5113495bSYour Name 
247*5113495bSYour Name 			dp_tx_mon_update_end_reason(mon_pdev,
248*5113495bSYour Name 						    hal_mon_tx_desc.ppdu_id,
249*5113495bSYour Name 						    hal_mon_tx_desc.end_reason);
250*5113495bSYour Name 			/* check and free packet buffer from status buffer */
251*5113495bSYour Name 			dp_tx_mon_status_free_packet_buf(pdev, status_frag,
252*5113495bSYour Name 							 end_offset,
253*5113495bSYour Name 							 &mon_desc_list);
254*5113495bSYour Name 
255*5113495bSYour Name 			tx_mon_be->stats.status_buf_free++;
256*5113495bSYour Name 			qdf_frag_free(status_frag);
257*5113495bSYour Name 
258*5113495bSYour Name 			work_done++;
259*5113495bSYour Name 			hal_srng_dst_get_next(hal_soc, mon_dst_srng);
260*5113495bSYour Name 			continue;
261*5113495bSYour Name 		}
262*5113495bSYour Name 
263*5113495bSYour Name 		dp_tx_process_pktlog_be(soc, pdev,
264*5113495bSYour Name 					status_frag,
265*5113495bSYour Name 					end_offset);
266*5113495bSYour Name 
267*5113495bSYour Name 		dp_tx_mon_process_status_tlv(soc, pdev,
268*5113495bSYour Name 					     &hal_mon_tx_desc,
269*5113495bSYour Name 					     status_frag,
270*5113495bSYour Name 					     end_offset,
271*5113495bSYour Name 					     &mon_desc_list);
272*5113495bSYour Name 
273*5113495bSYour Name 		work_done++;
274*5113495bSYour Name 		hal_srng_dst_get_next(hal_soc, mon_dst_srng);
275*5113495bSYour Name 	}
276*5113495bSYour Name 	dp_srng_access_end(int_ctx, soc, mon_dst_srng);
277*5113495bSYour Name 
278*5113495bSYour Name 	if (mon_desc_list.tx_mon_reap_cnt) {
279*5113495bSYour Name 		dp_mon_buffers_replenish(soc, &mon_soc_be->tx_mon_buf_ring,
280*5113495bSYour Name 					 tx_mon_desc_pool,
281*5113495bSYour Name 					 mon_desc_list.tx_mon_reap_cnt,
282*5113495bSYour Name 					 &mon_desc_list.desc_list,
283*5113495bSYour Name 					 &mon_desc_list.tail,
284*5113495bSYour Name 					 &replenish_cnt);
285*5113495bSYour Name 	}
286*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
287*5113495bSYour Name 	dp_mon_debug("mac_id: %d, work_done:%d tx_monitor_reap_cnt:%d",
288*5113495bSYour Name 		     mac_id, work_done, mon_desc_list.tx_mon_reap_cnt);
289*5113495bSYour Name 
290*5113495bSYour Name 	tx_mon_be->stats.total_tx_mon_reap_cnt += mon_desc_list.tx_mon_reap_cnt;
291*5113495bSYour Name 	tx_mon_be->stats.totat_tx_mon_replenish_cnt += replenish_cnt;
292*5113495bSYour Name 	dp_tx_mon_debug_status(tx_mon_be, work_done);
293*5113495bSYour Name 
294*5113495bSYour Name 	return work_done;
295*5113495bSYour Name }
296*5113495bSYour Name 
297*5113495bSYour Name uint32_t
dp_tx_mon_process_2_0(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)298*5113495bSYour Name dp_tx_mon_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx,
299*5113495bSYour Name 		      uint32_t mac_id, uint32_t quota)
300*5113495bSYour Name {
301*5113495bSYour Name 	uint32_t work_done;
302*5113495bSYour Name 
303*5113495bSYour Name 	work_done = dp_tx_mon_srng_process_2_0(soc, int_ctx, mac_id, quota);
304*5113495bSYour Name 
305*5113495bSYour Name 	return work_done;
306*5113495bSYour Name }
307*5113495bSYour Name 
308*5113495bSYour Name void
dp_tx_mon_print_ring_stat_2_0(struct dp_pdev * pdev)309*5113495bSYour Name dp_tx_mon_print_ring_stat_2_0(struct dp_pdev *pdev)
310*5113495bSYour Name {
311*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
312*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
313*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
314*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
315*5113495bSYour Name 	int lmac_id;
316*5113495bSYour Name 
317*5113495bSYour Name 	lmac_id = dp_get_lmac_id_for_pdev_id(soc, 0, pdev->pdev_id);
318*5113495bSYour Name 	dp_print_ring_stat_from_hal(soc, &mon_soc_be->tx_mon_buf_ring,
319*5113495bSYour Name 				    TX_MONITOR_BUF);
320*5113495bSYour Name 	dp_print_ring_stat_from_hal(soc, &mon_soc_be->tx_mon_dst_ring[lmac_id],
321*5113495bSYour Name 				    TX_MONITOR_DST);
322*5113495bSYour Name }
323*5113495bSYour Name 
324*5113495bSYour Name void
dp_tx_mon_buf_desc_pool_deinit(struct dp_soc * soc)325*5113495bSYour Name dp_tx_mon_buf_desc_pool_deinit(struct dp_soc *soc)
326*5113495bSYour Name {
327*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
328*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
329*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
330*5113495bSYour Name 
331*5113495bSYour Name 	dp_mon_desc_pool_deinit(&mon_soc_be->tx_desc_mon);
332*5113495bSYour Name }
333*5113495bSYour Name 
334*5113495bSYour Name QDF_STATUS
dp_tx_mon_buf_desc_pool_init(struct dp_soc * soc)335*5113495bSYour Name dp_tx_mon_buf_desc_pool_init(struct dp_soc *soc)
336*5113495bSYour Name {
337*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
338*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
339*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
340*5113495bSYour Name 	uint32_t num_entries;
341*5113495bSYour Name 
342*5113495bSYour Name 	num_entries =
343*5113495bSYour Name 		wlan_cfg_get_dp_soc_tx_mon_buf_ring_size(soc->wlan_cfg_ctx);
344*5113495bSYour Name 
345*5113495bSYour Name 	return dp_mon_desc_pool_init(&mon_soc_be->tx_desc_mon, num_entries);
346*5113495bSYour Name }
347*5113495bSYour Name 
dp_tx_mon_buf_desc_pool_free(struct dp_soc * soc)348*5113495bSYour Name void dp_tx_mon_buf_desc_pool_free(struct dp_soc *soc)
349*5113495bSYour Name {
350*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
351*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
352*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
353*5113495bSYour Name 
354*5113495bSYour Name 	if (mon_soc_be)
355*5113495bSYour Name 		dp_mon_desc_pool_free(soc, &mon_soc_be->tx_desc_mon,
356*5113495bSYour Name 				      DP_MON_TX_DESC_POOL_TYPE);
357*5113495bSYour Name }
358*5113495bSYour Name 
dp_tx_mon_soc_init_2_0(struct dp_soc * soc)359*5113495bSYour Name QDF_STATUS dp_tx_mon_soc_init_2_0(struct dp_soc *soc)
360*5113495bSYour Name {
361*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
362*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
363*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
364*5113495bSYour Name 
365*5113495bSYour Name 	if (dp_srng_init(soc, &mon_soc_be->tx_mon_buf_ring,
366*5113495bSYour Name 			 TX_MONITOR_BUF, 0, 0)) {
367*5113495bSYour Name 		dp_mon_err("%pK: " RNG_ERR "tx_mon_buf_ring", soc);
368*5113495bSYour Name 		goto fail;
369*5113495bSYour Name 	}
370*5113495bSYour Name 
371*5113495bSYour Name 	if (dp_tx_mon_buf_desc_pool_init(soc)) {
372*5113495bSYour Name 		dp_mon_err("%pK: " RNG_ERR "tx mon desc pool init", soc);
373*5113495bSYour Name 		goto fail;
374*5113495bSYour Name 	}
375*5113495bSYour Name 
376*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
377*5113495bSYour Name fail:
378*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
379*5113495bSYour Name }
380*5113495bSYour Name 
dp_tx_mon_soc_deinit_2_0(struct dp_soc * soc,uint32_t lmac_id)381*5113495bSYour Name void dp_tx_mon_soc_deinit_2_0(struct dp_soc *soc, uint32_t lmac_id)
382*5113495bSYour Name {
383*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
384*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
385*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
386*5113495bSYour Name 
387*5113495bSYour Name 	dp_tx_mon_buffers_free(soc);
388*5113495bSYour Name 	dp_tx_mon_buf_desc_pool_deinit(soc);
389*5113495bSYour Name 	dp_srng_deinit(soc, &mon_soc_be->tx_mon_buf_ring, TX_MONITOR_BUF, 0);
390*5113495bSYour Name }
391*5113495bSYour Name 
392*5113495bSYour Name QDF_STATUS
dp_tx_mon_buf_desc_pool_alloc(struct dp_soc * soc)393*5113495bSYour Name dp_tx_mon_buf_desc_pool_alloc(struct dp_soc *soc)
394*5113495bSYour Name {
395*5113495bSYour Name 	struct dp_mon_desc_pool *tx_mon_desc_pool;
396*5113495bSYour Name 	int entries;
397*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
398*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
399*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
400*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
401*5113495bSYour Name 
402*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
403*5113495bSYour Name 
404*5113495bSYour Name 	entries = wlan_cfg_get_dp_soc_tx_mon_buf_ring_size(soc_cfg_ctx);
405*5113495bSYour Name 
406*5113495bSYour Name 
407*5113495bSYour Name 	tx_mon_desc_pool = &mon_soc_be->tx_desc_mon;
408*5113495bSYour Name 
409*5113495bSYour Name 	qdf_print("%s:%d tx mon buf desc pool entries: %d", __func__, __LINE__, entries);
410*5113495bSYour Name 	return dp_mon_desc_pool_alloc(soc, DP_MON_TX_DESC_POOL_TYPE,
411*5113495bSYour Name 				      entries, tx_mon_desc_pool);
412*5113495bSYour Name }
413*5113495bSYour Name 
414*5113495bSYour Name void
dp_tx_mon_buffers_free(struct dp_soc * soc)415*5113495bSYour Name dp_tx_mon_buffers_free(struct dp_soc *soc)
416*5113495bSYour Name {
417*5113495bSYour Name 	struct dp_mon_desc_pool *tx_mon_desc_pool;
418*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
419*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
420*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
421*5113495bSYour Name 
422*5113495bSYour Name 	tx_mon_desc_pool = &mon_soc_be->tx_desc_mon;
423*5113495bSYour Name 
424*5113495bSYour Name 	dp_mon_pool_frag_unmap_and_free(soc, tx_mon_desc_pool);
425*5113495bSYour Name }
426*5113495bSYour Name 
427*5113495bSYour Name QDF_STATUS
dp_tx_mon_buffers_alloc(struct dp_soc * soc,uint32_t size)428*5113495bSYour Name dp_tx_mon_buffers_alloc(struct dp_soc *soc, uint32_t size)
429*5113495bSYour Name {
430*5113495bSYour Name 	struct dp_srng *mon_buf_ring;
431*5113495bSYour Name 	struct dp_mon_desc_pool *tx_mon_desc_pool;
432*5113495bSYour Name 	union dp_mon_desc_list_elem_t *desc_list = NULL;
433*5113495bSYour Name 	union dp_mon_desc_list_elem_t *tail = NULL;
434*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
435*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
436*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
437*5113495bSYour Name 
438*5113495bSYour Name 	mon_buf_ring = &mon_soc_be->tx_mon_buf_ring;
439*5113495bSYour Name 
440*5113495bSYour Name 	tx_mon_desc_pool = &mon_soc_be->tx_desc_mon;
441*5113495bSYour Name 
442*5113495bSYour Name 	return dp_mon_buffers_replenish(soc, mon_buf_ring,
443*5113495bSYour Name 					tx_mon_desc_pool,
444*5113495bSYour Name 					size,
445*5113495bSYour Name 					&desc_list, &tail, NULL);
446*5113495bSYour Name }
447*5113495bSYour Name 
448*5113495bSYour Name #ifdef WLAN_TX_PKT_CAPTURE_ENH_BE
449*5113495bSYour Name 
450*5113495bSYour Name /*
451*5113495bSYour Name  * dp_tx_mon_nbuf_get_num_frag() - get total number of fragments
452*5113495bSYour Name  * @buf: Network buf instance
453*5113495bSYour Name  *
454*5113495bSYour Name  * Return: number of fragments
455*5113495bSYour Name  */
456*5113495bSYour Name static inline
dp_tx_mon_nbuf_get_num_frag(qdf_nbuf_t nbuf)457*5113495bSYour Name uint32_t dp_tx_mon_nbuf_get_num_frag(qdf_nbuf_t nbuf)
458*5113495bSYour Name {
459*5113495bSYour Name 	uint32_t num_frag = 0;
460*5113495bSYour Name 
461*5113495bSYour Name 	if (qdf_unlikely(!nbuf))
462*5113495bSYour Name 		return num_frag;
463*5113495bSYour Name 
464*5113495bSYour Name 	num_frag = qdf_nbuf_get_nr_frags_in_fraglist(nbuf);
465*5113495bSYour Name 
466*5113495bSYour Name 	return num_frag;
467*5113495bSYour Name }
468*5113495bSYour Name 
469*5113495bSYour Name /*
470*5113495bSYour Name  * dp_tx_mon_free_usr_mpduq() - API to free user mpduq
471*5113495bSYour Name  * @tx_ppdu_info - pointer to tx_ppdu_info
472*5113495bSYour Name  * @usr_idx - user index
473*5113495bSYour Name  * @tx_mon_be - pointer to tx capture be
474*5113495bSYour Name  *
475*5113495bSYour Name  * Return: void
476*5113495bSYour Name  */
dp_tx_mon_free_usr_mpduq(struct dp_tx_ppdu_info * tx_ppdu_info,uint8_t usr_idx,struct dp_pdev_tx_monitor_be * tx_mon_be)477*5113495bSYour Name void dp_tx_mon_free_usr_mpduq(struct dp_tx_ppdu_info *tx_ppdu_info,
478*5113495bSYour Name 			      uint8_t usr_idx,
479*5113495bSYour Name 			      struct dp_pdev_tx_monitor_be *tx_mon_be)
480*5113495bSYour Name {
481*5113495bSYour Name 	qdf_nbuf_queue_t *mpdu_q;
482*5113495bSYour Name 	uint32_t num_frag = 0;
483*5113495bSYour Name 	qdf_nbuf_t buf = NULL;
484*5113495bSYour Name 
485*5113495bSYour Name 	if (qdf_unlikely(!tx_ppdu_info))
486*5113495bSYour Name 		return;
487*5113495bSYour Name 
488*5113495bSYour Name 	mpdu_q = &TXMON_PPDU_USR(tx_ppdu_info, usr_idx, mpdu_q);
489*5113495bSYour Name 
490*5113495bSYour Name 	while ((buf = qdf_nbuf_queue_remove(mpdu_q)) != NULL) {
491*5113495bSYour Name 		num_frag += dp_tx_mon_nbuf_get_num_frag(buf);
492*5113495bSYour Name 		qdf_nbuf_free(buf);
493*5113495bSYour Name 	}
494*5113495bSYour Name 	tx_mon_be->stats.pkt_buf_free += num_frag;
495*5113495bSYour Name }
496*5113495bSYour Name 
497*5113495bSYour Name /*
498*5113495bSYour Name  * dp_tx_mon_free_ppdu_info() - API to free dp_tx_ppdu_info
499*5113495bSYour Name  * @tx_ppdu_info - pointer to tx_ppdu_info
500*5113495bSYour Name  * @tx_mon_be - pointer to tx capture be
501*5113495bSYour Name  *
502*5113495bSYour Name  * Return: void
503*5113495bSYour Name  */
dp_tx_mon_free_ppdu_info(struct dp_tx_ppdu_info * tx_ppdu_info,struct dp_pdev_tx_monitor_be * tx_mon_be)504*5113495bSYour Name void dp_tx_mon_free_ppdu_info(struct dp_tx_ppdu_info *tx_ppdu_info,
505*5113495bSYour Name 			      struct dp_pdev_tx_monitor_be *tx_mon_be)
506*5113495bSYour Name {
507*5113495bSYour Name 	uint32_t user = 0;
508*5113495bSYour Name 
509*5113495bSYour Name 	for (; user < TXMON_PPDU_HAL(tx_ppdu_info, num_users); user++) {
510*5113495bSYour Name 		qdf_nbuf_queue_t *mpdu_q;
511*5113495bSYour Name 		uint32_t num_frag = 0;
512*5113495bSYour Name 		qdf_nbuf_t buf = NULL;
513*5113495bSYour Name 
514*5113495bSYour Name 		mpdu_q = &TXMON_PPDU_USR(tx_ppdu_info, user, mpdu_q);
515*5113495bSYour Name 
516*5113495bSYour Name 		while ((buf = qdf_nbuf_queue_remove(mpdu_q)) != NULL) {
517*5113495bSYour Name 			num_frag += dp_tx_mon_nbuf_get_num_frag(buf);
518*5113495bSYour Name 			qdf_nbuf_free(buf);
519*5113495bSYour Name 		}
520*5113495bSYour Name 		tx_mon_be->stats.pkt_buf_free += num_frag;
521*5113495bSYour Name 	}
522*5113495bSYour Name 
523*5113495bSYour Name 	TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 0;
524*5113495bSYour Name 	qdf_mem_free(tx_ppdu_info);
525*5113495bSYour Name }
526*5113495bSYour Name 
527*5113495bSYour Name /*
528*5113495bSYour Name  * dp_tx_mon_get_ppdu_info() - API to allocate dp_tx_ppdu_info
529*5113495bSYour Name  * @pdev - pdev handle
530*5113495bSYour Name  * @type - type of ppdu_info data or protection
531*5113495bSYour Name  * @num_user - number user in a ppdu_info
532*5113495bSYour Name  * @ppdu_id - ppdu_id number
533*5113495bSYour Name  *
534*5113495bSYour Name  * Return: pointer to dp_tx_ppdu_info
535*5113495bSYour Name  */
dp_tx_mon_get_ppdu_info(struct dp_pdev * pdev,enum tx_ppdu_info_type type,uint8_t num_user,uint32_t ppdu_id)536*5113495bSYour Name struct dp_tx_ppdu_info *dp_tx_mon_get_ppdu_info(struct dp_pdev *pdev,
537*5113495bSYour Name 						enum tx_ppdu_info_type type,
538*5113495bSYour Name 						uint8_t num_user,
539*5113495bSYour Name 						uint32_t ppdu_id)
540*5113495bSYour Name {
541*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
542*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
543*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
544*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be =
545*5113495bSYour Name 			&mon_pdev_be->tx_monitor_be;
546*5113495bSYour Name 	struct dp_tx_ppdu_info *tx_ppdu_info;
547*5113495bSYour Name 	size_t sz_ppdu_info = 0;
548*5113495bSYour Name 	uint8_t i;
549*5113495bSYour Name 
550*5113495bSYour Name 	/* allocate new tx_ppdu_info */
551*5113495bSYour Name 	sz_ppdu_info = (sizeof(struct dp_tx_ppdu_info) +
552*5113495bSYour Name 			(sizeof(struct mon_rx_user_status) * num_user));
553*5113495bSYour Name 
554*5113495bSYour Name 	tx_ppdu_info = (struct dp_tx_ppdu_info *)qdf_mem_malloc(sz_ppdu_info);
555*5113495bSYour Name 	if (!tx_ppdu_info) {
556*5113495bSYour Name 		dp_mon_err("allocation of tx_ppdu_info type[%d] failed!!!",
557*5113495bSYour Name 			   type);
558*5113495bSYour Name 		return NULL;
559*5113495bSYour Name 	}
560*5113495bSYour Name 
561*5113495bSYour Name 	TXMON_PPDU_HAL(tx_ppdu_info, is_used) = 0;
562*5113495bSYour Name 	TXMON_PPDU_HAL(tx_ppdu_info, num_users) = num_user;
563*5113495bSYour Name 	TXMON_PPDU_HAL(tx_ppdu_info, ppdu_id) = ppdu_id;
564*5113495bSYour Name 	TXMON_PPDU(tx_ppdu_info, ppdu_id) = ppdu_id;
565*5113495bSYour Name 
566*5113495bSYour Name 	for (i = 0; i < num_user; i++) {
567*5113495bSYour Name 		qdf_nbuf_queue_t *mpdu_q;
568*5113495bSYour Name 
569*5113495bSYour Name 		mpdu_q = &TXMON_PPDU_USR(tx_ppdu_info, i, mpdu_q);
570*5113495bSYour Name 		qdf_nbuf_queue_init(mpdu_q);
571*5113495bSYour Name 	}
572*5113495bSYour Name 
573*5113495bSYour Name 	/* assign tx_ppdu_info to monitor pdev for reference */
574*5113495bSYour Name 	if (type == TX_PROT_PPDU_INFO) {
575*5113495bSYour Name 		qdf_mem_zero(&tx_mon_be->prot_status_info, sizeof(struct hal_tx_status_info));
576*5113495bSYour Name 		tx_mon_be->tx_prot_ppdu_info = tx_ppdu_info;
577*5113495bSYour Name 		TXMON_PPDU_HAL(tx_ppdu_info, is_data) = 0;
578*5113495bSYour Name 	} else {
579*5113495bSYour Name 		qdf_mem_zero(&tx_mon_be->data_status_info, sizeof(struct hal_tx_status_info));
580*5113495bSYour Name 		tx_mon_be->tx_data_ppdu_info = tx_ppdu_info;
581*5113495bSYour Name 		TXMON_PPDU_HAL(tx_ppdu_info, is_data) = 1;
582*5113495bSYour Name 	}
583*5113495bSYour Name 
584*5113495bSYour Name 	return tx_ppdu_info;
585*5113495bSYour Name }
586*5113495bSYour Name 
587*5113495bSYour Name /*
588*5113495bSYour Name  * dp_print_pdev_tx_monitor_stats_2_0: print tx capture stats
589*5113495bSYour Name  * @pdev: DP PDEV handle
590*5113495bSYour Name  *
591*5113495bSYour Name  * return: void
592*5113495bSYour Name  */
dp_print_pdev_tx_monitor_stats_2_0(struct dp_pdev * pdev)593*5113495bSYour Name void dp_print_pdev_tx_monitor_stats_2_0(struct dp_pdev *pdev)
594*5113495bSYour Name {
595*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
596*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
597*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
598*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be =
599*5113495bSYour Name 			&mon_pdev_be->tx_monitor_be;
600*5113495bSYour Name 	struct dp_tx_monitor_drop_stats stats = {0};
601*5113495bSYour Name 
602*5113495bSYour Name 	qdf_mem_copy(&stats, &tx_mon_be->stats,
603*5113495bSYour Name 		     sizeof(struct dp_tx_monitor_drop_stats));
604*5113495bSYour Name 
605*5113495bSYour Name 	/* TX monitor stats needed for beryllium */
606*5113495bSYour Name 	DP_PRINT_STATS("\n\tTX Capture BE stats mode[%d]:", tx_mon_be->mode);
607*5113495bSYour Name 	DP_PRINT_STATS("\tbuffer pending : %u", tx_mon_be->last_frag_q_idx);
608*5113495bSYour Name 	DP_PRINT_STATS("\treplenish count: %llu",
609*5113495bSYour Name 		       stats.totat_tx_mon_replenish_cnt);
610*5113495bSYour Name 	DP_PRINT_STATS("\treap count     : %llu", stats.total_tx_mon_reap_cnt);
611*5113495bSYour Name 	DP_PRINT_STATS("\tmonitor stuck  : %u", stats.total_tx_mon_stuck);
612*5113495bSYour Name 	DP_PRINT_STATS("\tStatus buffer");
613*5113495bSYour Name 	DP_PRINT_STATS("\t\treceived  : %llu", stats.status_buf_recv);
614*5113495bSYour Name 	DP_PRINT_STATS("\t\tfree      : %llu", stats.status_buf_free);
615*5113495bSYour Name 	DP_PRINT_STATS("\tPacket buffer");
616*5113495bSYour Name 	DP_PRINT_STATS("\t\treceived  : %llu", stats.pkt_buf_recv);
617*5113495bSYour Name 	DP_PRINT_STATS("\t\tfree      : %llu", stats.pkt_buf_free);
618*5113495bSYour Name 	DP_PRINT_STATS("\t\tprocessed : %llu", stats.pkt_buf_processed);
619*5113495bSYour Name 	DP_PRINT_STATS("\t\tto stack  : %llu", stats.pkt_buf_to_stack);
620*5113495bSYour Name 	DP_PRINT_STATS("\tppdu info");
621*5113495bSYour Name 	DP_PRINT_STATS("\t\tthreshold : %llu", stats.ppdu_info_drop_th);
622*5113495bSYour Name 	DP_PRINT_STATS("\t\tflush     : %llu", stats.ppdu_info_drop_flush);
623*5113495bSYour Name 	DP_PRINT_STATS("\t\ttruncated : %llu", stats.ppdu_info_drop_trunc);
624*5113495bSYour Name 	DP_PRINT_STATS("\tDrop stats");
625*5113495bSYour Name 	DP_PRINT_STATS("\t\tppdu drop : %llu", stats.ppdu_drop_cnt);
626*5113495bSYour Name 	DP_PRINT_STATS("\t\tmpdu drop : %llu", stats.mpdu_drop_cnt);
627*5113495bSYour Name 	DP_PRINT_STATS("\t\ttlv drop : %llu", stats.tlv_drop_cnt);
628*5113495bSYour Name }
629*5113495bSYour Name 
630*5113495bSYour Name #ifdef QCA_SUPPORT_LITE_MONITOR
dp_lite_mon_free_tx_peers(struct dp_pdev * pdev)631*5113495bSYour Name static void dp_lite_mon_free_tx_peers(struct dp_pdev *pdev)
632*5113495bSYour Name {
633*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
634*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
635*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
636*5113495bSYour Name 	struct dp_lite_mon_tx_config *lite_mon_tx_config;
637*5113495bSYour Name 
638*5113495bSYour Name 	lite_mon_tx_config = mon_pdev_be->lite_mon_tx_config;
639*5113495bSYour Name 	qdf_spin_lock_bh(&lite_mon_tx_config->lite_mon_tx_lock);
640*5113495bSYour Name 	dp_lite_mon_free_peers(pdev, &lite_mon_tx_config->tx_config);
641*5113495bSYour Name 	qdf_spin_unlock_bh(&lite_mon_tx_config->lite_mon_tx_lock);
642*5113495bSYour Name }
643*5113495bSYour Name #else
dp_lite_mon_free_tx_peers(struct dp_pdev * pdev)644*5113495bSYour Name static void dp_lite_mon_free_tx_peers(struct dp_pdev *pdev)
645*5113495bSYour Name {
646*5113495bSYour Name }
647*5113495bSYour Name #endif
648*5113495bSYour Name 
649*5113495bSYour Name /*
650*5113495bSYour Name  * dp_config_enh_tx_monitor_2_0()- API to enable/disable enhanced tx capture
651*5113495bSYour Name  * @pdev_handle: DP_PDEV handle
652*5113495bSYour Name  * @val: user provided value
653*5113495bSYour Name  *
654*5113495bSYour Name  * Return: QDF_STATUS
655*5113495bSYour Name  */
656*5113495bSYour Name QDF_STATUS
dp_config_enh_tx_monitor_2_0(struct dp_pdev * pdev,uint8_t val)657*5113495bSYour Name dp_config_enh_tx_monitor_2_0(struct dp_pdev *pdev, uint8_t val)
658*5113495bSYour Name {
659*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
660*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
661*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
662*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
663*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be =
664*5113495bSYour Name 			&mon_pdev_be->tx_monitor_be;
665*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
666*5113495bSYour Name 	uint16_t num_of_buffers;
667*5113495bSYour Name 	QDF_STATUS status;
668*5113495bSYour Name 
669*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
670*5113495bSYour Name 	switch (val) {
671*5113495bSYour Name 	case TX_MON_BE_DISABLE:
672*5113495bSYour Name 	{
673*5113495bSYour Name 		tx_mon_be->mode = TX_MON_BE_DISABLE;
674*5113495bSYour Name 		mon_pdev_be->tx_mon_mode = 0;
675*5113495bSYour Name 		mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_64B;
676*5113495bSYour Name 		/* Free any peers that were added for tx peer filtering */
677*5113495bSYour Name 		dp_lite_mon_free_tx_peers(pdev);
678*5113495bSYour Name 		break;
679*5113495bSYour Name 	}
680*5113495bSYour Name 	case TX_MON_BE_FULL_CAPTURE:
681*5113495bSYour Name 	{
682*5113495bSYour Name 		num_of_buffers = wlan_cfg_get_dp_soc_tx_mon_buf_ring_size(soc_cfg_ctx);
683*5113495bSYour Name 		status = dp_vdev_set_monitor_mode_buf_rings_tx_2_0(pdev,
684*5113495bSYour Name 								   num_of_buffers);
685*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
686*5113495bSYour Name 			dp_mon_err("Tx monitor buffer allocation failed");
687*5113495bSYour Name 			return status;
688*5113495bSYour Name 		}
689*5113495bSYour Name 		qdf_mem_zero(&tx_mon_be->stats,
690*5113495bSYour Name 			     sizeof(struct dp_tx_monitor_drop_stats));
691*5113495bSYour Name 		tx_mon_be->last_tsft = 0;
692*5113495bSYour Name 		tx_mon_be->last_ppdu_timestamp = 0;
693*5113495bSYour Name 		tx_mon_be->mode = TX_MON_BE_FULL_CAPTURE;
694*5113495bSYour Name 		mon_pdev_be->tx_mon_mode = 1;
695*5113495bSYour Name 		mon_pdev_be->tx_mon_filter_length = DEFAULT_DMA_LENGTH;
696*5113495bSYour Name 		break;
697*5113495bSYour Name 	}
698*5113495bSYour Name 	case TX_MON_BE_PEER_FILTER:
699*5113495bSYour Name 	{
700*5113495bSYour Name 		status = dp_vdev_set_monitor_mode_buf_rings_tx_2_0(pdev,
701*5113495bSYour Name 								   DP_MON_RING_FILL_LEVEL_DEFAULT);
702*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
703*5113495bSYour Name 			dp_mon_err("Tx monitor buffer allocation failed");
704*5113495bSYour Name 			return status;
705*5113495bSYour Name 		}
706*5113495bSYour Name 		tx_mon_be->mode = TX_MON_BE_PEER_FILTER;
707*5113495bSYour Name 		mon_pdev_be->tx_mon_mode = 2;
708*5113495bSYour Name 		mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_256B;
709*5113495bSYour Name 		break;
710*5113495bSYour Name 	}
711*5113495bSYour Name 	default:
712*5113495bSYour Name 	{
713*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
714*5113495bSYour Name 	}
715*5113495bSYour Name 	}
716*5113495bSYour Name 
717*5113495bSYour Name 	dp_mon_info("Tx monitor mode:%d mon_mode_flag:%d config_length:%d",
718*5113495bSYour Name 		    tx_mon_be->mode, mon_pdev_be->tx_mon_mode,
719*5113495bSYour Name 		    mon_pdev_be->tx_mon_filter_length);
720*5113495bSYour Name 
721*5113495bSYour Name 	dp_mon_filter_setup_tx_mon_mode(pdev);
722*5113495bSYour Name 	dp_tx_mon_filter_update(pdev);
723*5113495bSYour Name 
724*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
725*5113495bSYour Name }
726*5113495bSYour Name 
727*5113495bSYour Name /*
728*5113495bSYour Name  * dp_peer_set_tx_capture_enabled_2_0() -  add tx monitor peer filter
729*5113495bSYour Name  * @pdev: Datapath PDEV handle
730*5113495bSYour Name  * @peer: Datapath PEER handle
731*5113495bSYour Name  * @is_tx_pkt_cap_enable: flag for tx capture enable/disable
732*5113495bSYour Name  * @peer_mac: peer mac address
733*5113495bSYour Name  *
734*5113495bSYour Name  * Return: status
735*5113495bSYour Name  */
dp_peer_set_tx_capture_enabled_2_0(struct dp_pdev * pdev_handle,struct dp_peer * peer_handle,uint8_t is_tx_pkt_cap_enable,uint8_t * peer_mac)736*5113495bSYour Name QDF_STATUS dp_peer_set_tx_capture_enabled_2_0(struct dp_pdev *pdev_handle,
737*5113495bSYour Name 					      struct dp_peer *peer_handle,
738*5113495bSYour Name 					      uint8_t is_tx_pkt_cap_enable,
739*5113495bSYour Name 					      uint8_t *peer_mac)
740*5113495bSYour Name {
741*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
742*5113495bSYour Name }
743*5113495bSYour Name 
744*5113495bSYour Name #ifdef QCA_SUPPORT_LITE_MONITOR
dp_fill_lite_mon_vdev(struct cdp_tx_indication_info * tx_cap_info,struct dp_mon_pdev_be * mon_pdev_be)745*5113495bSYour Name static void dp_fill_lite_mon_vdev(struct cdp_tx_indication_info *tx_cap_info,
746*5113495bSYour Name 				  struct dp_mon_pdev_be *mon_pdev_be)
747*5113495bSYour Name {
748*5113495bSYour Name 	struct dp_lite_mon_config *config;
749*5113495bSYour Name 	struct dp_vdev *lite_mon_vdev;
750*5113495bSYour Name 
751*5113495bSYour Name 	config = &mon_pdev_be->lite_mon_tx_config->tx_config;
752*5113495bSYour Name 	lite_mon_vdev = config->lite_mon_vdev;
753*5113495bSYour Name 
754*5113495bSYour Name 	if (lite_mon_vdev)
755*5113495bSYour Name 		tx_cap_info->osif_vdev = lite_mon_vdev->osif_vdev;
756*5113495bSYour Name }
757*5113495bSYour Name 
758*5113495bSYour Name /**
759*5113495bSYour Name  * dp_lite_mon_filter_ppdu() - Filter frames at ppdu level
760*5113495bSYour Name  * @mpdu_count: mpdu count in the nbuf queue
761*5113495bSYour Name  * @level: Lite monitor filter level
762*5113495bSYour Name  *
763*5113495bSYour Name  * Return: QDF_STATUS
764*5113495bSYour Name  */
765*5113495bSYour Name static inline QDF_STATUS
dp_lite_mon_filter_ppdu(uint8_t mpdu_count,uint8_t level)766*5113495bSYour Name dp_lite_mon_filter_ppdu(uint8_t mpdu_count, uint8_t level)
767*5113495bSYour Name {
768*5113495bSYour Name 	if (level == CDP_LITE_MON_LEVEL_PPDU && mpdu_count > 1)
769*5113495bSYour Name 		return QDF_STATUS_E_CANCELED;
770*5113495bSYour Name 
771*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
772*5113495bSYour Name }
773*5113495bSYour Name 
774*5113495bSYour Name /**
775*5113495bSYour Name  * dp_lite_mon_filter_peer() - filter frames with peer
776*5113495bSYour Name  * @config: Lite monitor configuration
777*5113495bSYour Name  * @wh: Pointer to ieee80211_frame
778*5113495bSYour Name  *
779*5113495bSYour Name  * Return: QDF_STATUS
780*5113495bSYour Name  */
781*5113495bSYour Name static inline QDF_STATUS
dp_lite_mon_filter_peer(struct dp_lite_mon_tx_config * config,struct ieee80211_frame_min_one * wh)782*5113495bSYour Name dp_lite_mon_filter_peer(struct dp_lite_mon_tx_config *config,
783*5113495bSYour Name 			struct ieee80211_frame_min_one *wh)
784*5113495bSYour Name {
785*5113495bSYour Name 	struct dp_lite_mon_peer *peer;
786*5113495bSYour Name 
787*5113495bSYour Name 	/* Return here if sw peer filtering is not required or if peer count
788*5113495bSYour Name 	 * is zero
789*5113495bSYour Name 	 */
790*5113495bSYour Name 	if (!config->sw_peer_filtering || !config->tx_config.peer_count)
791*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
792*5113495bSYour Name 
793*5113495bSYour Name 	TAILQ_FOREACH(peer, &config->tx_config.peer_list, peer_list_elem) {
794*5113495bSYour Name 		if (!qdf_mem_cmp(&peer->peer_mac.raw[0],
795*5113495bSYour Name 				 &wh->i_addr1[0], QDF_MAC_ADDR_SIZE)) {
796*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
797*5113495bSYour Name 		}
798*5113495bSYour Name 	}
799*5113495bSYour Name 
800*5113495bSYour Name 	return QDF_STATUS_E_ABORTED;
801*5113495bSYour Name }
802*5113495bSYour Name 
803*5113495bSYour Name /**
804*5113495bSYour Name  * dp_lite_mon_filter_subtype() - filter frames with subtype
805*5113495bSYour Name  * @config: Lite monitor configuration
806*5113495bSYour Name  * @wh: Pointer to ieee80211_frame
807*5113495bSYour Name  *
808*5113495bSYour Name  * Return: QDF_STATUS
809*5113495bSYour Name  */
810*5113495bSYour Name static inline QDF_STATUS
dp_lite_mon_filter_subtype(struct dp_lite_mon_tx_config * config,struct ieee80211_frame_min_one * wh)811*5113495bSYour Name dp_lite_mon_filter_subtype(struct dp_lite_mon_tx_config *config,
812*5113495bSYour Name 			   struct ieee80211_frame_min_one *wh)
813*5113495bSYour Name {
814*5113495bSYour Name 	uint16_t mgmt_filter, ctrl_filter, data_filter, type, subtype;
815*5113495bSYour Name 	uint8_t is_mcast = 0;
816*5113495bSYour Name 
817*5113495bSYour Name 	/* Return here if subtype filtering is not required */
818*5113495bSYour Name 	if (!config->subtype_filtering)
819*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
820*5113495bSYour Name 
821*5113495bSYour Name 	mgmt_filter = config->tx_config.mgmt_filter[DP_MON_FRM_FILTER_MODE_FP];
822*5113495bSYour Name 	ctrl_filter = config->tx_config.ctrl_filter[DP_MON_FRM_FILTER_MODE_FP];
823*5113495bSYour Name 	data_filter = config->tx_config.data_filter[DP_MON_FRM_FILTER_MODE_FP];
824*5113495bSYour Name 
825*5113495bSYour Name 	type = (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
826*5113495bSYour Name 	subtype = ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) >>
827*5113495bSYour Name 		IEEE80211_FC0_SUBTYPE_SHIFT);
828*5113495bSYour Name 
829*5113495bSYour Name 	switch (type) {
830*5113495bSYour Name 	case QDF_IEEE80211_FC0_TYPE_MGT:
831*5113495bSYour Name 		if (mgmt_filter >> subtype & 0x1)
832*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
833*5113495bSYour Name 		else
834*5113495bSYour Name 			return QDF_STATUS_E_ABORTED;
835*5113495bSYour Name 	case QDF_IEEE80211_FC0_TYPE_CTL:
836*5113495bSYour Name 		if (ctrl_filter >> subtype & 0x1)
837*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
838*5113495bSYour Name 		else
839*5113495bSYour Name 			return QDF_STATUS_E_ABORTED;
840*5113495bSYour Name 	case QDF_IEEE80211_FC0_TYPE_DATA:
841*5113495bSYour Name 		is_mcast = DP_FRAME_IS_MULTICAST(wh->i_addr1);
842*5113495bSYour Name 		if ((is_mcast && (data_filter & FILTER_DATA_MCAST)) ||
843*5113495bSYour Name 		    (!is_mcast && (data_filter & FILTER_DATA_UCAST)))
844*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
845*5113495bSYour Name 		return QDF_STATUS_E_ABORTED;
846*5113495bSYour Name 	default:
847*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
848*5113495bSYour Name 	}
849*5113495bSYour Name }
850*5113495bSYour Name 
851*5113495bSYour Name /**
852*5113495bSYour Name  * dp_lite_mon_filter_peer_subtype() - filter frames with subtype and peer
853*5113495bSYour Name  * @config: Lite monitor configuration
854*5113495bSYour Name  * @buf: Pointer to nbuf
855*5113495bSYour Name  *
856*5113495bSYour Name  * Return: QDF_STATUS
857*5113495bSYour Name  */
858*5113495bSYour Name static inline QDF_STATUS
dp_lite_mon_filter_peer_subtype(struct dp_lite_mon_tx_config * config,qdf_nbuf_t buf)859*5113495bSYour Name dp_lite_mon_filter_peer_subtype(struct dp_lite_mon_tx_config *config,
860*5113495bSYour Name 				qdf_nbuf_t buf)
861*5113495bSYour Name {
862*5113495bSYour Name 	struct ieee80211_frame_min_one *wh;
863*5113495bSYour Name 	qdf_nbuf_t nbuf;
864*5113495bSYour Name 	QDF_STATUS ret;
865*5113495bSYour Name 
866*5113495bSYour Name 	/* Return here if subtype and peer filtering is not required */
867*5113495bSYour Name 	if (!config->subtype_filtering && !config->sw_peer_filtering &&
868*5113495bSYour Name 	    !config->tx_config.peer_count)
869*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
870*5113495bSYour Name 
871*5113495bSYour Name 	if (dp_tx_mon_nbuf_get_num_frag(buf)) {
872*5113495bSYour Name 		wh = (struct ieee80211_frame_min_one *)qdf_nbuf_get_frag_addr(buf, 0);
873*5113495bSYour Name 	} else {
874*5113495bSYour Name 		nbuf = qdf_nbuf_get_ext_list(buf);
875*5113495bSYour Name 		if (nbuf)
876*5113495bSYour Name 			wh = (struct ieee80211_frame_min_one *)qdf_nbuf_data(nbuf);
877*5113495bSYour Name 		else
878*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
879*5113495bSYour Name 	}
880*5113495bSYour Name 
881*5113495bSYour Name 	ret = dp_lite_mon_filter_subtype(config, wh);
882*5113495bSYour Name 	if (ret)
883*5113495bSYour Name 		return ret;
884*5113495bSYour Name 
885*5113495bSYour Name 	ret = dp_lite_mon_filter_peer(config, wh);
886*5113495bSYour Name 	if (ret)
887*5113495bSYour Name 		return ret;
888*5113495bSYour Name 
889*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
890*5113495bSYour Name }
891*5113495bSYour Name 
892*5113495bSYour Name /**
893*5113495bSYour Name  * dp_tx_lite_mon_filtering() - Additional filtering for lite monitor
894*5113495bSYour Name  * @pdev: Pointer to physical device
895*5113495bSYour Name  * @tx_ppdu_info: pointer to dp_tx_ppdu_info structure
896*5113495bSYour Name  * @buf: qdf nbuf structure of buffer
897*5113495bSYour Name  * @mpdu_count: mpdu count in the nbuf queue
898*5113495bSYour Name  *
899*5113495bSYour Name  * Return: QDF_STATUS
900*5113495bSYour Name  */
901*5113495bSYour Name static inline QDF_STATUS
dp_tx_lite_mon_filtering(struct dp_pdev * pdev,struct dp_tx_ppdu_info * tx_ppdu_info,qdf_nbuf_t buf,int mpdu_count)902*5113495bSYour Name dp_tx_lite_mon_filtering(struct dp_pdev *pdev,
903*5113495bSYour Name 			 struct dp_tx_ppdu_info *tx_ppdu_info,
904*5113495bSYour Name 			 qdf_nbuf_t buf, int mpdu_count)
905*5113495bSYour Name {
906*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
907*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
908*5113495bSYour Name 		dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
909*5113495bSYour Name 	struct dp_lite_mon_tx_config *config =
910*5113495bSYour Name 		mon_pdev_be->lite_mon_tx_config;
911*5113495bSYour Name 	QDF_STATUS ret;
912*5113495bSYour Name 
913*5113495bSYour Name 	if (!dp_lite_mon_is_tx_enabled(mon_pdev) &&
914*5113495bSYour Name 	    !config->tx_config.peer_count)
915*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
916*5113495bSYour Name 
917*5113495bSYour Name 	/* PPDU level filtering */
918*5113495bSYour Name 	ret = dp_lite_mon_filter_ppdu(mpdu_count, config->tx_config.level);
919*5113495bSYour Name 	if (ret)
920*5113495bSYour Name 		return ret;
921*5113495bSYour Name 
922*5113495bSYour Name 	/* Subtype and peer filtering */
923*5113495bSYour Name 	ret = dp_lite_mon_filter_peer_subtype(config, buf);
924*5113495bSYour Name 	if (ret)
925*5113495bSYour Name 		return ret;
926*5113495bSYour Name 
927*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
928*5113495bSYour Name }
929*5113495bSYour Name 
930*5113495bSYour Name #else
dp_fill_lite_mon_vdev(struct cdp_tx_indication_info * tx_cap_info,struct dp_mon_pdev_be * mon_pdev_be)931*5113495bSYour Name static void dp_fill_lite_mon_vdev(struct cdp_tx_indication_info *tx_cap_info,
932*5113495bSYour Name 				  struct dp_mon_pdev_be *mon_pdev_be)
933*5113495bSYour Name {
934*5113495bSYour Name }
935*5113495bSYour Name 
936*5113495bSYour Name /**
937*5113495bSYour Name  * dp_tx_lite_mon_filtering() - Additional filtering for lite monitor
938*5113495bSYour Name  * @pdev: Pointer to physical device
939*5113495bSYour Name  * @tx_ppdu_info: pointer to dp_tx_ppdu_info structure
940*5113495bSYour Name  * @buf: qdf nbuf structure of buffer
941*5113495bSYour Name  * @mpdu_count: mpdu count in the nbuf queue
942*5113495bSYour Name  *
943*5113495bSYour Name  * Return: QDF_STATUS
944*5113495bSYour Name  */
945*5113495bSYour Name static inline QDF_STATUS
dp_tx_lite_mon_filtering(struct dp_pdev * pdev,struct dp_tx_ppdu_info * tx_ppdu_info,qdf_nbuf_t buf,int mpdu_count)946*5113495bSYour Name dp_tx_lite_mon_filtering(struct dp_pdev *pdev,
947*5113495bSYour Name 			 struct dp_tx_ppdu_info *tx_ppdu_info,
948*5113495bSYour Name 			 qdf_nbuf_t buf, int mpdu_count)
949*5113495bSYour Name {
950*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
951*5113495bSYour Name }
952*5113495bSYour Name #endif
953*5113495bSYour Name 
954*5113495bSYour Name #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
955*5113495bSYour Name /**
956*5113495bSYour Name  * dp_tx_mon_lpc_type_filtering() - Additional filtering for lpc
957*5113495bSYour Name  * @pdev: Pointer to physical device
958*5113495bSYour Name  * @tx_ppdu_info: pointer to dp_tx_ppdu_info structure
959*5113495bSYour Name  * @buf: qdf nbuf structure of buffer
960*5113495bSYour Name  *
961*5113495bSYour Name  * Return: QDF_STATUS
962*5113495bSYour Name  */
963*5113495bSYour Name static inline QDF_STATUS
dp_tx_mon_lpc_type_filtering(struct dp_pdev * pdev,struct dp_tx_ppdu_info * tx_ppdu_info,qdf_nbuf_t buf)964*5113495bSYour Name dp_tx_mon_lpc_type_filtering(struct dp_pdev *pdev,
965*5113495bSYour Name 			     struct dp_tx_ppdu_info *tx_ppdu_info,
966*5113495bSYour Name 			     qdf_nbuf_t buf)
967*5113495bSYour Name {
968*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
969*5113495bSYour Name 	qdf_nbuf_t nbuf;
970*5113495bSYour Name 	struct ieee80211_frame_min_one *wh;
971*5113495bSYour Name 	uint16_t mgmt_filter, ctrl_filter, data_filter, type;
972*5113495bSYour Name 
973*5113495bSYour Name 	if (qdf_unlikely(!IS_LOCAL_PKT_CAPTURE_RUNNING(mon_pdev,
974*5113495bSYour Name 			is_local_pkt_capture_running)))
975*5113495bSYour Name 		return QDF_STATUS_E_ABORTED;
976*5113495bSYour Name 
977*5113495bSYour Name 	if (dp_tx_mon_nbuf_get_num_frag(buf)) {
978*5113495bSYour Name 		wh = (struct ieee80211_frame_min_one *)qdf_nbuf_get_frag_addr(buf, 0);
979*5113495bSYour Name 	} else {
980*5113495bSYour Name 		nbuf = qdf_nbuf_get_ext_list(buf);
981*5113495bSYour Name 		if (nbuf)
982*5113495bSYour Name 			wh = (struct ieee80211_frame_min_one *)qdf_nbuf_data(nbuf);
983*5113495bSYour Name 		else
984*5113495bSYour Name 			return QDF_STATUS_E_ABORTED;
985*5113495bSYour Name 	}
986*5113495bSYour Name 
987*5113495bSYour Name 	mgmt_filter = mon_pdev->fp_mgmt_filter;
988*5113495bSYour Name 	ctrl_filter = mon_pdev->fp_ctrl_filter;
989*5113495bSYour Name 	data_filter = mon_pdev->fp_data_filter;
990*5113495bSYour Name 
991*5113495bSYour Name 	type = (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
992*5113495bSYour Name 
993*5113495bSYour Name 	switch (type) {
994*5113495bSYour Name 	case QDF_IEEE80211_FC0_TYPE_MGT:
995*5113495bSYour Name 		return mgmt_filter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_ABORTED;
996*5113495bSYour Name 	case QDF_IEEE80211_FC0_TYPE_CTL:
997*5113495bSYour Name 		return ctrl_filter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_ABORTED;
998*5113495bSYour Name 	case QDF_IEEE80211_FC0_TYPE_DATA:
999*5113495bSYour Name 		return data_filter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_ABORTED;
1000*5113495bSYour Name 	default:
1001*5113495bSYour Name 		return QDF_STATUS_E_ABORTED;
1002*5113495bSYour Name 	}
1003*5113495bSYour Name 
1004*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1005*5113495bSYour Name }
1006*5113495bSYour Name 
1007*5113495bSYour Name static int
dp_tx_handle_local_pkt_capture(struct dp_pdev * pdev,qdf_nbuf_t nbuf)1008*5113495bSYour Name dp_tx_handle_local_pkt_capture(struct dp_pdev *pdev, qdf_nbuf_t nbuf)
1009*5113495bSYour Name {
1010*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev;
1011*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1012*5113495bSYour Name 
1013*5113495bSYour Name 	if (!mon_pdev->mvdev) {
1014*5113495bSYour Name 		dp_mon_err("Monitor vdev is NULL !!");
1015*5113495bSYour Name 		return 1;
1016*5113495bSYour Name 	}
1017*5113495bSYour Name 
1018*5113495bSYour Name 	mon_vdev = mon_pdev->mvdev->monitor_vdev;
1019*5113495bSYour Name 
1020*5113495bSYour Name 	if (mon_vdev && mon_vdev->osif_rx_mon)
1021*5113495bSYour Name 		mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev, nbuf, NULL);
1022*5113495bSYour Name 
1023*5113495bSYour Name 	return 0;
1024*5113495bSYour Name }
1025*5113495bSYour Name #else
1026*5113495bSYour Name static int
dp_tx_handle_local_pkt_capture(struct dp_pdev * pdev,qdf_nbuf_t nbuf)1027*5113495bSYour Name dp_tx_handle_local_pkt_capture(struct dp_pdev *pdev, qdf_nbuf_t nbuf)
1028*5113495bSYour Name {
1029*5113495bSYour Name 	return 0;
1030*5113495bSYour Name }
1031*5113495bSYour Name 
1032*5113495bSYour Name static inline QDF_STATUS
dp_tx_mon_lpc_type_filtering(struct dp_pdev * pdev,struct dp_tx_ppdu_info * tx_ppdu_info,qdf_nbuf_t buf)1033*5113495bSYour Name dp_tx_mon_lpc_type_filtering(struct dp_pdev *pdev,
1034*5113495bSYour Name 			     struct dp_tx_ppdu_info *tx_ppdu_info,
1035*5113495bSYour Name 			     qdf_nbuf_t buf)
1036*5113495bSYour Name {
1037*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1038*5113495bSYour Name }
1039*5113495bSYour Name 
1040*5113495bSYour Name #endif
1041*5113495bSYour Name 
1042*5113495bSYour Name /**
1043*5113495bSYour Name  * dp_tx_mon_send_to_stack() - API to send to stack
1044*5113495bSYour Name  * @pdev: pdev Handle
1045*5113495bSYour Name  * @mpdu: pointer to mpdu
1046*5113495bSYour Name  * @num_frag: number of frag in mpdu
1047*5113495bSYour Name  * @ppdu_id: ppdu id of the mpdu
1048*5113495bSYour Name  *
1049*5113495bSYour Name  * Return: void
1050*5113495bSYour Name  */
1051*5113495bSYour Name static void
dp_tx_mon_send_to_stack(struct dp_pdev * pdev,qdf_nbuf_t mpdu,uint32_t num_frag,uint32_t ppdu_id)1052*5113495bSYour Name dp_tx_mon_send_to_stack(struct dp_pdev *pdev, qdf_nbuf_t mpdu,
1053*5113495bSYour Name 			uint32_t num_frag, uint32_t ppdu_id)
1054*5113495bSYour Name {
1055*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1056*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
1057*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1058*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be =
1059*5113495bSYour Name 			&mon_pdev_be->tx_monitor_be;
1060*5113495bSYour Name 	struct cdp_tx_indication_info tx_capture_info = {0};
1061*5113495bSYour Name 
1062*5113495bSYour Name 	tx_mon_be->stats.pkt_buf_to_stack += num_frag;
1063*5113495bSYour Name 
1064*5113495bSYour Name 	tx_capture_info.radiotap_done = 1;
1065*5113495bSYour Name 	tx_capture_info.mpdu_nbuf = mpdu;
1066*5113495bSYour Name 	tx_capture_info.mpdu_info.ppdu_id = ppdu_id;
1067*5113495bSYour Name 
1068*5113495bSYour Name 	if (qdf_unlikely(IS_LOCAL_PKT_CAPTURE_RUNNING(mon_pdev,
1069*5113495bSYour Name 			is_local_pkt_capture_running))) {
1070*5113495bSYour Name 		int ret = dp_tx_handle_local_pkt_capture(pdev, mpdu);
1071*5113495bSYour Name 
1072*5113495bSYour Name 		/*
1073*5113495bSYour Name 		 * On error, free the memory here,
1074*5113495bSYour Name 		 * otherwise it will be freed by the network stack
1075*5113495bSYour Name 		 */
1076*5113495bSYour Name 		if (ret)
1077*5113495bSYour Name 			qdf_nbuf_free(mpdu);
1078*5113495bSYour Name 		return;
1079*5113495bSYour Name 	} else if (!dp_lite_mon_is_tx_enabled(mon_pdev)) {
1080*5113495bSYour Name 		dp_wdi_event_handler(WDI_EVENT_TX_PKT_CAPTURE,
1081*5113495bSYour Name 				     pdev->soc,
1082*5113495bSYour Name 				     &tx_capture_info,
1083*5113495bSYour Name 				     HTT_INVALID_PEER,
1084*5113495bSYour Name 				     WDI_NO_VAL,
1085*5113495bSYour Name 				     pdev->pdev_id);
1086*5113495bSYour Name 	} else {
1087*5113495bSYour Name 		dp_fill_lite_mon_vdev(&tx_capture_info, mon_pdev_be);
1088*5113495bSYour Name 		dp_wdi_event_handler(WDI_EVENT_LITE_MON_TX,
1089*5113495bSYour Name 				     pdev->soc,
1090*5113495bSYour Name 				     &tx_capture_info,
1091*5113495bSYour Name 				     HTT_INVALID_PEER,
1092*5113495bSYour Name 				     WDI_NO_VAL,
1093*5113495bSYour Name 				     pdev->pdev_id);
1094*5113495bSYour Name 	}
1095*5113495bSYour Name 	if (tx_capture_info.mpdu_nbuf)
1096*5113495bSYour Name 		qdf_nbuf_free(tx_capture_info.mpdu_nbuf);
1097*5113495bSYour Name }
1098*5113495bSYour Name 
1099*5113495bSYour Name /**
1100*5113495bSYour Name  * dp_tx_mon_send_per_usr_mpdu() - API to send per usr mpdu to stack
1101*5113495bSYour Name  * @pdev: pdev Handle
1102*5113495bSYour Name  * @ppdu_info: pointer to dp_tx_ppdu_info
1103*5113495bSYour Name  * @user_idx: current user index
1104*5113495bSYour Name  *
1105*5113495bSYour Name  * Return: void
1106*5113495bSYour Name  */
1107*5113495bSYour Name static void
dp_tx_mon_send_per_usr_mpdu(struct dp_pdev * pdev,struct dp_tx_ppdu_info * ppdu_info,uint8_t user_idx)1108*5113495bSYour Name dp_tx_mon_send_per_usr_mpdu(struct dp_pdev *pdev,
1109*5113495bSYour Name 			    struct dp_tx_ppdu_info *ppdu_info,
1110*5113495bSYour Name 			    uint8_t user_idx)
1111*5113495bSYour Name {
1112*5113495bSYour Name 	qdf_nbuf_queue_t *usr_mpdu_q = NULL;
1113*5113495bSYour Name 	qdf_nbuf_t buf = NULL;
1114*5113495bSYour Name 	uint8_t mpdu_count = 0;
1115*5113495bSYour Name 
1116*5113495bSYour Name 	usr_mpdu_q = &TXMON_PPDU_USR(ppdu_info, user_idx, mpdu_q);
1117*5113495bSYour Name 
1118*5113495bSYour Name 	while ((buf = qdf_nbuf_queue_remove(usr_mpdu_q)) != NULL) {
1119*5113495bSYour Name 		uint32_t num_frag = dp_tx_mon_nbuf_get_num_frag(buf);
1120*5113495bSYour Name 
1121*5113495bSYour Name 		ppdu_info->hal_txmon.rx_status.rx_user_status =
1122*5113495bSYour Name 				&ppdu_info->hal_txmon.rx_user_status[user_idx];
1123*5113495bSYour Name 
1124*5113495bSYour Name 		if (dp_tx_lite_mon_filtering(pdev, ppdu_info, buf,
1125*5113495bSYour Name 					     ++mpdu_count) ||
1126*5113495bSYour Name 		    dp_tx_mon_lpc_type_filtering(pdev, ppdu_info, buf)) {
1127*5113495bSYour Name 			qdf_nbuf_free(buf);
1128*5113495bSYour Name 			continue;
1129*5113495bSYour Name 		}
1130*5113495bSYour Name 
1131*5113495bSYour Name 		qdf_nbuf_update_radiotap(&ppdu_info->hal_txmon.rx_status,
1132*5113495bSYour Name 					 buf, qdf_nbuf_headroom(buf));
1133*5113495bSYour Name 
1134*5113495bSYour Name 		dp_tx_mon_send_to_stack(pdev, buf, num_frag,
1135*5113495bSYour Name 					TXMON_PPDU(ppdu_info, ppdu_id));
1136*5113495bSYour Name 	}
1137*5113495bSYour Name }
1138*5113495bSYour Name 
1139*5113495bSYour Name #define PHY_MEDIUM_MHZ	960
1140*5113495bSYour Name #define PHY_TIMESTAMP_WRAP (0xFFFFFFFF / PHY_MEDIUM_MHZ)
1141*5113495bSYour Name 
1142*5113495bSYour Name /**
1143*5113495bSYour Name  * dp_populate_tsft_from_phy_timestamp() - API to get tsft from phy timestamp
1144*5113495bSYour Name  * @pdev: pdev Handle
1145*5113495bSYour Name  * @ppdu_info: ppdi_info Handle
1146*5113495bSYour Name  *
1147*5113495bSYour Name  * Return: QDF_STATUS
1148*5113495bSYour Name  */
1149*5113495bSYour Name static QDF_STATUS
dp_populate_tsft_from_phy_timestamp(struct dp_pdev * pdev,struct dp_tx_ppdu_info * ppdu_info)1150*5113495bSYour Name dp_populate_tsft_from_phy_timestamp(struct dp_pdev *pdev,
1151*5113495bSYour Name 				    struct dp_tx_ppdu_info *ppdu_info)
1152*5113495bSYour Name {
1153*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1154*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
1155*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1156*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be =
1157*5113495bSYour Name 			&mon_pdev_be->tx_monitor_be;
1158*5113495bSYour Name 	uint64_t tsft = 0;
1159*5113495bSYour Name 	uint32_t ppdu_timestamp = 0;
1160*5113495bSYour Name 
1161*5113495bSYour Name 	tsft = TXMON_PPDU_COM(ppdu_info, tsft);
1162*5113495bSYour Name 	ppdu_timestamp = TXMON_PPDU_COM(ppdu_info, ppdu_timestamp);
1163*5113495bSYour Name 
1164*5113495bSYour Name 	if (tsft && ppdu_timestamp) {
1165*5113495bSYour Name 		/* update tsft and ppdu timestamp */
1166*5113495bSYour Name 		tx_mon_be->last_tsft = tsft;
1167*5113495bSYour Name 		tx_mon_be->last_ppdu_timestamp = ppdu_timestamp;
1168*5113495bSYour Name 	} else if (!tx_mon_be->last_ppdu_timestamp || !tx_mon_be->last_tsft) {
1169*5113495bSYour Name 		return QDF_STATUS_E_EMPTY;
1170*5113495bSYour Name 	}
1171*5113495bSYour Name 
1172*5113495bSYour Name 	if (!tsft && ppdu_timestamp) {
1173*5113495bSYour Name 		/* response window */
1174*5113495bSYour Name 		uint32_t cur_usec = ppdu_timestamp / PHY_MEDIUM_MHZ;
1175*5113495bSYour Name 		uint32_t last_usec = (tx_mon_be->last_ppdu_timestamp /
1176*5113495bSYour Name 				      PHY_MEDIUM_MHZ);
1177*5113495bSYour Name 		uint32_t diff = 0;
1178*5113495bSYour Name 
1179*5113495bSYour Name 		if (last_usec < cur_usec) {
1180*5113495bSYour Name 			diff = cur_usec - last_usec;
1181*5113495bSYour Name 			tsft = tx_mon_be->last_tsft + diff;
1182*5113495bSYour Name 		} else {
1183*5113495bSYour Name 			diff = (PHY_TIMESTAMP_WRAP - last_usec) + cur_usec;
1184*5113495bSYour Name 			tsft = tx_mon_be->last_tsft + diff;
1185*5113495bSYour Name 		}
1186*5113495bSYour Name 		TXMON_PPDU_COM(ppdu_info, tsft) = tsft;
1187*5113495bSYour Name 		/* update tsft and ppdu timestamp */
1188*5113495bSYour Name 		tx_mon_be->last_tsft = tsft;
1189*5113495bSYour Name 		tx_mon_be->last_ppdu_timestamp = ppdu_timestamp;
1190*5113495bSYour Name 	}
1191*5113495bSYour Name 
1192*5113495bSYour Name 	if (!TXMON_PPDU_COM(ppdu_info, tsft) &&
1193*5113495bSYour Name 	    !TXMON_PPDU_COM(ppdu_info, ppdu_timestamp))
1194*5113495bSYour Name 		return QDF_STATUS_E_EMPTY;
1195*5113495bSYour Name 
1196*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1197*5113495bSYour Name }
1198*5113495bSYour Name 
1199*5113495bSYour Name /**
1200*5113495bSYour Name  * dp_tx_mon_update_channel_freq() - API to update channel frequency and number
1201*5113495bSYour Name  * @pdev: pdev Handle
1202*5113495bSYour Name  * @soc: soc Handle
1203*5113495bSYour Name  * @freq: Frequency
1204*5113495bSYour Name  *
1205*5113495bSYour Name  * Return: void
1206*5113495bSYour Name  */
1207*5113495bSYour Name static inline void
dp_tx_mon_update_channel_freq(struct dp_pdev * pdev,struct dp_soc * soc,uint16_t freq)1208*5113495bSYour Name dp_tx_mon_update_channel_freq(struct dp_pdev *pdev, struct dp_soc *soc,
1209*5113495bSYour Name 			      uint16_t freq)
1210*5113495bSYour Name {
1211*5113495bSYour Name 	if (soc && soc->cdp_soc.ol_ops->freq_to_channel) {
1212*5113495bSYour Name 		uint8_t c_num;
1213*5113495bSYour Name 
1214*5113495bSYour Name 		c_num = soc->cdp_soc.ol_ops->freq_to_channel(soc->ctrl_psoc,
1215*5113495bSYour Name 							     pdev->pdev_id,
1216*5113495bSYour Name 							     freq);
1217*5113495bSYour Name 		pdev->operating_channel.num = c_num;
1218*5113495bSYour Name 	}
1219*5113495bSYour Name 
1220*5113495bSYour Name 	if (soc && soc->cdp_soc.ol_ops->freq_to_band) {
1221*5113495bSYour Name 		uint8_t band;
1222*5113495bSYour Name 
1223*5113495bSYour Name 		band = soc->cdp_soc.ol_ops->freq_to_band(soc->ctrl_psoc,
1224*5113495bSYour Name 							 pdev->pdev_id,
1225*5113495bSYour Name 							 freq);
1226*5113495bSYour Name 		pdev->operating_channel.band = band;
1227*5113495bSYour Name 	}
1228*5113495bSYour Name }
1229*5113495bSYour Name 
1230*5113495bSYour Name /**
1231*5113495bSYour Name  * dp_tx_mon_update_radiotap() - API to update radiotap information
1232*5113495bSYour Name  * @pdev: pdev Handle
1233*5113495bSYour Name  * @ppdu_info: pointer to dp_tx_ppdu_info
1234*5113495bSYour Name  *
1235*5113495bSYour Name  * Return: void
1236*5113495bSYour Name  */
1237*5113495bSYour Name static void
dp_tx_mon_update_radiotap(struct dp_pdev * pdev,struct dp_tx_ppdu_info * ppdu_info)1238*5113495bSYour Name dp_tx_mon_update_radiotap(struct dp_pdev *pdev,
1239*5113495bSYour Name 			  struct dp_tx_ppdu_info *ppdu_info)
1240*5113495bSYour Name {
1241*5113495bSYour Name 	uint32_t usr_idx = 0;
1242*5113495bSYour Name 	uint32_t num_users = 0;
1243*5113495bSYour Name 
1244*5113495bSYour Name 	num_users = TXMON_PPDU_HAL(ppdu_info, num_users);
1245*5113495bSYour Name 
1246*5113495bSYour Name 	if (qdf_unlikely(TXMON_PPDU_COM(ppdu_info, chan_freq) == 0 &&
1247*5113495bSYour Name 			 TXMON_PPDU_COM(ppdu_info, chan_num) == 0)) {
1248*5113495bSYour Name 		TXMON_PPDU_COM(ppdu_info, chan_freq) =
1249*5113495bSYour Name 				pdev->operating_channel.freq;
1250*5113495bSYour Name 		TXMON_PPDU_COM(ppdu_info, chan_num) =
1251*5113495bSYour Name 				pdev->operating_channel.num;
1252*5113495bSYour Name 	} else if (TXMON_PPDU_COM(ppdu_info, chan_freq) != 0 &&
1253*5113495bSYour Name 		   TXMON_PPDU_COM(ppdu_info, chan_num) == 0) {
1254*5113495bSYour Name 		uint16_t freq = TXMON_PPDU_COM(ppdu_info, chan_freq);
1255*5113495bSYour Name 
1256*5113495bSYour Name 		if (qdf_unlikely(pdev->operating_channel.freq != freq)) {
1257*5113495bSYour Name 			dp_tx_mon_update_channel_freq(pdev, pdev->soc, freq);
1258*5113495bSYour Name 			pdev->operating_channel.freq = freq;
1259*5113495bSYour Name 		}
1260*5113495bSYour Name 		TXMON_PPDU_COM(ppdu_info,
1261*5113495bSYour Name 			       chan_num) = pdev->operating_channel.num;
1262*5113495bSYour Name 	}
1263*5113495bSYour Name 
1264*5113495bSYour Name 	if (QDF_STATUS_SUCCESS !=
1265*5113495bSYour Name 	    dp_populate_tsft_from_phy_timestamp(pdev, ppdu_info))
1266*5113495bSYour Name 		return;
1267*5113495bSYour Name 
1268*5113495bSYour Name 	/* update mlo timestamp */
1269*5113495bSYour Name 	TXMON_PPDU_COM(ppdu_info, tsft) =
1270*5113495bSYour Name 			(TXMON_PPDU_COM(ppdu_info, tsft) +
1271*5113495bSYour Name 			 pdev->timestamp.mlo_offset_lo_us +
1272*5113495bSYour Name 			 ((uint64_t)pdev->timestamp.mlo_offset_hi_us << 32));
1273*5113495bSYour Name 
1274*5113495bSYour Name 	for (usr_idx = 0; usr_idx < num_users; usr_idx++) {
1275*5113495bSYour Name 		qdf_nbuf_queue_t *mpdu_q = NULL;
1276*5113495bSYour Name 
1277*5113495bSYour Name 		/* set AMPDU flag if number mpdu is more than 1 */
1278*5113495bSYour Name 		mpdu_q = &TXMON_PPDU_USR(ppdu_info, usr_idx, mpdu_q);
1279*5113495bSYour Name 		if (mpdu_q && (qdf_nbuf_queue_len(mpdu_q) > 1)) {
1280*5113495bSYour Name 			TXMON_PPDU_COM(ppdu_info,
1281*5113495bSYour Name 				       rs_flags) |= IEEE80211_AMPDU_FLAG;
1282*5113495bSYour Name 			TXMON_PPDU_USR(ppdu_info, usr_idx, is_ampdu) = 1;
1283*5113495bSYour Name 		}
1284*5113495bSYour Name 
1285*5113495bSYour Name 		if (qdf_unlikely(!TXMON_PPDU_COM(ppdu_info, rate))) {
1286*5113495bSYour Name 			uint32_t rate = 0;
1287*5113495bSYour Name 			uint32_t rix = 0;
1288*5113495bSYour Name 			uint16_t ratecode = 0;
1289*5113495bSYour Name 
1290*5113495bSYour Name 			rate = dp_getrateindex(TXMON_PPDU_COM(ppdu_info, sgi),
1291*5113495bSYour Name 					       TXMON_PPDU_USR(ppdu_info,
1292*5113495bSYour Name 							      usr_idx, mcs),
1293*5113495bSYour Name 					       TXMON_PPDU_COM(ppdu_info, nss),
1294*5113495bSYour Name 					       TXMON_PPDU_COM(ppdu_info,
1295*5113495bSYour Name 							      preamble_type),
1296*5113495bSYour Name 					       TXMON_PPDU_COM(ppdu_info, bw),
1297*5113495bSYour Name 					       0,
1298*5113495bSYour Name 					       &rix, &ratecode);
1299*5113495bSYour Name 
1300*5113495bSYour Name 			/* update rate */
1301*5113495bSYour Name 			TXMON_PPDU_COM(ppdu_info, rate) = rate;
1302*5113495bSYour Name 		}
1303*5113495bSYour Name 
1304*5113495bSYour Name 		dp_tx_mon_send_per_usr_mpdu(pdev, ppdu_info, usr_idx);
1305*5113495bSYour Name 	}
1306*5113495bSYour Name }
1307*5113495bSYour Name 
1308*5113495bSYour Name /**
1309*5113495bSYour Name  * dp_tx_mon_ppdu_process - Deferred PPDU stats handler
1310*5113495bSYour Name  * @context: Opaque work context (PDEV)
1311*5113495bSYour Name  *
1312*5113495bSYour Name  * Return: none
1313*5113495bSYour Name  */
dp_tx_mon_ppdu_process(void * context)1314*5113495bSYour Name static void dp_tx_mon_ppdu_process(void *context)
1315*5113495bSYour Name {
1316*5113495bSYour Name 	struct dp_pdev *pdev = (struct dp_pdev *)context;
1317*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1318*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be;
1319*5113495bSYour Name 	struct dp_tx_ppdu_info *defer_ppdu_info = NULL;
1320*5113495bSYour Name 	struct dp_tx_ppdu_info *defer_ppdu_info_next = NULL;
1321*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be;
1322*5113495bSYour Name 
1323*5113495bSYour Name 	/* sanity check */
1324*5113495bSYour Name 	if (qdf_unlikely(!pdev))
1325*5113495bSYour Name 		return;
1326*5113495bSYour Name 
1327*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
1328*5113495bSYour Name 
1329*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev))
1330*5113495bSYour Name 		return;
1331*5113495bSYour Name 
1332*5113495bSYour Name 	mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1333*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev_be))
1334*5113495bSYour Name 		return;
1335*5113495bSYour Name 
1336*5113495bSYour Name 	tx_mon_be = &mon_pdev_be->tx_monitor_be;
1337*5113495bSYour Name 	if (qdf_unlikely(TX_MON_BE_DISABLE == tx_mon_be->mode &&
1338*5113495bSYour Name 			 !dp_lite_mon_is_tx_enabled(mon_pdev)))
1339*5113495bSYour Name 		return;
1340*5113495bSYour Name 
1341*5113495bSYour Name 	/* take lock here */
1342*5113495bSYour Name 	qdf_spin_lock_bh(&tx_mon_be->tx_mon_list_lock);
1343*5113495bSYour Name 	STAILQ_CONCAT(&tx_mon_be->defer_tx_ppdu_info_queue,
1344*5113495bSYour Name 		      &tx_mon_be->tx_ppdu_info_queue);
1345*5113495bSYour Name 	tx_mon_be->defer_ppdu_info_list_depth +=
1346*5113495bSYour Name 		tx_mon_be->tx_ppdu_info_list_depth;
1347*5113495bSYour Name 	tx_mon_be->tx_ppdu_info_list_depth = 0;
1348*5113495bSYour Name 	qdf_spin_unlock_bh(&tx_mon_be->tx_mon_list_lock);
1349*5113495bSYour Name 
1350*5113495bSYour Name 	STAILQ_FOREACH_SAFE(defer_ppdu_info,
1351*5113495bSYour Name 			    &tx_mon_be->defer_tx_ppdu_info_queue,
1352*5113495bSYour Name 			    tx_ppdu_info_queue_elem, defer_ppdu_info_next) {
1353*5113495bSYour Name 		/* remove dp_tx_ppdu_info from the list */
1354*5113495bSYour Name 		STAILQ_REMOVE(&tx_mon_be->defer_tx_ppdu_info_queue,
1355*5113495bSYour Name 			      defer_ppdu_info,
1356*5113495bSYour Name 			      dp_tx_ppdu_info,
1357*5113495bSYour Name 			      tx_ppdu_info_queue_elem);
1358*5113495bSYour Name 		tx_mon_be->defer_ppdu_info_list_depth--;
1359*5113495bSYour Name 
1360*5113495bSYour Name 		dp_tx_mon_update_radiotap(pdev, defer_ppdu_info);
1361*5113495bSYour Name 
1362*5113495bSYour Name 		/* free the ppdu_info */
1363*5113495bSYour Name 		dp_tx_mon_free_ppdu_info(defer_ppdu_info, tx_mon_be);
1364*5113495bSYour Name 		defer_ppdu_info = NULL;
1365*5113495bSYour Name 	}
1366*5113495bSYour Name }
1367*5113495bSYour Name 
dp_tx_ppdu_stats_attach_2_0(struct dp_pdev * pdev)1368*5113495bSYour Name void dp_tx_ppdu_stats_attach_2_0(struct dp_pdev *pdev)
1369*5113495bSYour Name {
1370*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1371*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be;
1372*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be;
1373*5113495bSYour Name 
1374*5113495bSYour Name 	if (qdf_unlikely(!pdev))
1375*5113495bSYour Name 		return;
1376*5113495bSYour Name 
1377*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
1378*5113495bSYour Name 
1379*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev))
1380*5113495bSYour Name 		return;
1381*5113495bSYour Name 
1382*5113495bSYour Name 	mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1383*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev_be))
1384*5113495bSYour Name 		return;
1385*5113495bSYour Name 
1386*5113495bSYour Name 	tx_mon_be = &mon_pdev_be->tx_monitor_be;
1387*5113495bSYour Name 
1388*5113495bSYour Name 	STAILQ_INIT(&tx_mon_be->tx_ppdu_info_queue);
1389*5113495bSYour Name 	tx_mon_be->tx_ppdu_info_list_depth = 0;
1390*5113495bSYour Name 
1391*5113495bSYour Name 	STAILQ_INIT(&tx_mon_be->defer_tx_ppdu_info_queue);
1392*5113495bSYour Name 	tx_mon_be->defer_ppdu_info_list_depth = 0;
1393*5113495bSYour Name 
1394*5113495bSYour Name 	qdf_spinlock_create(&tx_mon_be->tx_mon_list_lock);
1395*5113495bSYour Name 	/* Work queue setup for TX MONITOR post handling */
1396*5113495bSYour Name 	qdf_create_work(0, &tx_mon_be->post_ppdu_work,
1397*5113495bSYour Name 			dp_tx_mon_ppdu_process, pdev);
1398*5113495bSYour Name 
1399*5113495bSYour Name 	tx_mon_be->post_ppdu_workqueue =
1400*5113495bSYour Name 			qdf_alloc_unbound_workqueue("tx_mon_ppdu_work_queue");
1401*5113495bSYour Name }
1402*5113495bSYour Name 
dp_tx_ppdu_stats_detach_2_0(struct dp_pdev * pdev)1403*5113495bSYour Name void dp_tx_ppdu_stats_detach_2_0(struct dp_pdev *pdev)
1404*5113495bSYour Name {
1405*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1406*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be;
1407*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be;
1408*5113495bSYour Name 	struct dp_tx_ppdu_info *tx_ppdu_info = NULL;
1409*5113495bSYour Name 	struct dp_tx_ppdu_info *tx_ppdu_info_next = NULL;
1410*5113495bSYour Name 
1411*5113495bSYour Name 	if (qdf_unlikely(!pdev))
1412*5113495bSYour Name 		return;
1413*5113495bSYour Name 
1414*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
1415*5113495bSYour Name 
1416*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev))
1417*5113495bSYour Name 		return;
1418*5113495bSYour Name 
1419*5113495bSYour Name 	mon_pdev_be = dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1420*5113495bSYour Name 	if (qdf_unlikely(!mon_pdev_be))
1421*5113495bSYour Name 		return;
1422*5113495bSYour Name 
1423*5113495bSYour Name 	tx_mon_be = &mon_pdev_be->tx_monitor_be;
1424*5113495bSYour Name 	/* TODO: disable tx_monitor, to avoid further packet from HW */
1425*5113495bSYour Name 	dp_monitor_config_enh_tx_capture(pdev, TX_MON_BE_DISABLE);
1426*5113495bSYour Name 
1427*5113495bSYour Name 	/* flush workqueue */
1428*5113495bSYour Name 	qdf_flush_workqueue(0, tx_mon_be->post_ppdu_workqueue);
1429*5113495bSYour Name 	qdf_destroy_workqueue(0, tx_mon_be->post_ppdu_workqueue);
1430*5113495bSYour Name 
1431*5113495bSYour Name 	/*
1432*5113495bSYour Name 	 * TODO: iterate both tx_ppdu_info and defer_ppdu_info_list
1433*5113495bSYour Name 	 * free the tx_ppdu_info and decrement depth
1434*5113495bSYour Name 	 */
1435*5113495bSYour Name 	qdf_spin_lock_bh(&tx_mon_be->tx_mon_list_lock);
1436*5113495bSYour Name 	STAILQ_FOREACH_SAFE(tx_ppdu_info,
1437*5113495bSYour Name 			    &tx_mon_be->tx_ppdu_info_queue,
1438*5113495bSYour Name 			    tx_ppdu_info_queue_elem, tx_ppdu_info_next) {
1439*5113495bSYour Name 		/* remove dp_tx_ppdu_info from the list */
1440*5113495bSYour Name 		STAILQ_REMOVE(&tx_mon_be->tx_ppdu_info_queue, tx_ppdu_info,
1441*5113495bSYour Name 			      dp_tx_ppdu_info, tx_ppdu_info_queue_elem);
1442*5113495bSYour Name 		/* decrement list length */
1443*5113495bSYour Name 		tx_mon_be->tx_ppdu_info_list_depth--;
1444*5113495bSYour Name 		/* free tx_ppdu_info */
1445*5113495bSYour Name 		dp_tx_mon_free_ppdu_info(tx_ppdu_info, tx_mon_be);
1446*5113495bSYour Name 	}
1447*5113495bSYour Name 	qdf_spin_unlock_bh(&tx_mon_be->tx_mon_list_lock);
1448*5113495bSYour Name 
1449*5113495bSYour Name 	qdf_spin_lock_bh(&tx_mon_be->tx_mon_list_lock);
1450*5113495bSYour Name 	STAILQ_FOREACH_SAFE(tx_ppdu_info,
1451*5113495bSYour Name 			    &tx_mon_be->defer_tx_ppdu_info_queue,
1452*5113495bSYour Name 			    tx_ppdu_info_queue_elem, tx_ppdu_info_next) {
1453*5113495bSYour Name 		/* remove dp_tx_ppdu_info from the list */
1454*5113495bSYour Name 		STAILQ_REMOVE(&tx_mon_be->defer_tx_ppdu_info_queue,
1455*5113495bSYour Name 			      tx_ppdu_info,
1456*5113495bSYour Name 			      dp_tx_ppdu_info, tx_ppdu_info_queue_elem);
1457*5113495bSYour Name 		/* decrement list length */
1458*5113495bSYour Name 		tx_mon_be->defer_ppdu_info_list_depth--;
1459*5113495bSYour Name 		/* free tx_ppdu_info */
1460*5113495bSYour Name 		dp_tx_mon_free_ppdu_info(tx_ppdu_info, tx_mon_be);
1461*5113495bSYour Name 	}
1462*5113495bSYour Name 	qdf_spin_unlock_bh(&tx_mon_be->tx_mon_list_lock);
1463*5113495bSYour Name 
1464*5113495bSYour Name 	qdf_spinlock_destroy(&tx_mon_be->tx_mon_list_lock);
1465*5113495bSYour Name }
1466*5113495bSYour Name #endif /* WLAN_TX_PKT_CAPTURE_ENH_BE */
1467*5113495bSYour Name 
1468*5113495bSYour Name #if (defined(WIFI_MONITOR_SUPPORT) && defined(WLAN_TX_MON_CORE_DEBUG))
1469*5113495bSYour Name /*
1470*5113495bSYour Name  * dp_config_enh_tx_core_monitor_2_0()- API to validate core framework
1471*5113495bSYour Name  * @pdev_handle: DP_PDEV handle
1472*5113495bSYour Name  * @val: user provided value
1473*5113495bSYour Name  *
1474*5113495bSYour Name  * Return: QDF_STATUS
1475*5113495bSYour Name  */
1476*5113495bSYour Name QDF_STATUS
dp_config_enh_tx_core_monitor_2_0(struct dp_pdev * pdev,uint8_t val)1477*5113495bSYour Name dp_config_enh_tx_core_monitor_2_0(struct dp_pdev *pdev, uint8_t val)
1478*5113495bSYour Name {
1479*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
1480*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1481*5113495bSYour Name 	struct dp_mon_pdev_be *mon_pdev_be =
1482*5113495bSYour Name 			dp_get_be_mon_pdev_from_dp_mon_pdev(mon_pdev);
1483*5113495bSYour Name 	struct dp_pdev_tx_monitor_be *tx_mon_be =
1484*5113495bSYour Name 			&mon_pdev_be->tx_monitor_be;
1485*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1486*5113495bSYour Name 	uint16_t num_of_buffers;
1487*5113495bSYour Name 	QDF_STATUS status;
1488*5113495bSYour Name 
1489*5113495bSYour Name 	soc_cfg_ctx = soc->wlan_cfg_ctx;
1490*5113495bSYour Name 	switch (val) {
1491*5113495bSYour Name 	case TX_MON_BE_FRM_WRK_DISABLE:
1492*5113495bSYour Name 	{
1493*5113495bSYour Name 		tx_mon_be->mode = val;
1494*5113495bSYour Name 		mon_pdev_be->tx_mon_mode = 0;
1495*5113495bSYour Name 		mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_64B;
1496*5113495bSYour Name 		break;
1497*5113495bSYour Name 	}
1498*5113495bSYour Name 	case TX_MON_BE_FRM_WRK_FULL_CAPTURE:
1499*5113495bSYour Name 	{
1500*5113495bSYour Name 		num_of_buffers = wlan_cfg_get_dp_soc_tx_mon_buf_ring_size(soc_cfg_ctx);
1501*5113495bSYour Name 		status = dp_vdev_set_monitor_mode_buf_rings_tx_2_0(pdev,
1502*5113495bSYour Name 								   num_of_buffers);
1503*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
1504*5113495bSYour Name 			dp_mon_err("Tx monitor buffer allocation failed");
1505*5113495bSYour Name 			return status;
1506*5113495bSYour Name 		}
1507*5113495bSYour Name 		tx_mon_be->mode = val;
1508*5113495bSYour Name 		qdf_mem_zero(&tx_mon_be->stats,
1509*5113495bSYour Name 			     sizeof(struct dp_tx_monitor_drop_stats));
1510*5113495bSYour Name 		tx_mon_be->mode = val;
1511*5113495bSYour Name 		mon_pdev_be->tx_mon_mode = 1;
1512*5113495bSYour Name 		mon_pdev_be->tx_mon_filter_length = DEFAULT_DMA_LENGTH;
1513*5113495bSYour Name 		break;
1514*5113495bSYour Name 	}
1515*5113495bSYour Name 	case TX_MON_BE_FRM_WRK_128B_CAPTURE:
1516*5113495bSYour Name 	{
1517*5113495bSYour Name 		status = dp_vdev_set_monitor_mode_buf_rings_tx_2_0(pdev,
1518*5113495bSYour Name 								   DP_MON_RING_FILL_LEVEL_DEFAULT);
1519*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
1520*5113495bSYour Name 			dp_mon_err("Tx monitor buffer allocation failed");
1521*5113495bSYour Name 			return status;
1522*5113495bSYour Name 		}
1523*5113495bSYour Name 		tx_mon_be->mode = val;
1524*5113495bSYour Name 		mon_pdev_be->tx_mon_mode = 1;
1525*5113495bSYour Name 		mon_pdev_be->tx_mon_filter_length = DMA_LENGTH_128B;
1526*5113495bSYour Name 		break;
1527*5113495bSYour Name 	}
1528*5113495bSYour Name 	default:
1529*5113495bSYour Name 	{
1530*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
1531*5113495bSYour Name 	}
1532*5113495bSYour Name 	}
1533*5113495bSYour Name 
1534*5113495bSYour Name 	dp_mon_debug("Tx monitor mode:%d mon_mode_flag:%d config_length:%d",
1535*5113495bSYour Name 		    tx_mon_be->mode, mon_pdev_be->tx_mon_mode,
1536*5113495bSYour Name 		    mon_pdev_be->tx_mon_filter_length);
1537*5113495bSYour Name 
1538*5113495bSYour Name 	/* send HTT msg to configure TLV based on mode */
1539*5113495bSYour Name 	dp_mon_filter_setup_tx_mon_mode(pdev);
1540*5113495bSYour Name 	dp_tx_mon_filter_update(pdev);
1541*5113495bSYour Name 
1542*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1543*5113495bSYour Name }
1544*5113495bSYour Name #endif
1545*5113495bSYour Name 
1546*5113495bSYour Name #ifdef WLAN_PKT_CAPTURE_TX_2_0
dp_tx_mon_pdev_htt_srng_setup_2_0(struct dp_soc * soc,struct dp_pdev * pdev,int mac_id,int mac_for_pdev)1547*5113495bSYour Name QDF_STATUS dp_tx_mon_pdev_htt_srng_setup_2_0(struct dp_soc *soc,
1548*5113495bSYour Name 					     struct dp_pdev *pdev,
1549*5113495bSYour Name 					     int mac_id,
1550*5113495bSYour Name 					     int mac_for_pdev)
1551*5113495bSYour Name {
1552*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1553*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1554*5113495bSYour Name 
1555*5113495bSYour Name 	return htt_srng_setup(soc->htt_handle, mac_for_pdev,
1556*5113495bSYour Name 			      mon_soc_be->tx_mon_dst_ring[mac_id].hal_srng,
1557*5113495bSYour Name 			      TX_MONITOR_DST);
1558*5113495bSYour Name }
1559*5113495bSYour Name 
dp_tx_mon_soc_htt_srng_setup_2_0(struct dp_soc * soc,int mac_id)1560*5113495bSYour Name QDF_STATUS dp_tx_mon_soc_htt_srng_setup_2_0(struct dp_soc *soc,
1561*5113495bSYour Name 					    int mac_id)
1562*5113495bSYour Name {
1563*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1564*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1565*5113495bSYour Name 
1566*5113495bSYour Name 	hal_set_low_threshold(mon_soc_be->tx_mon_buf_ring.hal_srng, 0);
1567*5113495bSYour Name 	return htt_srng_setup(soc->htt_handle, mac_id,
1568*5113495bSYour Name 				mon_soc_be->tx_mon_buf_ring.hal_srng,
1569*5113495bSYour Name 				TX_MONITOR_BUF);
1570*5113495bSYour Name }
1571*5113495bSYour Name 
dp_tx_mon_pdev_rings_alloc_2_0(struct dp_pdev * pdev,uint32_t lmac_id)1572*5113495bSYour Name QDF_STATUS dp_tx_mon_pdev_rings_alloc_2_0(struct dp_pdev *pdev, uint32_t lmac_id)
1573*5113495bSYour Name {
1574*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1575*5113495bSYour Name 	int entries;
1576*5113495bSYour Name 	struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
1577*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1578*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1579*5113495bSYour Name 
1580*5113495bSYour Name 	pdev_cfg_ctx = pdev->wlan_cfg_ctx;
1581*5113495bSYour Name 	entries = wlan_cfg_get_dma_tx_mon_dest_ring_size(pdev_cfg_ctx);
1582*5113495bSYour Name 
1583*5113495bSYour Name 	return dp_srng_alloc(soc, &mon_soc_be->tx_mon_dst_ring[lmac_id],
1584*5113495bSYour Name 				  TX_MONITOR_DST, entries, 0);
1585*5113495bSYour Name }
1586*5113495bSYour Name 
dp_tx_mon_pdev_rings_free_2_0(struct dp_pdev * pdev,uint32_t lmac_id)1587*5113495bSYour Name void dp_tx_mon_pdev_rings_free_2_0(struct dp_pdev *pdev, uint32_t lmac_id)
1588*5113495bSYour Name {
1589*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1590*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1591*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1592*5113495bSYour Name 
1593*5113495bSYour Name 	dp_srng_free(soc, &mon_soc_be->tx_mon_dst_ring[lmac_id]);
1594*5113495bSYour Name }
1595*5113495bSYour Name 
dp_tx_mon_pdev_rings_init_2_0(struct dp_pdev * pdev,uint32_t lmac_id)1596*5113495bSYour Name QDF_STATUS dp_tx_mon_pdev_rings_init_2_0(struct dp_pdev *pdev, uint32_t lmac_id)
1597*5113495bSYour Name {
1598*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1599*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1600*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be = dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1601*5113495bSYour Name 
1602*5113495bSYour Name 	return dp_srng_init(soc, &mon_soc_be->tx_mon_dst_ring[lmac_id],
1603*5113495bSYour Name 				 TX_MONITOR_DST, pdev->pdev_id, lmac_id);
1604*5113495bSYour Name }
1605*5113495bSYour Name 
dp_tx_mon_pdev_rings_deinit_2_0(struct dp_pdev * pdev,uint32_t lmac_id)1606*5113495bSYour Name void dp_tx_mon_pdev_rings_deinit_2_0(struct dp_pdev *pdev, uint32_t lmac_id)
1607*5113495bSYour Name {
1608*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1609*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1610*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
1611*5113495bSYour Name 			dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1612*5113495bSYour Name 
1613*5113495bSYour Name 	dp_srng_deinit(soc, &mon_soc_be->tx_mon_dst_ring[lmac_id],
1614*5113495bSYour Name 		       TX_MONITOR_DST, pdev->pdev_id);
1615*5113495bSYour Name }
1616*5113495bSYour Name 
dp_tx_mon_soc_attach_2_0(struct dp_soc * soc,uint32_t lmac_id)1617*5113495bSYour Name QDF_STATUS dp_tx_mon_soc_attach_2_0(struct dp_soc *soc, uint32_t lmac_id)
1618*5113495bSYour Name {
1619*5113495bSYour Name 	int entries;
1620*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
1621*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1622*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
1623*5113495bSYour Name 		dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1624*5113495bSYour Name 
1625*5113495bSYour Name 	entries = wlan_cfg_get_dp_soc_tx_mon_buf_ring_size(soc_cfg_ctx);
1626*5113495bSYour Name 	qdf_print("%s:%d tx mon buf entries: %d", __func__, __LINE__, entries);
1627*5113495bSYour Name 
1628*5113495bSYour Name 	return dp_srng_alloc(soc, &mon_soc_be->tx_mon_buf_ring,
1629*5113495bSYour Name 			  TX_MONITOR_BUF, entries, 0);
1630*5113495bSYour Name }
1631*5113495bSYour Name 
dp_tx_mon_soc_detach_2_0(struct dp_soc * soc,uint32_t lmac_id)1632*5113495bSYour Name QDF_STATUS dp_tx_mon_soc_detach_2_0(struct dp_soc *soc, uint32_t lmac_id)
1633*5113495bSYour Name {
1634*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1635*5113495bSYour Name 	struct dp_mon_soc_be *mon_soc_be =
1636*5113495bSYour Name 			dp_get_be_mon_soc_from_dp_mon_soc(mon_soc);
1637*5113495bSYour Name 
1638*5113495bSYour Name 	if (!mon_soc_be) {
1639*5113495bSYour Name 		dp_mon_err("DP MON SOC NULL");
1640*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1641*5113495bSYour Name 	}
1642*5113495bSYour Name 
1643*5113495bSYour Name 	dp_tx_mon_buf_desc_pool_free(soc);
1644*5113495bSYour Name 	dp_srng_free(soc, &mon_soc_be->tx_mon_buf_ring);
1645*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1646*5113495bSYour Name }
1647*5113495bSYour Name 
1648*5113495bSYour Name #endif
1649