xref: /wlan-driver/qca-wifi-host-cmn/dp/wifi3.0/monitor/dp_mon.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 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 #include <dp_types.h>
18*5113495bSYour Name #include "dp_rx.h"
19*5113495bSYour Name #include "dp_tx.h"
20*5113495bSYour Name #include "dp_peer.h"
21*5113495bSYour Name #include <dp_htt.h>
22*5113495bSYour Name #include <dp_mon_filter.h>
23*5113495bSYour Name #include <dp_htt.h>
24*5113495bSYour Name #include <dp_mon.h>
25*5113495bSYour Name #include <dp_rx_mon.h>
26*5113495bSYour Name #include <dp_internal.h>
27*5113495bSYour Name #include "htt_ppdu_stats.h"
28*5113495bSYour Name #include "dp_cal_client_api.h"
29*5113495bSYour Name #if defined(DP_CON_MON)
30*5113495bSYour Name #ifndef REMOVE_PKT_LOG
31*5113495bSYour Name #include <pktlog_ac_api.h>
32*5113495bSYour Name #include <pktlog_ac.h>
33*5113495bSYour Name #endif
34*5113495bSYour Name #endif
35*5113495bSYour Name #ifdef FEATURE_PERPKT_INFO
36*5113495bSYour Name #include "dp_ratetable.h"
37*5113495bSYour Name #endif
38*5113495bSYour Name #ifdef QCA_SUPPORT_LITE_MONITOR
39*5113495bSYour Name #include "dp_lite_mon.h"
40*5113495bSYour Name #endif
41*5113495bSYour Name #include "dp_mon_1.0.h"
42*5113495bSYour Name #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
43*5113495bSYour Name #include "dp_mon_2.0.h"
44*5113495bSYour Name #include "dp_mon_filter_2.0.h"
45*5113495bSYour Name #endif
46*5113495bSYour Name 
47*5113495bSYour Name #define DP_INTR_POLL_TIMER_MS	5
48*5113495bSYour Name #define INVALID_FREE_BUFF 0xffffffff
49*5113495bSYour Name 
50*5113495bSYour Name #ifdef WLAN_RX_PKT_CAPTURE_ENH
51*5113495bSYour Name #include "dp_rx_mon_feature.h"
52*5113495bSYour Name #endif /* WLAN_RX_PKT_CAPTURE_ENH */
53*5113495bSYour Name 
54*5113495bSYour Name #ifdef QCA_UNDECODED_METADATA_SUPPORT
55*5113495bSYour Name #define MAX_STRING_LEN_PER_FIELD 6
56*5113495bSYour Name #define DP_UNDECODED_ERR_LENGTH (MAX_STRING_LEN_PER_FIELD * CDP_PHYRX_ERR_MAX)
57*5113495bSYour Name #endif
58*5113495bSYour Name 
59*5113495bSYour Name #ifdef QCA_MCOPY_SUPPORT
60*5113495bSYour Name static inline void
dp_pdev_disable_mcopy_code(struct dp_pdev * pdev)61*5113495bSYour Name dp_pdev_disable_mcopy_code(struct dp_pdev *pdev)
62*5113495bSYour Name {
63*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
64*5113495bSYour Name 
65*5113495bSYour Name 	mon_pdev->mcopy_mode = M_COPY_DISABLED;
66*5113495bSYour Name 	mon_pdev->mvdev = NULL;
67*5113495bSYour Name }
68*5113495bSYour Name 
69*5113495bSYour Name static inline void
dp_reset_mcopy_mode(struct dp_pdev * pdev)70*5113495bSYour Name dp_reset_mcopy_mode(struct dp_pdev *pdev)
71*5113495bSYour Name {
72*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
73*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
74*5113495bSYour Name 	struct cdp_mon_ops *cdp_ops;
75*5113495bSYour Name 
76*5113495bSYour Name 	if (mon_pdev->mcopy_mode) {
77*5113495bSYour Name 		cdp_ops = dp_mon_cdp_ops_get(pdev->soc);
78*5113495bSYour Name 		if (cdp_ops  && cdp_ops->config_full_mon_mode)
79*5113495bSYour Name 			cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev,
80*5113495bSYour Name 							  DP_FULL_MON_ENABLE);
81*5113495bSYour Name 		dp_pdev_disable_mcopy_code(pdev);
82*5113495bSYour Name 		dp_mon_filter_reset_mcopy_mode(pdev);
83*5113495bSYour Name 		status = dp_mon_filter_update(pdev);
84*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
85*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
86*5113495bSYour Name 				  FL("Failed to reset AM copy mode filters"));
87*5113495bSYour Name 		}
88*5113495bSYour Name 		mon_pdev->monitor_configured = false;
89*5113495bSYour Name 	}
90*5113495bSYour Name }
91*5113495bSYour Name 
92*5113495bSYour Name static QDF_STATUS
dp_config_mcopy_mode(struct dp_pdev * pdev,int val)93*5113495bSYour Name dp_config_mcopy_mode(struct dp_pdev *pdev, int val)
94*5113495bSYour Name {
95*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
96*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
97*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
98*5113495bSYour Name 	struct cdp_mon_ops *cdp_ops;
99*5113495bSYour Name 
100*5113495bSYour Name 	if (mon_pdev->mvdev)
101*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES;
102*5113495bSYour Name 
103*5113495bSYour Name 	mon_pdev->mcopy_mode = val;
104*5113495bSYour Name 	mon_pdev->tx_sniffer_enable = 0;
105*5113495bSYour Name 	mon_pdev->monitor_configured = true;
106*5113495bSYour Name 
107*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
108*5113495bSYour Name 	if (!wlan_cfg_is_delay_mon_replenish(pdev->soc->wlan_cfg_ctx)) {
109*5113495bSYour Name 		if (mon_ops && mon_ops->mon_vdev_set_monitor_mode_rings)
110*5113495bSYour Name 			mon_ops->mon_vdev_set_monitor_mode_rings(pdev, true);
111*5113495bSYour Name 	}
112*5113495bSYour Name 
113*5113495bSYour Name 	/*
114*5113495bSYour Name 	 * Setup the M copy mode filter.
115*5113495bSYour Name 	 */
116*5113495bSYour Name 	cdp_ops = dp_mon_cdp_ops_get(pdev->soc);
117*5113495bSYour Name 	if (cdp_ops  && cdp_ops->config_full_mon_mode)
118*5113495bSYour Name 		cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev,
119*5113495bSYour Name 						  DP_FULL_MON_ENABLE);
120*5113495bSYour Name 	dp_mon_filter_setup_mcopy_mode(pdev);
121*5113495bSYour Name 	status = dp_mon_filter_update(pdev);
122*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
123*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
124*5113495bSYour Name 			  FL("Failed to set M_copy mode filters"));
125*5113495bSYour Name 		dp_mon_filter_reset_mcopy_mode(pdev);
126*5113495bSYour Name 		dp_pdev_disable_mcopy_code(pdev);
127*5113495bSYour Name 		return status;
128*5113495bSYour Name 	}
129*5113495bSYour Name 
130*5113495bSYour Name 	if (!mon_pdev->pktlog_ppdu_stats)
131*5113495bSYour Name 		dp_h2t_cfg_stats_msg_send(pdev,
132*5113495bSYour Name 					  DP_PPDU_STATS_CFG_SNIFFER,
133*5113495bSYour Name 					  pdev->pdev_id);
134*5113495bSYour Name 
135*5113495bSYour Name 	return status;
136*5113495bSYour Name }
137*5113495bSYour Name #else
138*5113495bSYour Name static inline void
dp_reset_mcopy_mode(struct dp_pdev * pdev)139*5113495bSYour Name dp_reset_mcopy_mode(struct dp_pdev *pdev)
140*5113495bSYour Name {
141*5113495bSYour Name }
142*5113495bSYour Name 
143*5113495bSYour Name static inline QDF_STATUS
dp_config_mcopy_mode(struct dp_pdev * pdev,int val)144*5113495bSYour Name dp_config_mcopy_mode(struct dp_pdev *pdev, int val)
145*5113495bSYour Name {
146*5113495bSYour Name 	return QDF_STATUS_E_INVAL;
147*5113495bSYour Name }
148*5113495bSYour Name #endif /* QCA_MCOPY_SUPPORT */
149*5113495bSYour Name 
150*5113495bSYour Name #ifdef QCA_UNDECODED_METADATA_SUPPORT
151*5113495bSYour Name static QDF_STATUS
dp_reset_undecoded_metadata_capture(struct dp_pdev * pdev)152*5113495bSYour Name dp_reset_undecoded_metadata_capture(struct dp_pdev *pdev)
153*5113495bSYour Name {
154*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
155*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
156*5113495bSYour Name 
157*5113495bSYour Name 	if (mon_pdev->undecoded_metadata_capture) {
158*5113495bSYour Name 		dp_mon_filter_reset_undecoded_metadata_mode(pdev);
159*5113495bSYour Name 		status = dp_mon_filter_update(pdev);
160*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
161*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
162*5113495bSYour Name 				  FL("Undecoded capture filter reset failed"));
163*5113495bSYour Name 		}
164*5113495bSYour Name 	}
165*5113495bSYour Name 	mon_pdev->undecoded_metadata_capture = 0;
166*5113495bSYour Name 	return status;
167*5113495bSYour Name }
168*5113495bSYour Name 
169*5113495bSYour Name static QDF_STATUS
dp_enable_undecoded_metadata_capture(struct dp_pdev * pdev,int val)170*5113495bSYour Name dp_enable_undecoded_metadata_capture(struct dp_pdev *pdev, int val)
171*5113495bSYour Name {
172*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
173*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
174*5113495bSYour Name 
175*5113495bSYour Name 	if (!mon_pdev->mvdev) {
176*5113495bSYour Name 		qdf_err("monitor_pdev is NULL");
177*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES;
178*5113495bSYour Name 	}
179*5113495bSYour Name 
180*5113495bSYour Name 	mon_pdev->undecoded_metadata_capture = val;
181*5113495bSYour Name 	mon_pdev->monitor_configured = true;
182*5113495bSYour Name 
183*5113495bSYour Name 
184*5113495bSYour Name 	/* Setup the undecoded metadata capture mode filter. */
185*5113495bSYour Name 	dp_mon_filter_setup_undecoded_metadata_mode(pdev);
186*5113495bSYour Name 	status = dp_mon_filter_update(pdev);
187*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
188*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
189*5113495bSYour Name 			  FL("Failed to set Undecoded capture filters"));
190*5113495bSYour Name 		dp_mon_filter_reset_undecoded_metadata_mode(pdev);
191*5113495bSYour Name 		return status;
192*5113495bSYour Name 	}
193*5113495bSYour Name 
194*5113495bSYour Name 	return status;
195*5113495bSYour Name }
196*5113495bSYour Name #else
197*5113495bSYour Name static inline QDF_STATUS
dp_reset_undecoded_metadata_capture(struct dp_pdev * pdev)198*5113495bSYour Name dp_reset_undecoded_metadata_capture(struct dp_pdev *pdev)
199*5113495bSYour Name {
200*5113495bSYour Name 	return QDF_STATUS_E_INVAL;
201*5113495bSYour Name }
202*5113495bSYour Name 
203*5113495bSYour Name static inline QDF_STATUS
dp_enable_undecoded_metadata_capture(struct dp_pdev * pdev,int val)204*5113495bSYour Name dp_enable_undecoded_metadata_capture(struct dp_pdev *pdev, int val)
205*5113495bSYour Name {
206*5113495bSYour Name 	return QDF_STATUS_E_INVAL;
207*5113495bSYour Name }
208*5113495bSYour Name #endif /* QCA_UNDECODED_METADATA_SUPPORT */
209*5113495bSYour Name 
dp_reset_monitor_mode(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint8_t special_monitor)210*5113495bSYour Name QDF_STATUS dp_reset_monitor_mode(struct cdp_soc_t *soc_hdl,
211*5113495bSYour Name 				 uint8_t pdev_id,
212*5113495bSYour Name 				 uint8_t special_monitor)
213*5113495bSYour Name {
214*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
215*5113495bSYour Name 	struct dp_pdev *pdev =
216*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
217*5113495bSYour Name 						   pdev_id);
218*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
219*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
220*5113495bSYour Name 
221*5113495bSYour Name 	if (!pdev)
222*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
223*5113495bSYour Name 
224*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
225*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
226*5113495bSYour Name 	status = dp_reset_monitor_mode_unlock(soc_hdl, pdev_id,
227*5113495bSYour Name 					      special_monitor);
228*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
229*5113495bSYour Name 
230*5113495bSYour Name 	return status;
231*5113495bSYour Name }
232*5113495bSYour Name 
dp_reset_monitor_mode_unlock(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,uint8_t special_monitor)233*5113495bSYour Name QDF_STATUS dp_reset_monitor_mode_unlock(struct cdp_soc_t *soc_hdl,
234*5113495bSYour Name 					uint8_t pdev_id,
235*5113495bSYour Name 					uint8_t special_monitor)
236*5113495bSYour Name {
237*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
238*5113495bSYour Name 	struct dp_pdev *pdev =
239*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
240*5113495bSYour Name 						   pdev_id);
241*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
242*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
243*5113495bSYour Name 	struct cdp_mon_ops *cdp_ops;
244*5113495bSYour Name 
245*5113495bSYour Name 	if (!pdev)
246*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
247*5113495bSYour Name 
248*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
249*5113495bSYour Name 
250*5113495bSYour Name 	cdp_ops = dp_mon_cdp_ops_get(soc);
251*5113495bSYour Name 	if (cdp_ops  && cdp_ops->soc_config_full_mon_mode) {
252*5113495bSYour Name 		cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev,
253*5113495bSYour Name 						  DP_FULL_MON_DISABLE);
254*5113495bSYour Name 		mon_pdev->hold_mon_dest_ring = false;
255*5113495bSYour Name 		mon_pdev->is_bkpressure = false;
256*5113495bSYour Name 		mon_pdev->set_reset_mon = false;
257*5113495bSYour Name #if defined(QCA_SUPPORT_FULL_MON)
258*5113495bSYour Name 		if (mon_pdev->mon_desc)
259*5113495bSYour Name 			qdf_mem_zero(mon_pdev->mon_desc,
260*5113495bSYour Name 				     sizeof(struct hal_rx_mon_desc_info));
261*5113495bSYour Name #endif
262*5113495bSYour Name 	}
263*5113495bSYour Name 
264*5113495bSYour Name 	/*
265*5113495bSYour Name 	 * Lite monitor mode, smart monitor mode and monitor
266*5113495bSYour Name 	 * mode uses this APIs to filter reset and mode disable
267*5113495bSYour Name 	 */
268*5113495bSYour Name 	if (mon_pdev->mcopy_mode) {
269*5113495bSYour Name #if defined(QCA_MCOPY_SUPPORT)
270*5113495bSYour Name 		dp_pdev_disable_mcopy_code(pdev);
271*5113495bSYour Name 		dp_mon_filter_reset_mcopy_mode(pdev);
272*5113495bSYour Name #endif /* QCA_MCOPY_SUPPORT */
273*5113495bSYour Name 	} else if (special_monitor) {
274*5113495bSYour Name #if defined(ATH_SUPPORT_NAC)
275*5113495bSYour Name 		dp_mon_filter_reset_smart_monitor(pdev);
276*5113495bSYour Name #endif /* ATH_SUPPORT_NAC */
277*5113495bSYour Name 		/* for mon 2.0 we make use of lite mon to
278*5113495bSYour Name 		 * set filters for smart monitor use case.
279*5113495bSYour Name 		 */
280*5113495bSYour Name 		dp_monitor_lite_mon_disable_rx(pdev);
281*5113495bSYour Name 	} else if (mon_pdev->undecoded_metadata_capture) {
282*5113495bSYour Name #ifdef QCA_UNDECODED_METADATA_SUPPORT
283*5113495bSYour Name 		dp_reset_undecoded_metadata_capture(pdev);
284*5113495bSYour Name #endif
285*5113495bSYour Name 	} else {
286*5113495bSYour Name 		dp_mon_filter_reset_mon_mode(pdev);
287*5113495bSYour Name 	}
288*5113495bSYour Name 	status = dp_mon_filter_update(pdev);
289*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
290*5113495bSYour Name 		dp_rx_mon_dest_err("%pK: Failed to reset monitor filters",
291*5113495bSYour Name 				   soc);
292*5113495bSYour Name 	}
293*5113495bSYour Name 
294*5113495bSYour Name 	mon_pdev->mvdev = NULL;
295*5113495bSYour Name 	mon_pdev->monitor_configured = false;
296*5113495bSYour Name 
297*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
298*5113495bSYour Name }
299*5113495bSYour Name 
300*5113495bSYour Name #ifdef QCA_ADVANCE_MON_FILTER_SUPPORT
301*5113495bSYour Name QDF_STATUS
dp_pdev_set_advance_monitor_filter(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,struct cdp_monitor_filter * filter_val)302*5113495bSYour Name dp_pdev_set_advance_monitor_filter(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
303*5113495bSYour Name 				   struct cdp_monitor_filter *filter_val)
304*5113495bSYour Name {
305*5113495bSYour Name 	/* Many monitor VAPs can exists in a system but only one can be up at
306*5113495bSYour Name 	 * anytime
307*5113495bSYour Name 	 */
308*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
309*5113495bSYour Name 	struct dp_vdev *vdev;
310*5113495bSYour Name 	struct dp_pdev *pdev =
311*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
312*5113495bSYour Name 						   pdev_id);
313*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
314*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
315*5113495bSYour Name 
316*5113495bSYour Name 	if (!pdev || !pdev->monitor_pdev)
317*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
318*5113495bSYour Name 
319*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
320*5113495bSYour Name 	vdev = mon_pdev->mvdev;
321*5113495bSYour Name 
322*5113495bSYour Name 	if (!vdev)
323*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
324*5113495bSYour Name 
325*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
326*5113495bSYour Name 		  "pdev=%pK, pdev_id=%d, soc=%pK vdev=%pK",
327*5113495bSYour Name 		  pdev, pdev_id, soc, vdev);
328*5113495bSYour Name 
329*5113495bSYour Name 	/*Check if current pdev's monitor_vdev exists */
330*5113495bSYour Name 	if (!mon_pdev->mvdev) {
331*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
332*5113495bSYour Name 			  "vdev=%pK", vdev);
333*5113495bSYour Name 		qdf_assert(vdev);
334*5113495bSYour Name 	}
335*5113495bSYour Name 
336*5113495bSYour Name 	/* update filter mode, type in pdev structure */
337*5113495bSYour Name 	mon_pdev->mon_filter_mode = filter_val->mode;
338*5113495bSYour Name 	mon_pdev->fp_mgmt_filter = filter_val->fp_mgmt;
339*5113495bSYour Name 	mon_pdev->fp_ctrl_filter = filter_val->fp_ctrl;
340*5113495bSYour Name 	mon_pdev->fp_data_filter = filter_val->fp_data;
341*5113495bSYour Name 	mon_pdev->mo_mgmt_filter = filter_val->mo_mgmt;
342*5113495bSYour Name 	mon_pdev->mo_ctrl_filter = filter_val->mo_ctrl;
343*5113495bSYour Name 	mon_pdev->mo_data_filter = filter_val->mo_data;
344*5113495bSYour Name 
345*5113495bSYour Name 	dp_mon_filter_setup_mon_mode(pdev);
346*5113495bSYour Name 	status = dp_mon_filter_update(pdev);
347*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
348*5113495bSYour Name 		dp_rx_mon_dest_err("%pK: Failed to set filter for adv mon mode",
349*5113495bSYour Name 				   soc);
350*5113495bSYour Name 		dp_mon_filter_reset_mon_mode(pdev);
351*5113495bSYour Name 	}
352*5113495bSYour Name 
353*5113495bSYour Name 	return status;
354*5113495bSYour Name }
355*5113495bSYour Name #endif
356*5113495bSYour Name 
357*5113495bSYour Name QDF_STATUS
dp_deliver_tx_mgmt(struct cdp_soc_t * cdp_soc,uint8_t pdev_id,qdf_nbuf_t nbuf)358*5113495bSYour Name dp_deliver_tx_mgmt(struct cdp_soc_t *cdp_soc, uint8_t pdev_id, qdf_nbuf_t nbuf)
359*5113495bSYour Name {
360*5113495bSYour Name 	struct dp_pdev *pdev =
361*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)cdp_soc,
362*5113495bSYour Name 						   pdev_id);
363*5113495bSYour Name 
364*5113495bSYour Name 	if (!pdev)
365*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
366*5113495bSYour Name 
367*5113495bSYour Name 	dp_deliver_mgmt_frm(pdev, nbuf);
368*5113495bSYour Name 
369*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
370*5113495bSYour Name }
371*5113495bSYour Name 
372*5113495bSYour Name #ifdef QCA_SUPPORT_SCAN_SPCL_VAP_STATS
373*5113495bSYour Name /**
374*5113495bSYour Name  * dp_scan_spcl_vap_stats_attach() - alloc spcl vap stats struct
375*5113495bSYour Name  * @mon_vdev: Datapath mon VDEV handle
376*5113495bSYour Name  *
377*5113495bSYour Name  * Return: 0 on success, not 0 on failure
378*5113495bSYour Name  */
379*5113495bSYour Name static inline QDF_STATUS
dp_scan_spcl_vap_stats_attach(struct dp_mon_vdev * mon_vdev)380*5113495bSYour Name dp_scan_spcl_vap_stats_attach(struct dp_mon_vdev *mon_vdev)
381*5113495bSYour Name {
382*5113495bSYour Name 	mon_vdev->scan_spcl_vap_stats =
383*5113495bSYour Name 		qdf_mem_malloc(sizeof(struct cdp_scan_spcl_vap_stats));
384*5113495bSYour Name 
385*5113495bSYour Name 	if (!mon_vdev->scan_spcl_vap_stats) {
386*5113495bSYour Name 		dp_mon_err("scan spcl vap stats attach fail");
387*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
388*5113495bSYour Name 	}
389*5113495bSYour Name 
390*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
391*5113495bSYour Name }
392*5113495bSYour Name 
393*5113495bSYour Name /**
394*5113495bSYour Name  * dp_scan_spcl_vap_stats_detach() - free spcl vap stats struct
395*5113495bSYour Name  * @mon_vdev: Datapath mon VDEV handle
396*5113495bSYour Name  *
397*5113495bSYour Name  * Return: void
398*5113495bSYour Name  */
399*5113495bSYour Name static inline void
dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev * mon_vdev)400*5113495bSYour Name dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev *mon_vdev)
401*5113495bSYour Name {
402*5113495bSYour Name 	if (mon_vdev->scan_spcl_vap_stats) {
403*5113495bSYour Name 		qdf_mem_free(mon_vdev->scan_spcl_vap_stats);
404*5113495bSYour Name 		mon_vdev->scan_spcl_vap_stats = NULL;
405*5113495bSYour Name 	}
406*5113495bSYour Name }
407*5113495bSYour Name 
408*5113495bSYour Name /**
409*5113495bSYour Name  * dp_reset_scan_spcl_vap_stats() - reset spcl vap rx stats
410*5113495bSYour Name  * @vdev: Datapath VDEV handle
411*5113495bSYour Name  *
412*5113495bSYour Name  * Return: void
413*5113495bSYour Name  */
414*5113495bSYour Name static inline void
dp_reset_scan_spcl_vap_stats(struct dp_vdev * vdev)415*5113495bSYour Name dp_reset_scan_spcl_vap_stats(struct dp_vdev *vdev)
416*5113495bSYour Name {
417*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev;
418*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
419*5113495bSYour Name 
420*5113495bSYour Name 	mon_pdev = vdev->pdev->monitor_pdev;
421*5113495bSYour Name 	if (!mon_pdev || !mon_pdev->reset_scan_spcl_vap_stats_enable)
422*5113495bSYour Name 		return;
423*5113495bSYour Name 
424*5113495bSYour Name 	mon_vdev = vdev->monitor_vdev;
425*5113495bSYour Name 	if (!mon_vdev || !mon_vdev->scan_spcl_vap_stats)
426*5113495bSYour Name 		return;
427*5113495bSYour Name 
428*5113495bSYour Name 	qdf_mem_zero(mon_vdev->scan_spcl_vap_stats,
429*5113495bSYour Name 		     sizeof(struct cdp_scan_spcl_vap_stats));
430*5113495bSYour Name }
431*5113495bSYour Name 
432*5113495bSYour Name /**
433*5113495bSYour Name  * dp_get_scan_spcl_vap_stats() - get spcl vap rx stats
434*5113495bSYour Name  * @soc_hdl: Datapath soc handle
435*5113495bSYour Name  * @vdev_id: vdev id
436*5113495bSYour Name  * @stats: structure to hold spcl vap stats
437*5113495bSYour Name  *
438*5113495bSYour Name  * Return: 0 on success, not 0 on failure
439*5113495bSYour Name  */
440*5113495bSYour Name static QDF_STATUS
dp_get_scan_spcl_vap_stats(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,struct cdp_scan_spcl_vap_stats * stats)441*5113495bSYour Name dp_get_scan_spcl_vap_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
442*5113495bSYour Name 			   struct cdp_scan_spcl_vap_stats *stats)
443*5113495bSYour Name {
444*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev = NULL;
445*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
446*5113495bSYour Name 	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
447*5113495bSYour Name 						     DP_MOD_ID_CDP);
448*5113495bSYour Name 
449*5113495bSYour Name 	if (!vdev || !stats) {
450*5113495bSYour Name 		if (vdev)
451*5113495bSYour Name 			dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
452*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
453*5113495bSYour Name 	}
454*5113495bSYour Name 
455*5113495bSYour Name 	mon_vdev = vdev->monitor_vdev;
456*5113495bSYour Name 	if (!mon_vdev || !mon_vdev->scan_spcl_vap_stats) {
457*5113495bSYour Name 		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
458*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
459*5113495bSYour Name 	}
460*5113495bSYour Name 
461*5113495bSYour Name 	qdf_mem_copy(stats, mon_vdev->scan_spcl_vap_stats,
462*5113495bSYour Name 		     sizeof(struct cdp_scan_spcl_vap_stats));
463*5113495bSYour Name 
464*5113495bSYour Name 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
465*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
466*5113495bSYour Name }
467*5113495bSYour Name #else
468*5113495bSYour Name static inline void
dp_reset_scan_spcl_vap_stats(struct dp_vdev * vdev)469*5113495bSYour Name dp_reset_scan_spcl_vap_stats(struct dp_vdev *vdev)
470*5113495bSYour Name {
471*5113495bSYour Name }
472*5113495bSYour Name 
473*5113495bSYour Name static inline QDF_STATUS
dp_scan_spcl_vap_stats_attach(struct dp_mon_vdev * mon_vdev)474*5113495bSYour Name dp_scan_spcl_vap_stats_attach(struct dp_mon_vdev *mon_vdev)
475*5113495bSYour Name {
476*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
477*5113495bSYour Name }
478*5113495bSYour Name 
479*5113495bSYour Name static inline void
dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev * mon_vdev)480*5113495bSYour Name dp_scan_spcl_vap_stats_detach(struct dp_mon_vdev *mon_vdev)
481*5113495bSYour Name {
482*5113495bSYour Name }
483*5113495bSYour Name #endif
484*5113495bSYour Name 
485*5113495bSYour Name /**
486*5113495bSYour Name  * dp_vdev_set_monitor_mode() - Set DP VDEV to monitor mode
487*5113495bSYour Name  * @dp_soc: DP soc context
488*5113495bSYour Name  * @vdev_id: vdev ID
489*5113495bSYour Name  * @special_monitor: Flag to denote if its smart monitor mode
490*5113495bSYour Name  *
491*5113495bSYour Name  * Return: 0 on success, not 0 on failure
492*5113495bSYour Name  */
dp_vdev_set_monitor_mode(struct cdp_soc_t * dp_soc,uint8_t vdev_id,uint8_t special_monitor)493*5113495bSYour Name QDF_STATUS dp_vdev_set_monitor_mode(struct cdp_soc_t *dp_soc,
494*5113495bSYour Name 				    uint8_t vdev_id,
495*5113495bSYour Name 				    uint8_t special_monitor)
496*5113495bSYour Name {
497*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)dp_soc;
498*5113495bSYour Name 	struct dp_pdev *pdev;
499*5113495bSYour Name 	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
500*5113495bSYour Name 						     DP_MOD_ID_CDP);
501*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
502*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
503*5113495bSYour Name 	struct cdp_mon_ops *cdp_ops;
504*5113495bSYour Name 
505*5113495bSYour Name 	if (!vdev)
506*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
507*5113495bSYour Name 
508*5113495bSYour Name 	pdev = vdev->pdev;
509*5113495bSYour Name 
510*5113495bSYour Name 	if (!pdev || !pdev->monitor_pdev) {
511*5113495bSYour Name 		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
512*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
513*5113495bSYour Name 	}
514*5113495bSYour Name 
515*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
516*5113495bSYour Name 
517*5113495bSYour Name 	mon_pdev->mvdev = vdev;
518*5113495bSYour Name 
519*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_WARN,
520*5113495bSYour Name 		  "pdev=%pK, pdev_id=%d, soc=%pK vdev=%pK\n",
521*5113495bSYour Name 		  pdev, pdev->pdev_id, pdev->soc, vdev);
522*5113495bSYour Name 
523*5113495bSYour Name 	/*
524*5113495bSYour Name 	 * do not configure monitor buf ring and filter for smart and
525*5113495bSYour Name 	 * lite monitor
526*5113495bSYour Name 	 * for smart monitor filters are added along with first NAC
527*5113495bSYour Name 	 * for lite monitor required configuration done through
528*5113495bSYour Name 	 * dp_set_pdev_param
529*5113495bSYour Name 	 */
530*5113495bSYour Name 
531*5113495bSYour Name 	if (special_monitor) {
532*5113495bSYour Name 		status = QDF_STATUS_SUCCESS;
533*5113495bSYour Name 		goto fail;
534*5113495bSYour Name 	}
535*5113495bSYour Name 
536*5113495bSYour Name 	if (mon_pdev->scan_spcl_vap_configured)
537*5113495bSYour Name 		dp_reset_scan_spcl_vap_stats(vdev);
538*5113495bSYour Name 
539*5113495bSYour Name 	/*Check if current pdev's monitor_vdev exists */
540*5113495bSYour Name 	if (mon_pdev->monitor_configured) {
541*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
542*5113495bSYour Name 			  "monitor vap already created vdev=%pK\n", vdev);
543*5113495bSYour Name 		status = QDF_STATUS_E_RESOURCES;
544*5113495bSYour Name 		goto fail;
545*5113495bSYour Name 	}
546*5113495bSYour Name 
547*5113495bSYour Name 	mon_pdev->monitor_configured = true;
548*5113495bSYour Name 	mon_pdev->phy_ppdu_id_size = hal_rx_get_phy_ppdu_id_size(soc->hal_soc);
549*5113495bSYour Name 
550*5113495bSYour Name 	/* If advance monitor filter is applied using lite_mon
551*5113495bSYour Name 	 * via vap configuration, required filters are already applied
552*5113495bSYour Name 	 * hence returning SUCCESS from here.
553*5113495bSYour Name 	 */
554*5113495bSYour Name 	if (dp_monitor_lite_mon_is_rx_adv_filter_enable(pdev)) {
555*5113495bSYour Name 		status = QDF_STATUS_SUCCESS;
556*5113495bSYour Name 		goto fail;
557*5113495bSYour Name 	}
558*5113495bSYour Name 	/* disable lite mon if configured, monitor vap takes
559*5113495bSYour Name 	 * priority over lite mon when its created. Lite mon
560*5113495bSYour Name 	 * can be configured later again.
561*5113495bSYour Name 	 */
562*5113495bSYour Name 	dp_monitor_lite_mon_disable_rx(pdev);
563*5113495bSYour Name 
564*5113495bSYour Name 	cdp_ops = dp_mon_cdp_ops_get(soc);
565*5113495bSYour Name 	if (cdp_ops  && cdp_ops->soc_config_full_mon_mode)
566*5113495bSYour Name 		cdp_ops->soc_config_full_mon_mode((struct cdp_pdev *)pdev,
567*5113495bSYour Name 						  DP_FULL_MON_ENABLE);
568*5113495bSYour Name 	dp_mon_filter_setup_mon_mode(pdev);
569*5113495bSYour Name 	status = dp_mon_filter_update(pdev);
570*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
571*5113495bSYour Name 		dp_cdp_err("%pK: Failed to reset monitor filters", soc);
572*5113495bSYour Name 		dp_mon_filter_reset_mon_mode(pdev);
573*5113495bSYour Name 		mon_pdev->monitor_configured = false;
574*5113495bSYour Name 		mon_pdev->mvdev = NULL;
575*5113495bSYour Name 	}
576*5113495bSYour Name 
577*5113495bSYour Name fail:
578*5113495bSYour Name 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
579*5113495bSYour Name 	return status;
580*5113495bSYour Name }
581*5113495bSYour Name 
582*5113495bSYour Name #ifdef QCA_TX_CAPTURE_SUPPORT
583*5113495bSYour Name static QDF_STATUS
dp_config_tx_capture_mode(struct dp_pdev * pdev)584*5113495bSYour Name dp_config_tx_capture_mode(struct dp_pdev *pdev)
585*5113495bSYour Name {
586*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
587*5113495bSYour Name 
588*5113495bSYour Name 	mon_pdev->tx_sniffer_enable = 1;
589*5113495bSYour Name 	mon_pdev->monitor_configured = false;
590*5113495bSYour Name 
591*5113495bSYour Name 	if (!mon_pdev->pktlog_ppdu_stats)
592*5113495bSYour Name 		dp_h2t_cfg_stats_msg_send(pdev,
593*5113495bSYour Name 					  DP_PPDU_STATS_CFG_SNIFFER,
594*5113495bSYour Name 					  pdev->pdev_id);
595*5113495bSYour Name 
596*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
597*5113495bSYour Name }
598*5113495bSYour Name #else
599*5113495bSYour Name #ifdef QCA_MCOPY_SUPPORT
600*5113495bSYour Name static QDF_STATUS
dp_config_tx_capture_mode(struct dp_pdev * pdev)601*5113495bSYour Name dp_config_tx_capture_mode(struct dp_pdev *pdev)
602*5113495bSYour Name {
603*5113495bSYour Name 	return QDF_STATUS_E_INVAL;
604*5113495bSYour Name }
605*5113495bSYour Name #endif
606*5113495bSYour Name #endif
607*5113495bSYour Name 
608*5113495bSYour Name #if defined(QCA_MCOPY_SUPPORT) || defined(QCA_TX_CAPTURE_SUPPORT)
609*5113495bSYour Name QDF_STATUS
dp_config_debug_sniffer(struct dp_pdev * pdev,int val)610*5113495bSYour Name dp_config_debug_sniffer(struct dp_pdev *pdev, int val)
611*5113495bSYour Name {
612*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
613*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
614*5113495bSYour Name 
615*5113495bSYour Name 	/*
616*5113495bSYour Name 	 * Note: The mirror copy mode cannot co-exist with any other
617*5113495bSYour Name 	 * monitor modes. Hence disabling the filter for this mode will
618*5113495bSYour Name 	 * reset the monitor destination ring filters.
619*5113495bSYour Name 	 */
620*5113495bSYour Name 	dp_reset_mcopy_mode(pdev);
621*5113495bSYour Name 	switch (val) {
622*5113495bSYour Name 	case 0:
623*5113495bSYour Name 		mon_pdev->tx_sniffer_enable = 0;
624*5113495bSYour Name 		mon_pdev->monitor_configured = false;
625*5113495bSYour Name 
626*5113495bSYour Name 		/*
627*5113495bSYour Name 		 * We don't need to reset the Rx monitor status ring  or call
628*5113495bSYour Name 		 * the API dp_ppdu_ring_reset() if all debug sniffer mode is
629*5113495bSYour Name 		 * disabled. The Rx monitor status ring will be disabled when
630*5113495bSYour Name 		 * the last mode using the monitor status ring get disabled.
631*5113495bSYour Name 		 */
632*5113495bSYour Name 		if (!mon_pdev->pktlog_ppdu_stats &&
633*5113495bSYour Name 		    !mon_pdev->enhanced_stats_en &&
634*5113495bSYour Name 		    !mon_pdev->bpr_enable) {
635*5113495bSYour Name 			dp_h2t_cfg_stats_msg_send(pdev, 0, pdev->pdev_id);
636*5113495bSYour Name 		} else if (mon_pdev->enhanced_stats_en &&
637*5113495bSYour Name 			   !mon_pdev->bpr_enable) {
638*5113495bSYour Name 			dp_h2t_cfg_stats_msg_send(pdev,
639*5113495bSYour Name 						  DP_PPDU_STATS_CFG_ENH_STATS,
640*5113495bSYour Name 						  pdev->pdev_id);
641*5113495bSYour Name 		} else if (!mon_pdev->enhanced_stats_en &&
642*5113495bSYour Name 			   mon_pdev->bpr_enable) {
643*5113495bSYour Name 			dp_h2t_cfg_stats_msg_send(pdev,
644*5113495bSYour Name 						  DP_PPDU_STATS_CFG_BPR_ENH,
645*5113495bSYour Name 						  pdev->pdev_id);
646*5113495bSYour Name 		} else {
647*5113495bSYour Name 			dp_h2t_cfg_stats_msg_send(pdev,
648*5113495bSYour Name 						  DP_PPDU_STATS_CFG_BPR,
649*5113495bSYour Name 						  pdev->pdev_id);
650*5113495bSYour Name 		}
651*5113495bSYour Name 		break;
652*5113495bSYour Name 
653*5113495bSYour Name 	case 1:
654*5113495bSYour Name 		status = dp_config_tx_capture_mode(pdev);
655*5113495bSYour Name 		break;
656*5113495bSYour Name 	case 2:
657*5113495bSYour Name 	case 4:
658*5113495bSYour Name 		status = dp_config_mcopy_mode(pdev, val);
659*5113495bSYour Name 		break;
660*5113495bSYour Name 
661*5113495bSYour Name 	default:
662*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
663*5113495bSYour Name 			  "Invalid value, mode: %d not supported", val);
664*5113495bSYour Name 		status = QDF_STATUS_E_INVAL;
665*5113495bSYour Name 		break;
666*5113495bSYour Name 	}
667*5113495bSYour Name 	return status;
668*5113495bSYour Name }
669*5113495bSYour Name #endif
670*5113495bSYour Name 
671*5113495bSYour Name #ifdef QCA_UNDECODED_METADATA_SUPPORT
672*5113495bSYour Name QDF_STATUS
dp_mon_config_undecoded_metadata_capture(struct dp_pdev * pdev,int val)673*5113495bSYour Name dp_mon_config_undecoded_metadata_capture(struct dp_pdev *pdev, int val)
674*5113495bSYour Name {
675*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
676*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
677*5113495bSYour Name 
678*5113495bSYour Name 	if (!mon_pdev->mvdev && !mon_pdev->scan_spcl_vap_configured) {
679*5113495bSYour Name 		qdf_err("No monitor or Special vap, undecoded capture not supported");
680*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES;
681*5113495bSYour Name 	}
682*5113495bSYour Name 
683*5113495bSYour Name 	if (val)
684*5113495bSYour Name 		status = dp_enable_undecoded_metadata_capture(pdev, val);
685*5113495bSYour Name 	else
686*5113495bSYour Name 		status = dp_reset_undecoded_metadata_capture(pdev);
687*5113495bSYour Name 
688*5113495bSYour Name 	return status;
689*5113495bSYour Name }
690*5113495bSYour Name #endif
691*5113495bSYour Name 
692*5113495bSYour Name /**
693*5113495bSYour Name  * dp_monitor_mode_ring_config() - Send the tlv config to fw for monitor buffer
694*5113495bSYour Name  *                                 ring based on target
695*5113495bSYour Name  * @soc: soc handle
696*5113495bSYour Name  * @mac_for_pdev: WIN- pdev_id, MCL- mac id
697*5113495bSYour Name  * @pdev: physical device handle
698*5113495bSYour Name  * @ring_num: mac id
699*5113495bSYour Name  * @htt_tlv_filter: tlv filter
700*5113495bSYour Name  *
701*5113495bSYour Name  * Return: zero on success, non-zero on failure
702*5113495bSYour Name  */
703*5113495bSYour Name static inline QDF_STATUS
dp_monitor_mode_ring_config(struct dp_soc * soc,uint8_t mac_for_pdev,struct dp_pdev * pdev,uint8_t ring_num,struct htt_rx_ring_tlv_filter htt_tlv_filter)704*5113495bSYour Name dp_monitor_mode_ring_config(struct dp_soc *soc, uint8_t mac_for_pdev,
705*5113495bSYour Name 			    struct dp_pdev *pdev, uint8_t ring_num,
706*5113495bSYour Name 			    struct htt_rx_ring_tlv_filter htt_tlv_filter)
707*5113495bSYour Name {
708*5113495bSYour Name 	QDF_STATUS status;
709*5113495bSYour Name 
710*5113495bSYour Name 	if (soc->wlan_cfg_ctx->rxdma1_enable)
711*5113495bSYour Name 		status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
712*5113495bSYour Name 					     soc->rxdma_mon_buf_ring[ring_num]
713*5113495bSYour Name 					     .hal_srng,
714*5113495bSYour Name 					     RXDMA_MONITOR_BUF,
715*5113495bSYour Name 					     RX_MONITOR_BUFFER_SIZE,
716*5113495bSYour Name 					     &htt_tlv_filter);
717*5113495bSYour Name 	else
718*5113495bSYour Name 		status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
719*5113495bSYour Name 					     pdev->rx_mac_buf_ring[ring_num]
720*5113495bSYour Name 					     .hal_srng,
721*5113495bSYour Name 					     RXDMA_BUF, RX_DATA_BUFFER_SIZE,
722*5113495bSYour Name 					     &htt_tlv_filter);
723*5113495bSYour Name 
724*5113495bSYour Name 	return status;
725*5113495bSYour Name }
726*5113495bSYour Name 
727*5113495bSYour Name /**
728*5113495bSYour Name  * dp_get_mon_vdev_from_pdev_wifi3() - Get vdev id of monitor mode
729*5113495bSYour Name  * @soc_hdl: datapath soc handle
730*5113495bSYour Name  * @pdev_id: physical device instance id
731*5113495bSYour Name  *
732*5113495bSYour Name  * Return: virtual interface id
733*5113495bSYour Name  */
dp_get_mon_vdev_from_pdev_wifi3(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)734*5113495bSYour Name static uint8_t dp_get_mon_vdev_from_pdev_wifi3(struct cdp_soc_t *soc_hdl,
735*5113495bSYour Name 		uint8_t pdev_id)
736*5113495bSYour Name {
737*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
738*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
739*5113495bSYour Name 
740*5113495bSYour Name 	if (qdf_unlikely(!pdev || !pdev->monitor_pdev ||
741*5113495bSYour Name 				!pdev->monitor_pdev->mvdev))
742*5113495bSYour Name 		return -EINVAL;
743*5113495bSYour Name 
744*5113495bSYour Name 	return pdev->monitor_pdev->mvdev->vdev_id;
745*5113495bSYour Name }
746*5113495bSYour Name 
747*5113495bSYour Name #if defined(QCA_TX_CAPTURE_SUPPORT) || defined(QCA_ENHANCED_STATS_SUPPORT)
748*5113495bSYour Name #ifndef WLAN_TX_PKT_CAPTURE_ENH
dp_deliver_mgmt_frm(struct dp_pdev * pdev,qdf_nbuf_t nbuf)749*5113495bSYour Name void dp_deliver_mgmt_frm(struct dp_pdev *pdev, qdf_nbuf_t nbuf)
750*5113495bSYour Name {
751*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
752*5113495bSYour Name 
753*5113495bSYour Name 	if (mon_pdev->tx_sniffer_enable || mon_pdev->mcopy_mode) {
754*5113495bSYour Name 		dp_wdi_event_handler(WDI_EVENT_TX_MGMT_CTRL, pdev->soc,
755*5113495bSYour Name 				     nbuf, HTT_INVALID_PEER,
756*5113495bSYour Name 				     WDI_NO_VAL, pdev->pdev_id);
757*5113495bSYour Name 	} else {
758*5113495bSYour Name 		if (!mon_pdev->bpr_enable)
759*5113495bSYour Name 			qdf_nbuf_free(nbuf);
760*5113495bSYour Name 	}
761*5113495bSYour Name }
762*5113495bSYour Name #endif
763*5113495bSYour Name #endif
764*5113495bSYour Name 
dp_htt_ppdu_stats_attach(struct dp_pdev * pdev)765*5113495bSYour Name QDF_STATUS dp_htt_ppdu_stats_attach(struct dp_pdev *pdev)
766*5113495bSYour Name {
767*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
768*5113495bSYour Name 
769*5113495bSYour Name 	mon_pdev->ppdu_tlv_buf = qdf_mem_malloc(HTT_T2H_MAX_MSG_SIZE);
770*5113495bSYour Name 
771*5113495bSYour Name 	if (!mon_pdev->ppdu_tlv_buf) {
772*5113495bSYour Name 		QDF_TRACE_ERROR(QDF_MODULE_ID_DP, "ppdu_tlv_buf alloc fail");
773*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
774*5113495bSYour Name 	}
775*5113495bSYour Name 
776*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
777*5113495bSYour Name }
778*5113495bSYour Name 
dp_htt_ppdu_stats_detach(struct dp_pdev * pdev)779*5113495bSYour Name void dp_htt_ppdu_stats_detach(struct dp_pdev *pdev)
780*5113495bSYour Name {
781*5113495bSYour Name 	struct ppdu_info *ppdu_info, *ppdu_info_next;
782*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
783*5113495bSYour Name 
784*5113495bSYour Name 
785*5113495bSYour Name 	TAILQ_FOREACH_SAFE(ppdu_info, &mon_pdev->ppdu_info_list,
786*5113495bSYour Name 			   ppdu_info_list_elem, ppdu_info_next) {
787*5113495bSYour Name 		if (!ppdu_info)
788*5113495bSYour Name 			break;
789*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev->ppdu_info_list,
790*5113495bSYour Name 			     ppdu_info, ppdu_info_list_elem);
791*5113495bSYour Name 		mon_pdev->list_depth--;
792*5113495bSYour Name 		qdf_assert_always(ppdu_info->nbuf);
793*5113495bSYour Name 		qdf_nbuf_free(ppdu_info->nbuf);
794*5113495bSYour Name 		qdf_mem_free(ppdu_info);
795*5113495bSYour Name 	}
796*5113495bSYour Name 
797*5113495bSYour Name 	TAILQ_FOREACH_SAFE(ppdu_info, &mon_pdev->sched_comp_ppdu_list,
798*5113495bSYour Name 			   ppdu_info_list_elem, ppdu_info_next) {
799*5113495bSYour Name 		if (!ppdu_info)
800*5113495bSYour Name 			break;
801*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev->sched_comp_ppdu_list,
802*5113495bSYour Name 			     ppdu_info, ppdu_info_list_elem);
803*5113495bSYour Name 		mon_pdev->sched_comp_list_depth--;
804*5113495bSYour Name 		qdf_assert_always(ppdu_info->nbuf);
805*5113495bSYour Name 		qdf_nbuf_free(ppdu_info->nbuf);
806*5113495bSYour Name 		qdf_mem_free(ppdu_info);
807*5113495bSYour Name 	}
808*5113495bSYour Name 
809*5113495bSYour Name 	if (mon_pdev->ppdu_tlv_buf)
810*5113495bSYour Name 		qdf_mem_free(mon_pdev->ppdu_tlv_buf);
811*5113495bSYour Name }
812*5113495bSYour Name 
dp_pdev_get_rx_mon_stats(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,struct cdp_pdev_mon_stats * stats)813*5113495bSYour Name QDF_STATUS dp_pdev_get_rx_mon_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
814*5113495bSYour Name 				    struct cdp_pdev_mon_stats *stats)
815*5113495bSYour Name {
816*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
817*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
818*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
819*5113495bSYour Name 
820*5113495bSYour Name 	if (!pdev)
821*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
822*5113495bSYour Name 
823*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
824*5113495bSYour Name 	if (!mon_pdev)
825*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
826*5113495bSYour Name 
827*5113495bSYour Name 	qdf_mem_copy(stats, &mon_pdev->rx_mon_stats,
828*5113495bSYour Name 		     sizeof(struct cdp_pdev_mon_stats));
829*5113495bSYour Name 
830*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
831*5113495bSYour Name }
832*5113495bSYour Name 
833*5113495bSYour Name #ifdef QCA_UNDECODED_METADATA_SUPPORT
834*5113495bSYour Name /**
835*5113495bSYour Name  * dp_pdev_get_undecoded_capture_stats() - Get undecoded metadata captured
836*5113495bSYour Name  * monitor pdev stats
837*5113495bSYour Name  * @mon_pdev: Monitor PDEV handle
838*5113495bSYour Name  * @rx_mon_stats: Monitor pdev status/destination ring stats
839*5113495bSYour Name  *
840*5113495bSYour Name  * Return: None
841*5113495bSYour Name  */
842*5113495bSYour Name static inline void
dp_pdev_get_undecoded_capture_stats(struct dp_mon_pdev * mon_pdev,struct cdp_pdev_mon_stats * rx_mon_stats)843*5113495bSYour Name dp_pdev_get_undecoded_capture_stats(struct dp_mon_pdev *mon_pdev,
844*5113495bSYour Name 				    struct cdp_pdev_mon_stats *rx_mon_stats)
845*5113495bSYour Name {
846*5113495bSYour Name 	char undecoded_error[DP_UNDECODED_ERR_LENGTH];
847*5113495bSYour Name 	uint8_t index = 0, i;
848*5113495bSYour Name 
849*5113495bSYour Name 	DP_PRINT_STATS("Rx Undecoded Frame count:%d",
850*5113495bSYour Name 		       rx_mon_stats->rx_undecoded_count);
851*5113495bSYour Name 	index = 0;
852*5113495bSYour Name 	for (i = 0; i < (CDP_PHYRX_ERR_MAX); i++) {
853*5113495bSYour Name 		index += qdf_snprint(&undecoded_error[index],
854*5113495bSYour Name 				DP_UNDECODED_ERR_LENGTH - index,
855*5113495bSYour Name 				" %d", rx_mon_stats->rx_undecoded_error[i]);
856*5113495bSYour Name 	}
857*5113495bSYour Name 	DP_PRINT_STATS("Undecoded Error (0-63):%s", undecoded_error);
858*5113495bSYour Name }
859*5113495bSYour Name #else
860*5113495bSYour Name static inline void
dp_pdev_get_undecoded_capture_stats(struct dp_mon_pdev * mon_pdev,struct cdp_pdev_mon_stats * rx_mon_stats)861*5113495bSYour Name dp_pdev_get_undecoded_capture_stats(struct dp_mon_pdev *mon_pdev,
862*5113495bSYour Name 				    struct cdp_pdev_mon_stats *rx_mon_stats)
863*5113495bSYour Name {
864*5113495bSYour Name }
865*5113495bSYour Name #endif
866*5113495bSYour Name 
867*5113495bSYour Name static const char *
868*5113495bSYour Name dp_preamble_type_str[] = {
869*5113495bSYour Name 	"preamble OFDMA     ",
870*5113495bSYour Name 	"preamble CCK       ",
871*5113495bSYour Name 	"preamble HT        ",
872*5113495bSYour Name 	"preamble VHT       ",
873*5113495bSYour Name 	"preamble HE        ",
874*5113495bSYour Name 	"preamble EHT       ",
875*5113495bSYour Name 	"preamble NO SUPPORT",
876*5113495bSYour Name };
877*5113495bSYour Name 
878*5113495bSYour Name static const char *
879*5113495bSYour Name dp_reception_type_str[] = {
880*5113495bSYour Name 	"reception su        ",
881*5113495bSYour Name 	"reception mu_mimo   ",
882*5113495bSYour Name 	"reception ofdma     ",
883*5113495bSYour Name 	"reception ofdma mimo",
884*5113495bSYour Name };
885*5113495bSYour Name 
886*5113495bSYour Name static const char *
887*5113495bSYour Name dp_mu_dl_ul_str[] = {
888*5113495bSYour Name 	"MU DL",
889*5113495bSYour Name 	"MU UL",
890*5113495bSYour Name };
891*5113495bSYour Name 
892*5113495bSYour Name static inline void
dp_print_pdev_mpdu_fcs_ok_cnt(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t,uint32_t dl_ul,uint32_t user)893*5113495bSYour Name dp_print_pdev_mpdu_fcs_ok_cnt(struct cdp_pdev_mon_stats *rx_mon_sts,
894*5113495bSYour Name 			      uint32_t pkt_t, uint32_t rx_t,
895*5113495bSYour Name 			      uint32_t dl_ul, uint32_t user)
896*5113495bSYour Name {
897*5113495bSYour Name 	DP_PRINT_STATS("%s, %s, %s, user=%d, mpdu_fcs_ok=%d",
898*5113495bSYour Name 		       dp_preamble_type_str[pkt_t],
899*5113495bSYour Name 		       dp_reception_type_str[rx_t],
900*5113495bSYour Name 		       dp_mu_dl_ul_str[dl_ul],
901*5113495bSYour Name 		       user,
902*5113495bSYour Name 		       rx_mon_sts->mpdu_cnt_fcs_ok[pkt_t][rx_t][dl_ul][user]);
903*5113495bSYour Name }
904*5113495bSYour Name 
905*5113495bSYour Name static inline void
dp_print_pdev_mpdu_fcs_err_cnt(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t,uint32_t dl_ul,uint32_t user)906*5113495bSYour Name dp_print_pdev_mpdu_fcs_err_cnt(struct cdp_pdev_mon_stats *rx_mon_sts,
907*5113495bSYour Name 			       uint32_t pkt_t, uint32_t rx_t,
908*5113495bSYour Name 			       uint32_t dl_ul, uint32_t user)
909*5113495bSYour Name {
910*5113495bSYour Name 	DP_PRINT_STATS("%s, %s, %s, user=%d, mpdu_fcs_err=%d",
911*5113495bSYour Name 		       dp_preamble_type_str[pkt_t],
912*5113495bSYour Name 		       dp_reception_type_str[rx_t],
913*5113495bSYour Name 		       dp_mu_dl_ul_str[dl_ul],
914*5113495bSYour Name 		       user,
915*5113495bSYour Name 		       rx_mon_sts->mpdu_cnt_fcs_err[pkt_t][rx_t][dl_ul][user]);
916*5113495bSYour Name }
917*5113495bSYour Name 
918*5113495bSYour Name static inline void
dp_print_pdev_mpdu_cnt(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t,uint32_t dl_ul,uint32_t user)919*5113495bSYour Name dp_print_pdev_mpdu_cnt(struct cdp_pdev_mon_stats *rx_mon_sts,
920*5113495bSYour Name 		       uint32_t pkt_t, uint32_t rx_t,
921*5113495bSYour Name 		       uint32_t dl_ul, uint32_t user)
922*5113495bSYour Name {
923*5113495bSYour Name 	if (rx_mon_sts->mpdu_cnt_fcs_ok[pkt_t][rx_t][dl_ul][user])
924*5113495bSYour Name 		dp_print_pdev_mpdu_fcs_ok_cnt(rx_mon_sts, pkt_t, rx_t,
925*5113495bSYour Name 					      dl_ul, user);
926*5113495bSYour Name 
927*5113495bSYour Name 	if (rx_mon_sts->mpdu_cnt_fcs_err[pkt_t][rx_t][dl_ul][user])
928*5113495bSYour Name 		dp_print_pdev_mpdu_fcs_err_cnt(rx_mon_sts, pkt_t, rx_t,
929*5113495bSYour Name 					       dl_ul, user);
930*5113495bSYour Name }
931*5113495bSYour Name 
932*5113495bSYour Name static inline void
dp_print_pdev_mpdu_user(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t,uint32_t dl_ul)933*5113495bSYour Name dp_print_pdev_mpdu_user(struct cdp_pdev_mon_stats *rx_mon_sts,
934*5113495bSYour Name 			uint32_t pkt_t, uint32_t rx_t,
935*5113495bSYour Name 			uint32_t dl_ul)
936*5113495bSYour Name {
937*5113495bSYour Name 	uint32_t user;
938*5113495bSYour Name 
939*5113495bSYour Name 	for (user = 0; user < CDP_MU_SNIF_USER_MAX; user++)
940*5113495bSYour Name 		dp_print_pdev_mpdu_cnt(rx_mon_sts, pkt_t, rx_t,
941*5113495bSYour Name 				       dl_ul, user);
942*5113495bSYour Name }
943*5113495bSYour Name 
944*5113495bSYour Name static inline void
dp_print_pdev_mpdu_dl_ul(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t,uint32_t rx_t)945*5113495bSYour Name dp_print_pdev_mpdu_dl_ul(struct cdp_pdev_mon_stats *rx_mon_sts,
946*5113495bSYour Name 			 uint32_t pkt_t, uint32_t rx_t)
947*5113495bSYour Name {
948*5113495bSYour Name 	uint32_t dl_ul;
949*5113495bSYour Name 
950*5113495bSYour Name 	for (dl_ul = CDP_MU_TYPE_DL; dl_ul < CDP_MU_TYPE_MAX; dl_ul++)
951*5113495bSYour Name 		dp_print_pdev_mpdu_user(rx_mon_sts, pkt_t, rx_t,
952*5113495bSYour Name 					dl_ul);
953*5113495bSYour Name }
954*5113495bSYour Name 
955*5113495bSYour Name static inline void
dp_print_pdev_mpdu_rx_type(struct cdp_pdev_mon_stats * rx_mon_sts,uint32_t pkt_t)956*5113495bSYour Name dp_print_pdev_mpdu_rx_type(struct cdp_pdev_mon_stats *rx_mon_sts,
957*5113495bSYour Name 			   uint32_t pkt_t)
958*5113495bSYour Name {
959*5113495bSYour Name 	uint32_t rx_t;
960*5113495bSYour Name 
961*5113495bSYour Name 	for (rx_t = CDP_RX_TYPE_SU; rx_t < CDP_RX_TYPE_MAX; rx_t++)
962*5113495bSYour Name 		dp_print_pdev_mpdu_dl_ul(rx_mon_sts, pkt_t, rx_t);
963*5113495bSYour Name }
964*5113495bSYour Name 
965*5113495bSYour Name static inline void
dp_print_pdev_mpdu_pkt_type(struct cdp_pdev_mon_stats * rx_mon_sts)966*5113495bSYour Name dp_print_pdev_mpdu_pkt_type(struct cdp_pdev_mon_stats *rx_mon_sts)
967*5113495bSYour Name {
968*5113495bSYour Name 	uint32_t pkt_t;
969*5113495bSYour Name 
970*5113495bSYour Name 	for (pkt_t = CDP_PKT_TYPE_OFDM; pkt_t < CDP_PKT_TYPE_MAX; pkt_t++)
971*5113495bSYour Name 		dp_print_pdev_mpdu_rx_type(rx_mon_sts, pkt_t);
972*5113495bSYour Name }
973*5113495bSYour Name 
974*5113495bSYour Name static inline void
print_ppdu_eht_type_mode(struct cdp_pdev_mon_stats * rx_mon_stats,uint32_t ppdu_type_mode,uint32_t dl_ul)975*5113495bSYour Name print_ppdu_eht_type_mode(
976*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_stats,
977*5113495bSYour Name 	uint32_t ppdu_type_mode,
978*5113495bSYour Name 	uint32_t dl_ul)
979*5113495bSYour Name {
980*5113495bSYour Name 	DP_PRINT_STATS("type_mode=%d, dl_ul=%d, cnt=%d",
981*5113495bSYour Name 		       ppdu_type_mode,
982*5113495bSYour Name 		       dl_ul,
983*5113495bSYour Name 		       rx_mon_stats->ppdu_eht_type_mode[ppdu_type_mode][dl_ul]);
984*5113495bSYour Name }
985*5113495bSYour Name 
986*5113495bSYour Name static inline void
print_ppdu_eth_type_mode_dl_ul(struct cdp_pdev_mon_stats * rx_mon_stats,uint32_t ppdu_type_mode)987*5113495bSYour Name print_ppdu_eth_type_mode_dl_ul(
988*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_stats,
989*5113495bSYour Name 	uint32_t ppdu_type_mode
990*5113495bSYour Name )
991*5113495bSYour Name {
992*5113495bSYour Name 	uint32_t dl_ul;
993*5113495bSYour Name 
994*5113495bSYour Name 	for (dl_ul = 0; dl_ul < CDP_MU_TYPE_MAX; dl_ul++) {
995*5113495bSYour Name 		if (rx_mon_stats->ppdu_eht_type_mode[ppdu_type_mode][dl_ul])
996*5113495bSYour Name 			print_ppdu_eht_type_mode(rx_mon_stats,
997*5113495bSYour Name 						 ppdu_type_mode, dl_ul);
998*5113495bSYour Name 	}
999*5113495bSYour Name }
1000*5113495bSYour Name 
1001*5113495bSYour Name static inline void
dp_print_pdev_eht_ppdu_cnt(struct dp_pdev * pdev)1002*5113495bSYour Name dp_print_pdev_eht_ppdu_cnt(struct dp_pdev *pdev)
1003*5113495bSYour Name {
1004*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_stats;
1005*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1006*5113495bSYour Name 	uint32_t ppdu_type_mode;
1007*5113495bSYour Name 
1008*5113495bSYour Name 	rx_mon_stats = &mon_pdev->rx_mon_stats;
1009*5113495bSYour Name 	DP_PRINT_STATS("Monitor EHT PPDU  Count");
1010*5113495bSYour Name 	for (ppdu_type_mode = 0; ppdu_type_mode < CDP_EHT_TYPE_MODE_MAX;
1011*5113495bSYour Name 	     ppdu_type_mode++) {
1012*5113495bSYour Name 		print_ppdu_eth_type_mode_dl_ul(rx_mon_stats,
1013*5113495bSYour Name 					       ppdu_type_mode);
1014*5113495bSYour Name 	}
1015*5113495bSYour Name }
1016*5113495bSYour Name 
1017*5113495bSYour Name static inline void
dp_print_pdev_mpdu_stats(struct dp_pdev * pdev)1018*5113495bSYour Name dp_print_pdev_mpdu_stats(struct dp_pdev *pdev)
1019*5113495bSYour Name {
1020*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_stats;
1021*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1022*5113495bSYour Name 
1023*5113495bSYour Name 	rx_mon_stats = &mon_pdev->rx_mon_stats;
1024*5113495bSYour Name 	DP_PRINT_STATS("Monitor MPDU Count");
1025*5113495bSYour Name 	dp_print_pdev_mpdu_pkt_type(rx_mon_stats);
1026*5113495bSYour Name }
1027*5113495bSYour Name 
1028*5113495bSYour Name void
dp_print_pdev_rx_mon_stats(struct dp_pdev * pdev)1029*5113495bSYour Name dp_print_pdev_rx_mon_stats(struct dp_pdev *pdev)
1030*5113495bSYour Name {
1031*5113495bSYour Name 	struct cdp_pdev_mon_stats *rx_mon_stats;
1032*5113495bSYour Name 	uint32_t *stat_ring_ppdu_ids;
1033*5113495bSYour Name 	uint32_t *dest_ring_ppdu_ids;
1034*5113495bSYour Name 	int i, idx;
1035*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1036*5113495bSYour Name 
1037*5113495bSYour Name 	rx_mon_stats = &mon_pdev->rx_mon_stats;
1038*5113495bSYour Name 
1039*5113495bSYour Name 	DP_PRINT_STATS("PDEV Rx Monitor Stats:\n");
1040*5113495bSYour Name 
1041*5113495bSYour Name 	DP_PRINT_STATS("status_ppdu_compl_cnt = %d",
1042*5113495bSYour Name 		       rx_mon_stats->status_ppdu_compl);
1043*5113495bSYour Name 	DP_PRINT_STATS("status_ppdu_start_cnt = %d",
1044*5113495bSYour Name 		       rx_mon_stats->status_ppdu_start);
1045*5113495bSYour Name 	DP_PRINT_STATS("status_ppdu_end_cnt = %d",
1046*5113495bSYour Name 		       rx_mon_stats->status_ppdu_end);
1047*5113495bSYour Name 	DP_PRINT_STATS("status_ppdu_start_mis_cnt = %d",
1048*5113495bSYour Name 		       rx_mon_stats->status_ppdu_start_mis);
1049*5113495bSYour Name 	DP_PRINT_STATS("status_ppdu_end_mis_cnt = %d",
1050*5113495bSYour Name 		       rx_mon_stats->status_ppdu_end_mis);
1051*5113495bSYour Name 
1052*5113495bSYour Name 	DP_PRINT_STATS("start_user_info_cnt = %d",
1053*5113495bSYour Name 		       rx_mon_stats->start_user_info_cnt);
1054*5113495bSYour Name 	DP_PRINT_STATS("end_user_stats_cnt = %d",
1055*5113495bSYour Name 		       rx_mon_stats->end_user_stats_cnt);
1056*5113495bSYour Name 
1057*5113495bSYour Name 	DP_PRINT_STATS("status_ppdu_done_cnt = %d",
1058*5113495bSYour Name 		       rx_mon_stats->status_ppdu_done);
1059*5113495bSYour Name 	DP_PRINT_STATS("dest_ppdu_done_cnt = %d",
1060*5113495bSYour Name 		       rx_mon_stats->dest_ppdu_done);
1061*5113495bSYour Name 	DP_PRINT_STATS("dest_mpdu_done_cnt = %d",
1062*5113495bSYour Name 		       rx_mon_stats->dest_mpdu_done);
1063*5113495bSYour Name 	DP_PRINT_STATS("tlv_tag_status_err_cnt = %u",
1064*5113495bSYour Name 		       rx_mon_stats->tlv_tag_status_err);
1065*5113495bSYour Name 	DP_PRINT_STATS("mon status DMA not done WAR count= %u",
1066*5113495bSYour Name 		       rx_mon_stats->status_buf_done_war);
1067*5113495bSYour Name 	DP_PRINT_STATS("dest_mpdu_drop_cnt = %d",
1068*5113495bSYour Name 		       rx_mon_stats->dest_mpdu_drop);
1069*5113495bSYour Name 	DP_PRINT_STATS("dup_mon_linkdesc_cnt = %d",
1070*5113495bSYour Name 		       rx_mon_stats->dup_mon_linkdesc_cnt);
1071*5113495bSYour Name 	DP_PRINT_STATS("dup_mon_buf_cnt = %d",
1072*5113495bSYour Name 		       rx_mon_stats->dup_mon_buf_cnt);
1073*5113495bSYour Name 	DP_PRINT_STATS("mon_rx_buf_reaped = %u",
1074*5113495bSYour Name 		       rx_mon_stats->mon_rx_bufs_reaped_dest);
1075*5113495bSYour Name 	DP_PRINT_STATS("mon_rx_buf_replenished = %u",
1076*5113495bSYour Name 		       rx_mon_stats->mon_rx_bufs_replenished_dest);
1077*5113495bSYour Name 	DP_PRINT_STATS("ppdu_id_mismatch = %u",
1078*5113495bSYour Name 		       rx_mon_stats->ppdu_id_mismatch);
1079*5113495bSYour Name 	DP_PRINT_STATS("mpdu_ppdu_id_match_cnt = %d",
1080*5113495bSYour Name 		       rx_mon_stats->ppdu_id_match);
1081*5113495bSYour Name 	DP_PRINT_STATS("ppdus dropped frm status ring = %d",
1082*5113495bSYour Name 		       rx_mon_stats->status_ppdu_drop);
1083*5113495bSYour Name 	DP_PRINT_STATS("ppdus dropped frm dest ring = %d",
1084*5113495bSYour Name 		       rx_mon_stats->dest_ppdu_drop);
1085*5113495bSYour Name 	DP_PRINT_STATS("mpdu_ppdu_id_mismatch_drop = %u",
1086*5113495bSYour Name 		       rx_mon_stats->mpdu_ppdu_id_mismatch_drop);
1087*5113495bSYour Name 	DP_PRINT_STATS("mpdu_decap_type_invalid = %u",
1088*5113495bSYour Name 		       rx_mon_stats->mpdu_decap_type_invalid);
1089*5113495bSYour Name 	DP_PRINT_STATS("pending_desc_count = %u",
1090*5113495bSYour Name 		       rx_mon_stats->pending_desc_count);
1091*5113495bSYour Name 	stat_ring_ppdu_ids =
1092*5113495bSYour Name 		(uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST);
1093*5113495bSYour Name 	dest_ring_ppdu_ids =
1094*5113495bSYour Name 		(uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST);
1095*5113495bSYour Name 
1096*5113495bSYour Name 	if (!stat_ring_ppdu_ids || !dest_ring_ppdu_ids)
1097*5113495bSYour Name 		DP_PRINT_STATS("Unable to allocate ppdu id hist mem\n");
1098*5113495bSYour Name 
1099*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
1100*5113495bSYour Name 	idx = rx_mon_stats->ppdu_id_hist_idx;
1101*5113495bSYour Name 	qdf_mem_copy(stat_ring_ppdu_ids,
1102*5113495bSYour Name 		     rx_mon_stats->stat_ring_ppdu_id_hist,
1103*5113495bSYour Name 		     sizeof(uint32_t) * MAX_PPDU_ID_HIST);
1104*5113495bSYour Name 	qdf_mem_copy(dest_ring_ppdu_ids,
1105*5113495bSYour Name 		     rx_mon_stats->dest_ring_ppdu_id_hist,
1106*5113495bSYour Name 		     sizeof(uint32_t) * MAX_PPDU_ID_HIST);
1107*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
1108*5113495bSYour Name 
1109*5113495bSYour Name 	DP_PRINT_STATS("PPDU Id history:");
1110*5113495bSYour Name 	DP_PRINT_STATS("stat_ring_ppdu_ids\t dest_ring_ppdu_ids");
1111*5113495bSYour Name 	for (i = 0; i < MAX_PPDU_ID_HIST; i++) {
1112*5113495bSYour Name 		idx = (idx + 1) & (MAX_PPDU_ID_HIST - 1);
1113*5113495bSYour Name 		DP_PRINT_STATS("%*u\t%*u", 16,
1114*5113495bSYour Name 			       rx_mon_stats->stat_ring_ppdu_id_hist[idx], 16,
1115*5113495bSYour Name 			       rx_mon_stats->dest_ring_ppdu_id_hist[idx]);
1116*5113495bSYour Name 	}
1117*5113495bSYour Name 	qdf_mem_free(stat_ring_ppdu_ids);
1118*5113495bSYour Name 	qdf_mem_free(dest_ring_ppdu_ids);
1119*5113495bSYour Name 	DP_PRINT_STATS("mon_rx_dest_stuck = %d",
1120*5113495bSYour Name 		       rx_mon_stats->mon_rx_dest_stuck);
1121*5113495bSYour Name 
1122*5113495bSYour Name 	dp_pdev_get_undecoded_capture_stats(mon_pdev, rx_mon_stats);
1123*5113495bSYour Name 	dp_mon_rx_print_advanced_stats(pdev->soc, pdev);
1124*5113495bSYour Name 
1125*5113495bSYour Name 	dp_print_pdev_mpdu_stats(pdev);
1126*5113495bSYour Name 	dp_print_pdev_eht_ppdu_cnt(pdev);
1127*5113495bSYour Name 
1128*5113495bSYour Name }
1129*5113495bSYour Name 
1130*5113495bSYour Name #ifdef QCA_SUPPORT_BPR
1131*5113495bSYour Name QDF_STATUS
dp_set_bpr_enable(struct dp_pdev * pdev,int val)1132*5113495bSYour Name dp_set_bpr_enable(struct dp_pdev *pdev, int val)
1133*5113495bSYour Name {
1134*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
1135*5113495bSYour Name 
1136*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
1137*5113495bSYour Name 	if (mon_ops && mon_ops->mon_set_bpr_enable)
1138*5113495bSYour Name 		return mon_ops->mon_set_bpr_enable(pdev, val);
1139*5113495bSYour Name 
1140*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
1141*5113495bSYour Name }
1142*5113495bSYour Name #endif
1143*5113495bSYour Name 
1144*5113495bSYour Name #ifdef WDI_EVENT_ENABLE
1145*5113495bSYour Name #ifdef BE_PKTLOG_SUPPORT
1146*5113495bSYour Name static bool
dp_set_hybrid_pktlog_enable(struct dp_pdev * pdev,struct dp_mon_pdev * mon_pdev,struct dp_soc * soc)1147*5113495bSYour Name dp_set_hybrid_pktlog_enable(struct dp_pdev *pdev,
1148*5113495bSYour Name 			    struct dp_mon_pdev *mon_pdev,
1149*5113495bSYour Name 			    struct dp_soc *soc)
1150*5113495bSYour Name {
1151*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
1152*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
1153*5113495bSYour Name 	uint16_t num_buffers;
1154*5113495bSYour Name 
1155*5113495bSYour Name 	/* Nothing needs to be done if monitor mode is
1156*5113495bSYour Name 	 * enabled
1157*5113495bSYour Name 	 */
1158*5113495bSYour Name 	if (mon_pdev->mvdev)
1159*5113495bSYour Name 		return false;
1160*5113495bSYour Name 
1161*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
1162*5113495bSYour Name 	if (!mon_ops) {
1163*5113495bSYour Name 		dp_mon_filter_err("Mon ops uninitialized");
1164*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1165*5113495bSYour Name 	}
1166*5113495bSYour Name 
1167*5113495bSYour Name 	if (!mon_pdev->pktlog_hybrid_mode) {
1168*5113495bSYour Name 		mon_pdev->pktlog_hybrid_mode = true;
1169*5113495bSYour Name 		soc_cfg_ctx = soc->wlan_cfg_ctx;
1170*5113495bSYour Name 		num_buffers =
1171*5113495bSYour Name 			wlan_cfg_get_dp_soc_tx_mon_buf_ring_size(soc_cfg_ctx);
1172*5113495bSYour Name 
1173*5113495bSYour Name 		if (mon_ops && mon_ops->set_mon_mode_buf_rings_tx)
1174*5113495bSYour Name 			mon_ops->set_mon_mode_buf_rings_tx(pdev, num_buffers);
1175*5113495bSYour Name 
1176*5113495bSYour Name 		dp_mon_filter_setup_pktlog_hybrid(pdev);
1177*5113495bSYour Name 		if (dp_tx_mon_filter_update(pdev) !=
1178*5113495bSYour Name 		    QDF_STATUS_SUCCESS) {
1179*5113495bSYour Name 			dp_cdp_err("Set hybrid filters failed");
1180*5113495bSYour Name 			dp_mon_filter_reset_pktlog_hybrid(pdev);
1181*5113495bSYour Name 			mon_pdev->rx_pktlog_mode =
1182*5113495bSYour Name 				DP_RX_PKTLOG_DISABLED;
1183*5113495bSYour Name 			return false;
1184*5113495bSYour Name 		}
1185*5113495bSYour Name 
1186*5113495bSYour Name 		dp_monitor_reap_timer_start(soc, CDP_MON_REAP_SOURCE_PKTLOG);
1187*5113495bSYour Name 	}
1188*5113495bSYour Name 
1189*5113495bSYour Name 	return true;
1190*5113495bSYour Name }
1191*5113495bSYour Name 
1192*5113495bSYour Name static void
dp_set_hybrid_pktlog_disable(struct dp_mon_pdev * mon_pdev)1193*5113495bSYour Name dp_set_hybrid_pktlog_disable(struct dp_mon_pdev *mon_pdev)
1194*5113495bSYour Name {
1195*5113495bSYour Name 	mon_pdev->pktlog_hybrid_mode = false;
1196*5113495bSYour Name }
1197*5113495bSYour Name #else
1198*5113495bSYour Name static void
dp_set_hybrid_pktlog_disable(struct dp_mon_pdev * mon_pdev)1199*5113495bSYour Name dp_set_hybrid_pktlog_disable(struct dp_mon_pdev *mon_pdev)
1200*5113495bSYour Name {
1201*5113495bSYour Name }
1202*5113495bSYour Name 
1203*5113495bSYour Name static bool
dp_set_hybrid_pktlog_enable(struct dp_pdev * pdev,struct dp_mon_pdev * mon_pdev,struct dp_soc * soc)1204*5113495bSYour Name dp_set_hybrid_pktlog_enable(struct dp_pdev *pdev,
1205*5113495bSYour Name 			    struct dp_mon_pdev *mon_pdev,
1206*5113495bSYour Name 			    struct dp_soc *soc)
1207*5113495bSYour Name {
1208*5113495bSYour Name 	dp_cdp_err("Hybrid mode is supported only on beryllium");
1209*5113495bSYour Name 	return true;
1210*5113495bSYour Name }
1211*5113495bSYour Name #endif
dp_set_pktlog_wifi3(struct dp_pdev * pdev,uint32_t event,bool enable)1212*5113495bSYour Name int dp_set_pktlog_wifi3(struct dp_pdev *pdev, uint32_t event,
1213*5113495bSYour Name 		        bool enable)
1214*5113495bSYour Name {
1215*5113495bSYour Name 	struct dp_soc *soc = NULL;
1216*5113495bSYour Name 	int max_mac_rings = wlan_cfg_get_num_mac_rings
1217*5113495bSYour Name 					(pdev->wlan_cfg_ctx);
1218*5113495bSYour Name 	uint8_t mac_id = 0;
1219*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
1220*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1221*5113495bSYour Name 
1222*5113495bSYour Name 	soc = pdev->soc;
1223*5113495bSYour Name 	mon_ops = dp_mon_ops_get(soc);
1224*5113495bSYour Name 
1225*5113495bSYour Name 	if (!mon_ops)
1226*5113495bSYour Name 		return 0;
1227*5113495bSYour Name 
1228*5113495bSYour Name 	dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings);
1229*5113495bSYour Name 
1230*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
1231*5113495bSYour Name 		  FL("Max_mac_rings %d "),
1232*5113495bSYour Name 		  max_mac_rings);
1233*5113495bSYour Name 
1234*5113495bSYour Name 	if (enable) {
1235*5113495bSYour Name 		switch (event) {
1236*5113495bSYour Name 		case WDI_EVENT_RX_DESC:
1237*5113495bSYour Name 			/* Nothing needs to be done if monitor mode is
1238*5113495bSYour Name 			 * enabled
1239*5113495bSYour Name 			 */
1240*5113495bSYour Name 			if (mon_pdev->mvdev)
1241*5113495bSYour Name 				return 0;
1242*5113495bSYour Name 
1243*5113495bSYour Name 			if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_FULL)
1244*5113495bSYour Name 				break;
1245*5113495bSYour Name 
1246*5113495bSYour Name 			mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_FULL;
1247*5113495bSYour Name 			dp_mon_filter_setup_rx_pkt_log_full(pdev);
1248*5113495bSYour Name 			if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
1249*5113495bSYour Name 				dp_cdp_err("%pK: Pktlog full filters set failed",
1250*5113495bSYour Name 					   soc);
1251*5113495bSYour Name 				dp_mon_filter_reset_rx_pkt_log_full(pdev);
1252*5113495bSYour Name 				mon_pdev->rx_pktlog_mode =
1253*5113495bSYour Name 					DP_RX_PKTLOG_DISABLED;
1254*5113495bSYour Name 				return 0;
1255*5113495bSYour Name 			}
1256*5113495bSYour Name 
1257*5113495bSYour Name 			dp_monitor_reap_timer_start(soc,
1258*5113495bSYour Name 						    CDP_MON_REAP_SOURCE_PKTLOG);
1259*5113495bSYour Name 			break;
1260*5113495bSYour Name 
1261*5113495bSYour Name 		case WDI_EVENT_LITE_RX:
1262*5113495bSYour Name 			/* Nothing needs to be done if monitor mode is
1263*5113495bSYour Name 			 * enabled
1264*5113495bSYour Name 			 */
1265*5113495bSYour Name 			if (mon_pdev->mvdev)
1266*5113495bSYour Name 				return 0;
1267*5113495bSYour Name 
1268*5113495bSYour Name 			if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_LITE)
1269*5113495bSYour Name 				break;
1270*5113495bSYour Name 
1271*5113495bSYour Name 			mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_LITE;
1272*5113495bSYour Name 
1273*5113495bSYour Name 			/*
1274*5113495bSYour Name 			 * Set the packet log lite mode filter.
1275*5113495bSYour Name 			 */
1276*5113495bSYour Name 			dp_mon_filter_setup_rx_pkt_log_lite(pdev);
1277*5113495bSYour Name 			if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
1278*5113495bSYour Name 				dp_cdp_err("%pK: Pktlog lite filters set failed",
1279*5113495bSYour Name 					   soc);
1280*5113495bSYour Name 				dp_mon_filter_reset_rx_pkt_log_lite(pdev);
1281*5113495bSYour Name 				mon_pdev->rx_pktlog_mode =
1282*5113495bSYour Name 					DP_RX_PKTLOG_DISABLED;
1283*5113495bSYour Name 				return 0;
1284*5113495bSYour Name 			}
1285*5113495bSYour Name 
1286*5113495bSYour Name 			dp_monitor_reap_timer_start(soc,
1287*5113495bSYour Name 						    CDP_MON_REAP_SOURCE_PKTLOG);
1288*5113495bSYour Name 			break;
1289*5113495bSYour Name 		case WDI_EVENT_LITE_T2H:
1290*5113495bSYour Name 			for (mac_id = 0; mac_id < max_mac_rings; mac_id++) {
1291*5113495bSYour Name 				int mac_for_pdev = dp_get_mac_id_for_pdev(
1292*5113495bSYour Name 							mac_id,	pdev->pdev_id);
1293*5113495bSYour Name 
1294*5113495bSYour Name 				mon_pdev->pktlog_ppdu_stats = true;
1295*5113495bSYour Name 				dp_h2t_cfg_stats_msg_send(pdev,
1296*5113495bSYour Name 					DP_PPDU_TXLITE_STATS_BITMASK_CFG,
1297*5113495bSYour Name 					mac_for_pdev);
1298*5113495bSYour Name 			}
1299*5113495bSYour Name 			break;
1300*5113495bSYour Name 
1301*5113495bSYour Name 		case WDI_EVENT_RX_CBF:
1302*5113495bSYour Name 			/* Nothing needs to be done if monitor mode is
1303*5113495bSYour Name 			 * enabled
1304*5113495bSYour Name 			 */
1305*5113495bSYour Name 			if (mon_pdev->mvdev)
1306*5113495bSYour Name 				return 0;
1307*5113495bSYour Name 
1308*5113495bSYour Name 			if (mon_pdev->rx_pktlog_cbf)
1309*5113495bSYour Name 				break;
1310*5113495bSYour Name 
1311*5113495bSYour Name 			mon_pdev->rx_pktlog_cbf = true;
1312*5113495bSYour Name 			mon_pdev->monitor_configured = true;
1313*5113495bSYour Name 			if (mon_ops->mon_vdev_set_monitor_mode_buf_rings)
1314*5113495bSYour Name 				mon_ops->mon_vdev_set_monitor_mode_buf_rings(
1315*5113495bSYour Name 					pdev);
1316*5113495bSYour Name 
1317*5113495bSYour Name 			/*
1318*5113495bSYour Name 			 * Set the packet log lite mode filter.
1319*5113495bSYour Name 			 */
1320*5113495bSYour Name 			qdf_info("Non mon mode: Enable destination ring");
1321*5113495bSYour Name 
1322*5113495bSYour Name 			dp_mon_filter_setup_rx_pkt_log_cbf(pdev);
1323*5113495bSYour Name 			if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
1324*5113495bSYour Name 				dp_mon_err("Pktlog set CBF filters failed");
1325*5113495bSYour Name 				dp_mon_filter_reset_rx_pktlog_cbf(pdev);
1326*5113495bSYour Name 				mon_pdev->rx_pktlog_mode =
1327*5113495bSYour Name 					DP_RX_PKTLOG_DISABLED;
1328*5113495bSYour Name 				mon_pdev->monitor_configured = false;
1329*5113495bSYour Name 				return 0;
1330*5113495bSYour Name 			}
1331*5113495bSYour Name 
1332*5113495bSYour Name 			dp_monitor_reap_timer_start(soc,
1333*5113495bSYour Name 						    CDP_MON_REAP_SOURCE_PKTLOG);
1334*5113495bSYour Name 			break;
1335*5113495bSYour Name 		case WDI_EVENT_HYBRID_TX:
1336*5113495bSYour Name 			if (!dp_set_hybrid_pktlog_enable(pdev, mon_pdev, soc))
1337*5113495bSYour Name 				return 0;
1338*5113495bSYour Name 			break;
1339*5113495bSYour Name 
1340*5113495bSYour Name 		default:
1341*5113495bSYour Name 			/* Nothing needs to be done for other pktlog types */
1342*5113495bSYour Name 			break;
1343*5113495bSYour Name 		}
1344*5113495bSYour Name 	} else {
1345*5113495bSYour Name 		switch (event) {
1346*5113495bSYour Name 		case WDI_EVENT_RX_DESC:
1347*5113495bSYour Name 		case WDI_EVENT_LITE_RX:
1348*5113495bSYour Name 			/* Nothing needs to be done if monitor mode is
1349*5113495bSYour Name 			 * enabled
1350*5113495bSYour Name 			 */
1351*5113495bSYour Name 			if (mon_pdev->mvdev)
1352*5113495bSYour Name 				return 0;
1353*5113495bSYour Name 
1354*5113495bSYour Name 			if (mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_DISABLED)
1355*5113495bSYour Name 				break;
1356*5113495bSYour Name 
1357*5113495bSYour Name 			mon_pdev->rx_pktlog_mode = DP_RX_PKTLOG_DISABLED;
1358*5113495bSYour Name 			dp_mon_filter_reset_rx_pkt_log_full(pdev);
1359*5113495bSYour Name 			if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
1360*5113495bSYour Name 				dp_cdp_err("%pK: Pktlog filters reset failed",
1361*5113495bSYour Name 					   soc);
1362*5113495bSYour Name 				return 0;
1363*5113495bSYour Name 			}
1364*5113495bSYour Name 
1365*5113495bSYour Name 			dp_mon_filter_reset_rx_pkt_log_lite(pdev);
1366*5113495bSYour Name 			if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
1367*5113495bSYour Name 				dp_cdp_err("%pK: Pktlog filters reset failed",
1368*5113495bSYour Name 					   soc);
1369*5113495bSYour Name 				return 0;
1370*5113495bSYour Name 			}
1371*5113495bSYour Name 
1372*5113495bSYour Name 			dp_monitor_reap_timer_stop(soc,
1373*5113495bSYour Name 						   CDP_MON_REAP_SOURCE_PKTLOG);
1374*5113495bSYour Name 			break;
1375*5113495bSYour Name 		case WDI_EVENT_LITE_T2H:
1376*5113495bSYour Name 			/*
1377*5113495bSYour Name 			 * To disable HTT_H2T_MSG_TYPE_PPDU_STATS_CFG in FW
1378*5113495bSYour Name 			 * passing value 0. Once these macros will define in htt
1379*5113495bSYour Name 			 * header file will use proper macros
1380*5113495bSYour Name 			 */
1381*5113495bSYour Name 			for (mac_id = 0; mac_id < max_mac_rings; mac_id++) {
1382*5113495bSYour Name 				int mac_for_pdev =
1383*5113495bSYour Name 						dp_get_mac_id_for_pdev(mac_id,
1384*5113495bSYour Name 								pdev->pdev_id);
1385*5113495bSYour Name 
1386*5113495bSYour Name 				mon_pdev->pktlog_ppdu_stats = false;
1387*5113495bSYour Name 				if (!mon_pdev->enhanced_stats_en &&
1388*5113495bSYour Name 				    !mon_pdev->tx_sniffer_enable &&
1389*5113495bSYour Name 				    !mon_pdev->mcopy_mode) {
1390*5113495bSYour Name 					dp_h2t_cfg_stats_msg_send(pdev, 0,
1391*5113495bSYour Name 								  mac_for_pdev);
1392*5113495bSYour Name 				} else if (mon_pdev->tx_sniffer_enable ||
1393*5113495bSYour Name 					   mon_pdev->mcopy_mode) {
1394*5113495bSYour Name 					dp_h2t_cfg_stats_msg_send(pdev,
1395*5113495bSYour Name 						DP_PPDU_STATS_CFG_SNIFFER,
1396*5113495bSYour Name 						mac_for_pdev);
1397*5113495bSYour Name 				} else if (mon_pdev->enhanced_stats_en) {
1398*5113495bSYour Name 					dp_h2t_cfg_stats_msg_send(pdev,
1399*5113495bSYour Name 						DP_PPDU_STATS_CFG_ENH_STATS,
1400*5113495bSYour Name 						mac_for_pdev);
1401*5113495bSYour Name 				}
1402*5113495bSYour Name 			}
1403*5113495bSYour Name 
1404*5113495bSYour Name 			break;
1405*5113495bSYour Name 		case WDI_EVENT_RX_CBF:
1406*5113495bSYour Name 			mon_pdev->rx_pktlog_cbf = false;
1407*5113495bSYour Name 			break;
1408*5113495bSYour Name 
1409*5113495bSYour Name 		case WDI_EVENT_HYBRID_TX:
1410*5113495bSYour Name 			dp_set_hybrid_pktlog_disable(mon_pdev);
1411*5113495bSYour Name 			break;
1412*5113495bSYour Name 
1413*5113495bSYour Name 		default:
1414*5113495bSYour Name 			/* Nothing needs to be done for other pktlog types */
1415*5113495bSYour Name 			break;
1416*5113495bSYour Name 		}
1417*5113495bSYour Name 	}
1418*5113495bSYour Name 	return 0;
1419*5113495bSYour Name }
1420*5113495bSYour Name #endif
1421*5113495bSYour Name 
1422*5113495bSYour Name /* MCL specific functions */
1423*5113495bSYour Name #if defined(DP_CON_MON) && !defined(REMOVE_PKT_LOG)
dp_pktlogmod_exit(struct dp_pdev * pdev)1424*5113495bSYour Name void dp_pktlogmod_exit(struct dp_pdev *pdev)
1425*5113495bSYour Name {
1426*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1427*5113495bSYour Name 	struct hif_opaque_softc *scn = soc->hif_handle;
1428*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1429*5113495bSYour Name 
1430*5113495bSYour Name 	if (!scn) {
1431*5113495bSYour Name 		dp_mon_err("Invalid hif(scn) handle");
1432*5113495bSYour Name 		return;
1433*5113495bSYour Name 	}
1434*5113495bSYour Name 
1435*5113495bSYour Name 	dp_monitor_reap_timer_stop(soc, CDP_MON_REAP_SOURCE_PKTLOG);
1436*5113495bSYour Name 	pktlogmod_exit(scn);
1437*5113495bSYour Name 	mon_pdev->pkt_log_init = false;
1438*5113495bSYour Name }
1439*5113495bSYour Name #endif /*DP_CON_MON*/
1440*5113495bSYour Name 
1441*5113495bSYour Name #if defined(WDI_EVENT_ENABLE) && defined(QCA_ENHANCED_STATS_SUPPORT)
1442*5113495bSYour Name #ifdef IPA_OFFLOAD
1443*5113495bSYour Name static void
dp_peer_get_tx_rx_stats(struct dp_peer * peer,struct cdp_interface_peer_stats * peer_stats_intf)1444*5113495bSYour Name dp_peer_get_tx_rx_stats(struct dp_peer *peer,
1445*5113495bSYour Name 			struct cdp_interface_peer_stats *peer_stats_intf)
1446*5113495bSYour Name {
1447*5113495bSYour Name 	struct dp_rx_tid *rx_tid = NULL;
1448*5113495bSYour Name 	uint8_t i = 0;
1449*5113495bSYour Name 
1450*5113495bSYour Name 	for (i = 0; i < DP_MAX_TIDS; i++) {
1451*5113495bSYour Name 		rx_tid = &peer->rx_tid[i];
1452*5113495bSYour Name 		peer_stats_intf->rx_byte_count +=
1453*5113495bSYour Name 			rx_tid->rx_msdu_cnt.bytes;
1454*5113495bSYour Name 		peer_stats_intf->rx_packet_count +=
1455*5113495bSYour Name 			rx_tid->rx_msdu_cnt.num;
1456*5113495bSYour Name 	}
1457*5113495bSYour Name 	peer_stats_intf->tx_packet_count =
1458*5113495bSYour Name 		peer->monitor_peer->stats.tx.tx_ucast_success.num;
1459*5113495bSYour Name 	peer_stats_intf->tx_byte_count =
1460*5113495bSYour Name 		peer->monitor_peer->stats.tx.tx_ucast_success.bytes;
1461*5113495bSYour Name }
1462*5113495bSYour Name #else
1463*5113495bSYour Name static void
dp_peer_get_tx_rx_stats(struct dp_peer * peer,struct cdp_interface_peer_stats * peer_stats_intf)1464*5113495bSYour Name dp_peer_get_tx_rx_stats(struct dp_peer *peer,
1465*5113495bSYour Name 			struct cdp_interface_peer_stats *peer_stats_intf)
1466*5113495bSYour Name {
1467*5113495bSYour Name 	struct dp_txrx_peer *txrx_peer = NULL;
1468*5113495bSYour Name 	struct dp_peer *tgt_peer = NULL;
1469*5113495bSYour Name 	uint8_t inx = 0;
1470*5113495bSYour Name 	uint8_t stats_arr_size;
1471*5113495bSYour Name 
1472*5113495bSYour Name 	tgt_peer = dp_get_tgt_peer_from_peer(peer);
1473*5113495bSYour Name 	txrx_peer = tgt_peer->txrx_peer;
1474*5113495bSYour Name 	peer_stats_intf->rx_packet_count = txrx_peer->to_stack.num;
1475*5113495bSYour Name 	peer_stats_intf->rx_byte_count = txrx_peer->to_stack.bytes;
1476*5113495bSYour Name 	stats_arr_size = txrx_peer->stats_arr_size;
1477*5113495bSYour Name 
1478*5113495bSYour Name 	for (inx = 0; inx < stats_arr_size; inx++) {
1479*5113495bSYour Name 		peer_stats_intf->tx_packet_count +=
1480*5113495bSYour Name 			txrx_peer->stats[inx].per_pkt_stats.tx.ucast.num;
1481*5113495bSYour Name 		peer_stats_intf->tx_byte_count +=
1482*5113495bSYour Name 			txrx_peer->stats[inx].per_pkt_stats.tx.tx_success.bytes;
1483*5113495bSYour Name 	}
1484*5113495bSYour Name }
1485*5113495bSYour Name #endif
1486*5113495bSYour Name 
dp_peer_stats_notify(struct dp_pdev * dp_pdev,struct dp_peer * peer)1487*5113495bSYour Name QDF_STATUS dp_peer_stats_notify(struct dp_pdev *dp_pdev, struct dp_peer *peer)
1488*5113495bSYour Name {
1489*5113495bSYour Name 	struct cdp_interface_peer_stats peer_stats_intf = {0};
1490*5113495bSYour Name 	struct dp_mon_peer_stats *mon_peer_stats = NULL;
1491*5113495bSYour Name 	struct dp_peer *tgt_peer = NULL;
1492*5113495bSYour Name 	struct dp_txrx_peer *txrx_peer = NULL;
1493*5113495bSYour Name 
1494*5113495bSYour Name 	if (qdf_unlikely(!peer || !peer->vdev || !peer->monitor_peer))
1495*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
1496*5113495bSYour Name 
1497*5113495bSYour Name 	tgt_peer = dp_get_tgt_peer_from_peer(peer);
1498*5113495bSYour Name 	if (qdf_unlikely(!tgt_peer))
1499*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
1500*5113495bSYour Name 
1501*5113495bSYour Name 	txrx_peer = tgt_peer->txrx_peer;
1502*5113495bSYour Name 	if (!qdf_unlikely(txrx_peer))
1503*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
1504*5113495bSYour Name 
1505*5113495bSYour Name 	mon_peer_stats = &peer->monitor_peer->stats;
1506*5113495bSYour Name 
1507*5113495bSYour Name 	if (mon_peer_stats->rx.last_snr != mon_peer_stats->rx.snr)
1508*5113495bSYour Name 		peer_stats_intf.rssi_changed = true;
1509*5113495bSYour Name 
1510*5113495bSYour Name 	if ((mon_peer_stats->rx.snr && peer_stats_intf.rssi_changed) ||
1511*5113495bSYour Name 	    (mon_peer_stats->tx.tx_rate &&
1512*5113495bSYour Name 	     mon_peer_stats->tx.tx_rate != mon_peer_stats->tx.last_tx_rate)) {
1513*5113495bSYour Name 		qdf_mem_copy(peer_stats_intf.peer_mac, peer->mac_addr.raw,
1514*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
1515*5113495bSYour Name 		peer_stats_intf.vdev_id = peer->vdev->vdev_id;
1516*5113495bSYour Name 		peer_stats_intf.last_peer_tx_rate =
1517*5113495bSYour Name 					mon_peer_stats->tx.last_tx_rate;
1518*5113495bSYour Name 		peer_stats_intf.peer_tx_rate = mon_peer_stats->tx.tx_rate;
1519*5113495bSYour Name 		peer_stats_intf.peer_rssi = mon_peer_stats->rx.snr;
1520*5113495bSYour Name 		peer_stats_intf.ack_rssi = mon_peer_stats->tx.last_ack_rssi;
1521*5113495bSYour Name 		dp_peer_get_tx_rx_stats(peer, &peer_stats_intf);
1522*5113495bSYour Name 		peer_stats_intf.per = tgt_peer->stats.tx.last_per;
1523*5113495bSYour Name 		peer_stats_intf.free_buff = INVALID_FREE_BUFF;
1524*5113495bSYour Name 		dp_wdi_event_handler(WDI_EVENT_PEER_STATS, dp_pdev->soc,
1525*5113495bSYour Name 				     (void *)&peer_stats_intf, 0,
1526*5113495bSYour Name 				     WDI_NO_VAL, dp_pdev->pdev_id);
1527*5113495bSYour Name 	}
1528*5113495bSYour Name 
1529*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1530*5113495bSYour Name }
1531*5113495bSYour Name #endif
1532*5113495bSYour Name 
1533*5113495bSYour Name #ifdef FEATURE_NAC_RSSI
1534*5113495bSYour Name /**
1535*5113495bSYour Name  * dp_rx_nac_filter() - Function to perform filtering of non-associated
1536*5113495bSYour Name  * clients
1537*5113495bSYour Name  * @pdev: DP pdev handle
1538*5113495bSYour Name  * @rx_pkt_hdr: Rx packet Header
1539*5113495bSYour Name  *
1540*5113495bSYour Name  * Return: dp_vdev*
1541*5113495bSYour Name  */
1542*5113495bSYour Name static
dp_rx_nac_filter(struct dp_pdev * pdev,uint8_t * rx_pkt_hdr)1543*5113495bSYour Name struct dp_vdev *dp_rx_nac_filter(struct dp_pdev *pdev,
1544*5113495bSYour Name 				 uint8_t *rx_pkt_hdr)
1545*5113495bSYour Name {
1546*5113495bSYour Name 	struct ieee80211_frame *wh;
1547*5113495bSYour Name 	struct dp_neighbour_peer *peer = NULL;
1548*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1549*5113495bSYour Name 
1550*5113495bSYour Name 	wh = (struct ieee80211_frame *)rx_pkt_hdr;
1551*5113495bSYour Name 
1552*5113495bSYour Name 	if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) != IEEE80211_FC1_DIR_TODS)
1553*5113495bSYour Name 		return NULL;
1554*5113495bSYour Name 
1555*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex);
1556*5113495bSYour Name 	TAILQ_FOREACH(peer, &mon_pdev->neighbour_peers_list,
1557*5113495bSYour Name 		      neighbour_peer_list_elem) {
1558*5113495bSYour Name 		if (qdf_mem_cmp(&peer->neighbour_peers_macaddr.raw[0],
1559*5113495bSYour Name 				wh->i_addr2, QDF_MAC_ADDR_SIZE) == 0) {
1560*5113495bSYour Name 			dp_rx_debug("%pK: NAC configuration matched for mac-%2x:%2x:%2x:%2x:%2x:%2x",
1561*5113495bSYour Name 				    pdev->soc,
1562*5113495bSYour Name 				    peer->neighbour_peers_macaddr.raw[0],
1563*5113495bSYour Name 				    peer->neighbour_peers_macaddr.raw[1],
1564*5113495bSYour Name 				    peer->neighbour_peers_macaddr.raw[2],
1565*5113495bSYour Name 				    peer->neighbour_peers_macaddr.raw[3],
1566*5113495bSYour Name 				    peer->neighbour_peers_macaddr.raw[4],
1567*5113495bSYour Name 				    peer->neighbour_peers_macaddr.raw[5]);
1568*5113495bSYour Name 
1569*5113495bSYour Name 				qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex);
1570*5113495bSYour Name 
1571*5113495bSYour Name 			return mon_pdev->mvdev;
1572*5113495bSYour Name 		}
1573*5113495bSYour Name 	}
1574*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex);
1575*5113495bSYour Name 
1576*5113495bSYour Name 	return NULL;
1577*5113495bSYour Name }
1578*5113495bSYour Name 
dp_filter_neighbour_peer(struct dp_pdev * pdev,uint8_t * rx_pkt_hdr)1579*5113495bSYour Name QDF_STATUS dp_filter_neighbour_peer(struct dp_pdev *pdev,
1580*5113495bSYour Name 				    uint8_t *rx_pkt_hdr)
1581*5113495bSYour Name {
1582*5113495bSYour Name 	struct dp_vdev *vdev = NULL;
1583*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1584*5113495bSYour Name 
1585*5113495bSYour Name 	if (mon_pdev->filter_neighbour_peers) {
1586*5113495bSYour Name 		/* Next Hop scenario not yet handle */
1587*5113495bSYour Name 		vdev = dp_rx_nac_filter(pdev, rx_pkt_hdr);
1588*5113495bSYour Name 		if (vdev) {
1589*5113495bSYour Name 			dp_rx_mon_deliver(pdev->soc, pdev->pdev_id,
1590*5113495bSYour Name 					  pdev->invalid_peer_head_msdu,
1591*5113495bSYour Name 					  pdev->invalid_peer_tail_msdu);
1592*5113495bSYour Name 
1593*5113495bSYour Name 			pdev->invalid_peer_head_msdu = NULL;
1594*5113495bSYour Name 			pdev->invalid_peer_tail_msdu = NULL;
1595*5113495bSYour Name 			return QDF_STATUS_SUCCESS;
1596*5113495bSYour Name 		}
1597*5113495bSYour Name 	}
1598*5113495bSYour Name 
1599*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
1600*5113495bSYour Name }
1601*5113495bSYour Name #endif
1602*5113495bSYour Name 
1603*5113495bSYour Name /**
1604*5113495bSYour Name  * dp_update_mon_mac_filter() - Set/reset monitor mac filter
1605*5113495bSYour Name  * @soc_hdl: cdp soc handle
1606*5113495bSYour Name  * @vdev_id: id of virtual device object
1607*5113495bSYour Name  * @cmd: Add/Del command
1608*5113495bSYour Name  *
1609*5113495bSYour Name  * Return: 0 for success. nonzero for failure.
1610*5113495bSYour Name  */
dp_update_mon_mac_filter(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint32_t cmd)1611*5113495bSYour Name static QDF_STATUS dp_update_mon_mac_filter(struct cdp_soc_t *soc_hdl,
1612*5113495bSYour Name 					   uint8_t vdev_id, uint32_t cmd)
1613*5113495bSYour Name {
1614*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
1615*5113495bSYour Name 	struct dp_pdev *pdev;
1616*5113495bSYour Name 	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
1617*5113495bSYour Name 						     DP_MOD_ID_CDP);
1618*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1619*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1620*5113495bSYour Name 
1621*5113495bSYour Name 	if (!vdev)
1622*5113495bSYour Name 		return status;
1623*5113495bSYour Name 
1624*5113495bSYour Name 	pdev = vdev->pdev;
1625*5113495bSYour Name 	if (!pdev) {
1626*5113495bSYour Name 		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
1627*5113495bSYour Name 		return status;
1628*5113495bSYour Name 	}
1629*5113495bSYour Name 
1630*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
1631*5113495bSYour Name 	if (cmd == DP_NAC_PARAM_ADD) {
1632*5113495bSYour Name 		/* first neighbour added */
1633*5113495bSYour Name 		dp_mon_filter_set_reset_mon_mac_filter(pdev, true);
1634*5113495bSYour Name 		status = dp_mon_filter_update(pdev);
1635*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS) {
1636*5113495bSYour Name 			dp_cdp_err("%pK: Mon mac filter set failed", soc);
1637*5113495bSYour Name 			dp_mon_filter_set_reset_mon_mac_filter(pdev, false);
1638*5113495bSYour Name 		}
1639*5113495bSYour Name 	} else if (cmd == DP_NAC_PARAM_DEL) {
1640*5113495bSYour Name 		/* last neighbour deleted */
1641*5113495bSYour Name 		dp_mon_filter_set_reset_mon_mac_filter(pdev, false);
1642*5113495bSYour Name 		status = dp_mon_filter_update(pdev);
1643*5113495bSYour Name 		if (status != QDF_STATUS_SUCCESS)
1644*5113495bSYour Name 			dp_cdp_err("%pK: Mon mac filter reset failed", soc);
1645*5113495bSYour Name 	}
1646*5113495bSYour Name 
1647*5113495bSYour Name 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
1648*5113495bSYour Name 	return status;
1649*5113495bSYour Name }
1650*5113495bSYour Name 
1651*5113495bSYour Name 
1652*5113495bSYour Name bool
dp_enable_mon_reap_timer(struct cdp_soc_t * soc_hdl,enum cdp_mon_reap_source source,bool enable)1653*5113495bSYour Name dp_enable_mon_reap_timer(struct cdp_soc_t *soc_hdl,
1654*5113495bSYour Name 			 enum cdp_mon_reap_source source,
1655*5113495bSYour Name 			 bool enable)
1656*5113495bSYour Name {
1657*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
1658*5113495bSYour Name 
1659*5113495bSYour Name 	if (enable)
1660*5113495bSYour Name 		return dp_monitor_reap_timer_start(soc, source);
1661*5113495bSYour Name 	else
1662*5113495bSYour Name 		return dp_monitor_reap_timer_stop(soc, source);
1663*5113495bSYour Name }
1664*5113495bSYour Name 
1665*5113495bSYour Name #if defined(DP_CON_MON)
1666*5113495bSYour Name #ifndef REMOVE_PKT_LOG
dp_pkt_log_init(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,void * scn)1667*5113495bSYour Name void dp_pkt_log_init(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, void *scn)
1668*5113495bSYour Name {
1669*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
1670*5113495bSYour Name 	struct dp_pdev *handle =
1671*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
1672*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1673*5113495bSYour Name 
1674*5113495bSYour Name 	if (!handle) {
1675*5113495bSYour Name 		dp_mon_err("pdev handle is NULL");
1676*5113495bSYour Name 		return;
1677*5113495bSYour Name 	}
1678*5113495bSYour Name 
1679*5113495bSYour Name 	mon_pdev = handle->monitor_pdev;
1680*5113495bSYour Name 
1681*5113495bSYour Name 	if (mon_pdev->pkt_log_init) {
1682*5113495bSYour Name 		dp_mon_err("%pK: Packet log not initialized", soc);
1683*5113495bSYour Name 		return;
1684*5113495bSYour Name 	}
1685*5113495bSYour Name 
1686*5113495bSYour Name 	pktlog_sethandle(&mon_pdev->pl_dev, scn);
1687*5113495bSYour Name 	pktlog_set_pdev_id(mon_pdev->pl_dev, pdev_id);
1688*5113495bSYour Name 	pktlog_set_callback_regtype(PKTLOG_DEFAULT_CALLBACK_REGISTRATION);
1689*5113495bSYour Name 
1690*5113495bSYour Name 	if (pktlogmod_init(scn)) {
1691*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
1692*5113495bSYour Name 			  "%s: pktlogmod_init failed", __func__);
1693*5113495bSYour Name 		mon_pdev->pkt_log_init = false;
1694*5113495bSYour Name 	} else {
1695*5113495bSYour Name 		mon_pdev->pkt_log_init = true;
1696*5113495bSYour Name 	}
1697*5113495bSYour Name }
1698*5113495bSYour Name 
1699*5113495bSYour Name /**
1700*5113495bSYour Name  * dp_pkt_log_con_service() - connect packet log service
1701*5113495bSYour Name  * @soc_hdl: Datapath soc handle
1702*5113495bSYour Name  * @pdev_id: id of data path pdev handle
1703*5113495bSYour Name  * @scn: device context
1704*5113495bSYour Name  *
1705*5113495bSYour Name  * Return: none
1706*5113495bSYour Name  */
dp_pkt_log_con_service(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,void * scn)1707*5113495bSYour Name static void dp_pkt_log_con_service(struct cdp_soc_t *soc_hdl,
1708*5113495bSYour Name 				   uint8_t pdev_id, void *scn)
1709*5113495bSYour Name {
1710*5113495bSYour Name 	dp_pkt_log_init(soc_hdl, pdev_id, scn);
1711*5113495bSYour Name 	pktlog_htc_attach();
1712*5113495bSYour Name }
1713*5113495bSYour Name 
1714*5113495bSYour Name /**
1715*5113495bSYour Name  * dp_pkt_log_exit() - Wrapper API to cleanup pktlog info
1716*5113495bSYour Name  * @soc_hdl: Datapath soc handle
1717*5113495bSYour Name  * @pdev_id: id of data path pdev handle
1718*5113495bSYour Name  *
1719*5113495bSYour Name  * Return: none
1720*5113495bSYour Name  */
dp_pkt_log_exit(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)1721*5113495bSYour Name static void dp_pkt_log_exit(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
1722*5113495bSYour Name {
1723*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
1724*5113495bSYour Name 	struct dp_pdev *pdev =
1725*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
1726*5113495bSYour Name 
1727*5113495bSYour Name 	if (!pdev) {
1728*5113495bSYour Name 		dp_err("pdev handle is NULL");
1729*5113495bSYour Name 		return;
1730*5113495bSYour Name 	}
1731*5113495bSYour Name 
1732*5113495bSYour Name 	dp_pktlogmod_exit(pdev);
1733*5113495bSYour Name }
1734*5113495bSYour Name 
1735*5113495bSYour Name #else
dp_pkt_log_con_service(struct cdp_soc_t * soc_hdl,uint8_t pdev_id,void * scn)1736*5113495bSYour Name static void dp_pkt_log_con_service(struct cdp_soc_t *soc_hdl,
1737*5113495bSYour Name 				   uint8_t pdev_id, void *scn)
1738*5113495bSYour Name {
1739*5113495bSYour Name }
1740*5113495bSYour Name 
dp_pkt_log_exit(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)1741*5113495bSYour Name static void dp_pkt_log_exit(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
1742*5113495bSYour Name {
1743*5113495bSYour Name }
1744*5113495bSYour Name #endif
1745*5113495bSYour Name #endif
1746*5113495bSYour Name 
dp_neighbour_peers_detach(struct dp_pdev * pdev)1747*5113495bSYour Name void dp_neighbour_peers_detach(struct dp_pdev *pdev)
1748*5113495bSYour Name {
1749*5113495bSYour Name 	struct dp_neighbour_peer *peer = NULL;
1750*5113495bSYour Name 	struct dp_neighbour_peer *temp_peer = NULL;
1751*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1752*5113495bSYour Name 
1753*5113495bSYour Name 	TAILQ_FOREACH_SAFE(peer, &mon_pdev->neighbour_peers_list,
1754*5113495bSYour Name 			   neighbour_peer_list_elem, temp_peer) {
1755*5113495bSYour Name 		/* delete this peer from the list */
1756*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev->neighbour_peers_list,
1757*5113495bSYour Name 			     peer, neighbour_peer_list_elem);
1758*5113495bSYour Name 		qdf_mem_free(peer);
1759*5113495bSYour Name 	}
1760*5113495bSYour Name 
1761*5113495bSYour Name 	qdf_spinlock_destroy(&mon_pdev->neighbour_peer_mutex);
1762*5113495bSYour Name }
1763*5113495bSYour Name 
1764*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
1765*5113495bSYour Name /**
1766*5113495bSYour Name  * dp_mon_tx_enable_enhanced_stats() - Enable enhanced Tx stats
1767*5113495bSYour Name  * @pdev: Datapath pdev handle
1768*5113495bSYour Name  *
1769*5113495bSYour Name  * Return: void
1770*5113495bSYour Name  */
dp_mon_tx_enable_enhanced_stats(struct dp_pdev * pdev)1771*5113495bSYour Name static void dp_mon_tx_enable_enhanced_stats(struct dp_pdev *pdev)
1772*5113495bSYour Name {
1773*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1774*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
1775*5113495bSYour Name 
1776*5113495bSYour Name 	mon_ops = dp_mon_ops_get(soc);
1777*5113495bSYour Name 	if (mon_ops && mon_ops->mon_tx_enable_enhanced_stats)
1778*5113495bSYour Name 		mon_ops->mon_tx_enable_enhanced_stats(pdev);
1779*5113495bSYour Name }
1780*5113495bSYour Name 
1781*5113495bSYour Name /**
1782*5113495bSYour Name  * dp_enable_enhanced_stats()- API to enable enhanced statistcs
1783*5113495bSYour Name  * @soc: DP_SOC handle
1784*5113495bSYour Name  * @pdev_id: id of DP_PDEV handle
1785*5113495bSYour Name  *
1786*5113495bSYour Name  * Return: QDF_STATUS
1787*5113495bSYour Name  */
1788*5113495bSYour Name QDF_STATUS
dp_enable_enhanced_stats(struct cdp_soc_t * soc,uint8_t pdev_id)1789*5113495bSYour Name dp_enable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id)
1790*5113495bSYour Name {
1791*5113495bSYour Name 	struct dp_pdev *pdev = NULL;
1792*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1793*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1794*5113495bSYour Name 	struct dp_soc *dp_soc = cdp_soc_t_to_dp_soc(soc);
1795*5113495bSYour Name 
1796*5113495bSYour Name 	pdev = dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
1797*5113495bSYour Name 						  pdev_id);
1798*5113495bSYour Name 
1799*5113495bSYour Name 	if (!pdev)
1800*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1801*5113495bSYour Name 
1802*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
1803*5113495bSYour Name 
1804*5113495bSYour Name 	if (!mon_pdev)
1805*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1806*5113495bSYour Name 
1807*5113495bSYour Name 	if (mon_pdev->enhanced_stats_en == 0)
1808*5113495bSYour Name 		dp_cal_client_timer_start(mon_pdev->cal_client_ctx);
1809*5113495bSYour Name 
1810*5113495bSYour Name 	mon_pdev->enhanced_stats_en = 1;
1811*5113495bSYour Name 	pdev->enhanced_stats_en = 1;
1812*5113495bSYour Name 	pdev->link_peer_stats = wlan_cfg_is_peer_link_stats_enabled(
1813*5113495bSYour Name 							dp_soc->wlan_cfg_ctx);
1814*5113495bSYour Name 
1815*5113495bSYour Name 	dp_mon_filter_setup_enhanced_stats(pdev);
1816*5113495bSYour Name 	status = dp_mon_filter_update(pdev);
1817*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
1818*5113495bSYour Name 		dp_cdp_err("%pK: Failed to set enhanced mode filters", soc);
1819*5113495bSYour Name 		dp_mon_filter_reset_enhanced_stats(pdev);
1820*5113495bSYour Name 		dp_cal_client_timer_stop(mon_pdev->cal_client_ctx);
1821*5113495bSYour Name 		mon_pdev->enhanced_stats_en = 0;
1822*5113495bSYour Name 		pdev->enhanced_stats_en = 0;
1823*5113495bSYour Name 		pdev->link_peer_stats = 0;
1824*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1825*5113495bSYour Name 	}
1826*5113495bSYour Name 
1827*5113495bSYour Name 	dp_mon_tx_enable_enhanced_stats(pdev);
1828*5113495bSYour Name 
1829*5113495bSYour Name 	/* reset the tx fast path flag, as enhanced stats are enabled */
1830*5113495bSYour Name 	pdev->tx_fast_flag &= ~DP_TX_DESC_FLAG_SIMPLE;
1831*5113495bSYour Name 	if (dp_soc->hw_txrx_stats_en)
1832*5113495bSYour Name 		pdev->tx_fast_flag &= ~DP_TX_DESC_FLAG_FASTPATH_SIMPLE;
1833*5113495bSYour Name 
1834*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1835*5113495bSYour Name }
1836*5113495bSYour Name 
1837*5113495bSYour Name /**
1838*5113495bSYour Name  * dp_mon_tx_disable_enhanced_stats() - Disable enhanced Tx stats
1839*5113495bSYour Name  * @pdev: Datapath pdev handle
1840*5113495bSYour Name  *
1841*5113495bSYour Name  * Return: void
1842*5113495bSYour Name  */
dp_mon_tx_disable_enhanced_stats(struct dp_pdev * pdev)1843*5113495bSYour Name static void dp_mon_tx_disable_enhanced_stats(struct dp_pdev *pdev)
1844*5113495bSYour Name {
1845*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1846*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
1847*5113495bSYour Name 
1848*5113495bSYour Name 	mon_ops = dp_mon_ops_get(soc);
1849*5113495bSYour Name 	if (mon_ops && mon_ops->mon_tx_disable_enhanced_stats)
1850*5113495bSYour Name 		mon_ops->mon_tx_disable_enhanced_stats(pdev);
1851*5113495bSYour Name }
1852*5113495bSYour Name 
1853*5113495bSYour Name /**
1854*5113495bSYour Name  * dp_disable_enhanced_stats()- API to disable enhanced statistcs
1855*5113495bSYour Name  *
1856*5113495bSYour Name  * @soc: the soc handle
1857*5113495bSYour Name  * @pdev_id: pdev_id of pdev
1858*5113495bSYour Name  *
1859*5113495bSYour Name  * Return: QDF_STATUS
1860*5113495bSYour Name  */
1861*5113495bSYour Name QDF_STATUS
dp_disable_enhanced_stats(struct cdp_soc_t * soc,uint8_t pdev_id)1862*5113495bSYour Name dp_disable_enhanced_stats(struct cdp_soc_t *soc, uint8_t pdev_id)
1863*5113495bSYour Name {
1864*5113495bSYour Name 	struct dp_pdev *pdev =
1865*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
1866*5113495bSYour Name 						   pdev_id);
1867*5113495bSYour Name 	struct dp_soc *dp_soc = cdp_soc_t_to_dp_soc(soc);
1868*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1869*5113495bSYour Name 
1870*5113495bSYour Name 	if (!pdev || !pdev->monitor_pdev)
1871*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1872*5113495bSYour Name 
1873*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
1874*5113495bSYour Name 
1875*5113495bSYour Name 	if (mon_pdev->enhanced_stats_en == 1)
1876*5113495bSYour Name 		dp_cal_client_timer_stop(mon_pdev->cal_client_ctx);
1877*5113495bSYour Name 
1878*5113495bSYour Name 	mon_pdev->enhanced_stats_en = 0;
1879*5113495bSYour Name 	pdev->enhanced_stats_en = 0;
1880*5113495bSYour Name 	pdev->link_peer_stats = 0;
1881*5113495bSYour Name 
1882*5113495bSYour Name 	dp_mon_tx_disable_enhanced_stats(pdev);
1883*5113495bSYour Name 
1884*5113495bSYour Name 	dp_mon_filter_reset_enhanced_stats(pdev);
1885*5113495bSYour Name 	if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS) {
1886*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
1887*5113495bSYour Name 			  FL("Failed to reset enhanced mode filters"));
1888*5113495bSYour Name 	}
1889*5113495bSYour Name 
1890*5113495bSYour Name 	/* set the tx fast path flag, as enhanced stats are disabled */
1891*5113495bSYour Name 	pdev->tx_fast_flag |= DP_TX_DESC_FLAG_SIMPLE;
1892*5113495bSYour Name 	if (dp_soc->hw_txrx_stats_en)
1893*5113495bSYour Name 		pdev->tx_fast_flag |= DP_TX_DESC_FLAG_FASTPATH_SIMPLE;
1894*5113495bSYour Name 
1895*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1896*5113495bSYour Name }
1897*5113495bSYour Name 
1898*5113495bSYour Name #ifdef WDI_EVENT_ENABLE
dp_peer_qos_stats_notify(struct dp_pdev * dp_pdev,struct cdp_rx_stats_ppdu_user * ppdu_user)1899*5113495bSYour Name QDF_STATUS dp_peer_qos_stats_notify(struct dp_pdev *dp_pdev,
1900*5113495bSYour Name 				    struct cdp_rx_stats_ppdu_user *ppdu_user)
1901*5113495bSYour Name {
1902*5113495bSYour Name 	struct cdp_interface_peer_qos_stats qos_stats_intf = {0};
1903*5113495bSYour Name 
1904*5113495bSYour Name 	if (qdf_unlikely(ppdu_user->peer_id == HTT_INVALID_PEER)) {
1905*5113495bSYour Name 		dp_mon_warn("Invalid peer id: %u", ppdu_user->peer_id);
1906*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1907*5113495bSYour Name 	}
1908*5113495bSYour Name 
1909*5113495bSYour Name 	qdf_mem_copy(qos_stats_intf.peer_mac, ppdu_user->mac_addr,
1910*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
1911*5113495bSYour Name 	qos_stats_intf.frame_control = ppdu_user->frame_control;
1912*5113495bSYour Name 	qos_stats_intf.frame_control_info_valid =
1913*5113495bSYour Name 			ppdu_user->frame_control_info_valid;
1914*5113495bSYour Name 	qos_stats_intf.qos_control = ppdu_user->qos_control;
1915*5113495bSYour Name 	qos_stats_intf.qos_control_info_valid =
1916*5113495bSYour Name 			ppdu_user->qos_control_info_valid;
1917*5113495bSYour Name 	qos_stats_intf.vdev_id = ppdu_user->vdev_id;
1918*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_PEER_QOS_STATS, dp_pdev->soc,
1919*5113495bSYour Name 			     (void *)&qos_stats_intf, 0,
1920*5113495bSYour Name 			     WDI_NO_VAL, dp_pdev->pdev_id);
1921*5113495bSYour Name 
1922*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1923*5113495bSYour Name }
1924*5113495bSYour Name #else
1925*5113495bSYour Name static inline QDF_STATUS
dp_peer_qos_stats_notify(struct dp_pdev * dp_pdev,struct cdp_rx_stats_ppdu_user * ppdu_user)1926*5113495bSYour Name dp_peer_qos_stats_notify(struct dp_pdev *dp_pdev,
1927*5113495bSYour Name 			 struct cdp_rx_stats_ppdu_user *ppdu_user)
1928*5113495bSYour Name {
1929*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1930*5113495bSYour Name }
1931*5113495bSYour Name #endif
1932*5113495bSYour Name #endif /* QCA_ENHANCED_STATS_SUPPORT */
1933*5113495bSYour Name 
1934*5113495bSYour Name /**
1935*5113495bSYour Name  * dp_enable_peer_based_pktlog() - Set Flag for peer based filtering
1936*5113495bSYour Name  * for pktlog
1937*5113495bSYour Name  * @soc: cdp_soc handle
1938*5113495bSYour Name  * @pdev_id: id of dp pdev handle
1939*5113495bSYour Name  * @mac_addr: Peer mac address
1940*5113495bSYour Name  * @enb_dsb: Enable or disable peer based filtering
1941*5113495bSYour Name  *
1942*5113495bSYour Name  * Return: QDF_STATUS
1943*5113495bSYour Name  */
1944*5113495bSYour Name static int
dp_enable_peer_based_pktlog(struct cdp_soc_t * soc,uint8_t pdev_id,uint8_t * mac_addr,uint8_t enb_dsb)1945*5113495bSYour Name dp_enable_peer_based_pktlog(struct cdp_soc_t *soc, uint8_t pdev_id,
1946*5113495bSYour Name 			    uint8_t *mac_addr, uint8_t enb_dsb)
1947*5113495bSYour Name {
1948*5113495bSYour Name 	struct dp_peer *peer;
1949*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1950*5113495bSYour Name 	struct dp_pdev *pdev =
1951*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
1952*5113495bSYour Name 						   pdev_id);
1953*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
1954*5113495bSYour Name 
1955*5113495bSYour Name 	if (!pdev)
1956*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1957*5113495bSYour Name 
1958*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
1959*5113495bSYour Name 
1960*5113495bSYour Name 	peer = dp_peer_find_hash_find((struct dp_soc *)soc, mac_addr,
1961*5113495bSYour Name 				      0, DP_VDEV_ALL, DP_MOD_ID_CDP);
1962*5113495bSYour Name 
1963*5113495bSYour Name 	if (!peer) {
1964*5113495bSYour Name 		dp_mon_err("Peer is NULL");
1965*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1966*5113495bSYour Name 	}
1967*5113495bSYour Name 
1968*5113495bSYour Name 	if (!IS_MLO_DP_MLD_PEER(peer) && peer->monitor_peer) {
1969*5113495bSYour Name 		peer->monitor_peer->peer_based_pktlog_filter = enb_dsb;
1970*5113495bSYour Name 		mon_pdev->dp_peer_based_pktlog = enb_dsb;
1971*5113495bSYour Name 		status = QDF_STATUS_SUCCESS;
1972*5113495bSYour Name 	}
1973*5113495bSYour Name 
1974*5113495bSYour Name 	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
1975*5113495bSYour Name 
1976*5113495bSYour Name 	return status;
1977*5113495bSYour Name }
1978*5113495bSYour Name 
1979*5113495bSYour Name /**
1980*5113495bSYour Name  * dp_peer_update_pkt_capture_params() - Set Rx & Tx Capture flags for a peer
1981*5113495bSYour Name  * @soc: DP_SOC handle
1982*5113495bSYour Name  * @pdev_id: id of DP_PDEV handle
1983*5113495bSYour Name  * @is_rx_pkt_cap_enable: enable/disable Rx packet capture in monitor mode
1984*5113495bSYour Name  * @is_tx_pkt_cap_enable: enable/disable/delete/print
1985*5113495bSYour Name  * Tx packet capture in monitor mode
1986*5113495bSYour Name  * @peer_mac: MAC address for which the above need to be enabled/disabled
1987*5113495bSYour Name  *
1988*5113495bSYour Name  * Return: Success if Rx & Tx capture is enabled for peer, false otherwise
1989*5113495bSYour Name  */
1990*5113495bSYour Name #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH)
1991*5113495bSYour Name static QDF_STATUS
dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc,uint8_t pdev_id,bool is_rx_pkt_cap_enable,uint8_t is_tx_pkt_cap_enable,uint8_t * peer_mac)1992*5113495bSYour Name dp_peer_update_pkt_capture_params(ol_txrx_soc_handle soc,
1993*5113495bSYour Name 				  uint8_t pdev_id,
1994*5113495bSYour Name 				  bool is_rx_pkt_cap_enable,
1995*5113495bSYour Name 				  uint8_t is_tx_pkt_cap_enable,
1996*5113495bSYour Name 				  uint8_t *peer_mac)
1997*5113495bSYour Name {
1998*5113495bSYour Name 	struct dp_peer *peer;
1999*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
2000*5113495bSYour Name 	struct dp_pdev *pdev =
2001*5113495bSYour Name 			dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
2002*5113495bSYour Name 							   pdev_id);
2003*5113495bSYour Name 	if (!pdev)
2004*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2005*5113495bSYour Name 
2006*5113495bSYour Name 	peer = dp_peer_find_hash_find((struct dp_soc *)soc,
2007*5113495bSYour Name 				      peer_mac, 0, DP_VDEV_ALL,
2008*5113495bSYour Name 				      DP_MOD_ID_CDP);
2009*5113495bSYour Name 	if (!peer)
2010*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2011*5113495bSYour Name 
2012*5113495bSYour Name 	/* we need to set tx pkt capture for non associated peer */
2013*5113495bSYour Name 	if (!IS_MLO_DP_MLD_PEER(peer)) {
2014*5113495bSYour Name 		status = dp_monitor_tx_peer_filter(pdev, peer,
2015*5113495bSYour Name 						   is_tx_pkt_cap_enable,
2016*5113495bSYour Name 						   peer_mac);
2017*5113495bSYour Name 
2018*5113495bSYour Name 		status = dp_peer_set_rx_capture_enabled(pdev, peer,
2019*5113495bSYour Name 							is_rx_pkt_cap_enable,
2020*5113495bSYour Name 							peer_mac);
2021*5113495bSYour Name 	}
2022*5113495bSYour Name 
2023*5113495bSYour Name 	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
2024*5113495bSYour Name 
2025*5113495bSYour Name 	return status;
2026*5113495bSYour Name }
2027*5113495bSYour Name #endif
2028*5113495bSYour Name 
2029*5113495bSYour Name #ifdef QCA_MCOPY_SUPPORT
dp_mcopy_check_deliver(struct dp_pdev * pdev,uint16_t peer_id,uint32_t ppdu_id,uint8_t first_msdu)2030*5113495bSYour Name QDF_STATUS dp_mcopy_check_deliver(struct dp_pdev *pdev,
2031*5113495bSYour Name 				  uint16_t peer_id,
2032*5113495bSYour Name 				  uint32_t ppdu_id,
2033*5113495bSYour Name 				  uint8_t first_msdu)
2034*5113495bSYour Name {
2035*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
2036*5113495bSYour Name 
2037*5113495bSYour Name 	if (mon_pdev->mcopy_mode) {
2038*5113495bSYour Name 		if (mon_pdev->mcopy_mode == M_COPY) {
2039*5113495bSYour Name 			if ((mon_pdev->m_copy_id.tx_ppdu_id == ppdu_id) &&
2040*5113495bSYour Name 			    (mon_pdev->m_copy_id.tx_peer_id == peer_id)) {
2041*5113495bSYour Name 				return QDF_STATUS_E_INVAL;
2042*5113495bSYour Name 			}
2043*5113495bSYour Name 		}
2044*5113495bSYour Name 
2045*5113495bSYour Name 		if (!first_msdu)
2046*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2047*5113495bSYour Name 
2048*5113495bSYour Name 		mon_pdev->m_copy_id.tx_ppdu_id = ppdu_id;
2049*5113495bSYour Name 		mon_pdev->m_copy_id.tx_peer_id = peer_id;
2050*5113495bSYour Name 	}
2051*5113495bSYour Name 
2052*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2053*5113495bSYour Name }
2054*5113495bSYour Name #endif
2055*5113495bSYour Name 
2056*5113495bSYour Name #ifdef WDI_EVENT_ENABLE
2057*5113495bSYour Name #ifndef REMOVE_PKT_LOG
dp_get_pldev(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)2058*5113495bSYour Name static void *dp_get_pldev(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
2059*5113495bSYour Name {
2060*5113495bSYour Name 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
2061*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
2062*5113495bSYour Name 
2063*5113495bSYour Name 	if (!pdev || !pdev->monitor_pdev)
2064*5113495bSYour Name 		return NULL;
2065*5113495bSYour Name 
2066*5113495bSYour Name 	return pdev->monitor_pdev->pl_dev;
2067*5113495bSYour Name }
2068*5113495bSYour Name #else
dp_get_pldev(struct cdp_soc_t * soc_hdl,uint8_t pdev_id)2069*5113495bSYour Name static void *dp_get_pldev(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
2070*5113495bSYour Name {
2071*5113495bSYour Name 	return NULL;
2072*5113495bSYour Name }
2073*5113495bSYour Name #endif
2074*5113495bSYour Name #endif
2075*5113495bSYour Name 
dp_rx_populate_cbf_hdr(struct dp_soc * soc,uint32_t mac_id,uint32_t event,qdf_nbuf_t mpdu,uint32_t msdu_timestamp)2076*5113495bSYour Name QDF_STATUS dp_rx_populate_cbf_hdr(struct dp_soc *soc,
2077*5113495bSYour Name 				  uint32_t mac_id,
2078*5113495bSYour Name 				  uint32_t event,
2079*5113495bSYour Name 				  qdf_nbuf_t mpdu,
2080*5113495bSYour Name 				  uint32_t msdu_timestamp)
2081*5113495bSYour Name {
2082*5113495bSYour Name 	uint32_t data_size, hdr_size, ppdu_id, align4byte;
2083*5113495bSYour Name 	struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
2084*5113495bSYour Name 	uint32_t *msg_word;
2085*5113495bSYour Name 
2086*5113495bSYour Name 	if (!pdev)
2087*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2088*5113495bSYour Name 
2089*5113495bSYour Name 	ppdu_id = pdev->monitor_pdev->ppdu_info.com_info.ppdu_id;
2090*5113495bSYour Name 
2091*5113495bSYour Name 	hdr_size = HTT_T2H_PPDU_STATS_IND_HDR_SIZE
2092*5113495bSYour Name 		+ qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload);
2093*5113495bSYour Name 
2094*5113495bSYour Name 	data_size = qdf_nbuf_len(mpdu);
2095*5113495bSYour Name 
2096*5113495bSYour Name 	qdf_nbuf_push_head(mpdu, hdr_size);
2097*5113495bSYour Name 
2098*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(mpdu);
2099*5113495bSYour Name 	/*
2100*5113495bSYour Name 	 * Populate the PPDU Stats Indication header
2101*5113495bSYour Name 	 */
2102*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_T2H_MSG_TYPE_PPDU_STATS_IND);
2103*5113495bSYour Name 	HTT_T2H_PPDU_STATS_MAC_ID_SET(*msg_word, mac_id);
2104*5113495bSYour Name 	HTT_T2H_PPDU_STATS_PDEV_ID_SET(*msg_word, pdev->pdev_id);
2105*5113495bSYour Name 	align4byte = ((data_size +
2106*5113495bSYour Name 		qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload)
2107*5113495bSYour Name 		+ 3) >> 2) << 2;
2108*5113495bSYour Name 	HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_SET(*msg_word, align4byte);
2109*5113495bSYour Name 	msg_word++;
2110*5113495bSYour Name 	HTT_T2H_PPDU_STATS_PPDU_ID_SET(*msg_word, ppdu_id);
2111*5113495bSYour Name 	msg_word++;
2112*5113495bSYour Name 
2113*5113495bSYour Name 	*msg_word = msdu_timestamp;
2114*5113495bSYour Name 	msg_word++;
2115*5113495bSYour Name 	/* Skip reserved field */
2116*5113495bSYour Name 	msg_word++;
2117*5113495bSYour Name 	/*
2118*5113495bSYour Name 	 * Populate MGMT_CTRL Payload TLV first
2119*5113495bSYour Name 	 */
2120*5113495bSYour Name 	HTT_STATS_TLV_TAG_SET(*msg_word,
2121*5113495bSYour Name 			      HTT_PPDU_STATS_RX_MGMTCTRL_PAYLOAD_TLV);
2122*5113495bSYour Name 
2123*5113495bSYour Name 	align4byte = ((data_size - sizeof(htt_tlv_hdr_t) +
2124*5113495bSYour Name 		qdf_offsetof(htt_ppdu_stats_rx_mgmtctrl_payload_tlv, payload)
2125*5113495bSYour Name 		+ 3) >> 2) << 2;
2126*5113495bSYour Name 	HTT_STATS_TLV_LENGTH_SET(*msg_word, align4byte);
2127*5113495bSYour Name 	msg_word++;
2128*5113495bSYour Name 
2129*5113495bSYour Name 	HTT_PPDU_STATS_RX_MGMTCTRL_TLV_FRAME_LENGTH_SET(
2130*5113495bSYour Name 		*msg_word, data_size);
2131*5113495bSYour Name 	msg_word++;
2132*5113495bSYour Name 
2133*5113495bSYour Name 	dp_wdi_event_handler(event, soc, (void *)mpdu,
2134*5113495bSYour Name 			     HTT_INVALID_PEER, WDI_NO_VAL, pdev->pdev_id);
2135*5113495bSYour Name 
2136*5113495bSYour Name 	qdf_nbuf_pull_head(mpdu, hdr_size);
2137*5113495bSYour Name 
2138*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2139*5113495bSYour Name }
2140*5113495bSYour Name 
2141*5113495bSYour Name #ifdef ATH_SUPPORT_EXT_STAT
2142*5113495bSYour Name #ifdef WLAN_CONFIG_TELEMETRY_AGENT
2143*5113495bSYour Name /**
2144*5113495bSYour Name  * dp_pdev_clear_link_airtime_stats() - clear airtime stats for given pdev
2145*5113495bSYour Name  * @pdev: DP PDEV handle
2146*5113495bSYour Name  */
2147*5113495bSYour Name static inline
dp_pdev_clear_link_airtime_stats(struct dp_pdev * pdev)2148*5113495bSYour Name void dp_pdev_clear_link_airtime_stats(struct dp_pdev *pdev)
2149*5113495bSYour Name {
2150*5113495bSYour Name 	uint8_t ac;
2151*5113495bSYour Name 
2152*5113495bSYour Name 	for (ac = 0; ac < WME_AC_MAX; ac++)
2153*5113495bSYour Name 		pdev->stats.telemetry_stats.link_airtime[ac] = 0;
2154*5113495bSYour Name }
2155*5113495bSYour Name 
2156*5113495bSYour Name /**
2157*5113495bSYour Name  * dp_peer_update_telemetry_stats() - update peer telemetry stats
2158*5113495bSYour Name  * @soc: Datapath soc
2159*5113495bSYour Name  * @peer: Datapath peer
2160*5113495bSYour Name  * @arg: argument to callback function
2161*5113495bSYour Name  */
2162*5113495bSYour Name static inline
dp_peer_update_telemetry_stats(struct dp_soc * soc,struct dp_peer * peer,void * arg)2163*5113495bSYour Name void dp_peer_update_telemetry_stats(struct dp_soc *soc,
2164*5113495bSYour Name 				    struct dp_peer *peer,
2165*5113495bSYour Name 				    void *arg)
2166*5113495bSYour Name {
2167*5113495bSYour Name 	struct dp_pdev *pdev;
2168*5113495bSYour Name 	struct dp_vdev *vdev;
2169*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
2170*5113495bSYour Name 	uint8_t ac;
2171*5113495bSYour Name 	uint64_t current_time = qdf_get_log_timestamp();
2172*5113495bSYour Name 	uint32_t remn, time_diff, usage;
2173*5113495bSYour Name 	uint16_t usage_per_sec;
2174*5113495bSYour Name 	struct dp_mon_peer_airtime_stats *stat_airtime;
2175*5113495bSYour Name 	struct dp_mon_peer_airtime_consumption *consump;
2176*5113495bSYour Name 
2177*5113495bSYour Name 	vdev = peer->vdev;
2178*5113495bSYour Name 	if (!vdev)
2179*5113495bSYour Name 		return;
2180*5113495bSYour Name 
2181*5113495bSYour Name 	pdev = vdev->pdev;
2182*5113495bSYour Name 	if (!pdev)
2183*5113495bSYour Name 		return;
2184*5113495bSYour Name 
2185*5113495bSYour Name 	mon_peer = peer->monitor_peer;
2186*5113495bSYour Name 	if (qdf_likely(mon_peer)) {
2187*5113495bSYour Name 		stat_airtime = &mon_peer->stats.airtime_stats;
2188*5113495bSYour Name 		time_diff = (uint32_t)(current_time -
2189*5113495bSYour Name 					stat_airtime->last_update_time);
2190*5113495bSYour Name 		for (ac = 0; ac < WME_AC_MAX; ac++) {
2191*5113495bSYour Name 			consump = &stat_airtime->tx_airtime_consumption[ac];
2192*5113495bSYour Name 			usage = consump->consumption;
2193*5113495bSYour Name 			usage_per_sec = (uint8_t)qdf_do_div((uint64_t)
2194*5113495bSYour Name 						(usage * 100), time_diff);
2195*5113495bSYour Name 			remn = qdf_do_div_rem((uint64_t)
2196*5113495bSYour Name 						(usage * 100), time_diff);
2197*5113495bSYour Name 			if (remn < time_diff / 2) {
2198*5113495bSYour Name 				if (remn && usage_per_sec == 0)
2199*5113495bSYour Name 					usage_per_sec++;
2200*5113495bSYour Name 			} else {
2201*5113495bSYour Name 				if (usage_per_sec < 100)
2202*5113495bSYour Name 					usage_per_sec++;
2203*5113495bSYour Name 			}
2204*5113495bSYour Name 			consump->avg_consumption_per_sec = usage_per_sec;
2205*5113495bSYour Name 			/* Store each peer airtime consumption in pdev
2206*5113495bSYour Name 			 * link_airtime to calculate pdev's total airtime
2207*5113495bSYour Name 			 * consumption
2208*5113495bSYour Name 			 */
2209*5113495bSYour Name 			DP_STATS_INC(pdev,
2210*5113495bSYour Name 				     telemetry_stats.link_airtime[ac],
2211*5113495bSYour Name 				     consump->consumption);
2212*5113495bSYour Name 			consump->consumption = 0;
2213*5113495bSYour Name 
2214*5113495bSYour Name 			consump = &stat_airtime->rx_airtime_consumption[ac];
2215*5113495bSYour Name 			usage = consump->consumption;
2216*5113495bSYour Name 			usage_per_sec = (uint8_t)qdf_do_div((uint64_t)
2217*5113495bSYour Name 						(usage * 100), time_diff);
2218*5113495bSYour Name 			remn = qdf_do_div_rem((uint64_t)
2219*5113495bSYour Name 						(usage * 100), time_diff);
2220*5113495bSYour Name 			if (remn < time_diff / 2) {
2221*5113495bSYour Name 				if (remn && usage_per_sec == 0)
2222*5113495bSYour Name 					usage_per_sec++;
2223*5113495bSYour Name 			} else {
2224*5113495bSYour Name 				if (usage_per_sec < 100)
2225*5113495bSYour Name 					usage_per_sec++;
2226*5113495bSYour Name 			}
2227*5113495bSYour Name 			consump->avg_consumption_per_sec = usage_per_sec;
2228*5113495bSYour Name 			/* Store each peer airtime consumption in pdev
2229*5113495bSYour Name 			 * link_airtime to calculate pdev's total airtime
2230*5113495bSYour Name 			 * consumption
2231*5113495bSYour Name 			 */
2232*5113495bSYour Name 			DP_STATS_INC(pdev,
2233*5113495bSYour Name 				     telemetry_stats.link_airtime[ac],
2234*5113495bSYour Name 				     consump->consumption);
2235*5113495bSYour Name 			consump->consumption = 0;
2236*5113495bSYour Name 		}
2237*5113495bSYour Name 		stat_airtime->last_update_time = current_time;
2238*5113495bSYour Name 	}
2239*5113495bSYour Name }
2240*5113495bSYour Name 
dp_pdev_update_telemetry_airtime_stats(struct cdp_soc_t * soc,uint8_t pdev_id)2241*5113495bSYour Name QDF_STATUS dp_pdev_update_telemetry_airtime_stats(struct cdp_soc_t *soc,
2242*5113495bSYour Name 						  uint8_t pdev_id)
2243*5113495bSYour Name {
2244*5113495bSYour Name 	struct dp_pdev *pdev =
2245*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3(cdp_soc_t_to_dp_soc(soc),
2246*5113495bSYour Name 						   pdev_id);
2247*5113495bSYour Name 	if (!pdev)
2248*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2249*5113495bSYour Name 
2250*5113495bSYour Name 	/* Clear current airtime stats as the below API will increment the stats
2251*5113495bSYour Name 	 * for all peers on top of current value
2252*5113495bSYour Name 	 */
2253*5113495bSYour Name 	dp_pdev_clear_link_airtime_stats(pdev);
2254*5113495bSYour Name 	dp_pdev_iterate_peer(pdev, dp_peer_update_telemetry_stats, NULL,
2255*5113495bSYour Name 			     DP_MOD_ID_CDP);
2256*5113495bSYour Name 
2257*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2258*5113495bSYour Name }
2259*5113495bSYour Name #endif
2260*5113495bSYour Name 
2261*5113495bSYour Name /**
2262*5113495bSYour Name  * dp_peer_cal_clients_stats_update() - update peer stats on cal client timer
2263*5113495bSYour Name  * @soc: Datapath SOC
2264*5113495bSYour Name  * @peer: Datapath peer
2265*5113495bSYour Name  * @arg: argument to iter function
2266*5113495bSYour Name  */
2267*5113495bSYour Name #ifdef IPA_OFFLOAD
2268*5113495bSYour Name static void
dp_peer_cal_clients_stats_update(struct dp_soc * soc,struct dp_peer * peer,void * arg)2269*5113495bSYour Name dp_peer_cal_clients_stats_update(struct dp_soc *soc,
2270*5113495bSYour Name 				 struct dp_peer *peer,
2271*5113495bSYour Name 				 void *arg)
2272*5113495bSYour Name {
2273*5113495bSYour Name 	struct cdp_calibr_stats_intf peer_stats_intf = {0};
2274*5113495bSYour Name 	struct dp_peer *tgt_peer = NULL;
2275*5113495bSYour Name 	struct dp_txrx_peer *txrx_peer = NULL;
2276*5113495bSYour Name 
2277*5113495bSYour Name 	if (!dp_peer_is_primary_link_peer(peer))
2278*5113495bSYour Name 		return;
2279*5113495bSYour Name 
2280*5113495bSYour Name 	tgt_peer = dp_get_tgt_peer_from_peer(peer);
2281*5113495bSYour Name 	if (!tgt_peer || !(tgt_peer->txrx_peer))
2282*5113495bSYour Name 		return;
2283*5113495bSYour Name 
2284*5113495bSYour Name 	txrx_peer = tgt_peer->txrx_peer;
2285*5113495bSYour Name 	peer_stats_intf.to_stack = txrx_peer->to_stack;
2286*5113495bSYour Name 	peer_stats_intf.tx_success =
2287*5113495bSYour Name 				peer->monitor_peer->stats.tx.tx_ucast_success;
2288*5113495bSYour Name 	peer_stats_intf.tx_ucast =
2289*5113495bSYour Name 				peer->monitor_peer->stats.tx.tx_ucast_total;
2290*5113495bSYour Name 
2291*5113495bSYour Name 	dp_cal_client_update_peer_stats_wifi3(&peer_stats_intf,
2292*5113495bSYour Name 					      &tgt_peer->stats);
2293*5113495bSYour Name 	dp_peer_get_rxtid_stats_ipa(peer, dp_peer_update_tid_stats_from_reo);
2294*5113495bSYour Name }
2295*5113495bSYour Name #else
2296*5113495bSYour Name static void
dp_peer_cal_clients_stats_update(struct dp_soc * soc,struct dp_peer * peer,void * arg)2297*5113495bSYour Name dp_peer_cal_clients_stats_update(struct dp_soc *soc,
2298*5113495bSYour Name 				 struct dp_peer *peer,
2299*5113495bSYour Name 				 void *arg)
2300*5113495bSYour Name {
2301*5113495bSYour Name 	struct cdp_calibr_stats_intf peer_stats_intf = {0};
2302*5113495bSYour Name 	struct dp_peer *tgt_peer = NULL;
2303*5113495bSYour Name 	struct dp_txrx_peer *txrx_peer = NULL;
2304*5113495bSYour Name 	uint8_t inx = 0;
2305*5113495bSYour Name 	uint8_t stats_arr_size;
2306*5113495bSYour Name 
2307*5113495bSYour Name 	if (!dp_peer_is_primary_link_peer(peer))
2308*5113495bSYour Name 		return;
2309*5113495bSYour Name 
2310*5113495bSYour Name 	tgt_peer = dp_get_tgt_peer_from_peer(peer);
2311*5113495bSYour Name 	if (!tgt_peer || !(tgt_peer->txrx_peer))
2312*5113495bSYour Name 		return;
2313*5113495bSYour Name 
2314*5113495bSYour Name 	txrx_peer = tgt_peer->txrx_peer;
2315*5113495bSYour Name 	peer_stats_intf.to_stack = txrx_peer->to_stack;
2316*5113495bSYour Name 	stats_arr_size = txrx_peer->stats_arr_size;
2317*5113495bSYour Name 
2318*5113495bSYour Name 	for (inx = 0; inx < stats_arr_size; inx++) {
2319*5113495bSYour Name 		peer_stats_intf.tx_success.num +=
2320*5113495bSYour Name 			txrx_peer->stats[inx].per_pkt_stats.tx.tx_success.num;
2321*5113495bSYour Name 		peer_stats_intf.tx_success.bytes +=
2322*5113495bSYour Name 			txrx_peer->stats[inx].per_pkt_stats.tx.tx_success.bytes;
2323*5113495bSYour Name 		peer_stats_intf.tx_ucast.num +=
2324*5113495bSYour Name 			txrx_peer->stats[inx].per_pkt_stats.tx.ucast.num;
2325*5113495bSYour Name 		peer_stats_intf.tx_ucast.bytes +=
2326*5113495bSYour Name 			txrx_peer->stats[inx].per_pkt_stats.tx.ucast.bytes;
2327*5113495bSYour Name 	}
2328*5113495bSYour Name 
2329*5113495bSYour Name 	dp_cal_client_update_peer_stats_wifi3(&peer_stats_intf,
2330*5113495bSYour Name 					      &tgt_peer->stats);
2331*5113495bSYour Name }
2332*5113495bSYour Name #endif
2333*5113495bSYour Name 
2334*5113495bSYour Name /**
2335*5113495bSYour Name  * dp_iterate_update_peer_list() - update peer stats on cal client timer
2336*5113495bSYour Name  * @pdev_hdl: pdev handle
2337*5113495bSYour Name  */
dp_iterate_update_peer_list(struct cdp_pdev * pdev_hdl)2338*5113495bSYour Name static void dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl)
2339*5113495bSYour Name {
2340*5113495bSYour Name 	struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl;
2341*5113495bSYour Name 
2342*5113495bSYour Name 	dp_pdev_iterate_peer(pdev, dp_peer_cal_clients_stats_update, NULL,
2343*5113495bSYour Name 			     DP_MOD_ID_CDP);
2344*5113495bSYour Name }
2345*5113495bSYour Name #else
dp_iterate_update_peer_list(struct cdp_pdev * pdev_hdl)2346*5113495bSYour Name static void  dp_iterate_update_peer_list(struct cdp_pdev *pdev_hdl)
2347*5113495bSYour Name {
2348*5113495bSYour Name }
2349*5113495bSYour Name #endif
2350*5113495bSYour Name 
2351*5113495bSYour Name #ifdef ATH_SUPPORT_NAC
dp_set_filter_neigh_peers(struct dp_pdev * pdev,bool val)2352*5113495bSYour Name int dp_set_filter_neigh_peers(struct dp_pdev *pdev,
2353*5113495bSYour Name 			      bool val)
2354*5113495bSYour Name {
2355*5113495bSYour Name 	/* Enable/Disable smart mesh filtering. This flag will be checked
2356*5113495bSYour Name 	 * during rx processing to check if packets are from NAC clients.
2357*5113495bSYour Name 	 */
2358*5113495bSYour Name 	pdev->monitor_pdev->filter_neighbour_peers = val;
2359*5113495bSYour Name 	return 0;
2360*5113495bSYour Name }
2361*5113495bSYour Name #endif /* ATH_SUPPORT_NAC */
2362*5113495bSYour Name 
2363*5113495bSYour Name #ifdef WLAN_ATF_ENABLE
dp_set_atf_stats_enable(struct dp_pdev * pdev,bool value)2364*5113495bSYour Name void dp_set_atf_stats_enable(struct dp_pdev *pdev, bool value)
2365*5113495bSYour Name {
2366*5113495bSYour Name 	if (!pdev) {
2367*5113495bSYour Name 		dp_cdp_err("pdev is NULL");
2368*5113495bSYour Name 		return;
2369*5113495bSYour Name 	}
2370*5113495bSYour Name 
2371*5113495bSYour Name 	pdev->monitor_pdev->dp_atf_stats_enable = value;
2372*5113495bSYour Name }
2373*5113495bSYour Name #endif
2374*5113495bSYour Name 
2375*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
2376*5113495bSYour Name /**
2377*5113495bSYour Name  * dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv() - Process
2378*5113495bSYour Name  * htt_ppdu_stats_tx_mgmtctrl_payload_tlv
2379*5113495bSYour Name  * @pdev: DP PDEV handle
2380*5113495bSYour Name  * @tag_buf: buffer containing the htt_ppdu_stats_tx_mgmtctrl_payload_tlv
2381*5113495bSYour Name  * @ppdu_id: PPDU Id
2382*5113495bSYour Name  *
2383*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS if nbuf has to be freed in caller
2384*5113495bSYour Name  */
2385*5113495bSYour Name static QDF_STATUS
dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(struct dp_pdev * pdev,qdf_nbuf_t tag_buf,uint32_t ppdu_id)2386*5113495bSYour Name dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv(struct dp_pdev *pdev,
2387*5113495bSYour Name 					      qdf_nbuf_t tag_buf,
2388*5113495bSYour Name 					      uint32_t ppdu_id)
2389*5113495bSYour Name {
2390*5113495bSYour Name 	uint32_t *nbuf_ptr;
2391*5113495bSYour Name 	uint8_t trim_size;
2392*5113495bSYour Name 	size_t head_size;
2393*5113495bSYour Name 	struct cdp_tx_mgmt_comp_info *ptr_mgmt_comp_info;
2394*5113495bSYour Name 	uint32_t *msg_word;
2395*5113495bSYour Name 	uint32_t tsf_hdr;
2396*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
2397*5113495bSYour Name 
2398*5113495bSYour Name 	if ((!mon_pdev->tx_sniffer_enable) && (!mon_pdev->mcopy_mode) &&
2399*5113495bSYour Name 	    (!mon_pdev->bpr_enable) && (!mon_pdev->tx_capture_enabled))
2400*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2401*5113495bSYour Name 
2402*5113495bSYour Name 	/*
2403*5113495bSYour Name 	 * get timestamp from htt_t2h_ppdu_stats_ind_hdr_t
2404*5113495bSYour Name 	 */
2405*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(tag_buf);
2406*5113495bSYour Name 	msg_word = msg_word + 2;
2407*5113495bSYour Name 	tsf_hdr = *msg_word;
2408*5113495bSYour Name 
2409*5113495bSYour Name 	trim_size = ((mon_pdev->mgmtctrl_frm_info.mgmt_buf +
2410*5113495bSYour Name 		      HTT_MGMT_CTRL_TLV_HDR_RESERVERD_LEN) -
2411*5113495bSYour Name 		      qdf_nbuf_data(tag_buf));
2412*5113495bSYour Name 
2413*5113495bSYour Name 	if (!qdf_nbuf_pull_head(tag_buf, trim_size))
2414*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
2415*5113495bSYour Name 
2416*5113495bSYour Name 	qdf_nbuf_trim_tail(tag_buf, qdf_nbuf_len(tag_buf) -
2417*5113495bSYour Name 			    mon_pdev->mgmtctrl_frm_info.mgmt_buf_len);
2418*5113495bSYour Name 
2419*5113495bSYour Name 	if (mon_pdev->tx_capture_enabled) {
2420*5113495bSYour Name 		head_size = sizeof(struct cdp_tx_mgmt_comp_info);
2421*5113495bSYour Name 		if (qdf_unlikely(qdf_nbuf_headroom(tag_buf) < head_size)) {
2422*5113495bSYour Name 			qdf_err("Fail to get headroom h_sz %zu h_avail %d\n",
2423*5113495bSYour Name 				head_size, qdf_nbuf_headroom(tag_buf));
2424*5113495bSYour Name 			qdf_assert_always(0);
2425*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
2426*5113495bSYour Name 		}
2427*5113495bSYour Name 		ptr_mgmt_comp_info = (struct cdp_tx_mgmt_comp_info *)
2428*5113495bSYour Name 					qdf_nbuf_push_head(tag_buf, head_size);
2429*5113495bSYour Name 		qdf_assert_always(ptr_mgmt_comp_info);
2430*5113495bSYour Name 		ptr_mgmt_comp_info->ppdu_id = ppdu_id;
2431*5113495bSYour Name 		ptr_mgmt_comp_info->is_sgen_pkt = true;
2432*5113495bSYour Name 		ptr_mgmt_comp_info->tx_tsf = tsf_hdr;
2433*5113495bSYour Name 	} else {
2434*5113495bSYour Name 		head_size = sizeof(ppdu_id);
2435*5113495bSYour Name 		nbuf_ptr = (uint32_t *)qdf_nbuf_push_head(tag_buf, head_size);
2436*5113495bSYour Name 		*nbuf_ptr = ppdu_id;
2437*5113495bSYour Name 	}
2438*5113495bSYour Name 	if (mon_pdev->bpr_enable) {
2439*5113495bSYour Name 		dp_wdi_event_handler(WDI_EVENT_TX_BEACON, pdev->soc,
2440*5113495bSYour Name 				     tag_buf, HTT_INVALID_PEER,
2441*5113495bSYour Name 				     WDI_NO_VAL, pdev->pdev_id);
2442*5113495bSYour Name 	}
2443*5113495bSYour Name 
2444*5113495bSYour Name 	dp_deliver_mgmt_frm(pdev, tag_buf);
2445*5113495bSYour Name 
2446*5113495bSYour Name 	return QDF_STATUS_E_ALREADY;
2447*5113495bSYour Name }
2448*5113495bSYour Name 
2449*5113495bSYour Name int
dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap)2450*5113495bSYour Name dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(uint32_t bitmap)
2451*5113495bSYour Name {
2452*5113495bSYour Name 	if (bitmap == (HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP_64))
2453*5113495bSYour Name 		return HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP_64;
2454*5113495bSYour Name 	else if (bitmap == (HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP_256))
2455*5113495bSYour Name 		return HTT_PPDU_SNIFFER_AMPDU_TLV_BITMAP_256;
2456*5113495bSYour Name 
2457*5113495bSYour Name 	return 0;
2458*5113495bSYour Name }
2459*5113495bSYour Name 
2460*5113495bSYour Name /**
2461*5113495bSYour Name  * dp_peer_copy_delay_stats() - copy ppdu stats to peer delayed stats.
2462*5113495bSYour Name  * @peer: Datapath peer handle
2463*5113495bSYour Name  * @ppdu: User PPDU Descriptor
2464*5113495bSYour Name  * @cur_ppdu_id: PPDU_ID
2465*5113495bSYour Name  *
2466*5113495bSYour Name  * Return: None
2467*5113495bSYour Name  *
2468*5113495bSYour Name  * on Tx data frame, we may get delayed ba set
2469*5113495bSYour Name  * in htt_ppdu_stats_user_common_tlv. which mean we get Block Ack(BA) after we
2470*5113495bSYour Name  * request Block Ack Request(BAR). Successful msdu is received only after Block
2471*5113495bSYour Name  * Ack. To populate peer stats we need successful msdu(data frame).
2472*5113495bSYour Name  * So we hold the Tx data stats on delayed_ba for stats update.
2473*5113495bSYour Name  */
2474*5113495bSYour Name static void
dp_peer_copy_delay_stats(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * ppdu,uint32_t cur_ppdu_id)2475*5113495bSYour Name dp_peer_copy_delay_stats(struct dp_peer *peer,
2476*5113495bSYour Name 			 struct cdp_tx_completion_ppdu_user *ppdu,
2477*5113495bSYour Name 			 uint32_t cur_ppdu_id)
2478*5113495bSYour Name {
2479*5113495bSYour Name 	struct dp_pdev *pdev;
2480*5113495bSYour Name 	struct dp_vdev *vdev;
2481*5113495bSYour Name 	struct dp_mon_peer *mon_peer = peer->monitor_peer;
2482*5113495bSYour Name 
2483*5113495bSYour Name 	if (mon_peer->last_delayed_ba) {
2484*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
2485*5113495bSYour Name 			  "BA not yet recv for prev delayed ppdu[%d] - cur ppdu[%d]",
2486*5113495bSYour Name 			  mon_peer->last_delayed_ba_ppduid, cur_ppdu_id);
2487*5113495bSYour Name 		vdev = peer->vdev;
2488*5113495bSYour Name 		if (vdev) {
2489*5113495bSYour Name 			pdev = vdev->pdev;
2490*5113495bSYour Name 			pdev->stats.cdp_delayed_ba_not_recev++;
2491*5113495bSYour Name 		}
2492*5113495bSYour Name 	}
2493*5113495bSYour Name 
2494*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.ltf_size = ppdu->ltf_size;
2495*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.stbc = ppdu->stbc;
2496*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.he_re = ppdu->he_re;
2497*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.txbf = ppdu->txbf;
2498*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.bw = ppdu->bw;
2499*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.nss = ppdu->nss;
2500*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.gi = ppdu->gi;
2501*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
2502*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.ldpc = ppdu->ldpc;
2503*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
2504*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.mpdu_tried_ucast =
2505*5113495bSYour Name 					ppdu->mpdu_tried_ucast;
2506*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.mpdu_tried_mcast =
2507*5113495bSYour Name 					ppdu->mpdu_tried_mcast;
2508*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.frame_ctrl = ppdu->frame_ctrl;
2509*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.qos_ctrl = ppdu->qos_ctrl;
2510*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.dcm = ppdu->dcm;
2511*5113495bSYour Name 
2512*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.ru_start = ppdu->ru_start;
2513*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.ru_tones = ppdu->ru_tones;
2514*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.is_mcast = ppdu->is_mcast;
2515*5113495bSYour Name 
2516*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.user_pos = ppdu->user_pos;
2517*5113495bSYour Name 	mon_peer->delayed_ba_ppdu_stats.mu_group_id = ppdu->mu_group_id;
2518*5113495bSYour Name 
2519*5113495bSYour Name 	mon_peer->last_delayed_ba = true;
2520*5113495bSYour Name 
2521*5113495bSYour Name 	ppdu->debug_copied = true;
2522*5113495bSYour Name }
2523*5113495bSYour Name 
2524*5113495bSYour Name /**
2525*5113495bSYour Name  * dp_peer_copy_stats_to_bar() - copy delayed stats to ppdu stats.
2526*5113495bSYour Name  * @peer: Datapath peer handle
2527*5113495bSYour Name  * @ppdu: PPDU Descriptor
2528*5113495bSYour Name  *
2529*5113495bSYour Name  * Return: None
2530*5113495bSYour Name  *
2531*5113495bSYour Name  * For Tx BAR, PPDU stats TLV include Block Ack info. PPDU info
2532*5113495bSYour Name  * from Tx BAR frame not required to populate peer stats.
2533*5113495bSYour Name  * But we need successful MPDU and MSDU to update previous
2534*5113495bSYour Name  * transmitted Tx data frame. Overwrite ppdu stats with the previous
2535*5113495bSYour Name  * stored ppdu stats.
2536*5113495bSYour Name  */
2537*5113495bSYour Name static void
dp_peer_copy_stats_to_bar(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * ppdu)2538*5113495bSYour Name dp_peer_copy_stats_to_bar(struct dp_peer *peer,
2539*5113495bSYour Name 			  struct cdp_tx_completion_ppdu_user *ppdu)
2540*5113495bSYour Name {
2541*5113495bSYour Name 	struct dp_mon_peer *mon_peer = peer->monitor_peer;
2542*5113495bSYour Name 
2543*5113495bSYour Name 	ppdu->ltf_size = mon_peer->delayed_ba_ppdu_stats.ltf_size;
2544*5113495bSYour Name 	ppdu->stbc = mon_peer->delayed_ba_ppdu_stats.stbc;
2545*5113495bSYour Name 	ppdu->he_re = mon_peer->delayed_ba_ppdu_stats.he_re;
2546*5113495bSYour Name 	ppdu->txbf = mon_peer->delayed_ba_ppdu_stats.txbf;
2547*5113495bSYour Name 	ppdu->bw = mon_peer->delayed_ba_ppdu_stats.bw;
2548*5113495bSYour Name 	ppdu->nss = mon_peer->delayed_ba_ppdu_stats.nss;
2549*5113495bSYour Name 	ppdu->gi = mon_peer->delayed_ba_ppdu_stats.gi;
2550*5113495bSYour Name 	ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
2551*5113495bSYour Name 	ppdu->ldpc = mon_peer->delayed_ba_ppdu_stats.ldpc;
2552*5113495bSYour Name 	ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
2553*5113495bSYour Name 	ppdu->mpdu_tried_ucast =
2554*5113495bSYour Name 			mon_peer->delayed_ba_ppdu_stats.mpdu_tried_ucast;
2555*5113495bSYour Name 	ppdu->mpdu_tried_mcast =
2556*5113495bSYour Name 			mon_peer->delayed_ba_ppdu_stats.mpdu_tried_mcast;
2557*5113495bSYour Name 	ppdu->frame_ctrl = mon_peer->delayed_ba_ppdu_stats.frame_ctrl;
2558*5113495bSYour Name 	ppdu->qos_ctrl = mon_peer->delayed_ba_ppdu_stats.qos_ctrl;
2559*5113495bSYour Name 	ppdu->dcm = mon_peer->delayed_ba_ppdu_stats.dcm;
2560*5113495bSYour Name 
2561*5113495bSYour Name 	ppdu->ru_start = mon_peer->delayed_ba_ppdu_stats.ru_start;
2562*5113495bSYour Name 	ppdu->ru_tones = mon_peer->delayed_ba_ppdu_stats.ru_tones;
2563*5113495bSYour Name 	ppdu->is_mcast = mon_peer->delayed_ba_ppdu_stats.is_mcast;
2564*5113495bSYour Name 
2565*5113495bSYour Name 	ppdu->user_pos = mon_peer->delayed_ba_ppdu_stats.user_pos;
2566*5113495bSYour Name 	ppdu->mu_group_id = mon_peer->delayed_ba_ppdu_stats.mu_group_id;
2567*5113495bSYour Name 
2568*5113495bSYour Name 	mon_peer->last_delayed_ba = false;
2569*5113495bSYour Name 
2570*5113495bSYour Name 	ppdu->debug_copied = true;
2571*5113495bSYour Name }
2572*5113495bSYour Name 
2573*5113495bSYour Name /**
2574*5113495bSYour Name  * dp_tx_rate_stats_update() - Update rate per-peer statistics
2575*5113495bSYour Name  * @peer: Datapath peer handle
2576*5113495bSYour Name  * @ppdu: PPDU Descriptor
2577*5113495bSYour Name  *
2578*5113495bSYour Name  * Return: None
2579*5113495bSYour Name  */
2580*5113495bSYour Name static void
dp_tx_rate_stats_update(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * ppdu)2581*5113495bSYour Name dp_tx_rate_stats_update(struct dp_peer *peer,
2582*5113495bSYour Name 			struct cdp_tx_completion_ppdu_user *ppdu)
2583*5113495bSYour Name {
2584*5113495bSYour Name 	uint32_t ratekbps = 0;
2585*5113495bSYour Name 	uint64_t ppdu_tx_rate = 0;
2586*5113495bSYour Name 	uint32_t rix;
2587*5113495bSYour Name 	uint16_t ratecode = 0;
2588*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
2589*5113495bSYour Name 
2590*5113495bSYour Name 	if (!peer || !ppdu)
2591*5113495bSYour Name 		return;
2592*5113495bSYour Name 
2593*5113495bSYour Name 	if (ppdu->completion_status != HTT_PPDU_STATS_USER_STATUS_OK)
2594*5113495bSYour Name 		return;
2595*5113495bSYour Name 
2596*5113495bSYour Name 	mon_peer = peer->monitor_peer;
2597*5113495bSYour Name 	if (!mon_peer)
2598*5113495bSYour Name 		return;
2599*5113495bSYour Name 
2600*5113495bSYour Name 	ratekbps = dp_getrateindex(ppdu->gi,
2601*5113495bSYour Name 				   ppdu->mcs,
2602*5113495bSYour Name 				   ppdu->nss,
2603*5113495bSYour Name 				   ppdu->preamble,
2604*5113495bSYour Name 				   ppdu->bw,
2605*5113495bSYour Name 				   ppdu->punc_mode,
2606*5113495bSYour Name 				   &rix,
2607*5113495bSYour Name 				   &ratecode);
2608*5113495bSYour Name 
2609*5113495bSYour Name 	if (!ratekbps)
2610*5113495bSYour Name 		return;
2611*5113495bSYour Name 
2612*5113495bSYour Name 	/* Calculate goodput in non-training period
2613*5113495bSYour Name 	 * In training period, don't do anything as
2614*5113495bSYour Name 	 * pending pkt is send as goodput.
2615*5113495bSYour Name 	 */
2616*5113495bSYour Name 	if ((!peer->bss_peer) && (!ppdu->sa_is_training)) {
2617*5113495bSYour Name 		ppdu->sa_goodput = ((ratekbps / CDP_NUM_KB_IN_MB) *
2618*5113495bSYour Name 				(CDP_PERCENT_MACRO - ppdu->current_rate_per));
2619*5113495bSYour Name 	}
2620*5113495bSYour Name 	ppdu->rix = rix;
2621*5113495bSYour Name 	ppdu->tx_ratekbps = ratekbps;
2622*5113495bSYour Name 	ppdu->tx_ratecode = ratecode;
2623*5113495bSYour Name 	DP_STATS_UPD(mon_peer, tx.tx_rate, ratekbps);
2624*5113495bSYour Name 	mon_peer->stats.tx.avg_tx_rate =
2625*5113495bSYour Name 		dp_ath_rate_lpf(mon_peer->stats.tx.avg_tx_rate, ratekbps);
2626*5113495bSYour Name 	ppdu_tx_rate = dp_ath_rate_out(mon_peer->stats.tx.avg_tx_rate);
2627*5113495bSYour Name 	DP_STATS_UPD(mon_peer, tx.rnd_avg_tx_rate, ppdu_tx_rate);
2628*5113495bSYour Name 
2629*5113495bSYour Name 	mon_peer->stats.tx.bw_info = ppdu->bw;
2630*5113495bSYour Name 	mon_peer->stats.tx.gi_info = ppdu->gi;
2631*5113495bSYour Name 	mon_peer->stats.tx.nss_info = ppdu->nss;
2632*5113495bSYour Name 	mon_peer->stats.tx.mcs_info = ppdu->mcs;
2633*5113495bSYour Name 	mon_peer->stats.tx.preamble_info = ppdu->preamble;
2634*5113495bSYour Name 	if (peer->vdev) {
2635*5113495bSYour Name 		/*
2636*5113495bSYour Name 		 * In STA mode:
2637*5113495bSYour Name 		 *	We get ucast stats as BSS peer stats.
2638*5113495bSYour Name 		 *
2639*5113495bSYour Name 		 * In AP mode:
2640*5113495bSYour Name 		 *	We get mcast stats as BSS peer stats.
2641*5113495bSYour Name 		 *	We get ucast stats as assoc peer stats.
2642*5113495bSYour Name 		 */
2643*5113495bSYour Name 		if (peer->vdev->opmode == wlan_op_mode_ap && peer->bss_peer) {
2644*5113495bSYour Name 			peer->vdev->stats.tx.mcast_last_tx_rate = ratekbps;
2645*5113495bSYour Name 			peer->vdev->stats.tx.mcast_last_tx_rate_mcs = ppdu->mcs;
2646*5113495bSYour Name 		} else {
2647*5113495bSYour Name 			peer->vdev->stats.tx.last_tx_rate = ratekbps;
2648*5113495bSYour Name 			peer->vdev->stats.tx.last_tx_rate_mcs = ppdu->mcs;
2649*5113495bSYour Name 		}
2650*5113495bSYour Name 	}
2651*5113495bSYour Name }
2652*5113495bSYour Name 
2653*5113495bSYour Name #if defined(FEATURE_PERPKT_INFO) && defined(WDI_EVENT_ENABLE)
dp_send_stats_event(struct dp_pdev * pdev,struct dp_peer * peer,uint16_t peer_id)2654*5113495bSYour Name void dp_send_stats_event(struct dp_pdev *pdev, struct dp_peer *peer,
2655*5113495bSYour Name 			 uint16_t peer_id)
2656*5113495bSYour Name {
2657*5113495bSYour Name 	struct cdp_interface_peer_stats peer_stats_intf = {0};
2658*5113495bSYour Name 	struct dp_mon_peer *mon_peer = peer->monitor_peer;
2659*5113495bSYour Name 	struct dp_txrx_peer *txrx_peer = NULL;
2660*5113495bSYour Name 	uint8_t inx = 0;
2661*5113495bSYour Name 	uint8_t stats_arr_size;
2662*5113495bSYour Name 
2663*5113495bSYour Name 	if (qdf_unlikely(!mon_peer))
2664*5113495bSYour Name 		return;
2665*5113495bSYour Name 
2666*5113495bSYour Name 	mon_peer->stats.rx.rx_snr_measured_time = qdf_system_ticks();
2667*5113495bSYour Name 	peer_stats_intf.rx_avg_snr = mon_peer->stats.rx.avg_snr;
2668*5113495bSYour Name 
2669*5113495bSYour Name 	txrx_peer = dp_get_txrx_peer(peer);
2670*5113495bSYour Name 	if (qdf_likely(txrx_peer)) {
2671*5113495bSYour Name 		stats_arr_size = txrx_peer->stats_arr_size;
2672*5113495bSYour Name 		peer_stats_intf.rx_byte_count = txrx_peer->to_stack.bytes;
2673*5113495bSYour Name 		for (inx = 0; inx < stats_arr_size; inx++)
2674*5113495bSYour Name 			peer_stats_intf.tx_byte_count +=
2675*5113495bSYour Name 			txrx_peer->stats[inx].per_pkt_stats.tx.tx_success.bytes;
2676*5113495bSYour Name 	}
2677*5113495bSYour Name 
2678*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc,
2679*5113495bSYour Name 			     &peer_stats_intf, peer_id,
2680*5113495bSYour Name 			     UPDATE_PEER_STATS, pdev->pdev_id);
2681*5113495bSYour Name }
2682*5113495bSYour Name #endif
2683*5113495bSYour Name 
2684*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
2685*5113495bSYour Name /**
2686*5113495bSYour Name  * dp_get_ru_index_frm_ru_tones() - get ru index
2687*5113495bSYour Name  * @ru_tones: ru tones
2688*5113495bSYour Name  *
2689*5113495bSYour Name  * Return: ru index
2690*5113495bSYour Name  */
dp_get_ru_index_frm_ru_tones(uint16_t ru_tones)2691*5113495bSYour Name static inline enum cdp_ru_index dp_get_ru_index_frm_ru_tones(uint16_t ru_tones)
2692*5113495bSYour Name {
2693*5113495bSYour Name 	enum cdp_ru_index ru_index;
2694*5113495bSYour Name 
2695*5113495bSYour Name 	switch (ru_tones) {
2696*5113495bSYour Name 	case RU_26:
2697*5113495bSYour Name 		ru_index = RU_26_INDEX;
2698*5113495bSYour Name 		break;
2699*5113495bSYour Name 	case RU_52:
2700*5113495bSYour Name 		ru_index = RU_52_INDEX;
2701*5113495bSYour Name 		break;
2702*5113495bSYour Name 	case RU_52_26:
2703*5113495bSYour Name 		ru_index = RU_52_26_INDEX;
2704*5113495bSYour Name 		break;
2705*5113495bSYour Name 	case RU_106:
2706*5113495bSYour Name 		ru_index = RU_106_INDEX;
2707*5113495bSYour Name 		break;
2708*5113495bSYour Name 	case RU_106_26:
2709*5113495bSYour Name 		ru_index = RU_106_26_INDEX;
2710*5113495bSYour Name 		break;
2711*5113495bSYour Name 	case RU_242:
2712*5113495bSYour Name 		ru_index = RU_242_INDEX;
2713*5113495bSYour Name 		break;
2714*5113495bSYour Name 	case RU_484:
2715*5113495bSYour Name 		ru_index = RU_484_INDEX;
2716*5113495bSYour Name 		break;
2717*5113495bSYour Name 	case RU_484_242:
2718*5113495bSYour Name 		ru_index = RU_484_242_INDEX;
2719*5113495bSYour Name 		break;
2720*5113495bSYour Name 	case RU_996:
2721*5113495bSYour Name 		ru_index = RU_996_INDEX;
2722*5113495bSYour Name 		break;
2723*5113495bSYour Name 	case RU_996_484:
2724*5113495bSYour Name 		ru_index = RU_996_484_INDEX;
2725*5113495bSYour Name 		break;
2726*5113495bSYour Name 	case RU_996_484_242:
2727*5113495bSYour Name 		ru_index = RU_996_484_242_INDEX;
2728*5113495bSYour Name 		break;
2729*5113495bSYour Name 	case RU_2X996:
2730*5113495bSYour Name 		ru_index = RU_2X996_INDEX;
2731*5113495bSYour Name 		break;
2732*5113495bSYour Name 	case RU_2X996_484:
2733*5113495bSYour Name 		ru_index = RU_2X996_484_INDEX;
2734*5113495bSYour Name 		break;
2735*5113495bSYour Name 	case RU_3X996:
2736*5113495bSYour Name 		ru_index = RU_3X996_INDEX;
2737*5113495bSYour Name 		break;
2738*5113495bSYour Name 	case RU_3X996_484:
2739*5113495bSYour Name 		ru_index = RU_2X996_484_INDEX;
2740*5113495bSYour Name 		break;
2741*5113495bSYour Name 	case RU_4X996:
2742*5113495bSYour Name 		ru_index = RU_4X996_INDEX;
2743*5113495bSYour Name 		break;
2744*5113495bSYour Name 	default:
2745*5113495bSYour Name 		ru_index = RU_INDEX_MAX;
2746*5113495bSYour Name 		break;
2747*5113495bSYour Name 	}
2748*5113495bSYour Name 
2749*5113495bSYour Name 	return ru_index;
2750*5113495bSYour Name }
2751*5113495bSYour Name 
2752*5113495bSYour Name /**
2753*5113495bSYour Name  * dp_mon_get_ru_width_from_ru_size() - get ru_width from ru_size enum
2754*5113495bSYour Name  * @ru_size: HTT ru_size enum
2755*5113495bSYour Name  *
2756*5113495bSYour Name  * Return: ru_width of uint32_t type
2757*5113495bSYour Name  */
dp_mon_get_ru_width_from_ru_size(uint16_t ru_size)2758*5113495bSYour Name static uint32_t dp_mon_get_ru_width_from_ru_size(uint16_t ru_size)
2759*5113495bSYour Name {
2760*5113495bSYour Name 	uint32_t width = 0;
2761*5113495bSYour Name 
2762*5113495bSYour Name 	switch (ru_size) {
2763*5113495bSYour Name 	case HTT_PPDU_STATS_RU_26:
2764*5113495bSYour Name 		width = RU_26;
2765*5113495bSYour Name 		break;
2766*5113495bSYour Name 	case HTT_PPDU_STATS_RU_52:
2767*5113495bSYour Name 		width = RU_52;
2768*5113495bSYour Name 		break;
2769*5113495bSYour Name 	case HTT_PPDU_STATS_RU_52_26:
2770*5113495bSYour Name 		width = RU_52_26;
2771*5113495bSYour Name 		break;
2772*5113495bSYour Name 	case HTT_PPDU_STATS_RU_106:
2773*5113495bSYour Name 		width = RU_106;
2774*5113495bSYour Name 		break;
2775*5113495bSYour Name 	case HTT_PPDU_STATS_RU_106_26:
2776*5113495bSYour Name 		width = RU_106_26;
2777*5113495bSYour Name 		break;
2778*5113495bSYour Name 	case HTT_PPDU_STATS_RU_242:
2779*5113495bSYour Name 		width = RU_242;
2780*5113495bSYour Name 		break;
2781*5113495bSYour Name 	case HTT_PPDU_STATS_RU_484:
2782*5113495bSYour Name 		width = RU_484;
2783*5113495bSYour Name 		break;
2784*5113495bSYour Name 	case HTT_PPDU_STATS_RU_484_242:
2785*5113495bSYour Name 		width = RU_484_242;
2786*5113495bSYour Name 		break;
2787*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996:
2788*5113495bSYour Name 		width = RU_996;
2789*5113495bSYour Name 		break;
2790*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996_484:
2791*5113495bSYour Name 		width = RU_996_484;
2792*5113495bSYour Name 		break;
2793*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996_484_242:
2794*5113495bSYour Name 		width = RU_996_484_242;
2795*5113495bSYour Name 		break;
2796*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996x2:
2797*5113495bSYour Name 		width = RU_2X996;
2798*5113495bSYour Name 		break;
2799*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996x2_484:
2800*5113495bSYour Name 		width = RU_2X996_484;
2801*5113495bSYour Name 		break;
2802*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996x3:
2803*5113495bSYour Name 		width = RU_3X996;
2804*5113495bSYour Name 		break;
2805*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996x3_484:
2806*5113495bSYour Name 		width = RU_3X996_484;
2807*5113495bSYour Name 		break;
2808*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996x4:
2809*5113495bSYour Name 		width = RU_4X996;
2810*5113495bSYour Name 		break;
2811*5113495bSYour Name 	default:
2812*5113495bSYour Name 		dp_mon_debug("Unsupported ru_size: %d rcvd", ru_size);
2813*5113495bSYour Name 	}
2814*5113495bSYour Name 
2815*5113495bSYour Name 	return width;
2816*5113495bSYour Name }
2817*5113495bSYour Name #else
dp_get_ru_index_frm_ru_tones(uint16_t ru_tones)2818*5113495bSYour Name static inline enum cdp_ru_index dp_get_ru_index_frm_ru_tones(uint16_t ru_tones)
2819*5113495bSYour Name {
2820*5113495bSYour Name 	enum cdp_ru_index ru_index;
2821*5113495bSYour Name 
2822*5113495bSYour Name 	switch (ru_tones) {
2823*5113495bSYour Name 	case RU_26:
2824*5113495bSYour Name 		ru_index = RU_26_INDEX;
2825*5113495bSYour Name 		break;
2826*5113495bSYour Name 	case RU_52:
2827*5113495bSYour Name 		ru_index = RU_52_INDEX;
2828*5113495bSYour Name 		break;
2829*5113495bSYour Name 	case RU_106:
2830*5113495bSYour Name 		ru_index = RU_106_INDEX;
2831*5113495bSYour Name 		break;
2832*5113495bSYour Name 	case RU_242:
2833*5113495bSYour Name 		ru_index = RU_242_INDEX;
2834*5113495bSYour Name 		break;
2835*5113495bSYour Name 	case RU_484:
2836*5113495bSYour Name 		ru_index = RU_484_INDEX;
2837*5113495bSYour Name 		break;
2838*5113495bSYour Name 	case RU_996:
2839*5113495bSYour Name 		ru_index = RU_996_INDEX;
2840*5113495bSYour Name 		break;
2841*5113495bSYour Name 	default:
2842*5113495bSYour Name 		ru_index = RU_INDEX_MAX;
2843*5113495bSYour Name 		break;
2844*5113495bSYour Name 	}
2845*5113495bSYour Name 
2846*5113495bSYour Name 	return ru_index;
2847*5113495bSYour Name }
2848*5113495bSYour Name 
dp_mon_get_ru_width_from_ru_size(uint16_t ru_size)2849*5113495bSYour Name static uint32_t dp_mon_get_ru_width_from_ru_size(uint16_t ru_size)
2850*5113495bSYour Name {
2851*5113495bSYour Name 	uint32_t width = 0;
2852*5113495bSYour Name 
2853*5113495bSYour Name 	switch (ru_size) {
2854*5113495bSYour Name 	case HTT_PPDU_STATS_RU_26:
2855*5113495bSYour Name 		width = RU_26;
2856*5113495bSYour Name 		break;
2857*5113495bSYour Name 	case HTT_PPDU_STATS_RU_52:
2858*5113495bSYour Name 		width = RU_52;
2859*5113495bSYour Name 		break;
2860*5113495bSYour Name 	case HTT_PPDU_STATS_RU_106:
2861*5113495bSYour Name 		width = RU_106;
2862*5113495bSYour Name 		break;
2863*5113495bSYour Name 	case HTT_PPDU_STATS_RU_242:
2864*5113495bSYour Name 		width = RU_242;
2865*5113495bSYour Name 		break;
2866*5113495bSYour Name 	case HTT_PPDU_STATS_RU_484:
2867*5113495bSYour Name 		width = RU_484;
2868*5113495bSYour Name 		break;
2869*5113495bSYour Name 	case HTT_PPDU_STATS_RU_996:
2870*5113495bSYour Name 		width = RU_996;
2871*5113495bSYour Name 		break;
2872*5113495bSYour Name 	default:
2873*5113495bSYour Name 		dp_mon_debug("Unsupported ru_size: %d rcvd", ru_size);
2874*5113495bSYour Name 	}
2875*5113495bSYour Name 
2876*5113495bSYour Name 	return width;
2877*5113495bSYour Name }
2878*5113495bSYour Name #endif
2879*5113495bSYour Name 
2880*5113495bSYour Name #ifdef WLAN_CONFIG_TELEMETRY_AGENT
2881*5113495bSYour Name /**
2882*5113495bSYour Name  * dp_pdev_telemetry_stats_update() - Update pdev telemetry stats
2883*5113495bSYour Name  * @pdev: Datapath pdev handle
2884*5113495bSYour Name  * @ppdu: PPDU Descriptor
2885*5113495bSYour Name  *
2886*5113495bSYour Name  * Return: None
2887*5113495bSYour Name  */
2888*5113495bSYour Name static void
dp_pdev_telemetry_stats_update(struct dp_pdev * pdev,struct cdp_tx_completion_ppdu_user * ppdu)2889*5113495bSYour Name dp_pdev_telemetry_stats_update(
2890*5113495bSYour Name 		struct dp_pdev *pdev,
2891*5113495bSYour Name 		struct cdp_tx_completion_ppdu_user *ppdu)
2892*5113495bSYour Name {
2893*5113495bSYour Name 	uint16_t mpdu_tried;
2894*5113495bSYour Name 	uint16_t mpdu_failed;
2895*5113495bSYour Name 	uint16_t num_mpdu;
2896*5113495bSYour Name 	uint8_t ac = 0;
2897*5113495bSYour Name 
2898*5113495bSYour Name 	num_mpdu = ppdu->mpdu_success;
2899*5113495bSYour Name 	mpdu_tried = ppdu->mpdu_tried_ucast + ppdu->mpdu_tried_mcast;
2900*5113495bSYour Name 	mpdu_failed = mpdu_tried - num_mpdu;
2901*5113495bSYour Name 
2902*5113495bSYour Name 	ac = TID_TO_WME_AC(ppdu->tid);
2903*5113495bSYour Name 
2904*5113495bSYour Name 	DP_STATS_INC(pdev, telemetry_stats.tx_mpdu_failed[ac],
2905*5113495bSYour Name 		     mpdu_failed);
2906*5113495bSYour Name 
2907*5113495bSYour Name 	DP_STATS_INC(pdev, telemetry_stats.tx_mpdu_total[ac],
2908*5113495bSYour Name 		     mpdu_tried);
2909*5113495bSYour Name }
2910*5113495bSYour Name 
2911*5113495bSYour Name /*
2912*5113495bSYour Name  * dp_ppdu_desc_get_txmode() - Get TX mode
2913*5113495bSYour Name  * @ppdu: PPDU Descriptor
2914*5113495bSYour Name  *
2915*5113495bSYour Name  * Return: None
2916*5113495bSYour Name  */
2917*5113495bSYour Name static inline
dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu * ppdu)2918*5113495bSYour Name void dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu *ppdu)
2919*5113495bSYour Name {
2920*5113495bSYour Name 	uint16_t frame_type = ppdu->htt_frame_type;
2921*5113495bSYour Name 
2922*5113495bSYour Name 	ppdu->txmode_type = TX_MODE_TYPE_UNKNOWN;
2923*5113495bSYour Name 
2924*5113495bSYour Name 	if (ppdu->frame_type == CDP_PPDU_FTYPE_CTRL &&
2925*5113495bSYour Name 	    (frame_type != HTT_STATS_FTYPE_SGEN_MU_TRIG &&
2926*5113495bSYour Name 	     frame_type != HTT_STATS_FTYPE_SGEN_BE_MU_TRIG))
2927*5113495bSYour Name 		return;
2928*5113495bSYour Name 
2929*5113495bSYour Name 	if (frame_type == HTT_STATS_FTYPE_SGEN_MU_BAR ||
2930*5113495bSYour Name 	    frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_BAR) {
2931*5113495bSYour Name 		ppdu->txmode = TX_MODE_UL_OFDMA_MU_BAR_TRIGGER;
2932*5113495bSYour Name 		ppdu->txmode_type = TX_MODE_TYPE_UL;
2933*5113495bSYour Name 
2934*5113495bSYour Name 		return;
2935*5113495bSYour Name 	}
2936*5113495bSYour Name 
2937*5113495bSYour Name 	switch (ppdu->htt_seq_type) {
2938*5113495bSYour Name 	case HTT_SEQTYPE_SU:
2939*5113495bSYour Name 		if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_SU) {
2940*5113495bSYour Name 			ppdu->txmode = TX_MODE_DL_SU_DATA;
2941*5113495bSYour Name 			ppdu->txmode_type = TX_MODE_TYPE_DL;
2942*5113495bSYour Name 		}
2943*5113495bSYour Name 		break;
2944*5113495bSYour Name 	case HTT_SEQTYPE_MU_OFDMA:
2945*5113495bSYour Name 	case HTT_SEQTYPE_BE_MU_OFDMA:
2946*5113495bSYour Name 		if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_MU) {
2947*5113495bSYour Name 			ppdu->txmode = TX_MODE_DL_OFDMA_DATA;
2948*5113495bSYour Name 			ppdu->txmode_type = TX_MODE_TYPE_DL;
2949*5113495bSYour Name 		}
2950*5113495bSYour Name 		break;
2951*5113495bSYour Name 	case HTT_SEQTYPE_AC_MU_MIMO:
2952*5113495bSYour Name 	case HTT_SEQTYPE_AX_MU_MIMO:
2953*5113495bSYour Name 	case HTT_SEQTYPE_BE_MU_MIMO:
2954*5113495bSYour Name 		if (frame_type == HTT_STATS_FTYPE_TIDQ_DATA_MU) {
2955*5113495bSYour Name 			ppdu->txmode = TX_MODE_DL_MUMIMO_DATA;
2956*5113495bSYour Name 			ppdu->txmode_type = TX_MODE_TYPE_DL;
2957*5113495bSYour Name 		}
2958*5113495bSYour Name 		break;
2959*5113495bSYour Name 	case HTT_SEQTYPE_UL_MU_OFDMA_TRIG:
2960*5113495bSYour Name 	case HTT_SEQTYPE_BE_UL_MU_OFDMA_TRIG:
2961*5113495bSYour Name 		if (frame_type == HTT_STATS_FTYPE_SGEN_MU_TRIG ||
2962*5113495bSYour Name 		    frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_TRIG) {
2963*5113495bSYour Name 			ppdu->txmode = TX_MODE_UL_OFDMA_BASIC_TRIGGER_DATA;
2964*5113495bSYour Name 			ppdu->txmode_type = TX_MODE_TYPE_UL;
2965*5113495bSYour Name 		}
2966*5113495bSYour Name 		break;
2967*5113495bSYour Name 	case HTT_SEQTYPE_UL_MU_MIMO_TRIG:
2968*5113495bSYour Name 	case HTT_SEQTYPE_BE_UL_MU_MIMO_TRIG:
2969*5113495bSYour Name 		if (frame_type == HTT_STATS_FTYPE_SGEN_MU_TRIG ||
2970*5113495bSYour Name 		    frame_type == HTT_STATS_FTYPE_SGEN_BE_MU_TRIG) {
2971*5113495bSYour Name 			ppdu->txmode = TX_MODE_UL_MUMIMO_BASIC_TRIGGER_DATA;
2972*5113495bSYour Name 			ppdu->txmode_type = TX_MODE_TYPE_UL;
2973*5113495bSYour Name 		}
2974*5113495bSYour Name 		break;
2975*5113495bSYour Name 	default:
2976*5113495bSYour Name 		ppdu->txmode_type = TX_MODE_TYPE_UNKNOWN;
2977*5113495bSYour Name 		break;
2978*5113495bSYour Name 	}
2979*5113495bSYour Name }
2980*5113495bSYour Name 
2981*5113495bSYour Name /*
2982*5113495bSYour Name  * dp_pdev_update_deter_stats() - Update pdev deterministic stats
2983*5113495bSYour Name  * @pdev: Datapath pdev handle
2984*5113495bSYour Name  * @ppdu: PPDU Descriptor
2985*5113495bSYour Name  *
2986*5113495bSYour Name  * Return: None
2987*5113495bSYour Name  */
2988*5113495bSYour Name static inline void
dp_pdev_update_deter_stats(struct dp_pdev * pdev,struct cdp_tx_completion_ppdu * ppdu)2989*5113495bSYour Name dp_pdev_update_deter_stats(struct dp_pdev *pdev,
2990*5113495bSYour Name 			   struct cdp_tx_completion_ppdu *ppdu)
2991*5113495bSYour Name {
2992*5113495bSYour Name 	uint32_t user_idx;
2993*5113495bSYour Name 
2994*5113495bSYour Name 	if (!pdev || !ppdu)
2995*5113495bSYour Name 		return;
2996*5113495bSYour Name 
2997*5113495bSYour Name 	if (ppdu->txmode_type == TX_MODE_TYPE_UNKNOWN)
2998*5113495bSYour Name 		return;
2999*5113495bSYour Name 
3000*5113495bSYour Name 	if (ppdu->backoff_ac_valid) {
3001*5113495bSYour Name 		if (ppdu->backoff_ac >= WME_AC_MAX) {
3002*5113495bSYour Name 			dp_mon_err("backoff_ac %d exceed max limit",
3003*5113495bSYour Name 				   ppdu->backoff_ac);
3004*5113495bSYour Name 			return;
3005*5113495bSYour Name 		}
3006*5113495bSYour Name 		DP_STATS_UPD(pdev,
3007*5113495bSYour Name 			     deter_stats.ch_access_delay[ppdu->backoff_ac],
3008*5113495bSYour Name 			     ppdu->ch_access_delay);
3009*5113495bSYour Name 	}
3010*5113495bSYour Name 
3011*5113495bSYour Name 	if (ppdu->txmode_type == TX_MODE_TYPE_DL) {
3012*5113495bSYour Name 		DP_STATS_INC(pdev,
3013*5113495bSYour Name 			     deter_stats.dl_mode_cnt[ppdu->txmode],
3014*5113495bSYour Name 			     1);
3015*5113495bSYour Name 		if (!ppdu->num_users) {
3016*5113495bSYour Name 			dp_mon_err("dl users is %d", ppdu->num_users);
3017*5113495bSYour Name 			return;
3018*5113495bSYour Name 		}
3019*5113495bSYour Name 		user_idx = ppdu->num_users - 1;
3020*5113495bSYour Name 		switch (ppdu->txmode) {
3021*5113495bSYour Name 		case TX_MODE_DL_OFDMA_DATA:
3022*5113495bSYour Name 			DP_STATS_INC(pdev,
3023*5113495bSYour Name 				     deter_stats.dl_ofdma_usr[user_idx],
3024*5113495bSYour Name 				     1);
3025*5113495bSYour Name 			break;
3026*5113495bSYour Name 		case TX_MODE_DL_MUMIMO_DATA:
3027*5113495bSYour Name 			if (user_idx >= CDP_MU_MAX_MIMO_USERS) {
3028*5113495bSYour Name 				dp_mon_err("dl mimo users %d exceed max limit",
3029*5113495bSYour Name 					   ppdu->num_users);
3030*5113495bSYour Name 				return;
3031*5113495bSYour Name 			}
3032*5113495bSYour Name 			DP_STATS_INC(pdev,
3033*5113495bSYour Name 				     deter_stats.dl_mimo_usr[user_idx],
3034*5113495bSYour Name 				     1);
3035*5113495bSYour Name 			break;
3036*5113495bSYour Name 		}
3037*5113495bSYour Name 	} else {
3038*5113495bSYour Name 		DP_STATS_INC(pdev,
3039*5113495bSYour Name 			     deter_stats.ul_mode_cnt[ppdu->txmode],
3040*5113495bSYour Name 			     1);
3041*5113495bSYour Name 
3042*5113495bSYour Name 		if (!ppdu->num_ul_users) {
3043*5113495bSYour Name 			dp_mon_err("dl users is %d", ppdu->num_ul_users);
3044*5113495bSYour Name 			return;
3045*5113495bSYour Name 		}
3046*5113495bSYour Name 		user_idx = ppdu->num_ul_users - 1;
3047*5113495bSYour Name 		switch (ppdu->txmode) {
3048*5113495bSYour Name 		case TX_MODE_UL_OFDMA_BASIC_TRIGGER_DATA:
3049*5113495bSYour Name 			DP_STATS_INC(pdev,
3050*5113495bSYour Name 				     deter_stats.ul_ofdma_usr[user_idx],
3051*5113495bSYour Name 				     1);
3052*5113495bSYour Name 			break;
3053*5113495bSYour Name 		case TX_MODE_UL_MUMIMO_BASIC_TRIGGER_DATA:
3054*5113495bSYour Name 			if (user_idx >= CDP_MU_MAX_MIMO_USERS) {
3055*5113495bSYour Name 				dp_mon_err("ul mimo users %d exceed max limit",
3056*5113495bSYour Name 					   ppdu->num_ul_users);
3057*5113495bSYour Name 				return;
3058*5113495bSYour Name 			}
3059*5113495bSYour Name 			DP_STATS_INC(pdev,
3060*5113495bSYour Name 				     deter_stats.ul_mimo_usr[user_idx],
3061*5113495bSYour Name 				     1);
3062*5113495bSYour Name 			break;
3063*5113495bSYour Name 		}
3064*5113495bSYour Name 		if (ppdu->num_ul_user_resp_valid) {
3065*5113495bSYour Name 			if (ppdu->num_ul_user_resp) {
3066*5113495bSYour Name 				DP_STATS_INC(pdev,
3067*5113495bSYour Name 					     deter_stats.ts[ppdu->txmode].trigger_success,
3068*5113495bSYour Name 					     1);
3069*5113495bSYour Name 			} else {
3070*5113495bSYour Name 				DP_STATS_INC(pdev,
3071*5113495bSYour Name 					     deter_stats.ts[ppdu->txmode].trigger_fail,
3072*5113495bSYour Name 					     1);
3073*5113495bSYour Name 			}
3074*5113495bSYour Name 		}
3075*5113495bSYour Name 	}
3076*5113495bSYour Name }
3077*5113495bSYour Name 
3078*5113495bSYour Name /*
3079*5113495bSYour Name  * dp_ppdu_desc_get_msduq() - Get msduq index from bitmap
3080*5113495bSYour Name  * @ppdu: PPDU Descriptor
3081*5113495bSYour Name  * @msduq_index: MSDUQ index
3082*5113495bSYour Name  *
3083*5113495bSYour Name  * Return: None
3084*5113495bSYour Name  */
3085*5113495bSYour Name static inline void
dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap,uint32_t * msduq_index)3086*5113495bSYour Name dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap, uint32_t *msduq_index)
3087*5113495bSYour Name {
3088*5113495bSYour Name 	if ((msduq_bitmap & BIT(HTT_MSDUQ_INDEX_NON_UDP)) ||
3089*5113495bSYour Name 	    (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_UDP))) {
3090*5113495bSYour Name 		*msduq_index = MSDUQ_INDEX_DEFAULT;
3091*5113495bSYour Name 	} else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_PRIO_0)) {
3092*5113495bSYour Name 		*msduq_index = MSDUQ_INDEX_CUSTOM_PRIO_0;
3093*5113495bSYour Name 	} else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_PRIO_1)) {
3094*5113495bSYour Name 		*msduq_index = MSDUQ_INDEX_CUSTOM_PRIO_1;
3095*5113495bSYour Name 	} else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_0)) {
3096*5113495bSYour Name 		*msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_0;
3097*5113495bSYour Name 	} else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_1)) {
3098*5113495bSYour Name 		*msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_1;
3099*5113495bSYour Name 	} else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_2)) {
3100*5113495bSYour Name 		*msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_2;
3101*5113495bSYour Name 	} else if (msduq_bitmap & BIT(HTT_MSDUQ_INDEX_CUSTOM_EXT_PRIO_3)) {
3102*5113495bSYour Name 		*msduq_index = MSDUQ_INDEX_CUSTOM_EXT_PRIO_3;
3103*5113495bSYour Name 	} else {
3104*5113495bSYour Name 		*msduq_index = MSDUQ_INDEX_MAX;
3105*5113495bSYour Name 	}
3106*5113495bSYour Name }
3107*5113495bSYour Name 
3108*5113495bSYour Name /*
3109*5113495bSYour Name  * dp_ppdu_desc_user_deter_stats_update() - Update per-peer deterministic stats
3110*5113495bSYour Name  * @pdev: Datapath pdev handle
3111*5113495bSYour Name  * @peer: Datapath peer handle
3112*5113495bSYour Name  * @ppdu_desc: PPDU Descriptor
3113*5113495bSYour Name  * @user: PPDU Descriptor per user
3114*5113495bSYour Name  *
3115*5113495bSYour Name  * Return: None
3116*5113495bSYour Name  */
3117*5113495bSYour Name static void
dp_ppdu_desc_user_deter_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu * ppdu_desc,struct cdp_tx_completion_ppdu_user * user)3118*5113495bSYour Name dp_ppdu_desc_user_deter_stats_update(struct dp_pdev *pdev,
3119*5113495bSYour Name 				     struct dp_peer *peer,
3120*5113495bSYour Name 				     struct cdp_tx_completion_ppdu *ppdu_desc,
3121*5113495bSYour Name 				     struct cdp_tx_completion_ppdu_user *user)
3122*5113495bSYour Name {
3123*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
3124*5113495bSYour Name 	uint64_t avg_tx_rate = 0;
3125*5113495bSYour Name 	uint32_t ratekbps = 0;
3126*5113495bSYour Name 	uint32_t rix;
3127*5113495bSYour Name 	uint32_t msduq;
3128*5113495bSYour Name 	uint16_t ratecode = 0;
3129*5113495bSYour Name 	uint8_t txmode;
3130*5113495bSYour Name 	uint8_t tid;
3131*5113495bSYour Name 
3132*5113495bSYour Name 	if (!pdev || !ppdu_desc || !user || !peer)
3133*5113495bSYour Name 		return;
3134*5113495bSYour Name 
3135*5113495bSYour Name 	mon_peer = peer->monitor_peer;
3136*5113495bSYour Name 	if (qdf_unlikely(!mon_peer))
3137*5113495bSYour Name 		return;
3138*5113495bSYour Name 
3139*5113495bSYour Name 	if (ppdu_desc->txmode_type == TX_MODE_TYPE_UNKNOWN)
3140*5113495bSYour Name 		return;
3141*5113495bSYour Name 
3142*5113495bSYour Name 	if (ppdu_desc->txmode_type == TX_MODE_TYPE_UL &&
3143*5113495bSYour Name 	    (ppdu_desc->txmode != TX_MODE_UL_OFDMA_MU_BAR_TRIGGER)) {
3144*5113495bSYour Name 		if (user->tid < CDP_UL_TRIG_BK_TID ||
3145*5113495bSYour Name 		    user->tid > CDP_UL_TRIG_VO_TID)
3146*5113495bSYour Name 			return;
3147*5113495bSYour Name 
3148*5113495bSYour Name 		user->tid = UL_TRIGGER_TID_TO_DATA_TID(user->tid);
3149*5113495bSYour Name 	}
3150*5113495bSYour Name 
3151*5113495bSYour Name 	if (user->tid >= CDP_DATA_TID_MAX)
3152*5113495bSYour Name 		return;
3153*5113495bSYour Name 
3154*5113495bSYour Name 	ratekbps = dp_getrateindex(user->gi,
3155*5113495bSYour Name 				   user->mcs,
3156*5113495bSYour Name 				   user->nss,
3157*5113495bSYour Name 				   user->preamble,
3158*5113495bSYour Name 				   user->bw,
3159*5113495bSYour Name 				   user->punc_mode,
3160*5113495bSYour Name 				   &rix,
3161*5113495bSYour Name 				   &ratecode);
3162*5113495bSYour Name 
3163*5113495bSYour Name 	if (!ratekbps)
3164*5113495bSYour Name 		return;
3165*5113495bSYour Name 
3166*5113495bSYour Name 	avg_tx_rate = mon_peer->stats.deter_stats.avg_tx_rate;
3167*5113495bSYour Name 	avg_tx_rate = dp_ath_rate_lpf(avg_tx_rate,
3168*5113495bSYour Name 				      ratekbps);
3169*5113495bSYour Name 	DP_STATS_UPD(mon_peer,
3170*5113495bSYour Name 		     deter_stats.avg_tx_rate,
3171*5113495bSYour Name 		     avg_tx_rate);
3172*5113495bSYour Name 
3173*5113495bSYour Name 	txmode = ppdu_desc->txmode;
3174*5113495bSYour Name 	tid = user->tid;
3175*5113495bSYour Name 
3176*5113495bSYour Name 	if (ppdu_desc->txmode_type == TX_MODE_TYPE_DL) {
3177*5113495bSYour Name 		dp_ppdu_desc_get_msduq(user->msduq_bitmap, &msduq);
3178*5113495bSYour Name 		if (msduq == MSDUQ_INDEX_MAX)
3179*5113495bSYour Name 			return;
3180*5113495bSYour Name 
3181*5113495bSYour Name 		DP_STATS_INC(mon_peer,
3182*5113495bSYour Name 			     deter_stats.deter[tid].dl_det[msduq][txmode].mode_cnt,
3183*5113495bSYour Name 			     1);
3184*5113495bSYour Name 
3185*5113495bSYour Name 		DP_STATS_UPD(mon_peer,
3186*5113495bSYour Name 			     deter_stats.deter[tid].dl_det[msduq][txmode].avg_rate,
3187*5113495bSYour Name 			     avg_tx_rate);
3188*5113495bSYour Name 	} else {
3189*5113495bSYour Name 		DP_STATS_INC(mon_peer,
3190*5113495bSYour Name 			     deter_stats.deter[tid].ul_det[txmode].mode_cnt,
3191*5113495bSYour Name 			     1);
3192*5113495bSYour Name 
3193*5113495bSYour Name 		DP_STATS_UPD(mon_peer,
3194*5113495bSYour Name 			     deter_stats.deter[tid].ul_det[txmode].avg_rate,
3195*5113495bSYour Name 			     avg_tx_rate);
3196*5113495bSYour Name 		if (!user->completion_status) {
3197*5113495bSYour Name 			DP_STATS_INC(mon_peer,
3198*5113495bSYour Name 				     deter_stats.deter[tid].ul_det[txmode].trigger_success,
3199*5113495bSYour Name 				     1);
3200*5113495bSYour Name 		} else {
3201*5113495bSYour Name 			DP_STATS_INC(mon_peer,
3202*5113495bSYour Name 				     deter_stats.deter[tid].ul_det[txmode].trigger_fail,
3203*5113495bSYour Name 				     1);
3204*5113495bSYour Name 		}
3205*5113495bSYour Name 	}
3206*5113495bSYour Name }
3207*5113495bSYour Name #else
3208*5113495bSYour Name static inline
dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu * ppdu)3209*5113495bSYour Name void dp_ppdu_desc_get_txmode(struct cdp_tx_completion_ppdu *ppdu)
3210*5113495bSYour Name {
3211*5113495bSYour Name }
3212*5113495bSYour Name 
3213*5113495bSYour Name static inline void
dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap,uint32_t * msduq_index)3214*5113495bSYour Name dp_ppdu_desc_get_msduq(uint32_t msduq_bitmap, uint32_t *msduq_index)
3215*5113495bSYour Name {
3216*5113495bSYour Name }
3217*5113495bSYour Name 
3218*5113495bSYour Name static void
dp_ppdu_desc_user_deter_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu * ppdu_desc,struct cdp_tx_completion_ppdu_user * user)3219*5113495bSYour Name dp_ppdu_desc_user_deter_stats_update(struct dp_pdev *pdev,
3220*5113495bSYour Name 				     struct dp_peer *peer,
3221*5113495bSYour Name 				     struct cdp_tx_completion_ppdu *ppdu_desc,
3222*5113495bSYour Name 				     struct cdp_tx_completion_ppdu_user *user)
3223*5113495bSYour Name {
3224*5113495bSYour Name }
3225*5113495bSYour Name 
3226*5113495bSYour Name static inline void
dp_pdev_telemetry_stats_update(struct dp_pdev * pdev,struct cdp_tx_completion_ppdu_user * ppdu)3227*5113495bSYour Name dp_pdev_telemetry_stats_update(
3228*5113495bSYour Name 		struct dp_pdev *pdev,
3229*5113495bSYour Name 		struct cdp_tx_completion_ppdu_user *ppdu)
3230*5113495bSYour Name { }
3231*5113495bSYour Name 
3232*5113495bSYour Name static inline void
dp_pdev_update_deter_stats(struct dp_pdev * pdev,struct cdp_tx_completion_ppdu * ppdu)3233*5113495bSYour Name dp_pdev_update_deter_stats(struct dp_pdev *pdev,
3234*5113495bSYour Name 			   struct cdp_tx_completion_ppdu *ppdu)
3235*5113495bSYour Name { }
3236*5113495bSYour Name #endif
3237*5113495bSYour Name 
3238*5113495bSYour Name /**
3239*5113495bSYour Name  * dp_tx_stats_update() - Update per-peer statistics
3240*5113495bSYour Name  * @pdev: Datapath pdev handle
3241*5113495bSYour Name  * @peer: Datapath peer handle
3242*5113495bSYour Name  * @ppdu: PPDU Descriptor per user
3243*5113495bSYour Name  * @ppdu_desc: PPDU Descriptor
3244*5113495bSYour Name  *
3245*5113495bSYour Name  * Return: None
3246*5113495bSYour Name  */
3247*5113495bSYour Name static void
dp_tx_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * ppdu,struct cdp_tx_completion_ppdu * ppdu_desc)3248*5113495bSYour Name dp_tx_stats_update(struct dp_pdev *pdev, struct dp_peer *peer,
3249*5113495bSYour Name 		   struct cdp_tx_completion_ppdu_user *ppdu,
3250*5113495bSYour Name 		   struct cdp_tx_completion_ppdu *ppdu_desc)
3251*5113495bSYour Name {
3252*5113495bSYour Name 	uint8_t preamble, mcs, res_mcs = 0;
3253*5113495bSYour Name 	uint16_t num_msdu;
3254*5113495bSYour Name 	uint16_t num_mpdu;
3255*5113495bSYour Name 	uint16_t mpdu_tried;
3256*5113495bSYour Name 	uint16_t mpdu_failed;
3257*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
3258*5113495bSYour Name 	enum cdp_ru_index ru_index;
3259*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
3260*5113495bSYour Name 	uint32_t ratekbps = 0;
3261*5113495bSYour Name 	uint64_t tx_byte_count;
3262*5113495bSYour Name 	uint8_t idx = 0;
3263*5113495bSYour Name 	bool is_preamble_valid = true;
3264*5113495bSYour Name 
3265*5113495bSYour Name 	preamble = ppdu->preamble;
3266*5113495bSYour Name 	mcs = ppdu->mcs;
3267*5113495bSYour Name 	num_msdu = ppdu->num_msdu;
3268*5113495bSYour Name 	num_mpdu = ppdu->mpdu_success;
3269*5113495bSYour Name 	mpdu_tried = ppdu->mpdu_tried_ucast + ppdu->mpdu_tried_mcast;
3270*5113495bSYour Name 	mpdu_failed = mpdu_tried - num_mpdu;
3271*5113495bSYour Name 	tx_byte_count = ppdu->success_bytes;
3272*5113495bSYour Name 
3273*5113495bSYour Name 	/* If the peer statistics are already processed as part of
3274*5113495bSYour Name 	 * per-MSDU completion handler, do not process these again in per-PPDU
3275*5113495bSYour Name 	 * indications
3276*5113495bSYour Name 	 */
3277*5113495bSYour Name 	if (pdev->soc->process_tx_status)
3278*5113495bSYour Name 		return;
3279*5113495bSYour Name 
3280*5113495bSYour Name 	mon_peer = peer->monitor_peer;
3281*5113495bSYour Name 	if (!mon_peer)
3282*5113495bSYour Name 		return;
3283*5113495bSYour Name 
3284*5113495bSYour Name 	if (!ppdu->is_mcast) {
3285*5113495bSYour Name 		DP_STATS_INC(mon_peer, tx.tx_ucast_total.num, num_msdu);
3286*5113495bSYour Name 		DP_STATS_INC(mon_peer, tx.tx_ucast_total.bytes,
3287*5113495bSYour Name 			     tx_byte_count);
3288*5113495bSYour Name 	}
3289*5113495bSYour Name 
3290*5113495bSYour Name 	if (ppdu->completion_status != HTT_PPDU_STATS_USER_STATUS_OK) {
3291*5113495bSYour Name 		/*
3292*5113495bSYour Name 		 * All failed mpdu will be retried, so incrementing
3293*5113495bSYour Name 		 * retries mpdu based on mpdu failed. Even for
3294*5113495bSYour Name 		 * ack failure i.e for long retries we get
3295*5113495bSYour Name 		 * mpdu failed equal mpdu tried.
3296*5113495bSYour Name 		 */
3297*5113495bSYour Name 		DP_STATS_INC(mon_peer, tx.retries, mpdu_failed);
3298*5113495bSYour Name 		dp_pdev_telemetry_stats_update(pdev, ppdu);
3299*5113495bSYour Name 		return;
3300*5113495bSYour Name 	}
3301*5113495bSYour Name 
3302*5113495bSYour Name 	if (ppdu->is_ppdu_cookie_valid)
3303*5113495bSYour Name 		DP_STATS_INC(mon_peer, tx.num_ppdu_cookie_valid, 1);
3304*5113495bSYour Name 
3305*5113495bSYour Name 	if (ppdu->mu_group_id <= MAX_MU_GROUP_ID &&
3306*5113495bSYour Name 	    ppdu->ppdu_type != HTT_PPDU_STATS_PPDU_TYPE_SU) {
3307*5113495bSYour Name 		if (qdf_unlikely(ppdu->mu_group_id &&
3308*5113495bSYour Name 				 !(ppdu->mu_group_id & (MAX_MU_GROUP_ID - 1))))
3309*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
3310*5113495bSYour Name 				  "mu_group_id out of bound!!\n");
3311*5113495bSYour Name 		else
3312*5113495bSYour Name 			DP_STATS_UPD(mon_peer, tx.mu_group_id[ppdu->mu_group_id],
3313*5113495bSYour Name 				     (ppdu->user_pos + 1));
3314*5113495bSYour Name 	}
3315*5113495bSYour Name 
3316*5113495bSYour Name 	if (ppdu->ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA ||
3317*5113495bSYour Name 	    ppdu->ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA) {
3318*5113495bSYour Name 		DP_STATS_UPD(mon_peer, tx.ru_tones, ppdu->ru_tones);
3319*5113495bSYour Name 		DP_STATS_UPD(mon_peer, tx.ru_start, ppdu->ru_start);
3320*5113495bSYour Name 		ru_index = dp_get_ru_index_frm_ru_tones(ppdu->ru_tones);
3321*5113495bSYour Name 		if (ru_index != RU_INDEX_MAX) {
3322*5113495bSYour Name 			DP_STATS_INC(mon_peer, tx.ru_loc[ru_index].num_msdu,
3323*5113495bSYour Name 				     num_msdu);
3324*5113495bSYour Name 			DP_STATS_INC(mon_peer, tx.ru_loc[ru_index].num_mpdu,
3325*5113495bSYour Name 				     num_mpdu);
3326*5113495bSYour Name 			DP_STATS_INC(mon_peer, tx.ru_loc[ru_index].mpdu_tried,
3327*5113495bSYour Name 				     mpdu_tried);
3328*5113495bSYour Name 		}
3329*5113495bSYour Name 	}
3330*5113495bSYour Name 
3331*5113495bSYour Name 	/*
3332*5113495bSYour Name 	 * All failed mpdu will be retried, so incrementing
3333*5113495bSYour Name 	 * retries mpdu based on mpdu failed. Even for
3334*5113495bSYour Name 	 * ack failure i.e for long retries we get
3335*5113495bSYour Name 	 * mpdu failed equal mpdu tried.
3336*5113495bSYour Name 	 */
3337*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.retries, mpdu_failed);
3338*5113495bSYour Name 
3339*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.transmit_type[ppdu->ppdu_type].num_msdu,
3340*5113495bSYour Name 		     num_msdu);
3341*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.transmit_type[ppdu->ppdu_type].num_mpdu,
3342*5113495bSYour Name 		     num_mpdu);
3343*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.transmit_type[ppdu->ppdu_type].mpdu_tried,
3344*5113495bSYour Name 		     mpdu_tried);
3345*5113495bSYour Name 
3346*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.sgi_count[ppdu->gi], num_msdu);
3347*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.bw[ppdu->bw], num_msdu);
3348*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.nss[ppdu->nss], num_msdu);
3349*5113495bSYour Name 	if (ppdu->tid < CDP_DATA_TID_MAX) {
3350*5113495bSYour Name 		DP_STATS_INC(mon_peer, tx.wme_ac_type[TID_TO_WME_AC(ppdu->tid)],
3351*5113495bSYour Name 			     num_msdu);
3352*5113495bSYour Name 		DP_STATS_INC(mon_peer,
3353*5113495bSYour Name 			     tx.wme_ac_type_bytes[TID_TO_WME_AC(ppdu->tid)],
3354*5113495bSYour Name 			     tx_byte_count);
3355*5113495bSYour Name 	}
3356*5113495bSYour Name 
3357*5113495bSYour Name 	DP_STATS_INCC(mon_peer, tx.stbc, num_msdu, ppdu->stbc);
3358*5113495bSYour Name 	DP_STATS_INCC(mon_peer, tx.ldpc, num_msdu, ppdu->ldpc);
3359*5113495bSYour Name 	if (!(ppdu->is_mcast) && ppdu->ack_rssi_valid)
3360*5113495bSYour Name 		DP_STATS_UPD(mon_peer, tx.last_ack_rssi, ppdu_desc->ack_rssi);
3361*5113495bSYour Name 
3362*5113495bSYour Name 	if (!ppdu->is_mcast) {
3363*5113495bSYour Name 		DP_STATS_INC(mon_peer, tx.tx_ucast_success.num, num_msdu);
3364*5113495bSYour Name 		DP_STATS_INC(mon_peer, tx.tx_ucast_success.bytes,
3365*5113495bSYour Name 			     tx_byte_count);
3366*5113495bSYour Name 	}
3367*5113495bSYour Name 
3368*5113495bSYour Name 	switch (preamble) {
3369*5113495bSYour Name 	case DOT11_A:
3370*5113495bSYour Name 		res_mcs = (mcs < MAX_MCS_11A) ? mcs : (MAX_MCS - 1);
3371*5113495bSYour Name 	break;
3372*5113495bSYour Name 	case DOT11_B:
3373*5113495bSYour Name 		res_mcs = (mcs < MAX_MCS_11B) ? mcs : (MAX_MCS - 1);
3374*5113495bSYour Name 	break;
3375*5113495bSYour Name 	case DOT11_N:
3376*5113495bSYour Name 		res_mcs = (mcs < MAX_MCS_11N) ? mcs : (MAX_MCS - 1);
3377*5113495bSYour Name 	break;
3378*5113495bSYour Name 	case DOT11_AC:
3379*5113495bSYour Name 		res_mcs = (mcs < MAX_MCS_11AC) ? mcs : (MAX_MCS - 1);
3380*5113495bSYour Name 	break;
3381*5113495bSYour Name 	case DOT11_AX:
3382*5113495bSYour Name 		res_mcs = (mcs < MAX_MCS_11AX) ? mcs : (MAX_MCS - 1);
3383*5113495bSYour Name 	break;
3384*5113495bSYour Name 	default:
3385*5113495bSYour Name 		is_preamble_valid = false;
3386*5113495bSYour Name 	}
3387*5113495bSYour Name 
3388*5113495bSYour Name 	DP_STATS_INCC(mon_peer,
3389*5113495bSYour Name 		      tx.pkt_type[preamble].mcs_count[res_mcs], num_msdu,
3390*5113495bSYour Name 		      is_preamble_valid);
3391*5113495bSYour Name 	DP_STATS_INCC(mon_peer, tx.ampdu_cnt, num_mpdu, ppdu->is_ampdu);
3392*5113495bSYour Name 	DP_STATS_INCC(mon_peer, tx.non_ampdu_cnt, num_mpdu, !(ppdu->is_ampdu));
3393*5113495bSYour Name 	DP_STATS_INCC(mon_peer, tx.pream_punct_cnt, 1, ppdu->pream_punct);
3394*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.tx_ppdus, 1);
3395*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.tx_mpdus_success, num_mpdu);
3396*5113495bSYour Name 	DP_STATS_INC(mon_peer, tx.tx_mpdus_tried, mpdu_tried);
3397*5113495bSYour Name 
3398*5113495bSYour Name 	for (idx = 0; idx < CDP_RSSI_CHAIN_LEN; idx++)
3399*5113495bSYour Name 		DP_STATS_UPD(mon_peer, tx.rssi_chain[idx], ppdu->rssi_chain[idx]);
3400*5113495bSYour Name 
3401*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
3402*5113495bSYour Name 	if (mon_ops && mon_ops->mon_tx_stats_update)
3403*5113495bSYour Name 		mon_ops->mon_tx_stats_update(mon_peer, ppdu);
3404*5113495bSYour Name 
3405*5113495bSYour Name 	if (!ppdu->fixed_rate_used)
3406*5113495bSYour Name 		dp_tx_rate_stats_update(peer, ppdu);
3407*5113495bSYour Name 
3408*5113495bSYour Name 	dp_pdev_telemetry_stats_update(pdev, ppdu);
3409*5113495bSYour Name 
3410*5113495bSYour Name 	dp_peer_stats_notify(pdev, peer);
3411*5113495bSYour Name 
3412*5113495bSYour Name 	ratekbps = mon_peer->stats.tx.tx_rate;
3413*5113495bSYour Name 	DP_STATS_UPD(mon_peer, tx.last_tx_rate, ratekbps);
3414*5113495bSYour Name 
3415*5113495bSYour Name 	dp_send_stats_event(pdev, peer, ppdu->peer_id);
3416*5113495bSYour Name }
3417*5113495bSYour Name 
3418*5113495bSYour Name /**
3419*5113495bSYour Name  * dp_get_ppdu_info_user_index() - Find and allocate a per-user
3420*5113495bSYour Name  * descriptor for a PPDU, if a new peer id arrives in a PPDU
3421*5113495bSYour Name  * @pdev: DP pdev handle
3422*5113495bSYour Name  * @peer_id: peer unique identifier
3423*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
3424*5113495bSYour Name  *
3425*5113495bSYour Name  * Return: user index to be populated
3426*5113495bSYour Name  */
dp_get_ppdu_info_user_index(struct dp_pdev * pdev,uint16_t peer_id,struct ppdu_info * ppdu_info)3427*5113495bSYour Name static uint8_t dp_get_ppdu_info_user_index(struct dp_pdev *pdev,
3428*5113495bSYour Name 					   uint16_t peer_id,
3429*5113495bSYour Name 					   struct ppdu_info *ppdu_info)
3430*5113495bSYour Name {
3431*5113495bSYour Name 	uint8_t user_index = 0;
3432*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
3433*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
3434*5113495bSYour Name 
3435*5113495bSYour Name 	ppdu_desc =
3436*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
3437*5113495bSYour Name 
3438*5113495bSYour Name 	while ((user_index + 1) <= ppdu_info->last_user) {
3439*5113495bSYour Name 		ppdu_user_desc = &ppdu_desc->user[user_index];
3440*5113495bSYour Name 		if (ppdu_user_desc->peer_id != peer_id) {
3441*5113495bSYour Name 			user_index++;
3442*5113495bSYour Name 			continue;
3443*5113495bSYour Name 		} else {
3444*5113495bSYour Name 			/* Max users possible is 8 so user array index should
3445*5113495bSYour Name 			 * not exceed 7
3446*5113495bSYour Name 			 */
3447*5113495bSYour Name 			qdf_assert_always(user_index <= (ppdu_desc->max_users - 1));
3448*5113495bSYour Name 			return user_index;
3449*5113495bSYour Name 		}
3450*5113495bSYour Name 	}
3451*5113495bSYour Name 
3452*5113495bSYour Name 	ppdu_info->last_user++;
3453*5113495bSYour Name 	/* Max users possible is 8 so last user should not exceed 8 */
3454*5113495bSYour Name 	qdf_assert_always(ppdu_info->last_user <= ppdu_desc->max_users);
3455*5113495bSYour Name 	return ppdu_info->last_user - 1;
3456*5113495bSYour Name }
3457*5113495bSYour Name 
3458*5113495bSYour Name /**
3459*5113495bSYour Name  * dp_process_ppdu_stats_common_tlv() - Process htt_ppdu_stats_common_tlv
3460*5113495bSYour Name  * @pdev: DP pdev handle
3461*5113495bSYour Name  * @tag_buf: buffer containing the tlv htt_ppdu_stats_common_tlv
3462*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
3463*5113495bSYour Name  *
3464*5113495bSYour Name  * Return: void
3465*5113495bSYour Name  */
3466*5113495bSYour Name static void
dp_process_ppdu_stats_common_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3467*5113495bSYour Name dp_process_ppdu_stats_common_tlv(struct dp_pdev *pdev,
3468*5113495bSYour Name 				 uint32_t *tag_buf,
3469*5113495bSYour Name 				 struct ppdu_info *ppdu_info)
3470*5113495bSYour Name {
3471*5113495bSYour Name 	uint16_t frame_type;
3472*5113495bSYour Name 	uint16_t frame_ctrl;
3473*5113495bSYour Name 	uint16_t freq;
3474*5113495bSYour Name 	struct dp_soc *soc = NULL;
3475*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc = NULL;
3476*5113495bSYour Name 	uint64_t ppdu_start_timestamp;
3477*5113495bSYour Name 	uint32_t eval_start_timestamp;
3478*5113495bSYour Name 	uint32_t *start_tag_buf;
3479*5113495bSYour Name 	uint32_t *ts_tag_buf;
3480*5113495bSYour Name 
3481*5113495bSYour Name 	start_tag_buf = tag_buf;
3482*5113495bSYour Name 	ppdu_desc =
3483*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
3484*5113495bSYour Name 
3485*5113495bSYour Name 	ppdu_desc->ppdu_id = ppdu_info->ppdu_id;
3486*5113495bSYour Name 
3487*5113495bSYour Name 	tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(RING_ID_SCH_CMD_ID);
3488*5113495bSYour Name 	ppdu_info->sched_cmdid =
3489*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_SCH_CMDID_GET(*tag_buf);
3490*5113495bSYour Name 	ppdu_desc->num_users =
3491*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_NUM_USERS_GET(*tag_buf);
3492*5113495bSYour Name 
3493*5113495bSYour Name 	qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users);
3494*5113495bSYour Name 
3495*5113495bSYour Name 	tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(QTYPE_FRM_TYPE);
3496*5113495bSYour Name 	frame_type = HTT_PPDU_STATS_COMMON_TLV_FRM_TYPE_GET(*tag_buf);
3497*5113495bSYour Name 	ppdu_desc->htt_frame_type = frame_type;
3498*5113495bSYour Name 
3499*5113495bSYour Name 	ppdu_desc->htt_seq_type =
3500*5113495bSYour Name 			HTT_PPDU_STATS_COMMON_TLV_PPDU_SEQ_TYPE_GET(*tag_buf);
3501*5113495bSYour Name 
3502*5113495bSYour Name 	frame_ctrl = ppdu_desc->frame_ctrl;
3503*5113495bSYour Name 
3504*5113495bSYour Name 	ppdu_desc->bar_ppdu_id = ppdu_info->ppdu_id;
3505*5113495bSYour Name 
3506*5113495bSYour Name 	switch (frame_type) {
3507*5113495bSYour Name 	case HTT_STATS_FTYPE_TIDQ_DATA_SU:
3508*5113495bSYour Name 	case HTT_STATS_FTYPE_TIDQ_DATA_MU:
3509*5113495bSYour Name 	case HTT_STATS_FTYPE_SGEN_QOS_NULL:
3510*5113495bSYour Name 		/*
3511*5113495bSYour Name 		 * for management packet, frame type come as DATA_SU
3512*5113495bSYour Name 		 * need to check frame_ctrl before setting frame_type
3513*5113495bSYour Name 		 */
3514*5113495bSYour Name 		if (HTT_GET_FRAME_CTRL_TYPE(frame_ctrl) <= FRAME_CTRL_TYPE_CTRL)
3515*5113495bSYour Name 			ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL;
3516*5113495bSYour Name 		else
3517*5113495bSYour Name 			ppdu_desc->frame_type = CDP_PPDU_FTYPE_DATA;
3518*5113495bSYour Name 	break;
3519*5113495bSYour Name 	case HTT_STATS_FTYPE_SGEN_MU_BAR:
3520*5113495bSYour Name 	case HTT_STATS_FTYPE_SGEN_BAR:
3521*5113495bSYour Name 	case HTT_STATS_FTYPE_SGEN_BE_MU_BAR:
3522*5113495bSYour Name 		ppdu_desc->frame_type = CDP_PPDU_FTYPE_BAR;
3523*5113495bSYour Name 	break;
3524*5113495bSYour Name 	default:
3525*5113495bSYour Name 		ppdu_desc->frame_type = CDP_PPDU_FTYPE_CTRL;
3526*5113495bSYour Name 	break;
3527*5113495bSYour Name 	}
3528*5113495bSYour Name 
3529*5113495bSYour Name 	tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(FES_DUR_US);
3530*5113495bSYour Name 	ppdu_desc->tx_duration = *tag_buf;
3531*5113495bSYour Name 
3532*5113495bSYour Name 	tag_buf = start_tag_buf +
3533*5113495bSYour Name 			HTT_GET_STATS_CMN_INDEX(SCH_EVAL_START_TSTMP_L32_US);
3534*5113495bSYour Name 	eval_start_timestamp = *tag_buf;
3535*5113495bSYour Name 
3536*5113495bSYour Name 	tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(START_TSTMP_L32_US);
3537*5113495bSYour Name 	ppdu_desc->ppdu_start_timestamp = *tag_buf;
3538*5113495bSYour Name 
3539*5113495bSYour Name 	tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(CHAN_MHZ_PHY_MODE);
3540*5113495bSYour Name 	freq = HTT_PPDU_STATS_COMMON_TLV_CHAN_MHZ_GET(*tag_buf);
3541*5113495bSYour Name 	if (freq != ppdu_desc->channel) {
3542*5113495bSYour Name 		soc = pdev->soc;
3543*5113495bSYour Name 		ppdu_desc->channel = freq;
3544*5113495bSYour Name 		pdev->operating_channel.freq = freq;
3545*5113495bSYour Name 		if (soc && soc->cdp_soc.ol_ops->freq_to_channel)
3546*5113495bSYour Name 			pdev->operating_channel.num =
3547*5113495bSYour Name 			    soc->cdp_soc.ol_ops->freq_to_channel(soc->ctrl_psoc,
3548*5113495bSYour Name 								 pdev->pdev_id,
3549*5113495bSYour Name 								 freq);
3550*5113495bSYour Name 
3551*5113495bSYour Name 		if (soc && soc->cdp_soc.ol_ops->freq_to_band)
3552*5113495bSYour Name 			pdev->operating_channel.band =
3553*5113495bSYour Name 			       soc->cdp_soc.ol_ops->freq_to_band(soc->ctrl_psoc,
3554*5113495bSYour Name 								 pdev->pdev_id,
3555*5113495bSYour Name 								 freq);
3556*5113495bSYour Name 	}
3557*5113495bSYour Name 
3558*5113495bSYour Name 	ppdu_desc->phy_mode = HTT_PPDU_STATS_COMMON_TLV_PHY_MODE_GET(*tag_buf);
3559*5113495bSYour Name 
3560*5113495bSYour Name 	tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(RESV_NUM_UL_BEAM);
3561*5113495bSYour Name 	ppdu_desc->phy_ppdu_tx_time_us =
3562*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_PHY_PPDU_TX_TIME_US_GET(*tag_buf);
3563*5113495bSYour Name 	ppdu_desc->beam_change =
3564*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_BEAM_CHANGE_GET(*tag_buf);
3565*5113495bSYour Name 	ppdu_desc->doppler =
3566*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_DOPPLER_INDICATION_GET(*tag_buf);
3567*5113495bSYour Name 	ppdu_desc->spatial_reuse =
3568*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_SPATIAL_REUSE_GET(*tag_buf);
3569*5113495bSYour Name 	ppdu_desc->num_ul_users =
3570*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_NUM_UL_EXPECTED_USERS_GET(*tag_buf);
3571*5113495bSYour Name 
3572*5113495bSYour Name 	dp_tx_capture_htt_frame_counter(pdev, frame_type);
3573*5113495bSYour Name 
3574*5113495bSYour Name 	tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(START_TSTMP_U32_US);
3575*5113495bSYour Name 	ppdu_start_timestamp = *tag_buf;
3576*5113495bSYour Name 	ppdu_desc->ppdu_start_timestamp |= ((ppdu_start_timestamp <<
3577*5113495bSYour Name 					     HTT_SHIFT_UPPER_TIMESTAMP) &
3578*5113495bSYour Name 					    HTT_MASK_UPPER_TIMESTAMP);
3579*5113495bSYour Name 
3580*5113495bSYour Name 	ppdu_desc->ppdu_end_timestamp = ppdu_desc->ppdu_start_timestamp +
3581*5113495bSYour Name 					ppdu_desc->tx_duration;
3582*5113495bSYour Name 	/* Ack time stamp is same as end time stamp*/
3583*5113495bSYour Name 	ppdu_desc->ack_timestamp = ppdu_desc->ppdu_end_timestamp;
3584*5113495bSYour Name 
3585*5113495bSYour Name 	ppdu_desc->ppdu_end_timestamp = ppdu_desc->ppdu_start_timestamp +
3586*5113495bSYour Name 					ppdu_desc->tx_duration;
3587*5113495bSYour Name 
3588*5113495bSYour Name 	ppdu_desc->bar_ppdu_start_timestamp = ppdu_desc->ppdu_start_timestamp;
3589*5113495bSYour Name 	ppdu_desc->bar_ppdu_end_timestamp = ppdu_desc->ppdu_end_timestamp;
3590*5113495bSYour Name 	ppdu_desc->bar_tx_duration = ppdu_desc->tx_duration;
3591*5113495bSYour Name 
3592*5113495bSYour Name 	/* Ack time stamp is same as end time stamp*/
3593*5113495bSYour Name 	ppdu_desc->ack_timestamp = ppdu_desc->ppdu_end_timestamp;
3594*5113495bSYour Name 
3595*5113495bSYour Name 	tag_buf = start_tag_buf + HTT_GET_STATS_CMN_INDEX(BSSCOLOR_OBSS_PSR);
3596*5113495bSYour Name 	ppdu_desc->bss_color =
3597*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_BSS_COLOR_ID_GET(*tag_buf);
3598*5113495bSYour Name 
3599*5113495bSYour Name 	ppdu_desc->backoff_ac_valid =
3600*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_BACKOFF_AC_VALID_GET(*tag_buf);
3601*5113495bSYour Name 	if (ppdu_desc->backoff_ac_valid) {
3602*5113495bSYour Name 		ppdu_desc->backoff_ac =
3603*5113495bSYour Name 			HTT_PPDU_STATS_COMMON_TLV_BACKOFF_AC_GET(*tag_buf);
3604*5113495bSYour Name 		ts_tag_buf = start_tag_buf +
3605*5113495bSYour Name 			HTT_GET_STATS_CMN_INDEX(SCH_EVAL_START_TSTMP_L32_US);
3606*5113495bSYour Name 		eval_start_timestamp = *ts_tag_buf;
3607*5113495bSYour Name 
3608*5113495bSYour Name 		ts_tag_buf = start_tag_buf +
3609*5113495bSYour Name 			HTT_GET_STATS_CMN_INDEX(START_TSTMP_L32_US);
3610*5113495bSYour Name 		ppdu_desc->ch_access_delay =
3611*5113495bSYour Name 			*ts_tag_buf - eval_start_timestamp;
3612*5113495bSYour Name 	}
3613*5113495bSYour Name 	ppdu_desc->num_ul_user_resp_valid =
3614*5113495bSYour Name 		HTT_PPDU_STATS_COMMON_TLV_NUM_UL_USER_RESPONSES_VALID_GET(*tag_buf);
3615*5113495bSYour Name 	if (ppdu_desc->num_ul_user_resp_valid)
3616*5113495bSYour Name 		ppdu_desc->num_ul_user_resp =
3617*5113495bSYour Name 			HTT_PPDU_STATS_COMMON_TLV_NUM_UL_USER_RESPONSES_GET(*tag_buf);
3618*5113495bSYour Name }
3619*5113495bSYour Name 
3620*5113495bSYour Name /**
3621*5113495bSYour Name  * dp_process_ppdu_stats_user_common_tlv() - Process ppdu_stats_user_common
3622*5113495bSYour Name  * @pdev: DP PDEV handle
3623*5113495bSYour Name  * @tag_buf: buffer containing the tlv htt_ppdu_stats_user_common_tlv
3624*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
3625*5113495bSYour Name  *
3626*5113495bSYour Name  * Return: void
3627*5113495bSYour Name  */
dp_process_ppdu_stats_user_common_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3628*5113495bSYour Name static void dp_process_ppdu_stats_user_common_tlv(
3629*5113495bSYour Name 		struct dp_pdev *pdev, uint32_t *tag_buf,
3630*5113495bSYour Name 		struct ppdu_info *ppdu_info)
3631*5113495bSYour Name {
3632*5113495bSYour Name 	uint16_t peer_id;
3633*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
3634*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
3635*5113495bSYour Name 	uint8_t curr_user_index = 0;
3636*5113495bSYour Name 	struct dp_peer *peer;
3637*5113495bSYour Name 	struct dp_vdev *vdev;
3638*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
3639*5113495bSYour Name 
3640*5113495bSYour Name 	ppdu_desc =
3641*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
3642*5113495bSYour Name 
3643*5113495bSYour Name 	tag_buf++;
3644*5113495bSYour Name 	peer_id = HTT_PPDU_STATS_USER_RATE_TLV_SW_PEER_ID_GET(*tag_buf);
3645*5113495bSYour Name 
3646*5113495bSYour Name 	curr_user_index =
3647*5113495bSYour Name 		dp_get_ppdu_info_user_index(pdev,
3648*5113495bSYour Name 					    peer_id, ppdu_info);
3649*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
3650*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
3651*5113495bSYour Name 
3652*5113495bSYour Name 	ppdu_desc->vdev_id =
3653*5113495bSYour Name 		HTT_PPDU_STATS_USER_COMMON_TLV_VAP_ID_GET(*tag_buf);
3654*5113495bSYour Name 
3655*5113495bSYour Name 	ppdu_user_desc->peer_id = peer_id;
3656*5113495bSYour Name 
3657*5113495bSYour Name 	tag_buf++;
3658*5113495bSYour Name 
3659*5113495bSYour Name 	if (HTT_PPDU_STATS_USER_COMMON_TLV_DELAYED_BA_GET(*tag_buf)) {
3660*5113495bSYour Name 		ppdu_user_desc->delayed_ba = 1;
3661*5113495bSYour Name 		ppdu_desc->delayed_ba = 1;
3662*5113495bSYour Name 	}
3663*5113495bSYour Name 
3664*5113495bSYour Name 	if (HTT_PPDU_STATS_USER_COMMON_TLV_MCAST_GET(*tag_buf)) {
3665*5113495bSYour Name 		ppdu_user_desc->is_mcast = true;
3666*5113495bSYour Name 		ppdu_user_desc->mpdu_tried_mcast =
3667*5113495bSYour Name 		HTT_PPDU_STATS_USER_COMMON_TLV_MPDUS_TRIED_GET(*tag_buf);
3668*5113495bSYour Name 		ppdu_user_desc->num_mpdu = ppdu_user_desc->mpdu_tried_mcast;
3669*5113495bSYour Name 	} else {
3670*5113495bSYour Name 		ppdu_user_desc->mpdu_tried_ucast =
3671*5113495bSYour Name 		HTT_PPDU_STATS_USER_COMMON_TLV_MPDUS_TRIED_GET(*tag_buf);
3672*5113495bSYour Name 	}
3673*5113495bSYour Name 
3674*5113495bSYour Name 	ppdu_user_desc->is_seq_num_valid =
3675*5113495bSYour Name 	HTT_PPDU_STATS_USER_COMMON_TLV_IS_SQNUM_VALID_IN_BUFFER_GET(*tag_buf);
3676*5113495bSYour Name 	tag_buf++;
3677*5113495bSYour Name 
3678*5113495bSYour Name 	ppdu_user_desc->qos_ctrl =
3679*5113495bSYour Name 		HTT_PPDU_STATS_USER_COMMON_TLV_QOS_CTRL_GET(*tag_buf);
3680*5113495bSYour Name 	ppdu_user_desc->frame_ctrl =
3681*5113495bSYour Name 		HTT_PPDU_STATS_USER_COMMON_TLV_FRAME_CTRL_GET(*tag_buf);
3682*5113495bSYour Name 	ppdu_desc->frame_ctrl = ppdu_user_desc->frame_ctrl;
3683*5113495bSYour Name 
3684*5113495bSYour Name 	if (ppdu_user_desc->delayed_ba)
3685*5113495bSYour Name 		ppdu_user_desc->mpdu_success = 0;
3686*5113495bSYour Name 
3687*5113495bSYour Name 	tag_buf += 3;
3688*5113495bSYour Name 
3689*5113495bSYour Name 	if (HTT_PPDU_STATS_IS_OPAQUE_VALID_GET(*tag_buf)) {
3690*5113495bSYour Name 		ppdu_user_desc->ppdu_cookie =
3691*5113495bSYour Name 			HTT_PPDU_STATS_HOST_OPAQUE_COOKIE_GET(*tag_buf);
3692*5113495bSYour Name 		ppdu_user_desc->is_ppdu_cookie_valid = 1;
3693*5113495bSYour Name 	}
3694*5113495bSYour Name 
3695*5113495bSYour Name 	/* returning earlier causes other feilds unpopulated */
3696*5113495bSYour Name 	if (peer_id == DP_SCAN_PEER_ID) {
3697*5113495bSYour Name 		vdev = dp_vdev_get_ref_by_id(pdev->soc, ppdu_desc->vdev_id,
3698*5113495bSYour Name 					     DP_MOD_ID_TX_PPDU_STATS);
3699*5113495bSYour Name 		if (!vdev)
3700*5113495bSYour Name 			return;
3701*5113495bSYour Name 		qdf_mem_copy(ppdu_user_desc->mac_addr, vdev->mac_addr.raw,
3702*5113495bSYour Name 			     QDF_MAC_ADDR_SIZE);
3703*5113495bSYour Name 		dp_vdev_unref_delete(pdev->soc, vdev, DP_MOD_ID_TX_PPDU_STATS);
3704*5113495bSYour Name 	} else {
3705*5113495bSYour Name 		peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
3706*5113495bSYour Name 					     DP_MOD_ID_TX_PPDU_STATS);
3707*5113495bSYour Name 		if (!peer) {
3708*5113495bSYour Name 			/*
3709*5113495bSYour Name 			 * fw sends peer_id which is about to removed but
3710*5113495bSYour Name 			 * it was already removed in host.
3711*5113495bSYour Name 			 * eg: for disassoc, fw send ppdu stats
3712*5113495bSYour Name 			 * with peer id equal to previously associated
3713*5113495bSYour Name 			 * peer's peer_id but it was removed
3714*5113495bSYour Name 			 */
3715*5113495bSYour Name 			vdev = dp_vdev_get_ref_by_id(pdev->soc,
3716*5113495bSYour Name 						     ppdu_desc->vdev_id,
3717*5113495bSYour Name 						     DP_MOD_ID_TX_PPDU_STATS);
3718*5113495bSYour Name 			if (!vdev)
3719*5113495bSYour Name 				return;
3720*5113495bSYour Name 			qdf_mem_copy(ppdu_user_desc->mac_addr,
3721*5113495bSYour Name 				     vdev->mac_addr.raw, QDF_MAC_ADDR_SIZE);
3722*5113495bSYour Name 			dp_vdev_unref_delete(pdev->soc, vdev,
3723*5113495bSYour Name 					     DP_MOD_ID_TX_PPDU_STATS);
3724*5113495bSYour Name 			return;
3725*5113495bSYour Name 		}
3726*5113495bSYour Name 		qdf_mem_copy(ppdu_user_desc->mac_addr,
3727*5113495bSYour Name 			     peer->mac_addr.raw, QDF_MAC_ADDR_SIZE);
3728*5113495bSYour Name 		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
3729*5113495bSYour Name 	}
3730*5113495bSYour Name 
3731*5113495bSYour Name 	tag_buf += 10;
3732*5113495bSYour Name 	ppdu_user_desc->msduq_bitmap = *tag_buf;
3733*5113495bSYour Name }
3734*5113495bSYour Name 
3735*5113495bSYour Name /**
3736*5113495bSYour Name  * dp_process_ppdu_stats_user_rate_tlv() - Process htt_ppdu_stats_user_rate_tlv
3737*5113495bSYour Name  * @pdev: DP pdev handle
3738*5113495bSYour Name  * @tag_buf: T2H message buffer carrying the user rate TLV
3739*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
3740*5113495bSYour Name  *
3741*5113495bSYour Name  * Return: void
3742*5113495bSYour Name  */
3743*5113495bSYour Name static void
dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3744*5113495bSYour Name dp_process_ppdu_stats_user_rate_tlv(struct dp_pdev *pdev,
3745*5113495bSYour Name 				    uint32_t *tag_buf,
3746*5113495bSYour Name 				    struct ppdu_info *ppdu_info)
3747*5113495bSYour Name {
3748*5113495bSYour Name 	uint16_t peer_id;
3749*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
3750*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
3751*5113495bSYour Name 	uint8_t curr_user_index = 0;
3752*5113495bSYour Name 	struct dp_vdev *vdev;
3753*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
3754*5113495bSYour Name 	uint8_t bw, ru_format;
3755*5113495bSYour Name 	uint16_t ru_size;
3756*5113495bSYour Name 	htt_ppdu_stats_user_rate_tlv *stats_buf =
3757*5113495bSYour Name 		(htt_ppdu_stats_user_rate_tlv *)tag_buf;
3758*5113495bSYour Name 
3759*5113495bSYour Name 	ppdu_desc =
3760*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
3761*5113495bSYour Name 
3762*5113495bSYour Name 	tag_buf++;
3763*5113495bSYour Name 	peer_id = HTT_PPDU_STATS_USER_RATE_TLV_SW_PEER_ID_GET(*tag_buf);
3764*5113495bSYour Name 
3765*5113495bSYour Name 	curr_user_index =
3766*5113495bSYour Name 		dp_get_ppdu_info_user_index(pdev,
3767*5113495bSYour Name 					    peer_id, ppdu_info);
3768*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
3769*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
3770*5113495bSYour Name 	if (peer_id == DP_SCAN_PEER_ID) {
3771*5113495bSYour Name 		vdev = dp_vdev_get_ref_by_id(pdev->soc, ppdu_desc->vdev_id,
3772*5113495bSYour Name 					     DP_MOD_ID_TX_PPDU_STATS);
3773*5113495bSYour Name 		if (!vdev)
3774*5113495bSYour Name 			return;
3775*5113495bSYour Name 		dp_vdev_unref_delete(pdev->soc, vdev,
3776*5113495bSYour Name 				     DP_MOD_ID_TX_PPDU_STATS);
3777*5113495bSYour Name 	}
3778*5113495bSYour Name 	ppdu_user_desc->peer_id = peer_id;
3779*5113495bSYour Name 
3780*5113495bSYour Name 	ppdu_user_desc->tid =
3781*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_TID_NUM_GET(*tag_buf);
3782*5113495bSYour Name 
3783*5113495bSYour Name 	tag_buf += 1;
3784*5113495bSYour Name 
3785*5113495bSYour Name 	ppdu_user_desc->user_pos =
3786*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_USER_POS_GET(*tag_buf);
3787*5113495bSYour Name 	ppdu_user_desc->mu_group_id =
3788*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_MU_GROUPID_GET(*tag_buf);
3789*5113495bSYour Name 
3790*5113495bSYour Name 	ru_format = HTT_PPDU_STATS_USER_RATE_TLV_RU_FORMAT_GET(*tag_buf);
3791*5113495bSYour Name 
3792*5113495bSYour Name 	tag_buf += 1;
3793*5113495bSYour Name 
3794*5113495bSYour Name 	if (!ru_format) {
3795*5113495bSYour Name 		/* ru_format = 0: ru_end, ru_start */
3796*5113495bSYour Name 		ppdu_user_desc->ru_start =
3797*5113495bSYour Name 			HTT_PPDU_STATS_USER_RATE_TLV_RU_START_GET(*tag_buf);
3798*5113495bSYour Name 		ppdu_user_desc->ru_tones =
3799*5113495bSYour Name 			(HTT_PPDU_STATS_USER_RATE_TLV_RU_END_GET(*tag_buf) -
3800*5113495bSYour Name 			HTT_PPDU_STATS_USER_RATE_TLV_RU_START_GET(*tag_buf)) + 1;
3801*5113495bSYour Name 	} else if (ru_format == 1) {
3802*5113495bSYour Name 		/* ru_format = 1: ru_index, ru_size */
3803*5113495bSYour Name 		ru_size = HTT_PPDU_STATS_USER_RATE_TLV_RU_SIZE_GET(*tag_buf);
3804*5113495bSYour Name 		ppdu_user_desc->ru_tones =
3805*5113495bSYour Name 				dp_mon_get_ru_width_from_ru_size(ru_size);
3806*5113495bSYour Name 	} else {
3807*5113495bSYour Name 		dp_mon_debug("Unsupported ru_format: %d rcvd", ru_format);
3808*5113495bSYour Name 	}
3809*5113495bSYour Name 	ppdu_desc->usr_ru_tones_sum += ppdu_user_desc->ru_tones;
3810*5113495bSYour Name 
3811*5113495bSYour Name 	tag_buf += 2;
3812*5113495bSYour Name 
3813*5113495bSYour Name 	ppdu_user_desc->ppdu_type =
3814*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_PPDU_TYPE_GET(*tag_buf);
3815*5113495bSYour Name 
3816*5113495bSYour Name 	tag_buf++;
3817*5113495bSYour Name 	ppdu_user_desc->tx_rate = *tag_buf;
3818*5113495bSYour Name 
3819*5113495bSYour Name 	ppdu_user_desc->ltf_size =
3820*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_LTF_SIZE_GET(*tag_buf);
3821*5113495bSYour Name 	ppdu_user_desc->stbc =
3822*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_STBC_GET(*tag_buf);
3823*5113495bSYour Name 	ppdu_user_desc->he_re =
3824*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_HE_RE_GET(*tag_buf);
3825*5113495bSYour Name 	ppdu_user_desc->txbf =
3826*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_TXBF_GET(*tag_buf);
3827*5113495bSYour Name 	bw = HTT_PPDU_STATS_USER_RATE_TLV_BW_GET(*tag_buf);
3828*5113495bSYour Name 	/* Align bw value as per host data structures */
3829*5113495bSYour Name 	if (bw == HTT_PPDU_STATS_BANDWIDTH_320MHZ)
3830*5113495bSYour Name 		ppdu_user_desc->bw = bw - 3;
3831*5113495bSYour Name 	else
3832*5113495bSYour Name 		ppdu_user_desc->bw = bw - 2;
3833*5113495bSYour Name 	ppdu_user_desc->nss = HTT_PPDU_STATS_USER_RATE_TLV_NSS_GET(*tag_buf);
3834*5113495bSYour Name 	ppdu_desc->usr_nss_sum += ppdu_user_desc->nss;
3835*5113495bSYour Name 	ppdu_user_desc->mcs = HTT_PPDU_STATS_USER_RATE_TLV_MCS_GET(*tag_buf);
3836*5113495bSYour Name 	ppdu_user_desc->preamble =
3837*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_PREAMBLE_GET(*tag_buf);
3838*5113495bSYour Name 	ppdu_user_desc->gi = HTT_PPDU_STATS_USER_RATE_TLV_GI_GET(*tag_buf);
3839*5113495bSYour Name 	ppdu_user_desc->dcm = HTT_PPDU_STATS_USER_RATE_TLV_DCM_GET(*tag_buf);
3840*5113495bSYour Name 	ppdu_user_desc->ldpc = HTT_PPDU_STATS_USER_RATE_TLV_LDPC_GET(*tag_buf);
3841*5113495bSYour Name 
3842*5113495bSYour Name 	tag_buf += 2;
3843*5113495bSYour Name 	ppdu_user_desc->punc_pattern_bitmap =
3844*5113495bSYour Name 		HTT_PPDU_STATS_USER_RATE_TLV_PUNC_PATTERN_BITMAP_GET(*tag_buf);
3845*5113495bSYour Name 	ppdu_user_desc->fixed_rate_used = stats_buf->is_min_rate;
3846*5113495bSYour Name }
3847*5113495bSYour Name 
3848*5113495bSYour Name /**
3849*5113495bSYour Name  * dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv() - Process
3850*5113495bSYour Name  * htt_ppdu_stats_enq_mpdu_bitmap_64_tlv
3851*5113495bSYour Name  * @pdev: DP PDEV handle
3852*5113495bSYour Name  * @tag_buf: buffer containing the tlv htt_ppdu_stats_enq_mpdu_bitmap_64_tlv
3853*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
3854*5113495bSYour Name  *
3855*5113495bSYour Name  * Return: void
3856*5113495bSYour Name  */
dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3857*5113495bSYour Name static void dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
3858*5113495bSYour Name 		struct dp_pdev *pdev, uint32_t *tag_buf,
3859*5113495bSYour Name 		struct ppdu_info *ppdu_info)
3860*5113495bSYour Name {
3861*5113495bSYour Name 	htt_ppdu_stats_enq_mpdu_bitmap_64_tlv *dp_stats_buf =
3862*5113495bSYour Name 		(htt_ppdu_stats_enq_mpdu_bitmap_64_tlv *)tag_buf;
3863*5113495bSYour Name 
3864*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
3865*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
3866*5113495bSYour Name 	uint8_t curr_user_index = 0;
3867*5113495bSYour Name 	uint16_t peer_id;
3868*5113495bSYour Name 	uint32_t size = CDP_BA_64_BIT_MAP_SIZE_DWORDS;
3869*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
3870*5113495bSYour Name 
3871*5113495bSYour Name 	ppdu_desc =
3872*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
3873*5113495bSYour Name 
3874*5113495bSYour Name 	tag_buf++;
3875*5113495bSYour Name 
3876*5113495bSYour Name 	peer_id =
3877*5113495bSYour Name 	HTT_PPDU_STATS_ENQ_MPDU_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
3878*5113495bSYour Name 
3879*5113495bSYour Name 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
3880*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
3881*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
3882*5113495bSYour Name 	ppdu_user_desc->peer_id = peer_id;
3883*5113495bSYour Name 
3884*5113495bSYour Name 	ppdu_user_desc->start_seq = dp_stats_buf->start_seq;
3885*5113495bSYour Name 	qdf_mem_copy(&ppdu_user_desc->enq_bitmap, &dp_stats_buf->enq_bitmap,
3886*5113495bSYour Name 		     sizeof(uint32_t) * CDP_BA_64_BIT_MAP_SIZE_DWORDS);
3887*5113495bSYour Name 
3888*5113495bSYour Name 	dp_process_ppdu_stats_update_failed_bitmap(pdev,
3889*5113495bSYour Name 						   (void *)ppdu_user_desc,
3890*5113495bSYour Name 						   ppdu_info->ppdu_id,
3891*5113495bSYour Name 						   size);
3892*5113495bSYour Name }
3893*5113495bSYour Name 
3894*5113495bSYour Name /**
3895*5113495bSYour Name  * dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv() - Process
3896*5113495bSYour Name  * htt_ppdu_stats_enq_mpdu_bitmap_256_tlv
3897*5113495bSYour Name  * @pdev: DP PDEV handle
3898*5113495bSYour Name  * @tag_buf: buffer containing the tlv htt_ppdu_stats_enq_mpdu_bitmap_256_tlv
3899*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
3900*5113495bSYour Name  *
3901*5113495bSYour Name  * Return: void
3902*5113495bSYour Name  */
dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3903*5113495bSYour Name static void dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
3904*5113495bSYour Name 		struct dp_pdev *pdev, uint32_t *tag_buf,
3905*5113495bSYour Name 		struct ppdu_info *ppdu_info)
3906*5113495bSYour Name {
3907*5113495bSYour Name 	htt_ppdu_stats_enq_mpdu_bitmap_256_tlv *dp_stats_buf =
3908*5113495bSYour Name 		(htt_ppdu_stats_enq_mpdu_bitmap_256_tlv *)tag_buf;
3909*5113495bSYour Name 
3910*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
3911*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
3912*5113495bSYour Name 	uint8_t curr_user_index = 0;
3913*5113495bSYour Name 	uint16_t peer_id;
3914*5113495bSYour Name 	uint32_t size = CDP_BA_256_BIT_MAP_SIZE_DWORDS;
3915*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
3916*5113495bSYour Name 
3917*5113495bSYour Name 	ppdu_desc =
3918*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
3919*5113495bSYour Name 
3920*5113495bSYour Name 	tag_buf++;
3921*5113495bSYour Name 
3922*5113495bSYour Name 	peer_id =
3923*5113495bSYour Name 	HTT_PPDU_STATS_ENQ_MPDU_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
3924*5113495bSYour Name 
3925*5113495bSYour Name 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
3926*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
3927*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
3928*5113495bSYour Name 	ppdu_user_desc->peer_id = peer_id;
3929*5113495bSYour Name 
3930*5113495bSYour Name 	ppdu_user_desc->start_seq = dp_stats_buf->start_seq;
3931*5113495bSYour Name 	qdf_mem_copy(&ppdu_user_desc->enq_bitmap, &dp_stats_buf->enq_bitmap,
3932*5113495bSYour Name 		     sizeof(uint32_t) * CDP_BA_256_BIT_MAP_SIZE_DWORDS);
3933*5113495bSYour Name 
3934*5113495bSYour Name 	dp_process_ppdu_stats_update_failed_bitmap(pdev,
3935*5113495bSYour Name 						   (void *)ppdu_user_desc,
3936*5113495bSYour Name 						   ppdu_info->ppdu_id,
3937*5113495bSYour Name 						   size);
3938*5113495bSYour Name }
3939*5113495bSYour Name 
3940*5113495bSYour Name /**
3941*5113495bSYour Name  * dp_process_ppdu_stats_user_cmpltn_common_tlv() - Process
3942*5113495bSYour Name  * htt_ppdu_stats_user_cmpltn_common_tlv
3943*5113495bSYour Name  * @pdev: DP PDEV handle
3944*5113495bSYour Name  * @tag_buf: buffer containing the tlv htt_ppdu_stats_user_cmpltn_common_tlv
3945*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
3946*5113495bSYour Name  *
3947*5113495bSYour Name  * Return: void
3948*5113495bSYour Name  */
dp_process_ppdu_stats_user_cmpltn_common_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)3949*5113495bSYour Name static void dp_process_ppdu_stats_user_cmpltn_common_tlv(
3950*5113495bSYour Name 		struct dp_pdev *pdev, uint32_t *tag_buf,
3951*5113495bSYour Name 		struct ppdu_info *ppdu_info)
3952*5113495bSYour Name {
3953*5113495bSYour Name 	uint16_t peer_id;
3954*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
3955*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
3956*5113495bSYour Name 	uint8_t curr_user_index = 0;
3957*5113495bSYour Name 	uint8_t bw_iter;
3958*5113495bSYour Name 	htt_ppdu_stats_user_cmpltn_common_tlv *dp_stats_buf =
3959*5113495bSYour Name 		(htt_ppdu_stats_user_cmpltn_common_tlv *)tag_buf;
3960*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
3961*5113495bSYour Name 
3962*5113495bSYour Name 	ppdu_desc =
3963*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
3964*5113495bSYour Name 
3965*5113495bSYour Name 	tag_buf++;
3966*5113495bSYour Name 	peer_id =
3967*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_SW_PEER_ID_GET(*tag_buf);
3968*5113495bSYour Name 
3969*5113495bSYour Name 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
3970*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
3971*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
3972*5113495bSYour Name 	ppdu_user_desc->peer_id = peer_id;
3973*5113495bSYour Name 
3974*5113495bSYour Name 	ppdu_user_desc->completion_status =
3975*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_COMPLETION_STATUS_GET(
3976*5113495bSYour Name 				*tag_buf);
3977*5113495bSYour Name 
3978*5113495bSYour Name 	ppdu_user_desc->tid =
3979*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_TID_NUM_GET(*tag_buf);
3980*5113495bSYour Name 
3981*5113495bSYour Name 	tag_buf++;
3982*5113495bSYour Name 	if (qdf_likely(ppdu_user_desc->completion_status ==
3983*5113495bSYour Name 			HTT_PPDU_STATS_USER_STATUS_OK)) {
3984*5113495bSYour Name 		ppdu_desc->ack_rssi = dp_stats_buf->ack_rssi;
3985*5113495bSYour Name 		ppdu_user_desc->usr_ack_rssi = dp_stats_buf->ack_rssi;
3986*5113495bSYour Name 		ppdu_user_desc->ack_rssi_valid = 1;
3987*5113495bSYour Name 	} else {
3988*5113495bSYour Name 		ppdu_user_desc->ack_rssi_valid = 0;
3989*5113495bSYour Name 	}
3990*5113495bSYour Name 
3991*5113495bSYour Name 	tag_buf++;
3992*5113495bSYour Name 
3993*5113495bSYour Name 	ppdu_user_desc->mpdu_success =
3994*5113495bSYour Name 	HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPDU_SUCCESS_GET(*tag_buf);
3995*5113495bSYour Name 
3996*5113495bSYour Name 	ppdu_user_desc->mpdu_failed =
3997*5113495bSYour Name 	HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPDU_TRIED_GET(*tag_buf) -
3998*5113495bSYour Name 						ppdu_user_desc->mpdu_success;
3999*5113495bSYour Name 
4000*5113495bSYour Name 	tag_buf++;
4001*5113495bSYour Name 
4002*5113495bSYour Name 	ppdu_user_desc->long_retries =
4003*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_LONG_RETRY_GET(*tag_buf);
4004*5113495bSYour Name 
4005*5113495bSYour Name 	ppdu_user_desc->short_retries =
4006*5113495bSYour Name 	HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_SHORT_RETRY_GET(*tag_buf);
4007*5113495bSYour Name 	ppdu_user_desc->retry_mpdus =
4008*5113495bSYour Name 		ppdu_user_desc->long_retries + ppdu_user_desc->short_retries;
4009*5113495bSYour Name 
4010*5113495bSYour Name 	ppdu_user_desc->is_ampdu =
4011*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_IS_AMPDU_GET(*tag_buf);
4012*5113495bSYour Name 	ppdu_info->is_ampdu = ppdu_user_desc->is_ampdu;
4013*5113495bSYour Name 
4014*5113495bSYour Name 	ppdu_desc->resp_type =
4015*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RESP_TYPE_GET(*tag_buf);
4016*5113495bSYour Name 	ppdu_desc->mprot_type =
4017*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MPROT_TYPE_GET(*tag_buf);
4018*5113495bSYour Name 	ppdu_desc->rts_success =
4019*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RTS_SUCCESS_GET(*tag_buf);
4020*5113495bSYour Name 	ppdu_desc->rts_failure =
4021*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_RTS_FAILURE_GET(*tag_buf);
4022*5113495bSYour Name 
4023*5113495bSYour Name 	ppdu_user_desc->mprot_type = ppdu_desc->mprot_type;
4024*5113495bSYour Name 	ppdu_user_desc->rts_success = ppdu_desc->rts_success;
4025*5113495bSYour Name 	ppdu_user_desc->rts_failure = ppdu_desc->rts_failure;
4026*5113495bSYour Name 
4027*5113495bSYour Name 	ppdu_user_desc->pream_punct =
4028*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_PREAM_PUNC_TX_GET(*tag_buf);
4029*5113495bSYour Name 
4030*5113495bSYour Name 	ppdu_info->compltn_common_tlv++;
4031*5113495bSYour Name 
4032*5113495bSYour Name 	/*
4033*5113495bSYour Name 	 * MU BAR may send request to n users but we may received ack only from
4034*5113495bSYour Name 	 * m users. To have count of number of users respond back, we have a
4035*5113495bSYour Name 	 * separate counter bar_num_users per PPDU that get increment for every
4036*5113495bSYour Name 	 * htt_ppdu_stats_user_cmpltn_common_tlv
4037*5113495bSYour Name 	 */
4038*5113495bSYour Name 	ppdu_desc->bar_num_users++;
4039*5113495bSYour Name 
4040*5113495bSYour Name 	tag_buf++;
4041*5113495bSYour Name 	for (bw_iter = 0; bw_iter < CDP_RSSI_CHAIN_LEN; bw_iter++) {
4042*5113495bSYour Name 		ppdu_user_desc->rssi_chain[bw_iter] =
4043*5113495bSYour Name 			HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_CHAIN_RSSI_GET(*tag_buf);
4044*5113495bSYour Name 		tag_buf++;
4045*5113495bSYour Name 	}
4046*5113495bSYour Name 
4047*5113495bSYour Name 	ppdu_user_desc->sa_tx_antenna =
4048*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_TX_ANTENNA_MASK_GET(*tag_buf);
4049*5113495bSYour Name 
4050*5113495bSYour Name 	tag_buf++;
4051*5113495bSYour Name 	ppdu_user_desc->sa_is_training =
4052*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_IS_TRAINING_GET(*tag_buf);
4053*5113495bSYour Name 	if (ppdu_user_desc->sa_is_training) {
4054*5113495bSYour Name 		ppdu_user_desc->sa_goodput =
4055*5113495bSYour Name 			HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_PENDING_TRAINING_PKTS_GET(*tag_buf);
4056*5113495bSYour Name 	}
4057*5113495bSYour Name 
4058*5113495bSYour Name 	tag_buf++;
4059*5113495bSYour Name 	for (bw_iter = 0; bw_iter < CDP_NUM_SA_BW; bw_iter++) {
4060*5113495bSYour Name 		ppdu_user_desc->sa_max_rates[bw_iter] =
4061*5113495bSYour Name 			HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MAX_RATES_GET(tag_buf[bw_iter]);
4062*5113495bSYour Name 	}
4063*5113495bSYour Name 
4064*5113495bSYour Name 	tag_buf += CDP_NUM_SA_BW;
4065*5113495bSYour Name 	ppdu_user_desc->current_rate_per =
4066*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_CURRENT_RATE_PER_GET(*tag_buf);
4067*5113495bSYour Name 
4068*5113495bSYour Name 	tag_buf++;
4069*5113495bSYour Name 	/* Skip SW RTS */
4070*5113495bSYour Name 
4071*5113495bSYour Name 	tag_buf++;
4072*5113495bSYour Name 	/* Extract 320MHz MAX PHY ratecode */
4073*5113495bSYour Name 	ppdu_user_desc->sa_max_rates[CDP_SA_BW320_INX] =
4074*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_COMMON_TLV_MAX_RATES_GET(*tag_buf);
4075*5113495bSYour Name }
4076*5113495bSYour Name 
4077*5113495bSYour Name /**
4078*5113495bSYour Name  * dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv() - Process
4079*5113495bSYour Name  * htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv
4080*5113495bSYour Name  * @pdev: DP PDEV handle
4081*5113495bSYour Name  * @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv
4082*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
4083*5113495bSYour Name  *
4084*5113495bSYour Name  * Return: void
4085*5113495bSYour Name  */
dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4086*5113495bSYour Name static void dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
4087*5113495bSYour Name 		struct dp_pdev *pdev, uint32_t *tag_buf,
4088*5113495bSYour Name 		struct ppdu_info *ppdu_info)
4089*5113495bSYour Name {
4090*5113495bSYour Name 	htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv *dp_stats_buf =
4091*5113495bSYour Name 		(htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv *)tag_buf;
4092*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
4093*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
4094*5113495bSYour Name 	uint8_t curr_user_index = 0;
4095*5113495bSYour Name 	uint16_t peer_id;
4096*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
4097*5113495bSYour Name 
4098*5113495bSYour Name 	ppdu_desc =
4099*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
4100*5113495bSYour Name 
4101*5113495bSYour Name 	tag_buf++;
4102*5113495bSYour Name 
4103*5113495bSYour Name 	peer_id =
4104*5113495bSYour Name 	HTT_PPDU_STATS_USER_CMPLTN_BA_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
4105*5113495bSYour Name 
4106*5113495bSYour Name 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
4107*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
4108*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
4109*5113495bSYour Name 	ppdu_user_desc->peer_id = peer_id;
4110*5113495bSYour Name 
4111*5113495bSYour Name 	ppdu_user_desc->ba_seq_no = dp_stats_buf->ba_seq_no;
4112*5113495bSYour Name 	qdf_mem_copy(&ppdu_user_desc->ba_bitmap, &dp_stats_buf->ba_bitmap,
4113*5113495bSYour Name 		     sizeof(uint32_t) * CDP_BA_64_BIT_MAP_SIZE_DWORDS);
4114*5113495bSYour Name 	ppdu_user_desc->ba_size = CDP_BA_64_BIT_MAP_SIZE_DWORDS * 32;
4115*5113495bSYour Name }
4116*5113495bSYour Name 
4117*5113495bSYour Name /**
4118*5113495bSYour Name  * dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv() - Process
4119*5113495bSYour Name  * htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv
4120*5113495bSYour Name  * @pdev: DP PDEV handle
4121*5113495bSYour Name  * @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv
4122*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
4123*5113495bSYour Name  *
4124*5113495bSYour Name  * Return: void
4125*5113495bSYour Name  */
dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4126*5113495bSYour Name static void dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
4127*5113495bSYour Name 		struct dp_pdev *pdev, uint32_t *tag_buf,
4128*5113495bSYour Name 		struct ppdu_info *ppdu_info)
4129*5113495bSYour Name {
4130*5113495bSYour Name 	htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv *dp_stats_buf =
4131*5113495bSYour Name 		(htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv *)tag_buf;
4132*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
4133*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
4134*5113495bSYour Name 	uint8_t curr_user_index = 0;
4135*5113495bSYour Name 	uint16_t peer_id;
4136*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
4137*5113495bSYour Name 
4138*5113495bSYour Name 	ppdu_desc =
4139*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
4140*5113495bSYour Name 
4141*5113495bSYour Name 	tag_buf++;
4142*5113495bSYour Name 
4143*5113495bSYour Name 	peer_id =
4144*5113495bSYour Name 	HTT_PPDU_STATS_USER_CMPLTN_BA_BITMAP_TLV_SW_PEER_ID_GET(*tag_buf);
4145*5113495bSYour Name 
4146*5113495bSYour Name 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
4147*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
4148*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
4149*5113495bSYour Name 	ppdu_user_desc->peer_id = peer_id;
4150*5113495bSYour Name 
4151*5113495bSYour Name 	ppdu_user_desc->ba_seq_no = dp_stats_buf->ba_seq_no;
4152*5113495bSYour Name 	qdf_mem_copy(&ppdu_user_desc->ba_bitmap, &dp_stats_buf->ba_bitmap,
4153*5113495bSYour Name 		     sizeof(uint32_t) * CDP_BA_256_BIT_MAP_SIZE_DWORDS);
4154*5113495bSYour Name 	ppdu_user_desc->ba_size = CDP_BA_256_BIT_MAP_SIZE_DWORDS * 32;
4155*5113495bSYour Name }
4156*5113495bSYour Name 
4157*5113495bSYour Name /**
4158*5113495bSYour Name  * dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv() - Process
4159*5113495bSYour Name  * htt_ppdu_stats_user_compltn_ack_ba_status_tlv
4160*5113495bSYour Name  * @pdev: DP PDEV handle
4161*5113495bSYour Name  * @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ack_ba_status_tlv
4162*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
4163*5113495bSYour Name  *
4164*5113495bSYour Name  * Return: void
4165*5113495bSYour Name  */
dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4166*5113495bSYour Name static void dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
4167*5113495bSYour Name 		struct dp_pdev *pdev, uint32_t *tag_buf,
4168*5113495bSYour Name 		struct ppdu_info *ppdu_info)
4169*5113495bSYour Name {
4170*5113495bSYour Name 	uint16_t peer_id;
4171*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
4172*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
4173*5113495bSYour Name 	uint8_t curr_user_index = 0;
4174*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
4175*5113495bSYour Name 
4176*5113495bSYour Name 	ppdu_desc =
4177*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
4178*5113495bSYour Name 
4179*5113495bSYour Name 	tag_buf += 2;
4180*5113495bSYour Name 	peer_id =
4181*5113495bSYour Name 	HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_SW_PEER_ID_GET(*tag_buf);
4182*5113495bSYour Name 
4183*5113495bSYour Name 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
4184*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
4185*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
4186*5113495bSYour Name 	if (!ppdu_user_desc->ack_ba_tlv) {
4187*5113495bSYour Name 		ppdu_user_desc->ack_ba_tlv = 1;
4188*5113495bSYour Name 	} else {
4189*5113495bSYour Name 		pdev->stats.ack_ba_comes_twice++;
4190*5113495bSYour Name 		return;
4191*5113495bSYour Name 	}
4192*5113495bSYour Name 
4193*5113495bSYour Name 	ppdu_user_desc->peer_id = peer_id;
4194*5113495bSYour Name 
4195*5113495bSYour Name 	tag_buf++;
4196*5113495bSYour Name 	/* not to update ppdu_desc->tid from this TLV */
4197*5113495bSYour Name 	ppdu_user_desc->num_mpdu =
4198*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MPDU_GET(*tag_buf);
4199*5113495bSYour Name 
4200*5113495bSYour Name 	ppdu_user_desc->num_msdu =
4201*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_NUM_MSDU_GET(*tag_buf);
4202*5113495bSYour Name 
4203*5113495bSYour Name 	ppdu_user_desc->success_msdus = ppdu_user_desc->num_msdu;
4204*5113495bSYour Name 
4205*5113495bSYour Name 	tag_buf++;
4206*5113495bSYour Name 	ppdu_user_desc->start_seq =
4207*5113495bSYour Name 		HTT_PPDU_STATS_USER_CMPLTN_ACK_BA_STATUS_TLV_START_SEQ_GET(
4208*5113495bSYour Name 			*tag_buf);
4209*5113495bSYour Name 
4210*5113495bSYour Name 	tag_buf++;
4211*5113495bSYour Name 	ppdu_user_desc->success_bytes = *tag_buf;
4212*5113495bSYour Name 
4213*5113495bSYour Name 	/* increase ack ba tlv counter on successful mpdu */
4214*5113495bSYour Name 	if (ppdu_user_desc->num_mpdu)
4215*5113495bSYour Name 		ppdu_info->ack_ba_tlv++;
4216*5113495bSYour Name 
4217*5113495bSYour Name 	if (ppdu_user_desc->ba_size == 0) {
4218*5113495bSYour Name 		ppdu_user_desc->ba_seq_no = ppdu_user_desc->start_seq;
4219*5113495bSYour Name 		ppdu_user_desc->ba_bitmap[0] = 1;
4220*5113495bSYour Name 		ppdu_user_desc->ba_size = 1;
4221*5113495bSYour Name 	}
4222*5113495bSYour Name }
4223*5113495bSYour Name 
4224*5113495bSYour Name /**
4225*5113495bSYour Name  * dp_process_ppdu_stats_user_common_array_tlv() - Process
4226*5113495bSYour Name  * htt_ppdu_stats_user_common_array_tlv
4227*5113495bSYour Name  * @pdev: DP PDEV handle
4228*5113495bSYour Name  * @tag_buf: buffer containing the htt_ppdu_stats_user_compltn_ack_ba_status_tlv
4229*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
4230*5113495bSYour Name  *
4231*5113495bSYour Name  * Return: void
4232*5113495bSYour Name  */
dp_process_ppdu_stats_user_common_array_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4233*5113495bSYour Name static void dp_process_ppdu_stats_user_common_array_tlv(
4234*5113495bSYour Name 		struct dp_pdev *pdev, uint32_t *tag_buf,
4235*5113495bSYour Name 		struct ppdu_info *ppdu_info)
4236*5113495bSYour Name {
4237*5113495bSYour Name 	uint32_t peer_id;
4238*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
4239*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *ppdu_user_desc;
4240*5113495bSYour Name 	uint8_t curr_user_index = 0;
4241*5113495bSYour Name 	struct htt_tx_ppdu_stats_info *dp_stats_buf;
4242*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
4243*5113495bSYour Name 
4244*5113495bSYour Name 	ppdu_desc =
4245*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
4246*5113495bSYour Name 
4247*5113495bSYour Name 	tag_buf++;
4248*5113495bSYour Name 	dp_stats_buf = (struct htt_tx_ppdu_stats_info *)tag_buf;
4249*5113495bSYour Name 	tag_buf += 3;
4250*5113495bSYour Name 	peer_id =
4251*5113495bSYour Name 		HTT_PPDU_STATS_ARRAY_ITEM_TLV_PEERID_GET(*tag_buf);
4252*5113495bSYour Name 
4253*5113495bSYour Name 	if (!dp_peer_find_by_id_valid(pdev->soc, peer_id)) {
4254*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
4255*5113495bSYour Name 			  "Peer with peer_id: %u not found", peer_id);
4256*5113495bSYour Name 		return;
4257*5113495bSYour Name 	}
4258*5113495bSYour Name 
4259*5113495bSYour Name 	curr_user_index = dp_get_ppdu_info_user_index(pdev, peer_id, ppdu_info);
4260*5113495bSYour Name 
4261*5113495bSYour Name 	ppdu_user_desc = &ppdu_desc->user[curr_user_index];
4262*5113495bSYour Name 	ppdu_user_desc->tlv_bitmap |= (1 << tlv_type);
4263*5113495bSYour Name 
4264*5113495bSYour Name 	ppdu_user_desc->retry_bytes = dp_stats_buf->tx_retry_bytes;
4265*5113495bSYour Name 	ppdu_user_desc->failed_bytes = dp_stats_buf->tx_failed_bytes;
4266*5113495bSYour Name 
4267*5113495bSYour Name 	tag_buf++;
4268*5113495bSYour Name 
4269*5113495bSYour Name 	ppdu_user_desc->success_msdus =
4270*5113495bSYour Name 		HTT_PPDU_STATS_ARRAY_ITEM_TLV_TX_SUCC_MSDUS_GET(*tag_buf);
4271*5113495bSYour Name 	ppdu_user_desc->retry_msdus =
4272*5113495bSYour Name 		HTT_PPDU_STATS_ARRAY_ITEM_TLV_TX_RETRY_MSDUS_GET(*tag_buf);
4273*5113495bSYour Name 	tag_buf++;
4274*5113495bSYour Name 	ppdu_user_desc->failed_msdus =
4275*5113495bSYour Name 		HTT_PPDU_STATS_ARRAY_ITEM_TLV_TX_FAILED_MSDUS_GET(*tag_buf);
4276*5113495bSYour Name }
4277*5113495bSYour Name 
4278*5113495bSYour Name /**
4279*5113495bSYour Name  * dp_process_ppdu_stats_user_compltn_flush_tlv() - Process
4280*5113495bSYour Name  * htt_ppdu_stats_flush_tlv
4281*5113495bSYour Name  * @pdev: DP PDEV handle
4282*5113495bSYour Name  * @tag_buf: buffer containing the htt_ppdu_stats_flush_tlv
4283*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
4284*5113495bSYour Name  *
4285*5113495bSYour Name  * Return: void
4286*5113495bSYour Name  */
4287*5113495bSYour Name static void
dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,struct ppdu_info * ppdu_info)4288*5113495bSYour Name dp_process_ppdu_stats_user_compltn_flush_tlv(struct dp_pdev *pdev,
4289*5113495bSYour Name 					     uint32_t *tag_buf,
4290*5113495bSYour Name 					     struct ppdu_info *ppdu_info)
4291*5113495bSYour Name {
4292*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
4293*5113495bSYour Name 	uint32_t peer_id;
4294*5113495bSYour Name 	uint8_t tid;
4295*5113495bSYour Name 	struct dp_peer *peer;
4296*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
4297*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
4298*5113495bSYour Name 
4299*5113495bSYour Name 	ppdu_desc = (struct cdp_tx_completion_ppdu *)
4300*5113495bSYour Name 				qdf_nbuf_data(ppdu_info->nbuf);
4301*5113495bSYour Name 	ppdu_desc->is_flush = 1;
4302*5113495bSYour Name 
4303*5113495bSYour Name 	tag_buf++;
4304*5113495bSYour Name 	ppdu_desc->drop_reason = *tag_buf;
4305*5113495bSYour Name 
4306*5113495bSYour Name 	tag_buf++;
4307*5113495bSYour Name 	ppdu_desc->num_msdu = HTT_PPDU_STATS_FLUSH_TLV_NUM_MSDU_GET(*tag_buf);
4308*5113495bSYour Name 	ppdu_desc->num_mpdu = HTT_PPDU_STATS_FLUSH_TLV_NUM_MPDU_GET(*tag_buf);
4309*5113495bSYour Name 	ppdu_desc->flow_type = HTT_PPDU_STATS_FLUSH_TLV_FLOW_TYPE_GET(*tag_buf);
4310*5113495bSYour Name 
4311*5113495bSYour Name 	tag_buf++;
4312*5113495bSYour Name 	peer_id = HTT_PPDU_STATS_FLUSH_TLV_SW_PEER_ID_GET(*tag_buf);
4313*5113495bSYour Name 	tid = HTT_PPDU_STATS_FLUSH_TLV_TID_NUM_GET(*tag_buf);
4314*5113495bSYour Name 
4315*5113495bSYour Name 	ppdu_desc->num_users = 1;
4316*5113495bSYour Name 	ppdu_desc->user[0].peer_id = peer_id;
4317*5113495bSYour Name 	ppdu_desc->user[0].tid = tid;
4318*5113495bSYour Name 
4319*5113495bSYour Name 	ppdu_desc->queue_type =
4320*5113495bSYour Name 			HTT_PPDU_STATS_FLUSH_TLV_QUEUE_TYPE_GET(*tag_buf);
4321*5113495bSYour Name 
4322*5113495bSYour Name 	peer = dp_peer_get_ref_by_id(pdev->soc, peer_id,
4323*5113495bSYour Name 				     DP_MOD_ID_TX_PPDU_STATS);
4324*5113495bSYour Name 	if (!peer)
4325*5113495bSYour Name 		goto add_ppdu_to_sched_list;
4326*5113495bSYour Name 
4327*5113495bSYour Name 	if (ppdu_desc->drop_reason == HTT_FLUSH_EXCESS_RETRIES) {
4328*5113495bSYour Name 		mon_peer = peer->monitor_peer;
4329*5113495bSYour Name 		DP_STATS_INC(mon_peer,
4330*5113495bSYour Name 			     tx.excess_retries_per_ac[TID_TO_WME_AC(tid)],
4331*5113495bSYour Name 			     ppdu_desc->num_msdu);
4332*5113495bSYour Name 	}
4333*5113495bSYour Name 
4334*5113495bSYour Name 	dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
4335*5113495bSYour Name 
4336*5113495bSYour Name add_ppdu_to_sched_list:
4337*5113495bSYour Name 	ppdu_info->done = 1;
4338*5113495bSYour Name 	TAILQ_REMOVE(&mon_pdev->ppdu_info_list, ppdu_info, ppdu_info_list_elem);
4339*5113495bSYour Name 	mon_pdev->list_depth--;
4340*5113495bSYour Name 	TAILQ_INSERT_TAIL(&mon_pdev->sched_comp_ppdu_list, ppdu_info,
4341*5113495bSYour Name 			  ppdu_info_list_elem);
4342*5113495bSYour Name 	mon_pdev->sched_comp_list_depth++;
4343*5113495bSYour Name }
4344*5113495bSYour Name 
4345*5113495bSYour Name /**
4346*5113495bSYour Name  * dp_process_ppdu_stats_sch_cmd_status_tlv() - Process schedule command status tlv
4347*5113495bSYour Name  * Here we are not going to process the buffer.
4348*5113495bSYour Name  * @pdev: DP PDEV handle
4349*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
4350*5113495bSYour Name  *
4351*5113495bSYour Name  * Return: void
4352*5113495bSYour Name  */
4353*5113495bSYour Name static void
dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev * pdev,struct ppdu_info * ppdu_info)4354*5113495bSYour Name dp_process_ppdu_stats_sch_cmd_status_tlv(struct dp_pdev *pdev,
4355*5113495bSYour Name 					 struct ppdu_info *ppdu_info)
4356*5113495bSYour Name {
4357*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc;
4358*5113495bSYour Name 	struct dp_peer *peer;
4359*5113495bSYour Name 	uint8_t num_users;
4360*5113495bSYour Name 	uint8_t i;
4361*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
4362*5113495bSYour Name 
4363*5113495bSYour Name 	ppdu_desc = (struct cdp_tx_completion_ppdu *)
4364*5113495bSYour Name 				qdf_nbuf_data(ppdu_info->nbuf);
4365*5113495bSYour Name 
4366*5113495bSYour Name 	num_users = ppdu_desc->bar_num_users;
4367*5113495bSYour Name 
4368*5113495bSYour Name 	for (i = 0; i < num_users; i++) {
4369*5113495bSYour Name 		if (ppdu_desc->user[i].user_pos == 0) {
4370*5113495bSYour Name 			if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) {
4371*5113495bSYour Name 				/* update phy mode for bar frame */
4372*5113495bSYour Name 				ppdu_desc->phy_mode =
4373*5113495bSYour Name 					ppdu_desc->user[i].preamble;
4374*5113495bSYour Name 				ppdu_desc->user[0].mcs = ppdu_desc->user[i].mcs;
4375*5113495bSYour Name 				break;
4376*5113495bSYour Name 			}
4377*5113495bSYour Name 			if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_CTRL) {
4378*5113495bSYour Name 				ppdu_desc->frame_ctrl =
4379*5113495bSYour Name 					ppdu_desc->user[i].frame_ctrl;
4380*5113495bSYour Name 				break;
4381*5113495bSYour Name 			}
4382*5113495bSYour Name 		}
4383*5113495bSYour Name 	}
4384*5113495bSYour Name 
4385*5113495bSYour Name 	if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA &&
4386*5113495bSYour Name 	    ppdu_desc->delayed_ba) {
4387*5113495bSYour Name 		qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users);
4388*5113495bSYour Name 
4389*5113495bSYour Name 		for (i = 0; i < ppdu_desc->num_users; i++) {
4390*5113495bSYour Name 			struct cdp_delayed_tx_completion_ppdu_user *delay_ppdu;
4391*5113495bSYour Name 			uint64_t start_tsf;
4392*5113495bSYour Name 			uint64_t end_tsf;
4393*5113495bSYour Name 			uint32_t ppdu_id;
4394*5113495bSYour Name 			struct dp_mon_peer *mon_peer;
4395*5113495bSYour Name 
4396*5113495bSYour Name 			ppdu_id = ppdu_desc->ppdu_id;
4397*5113495bSYour Name 			peer = dp_peer_get_ref_by_id
4398*5113495bSYour Name 				(pdev->soc, ppdu_desc->user[i].peer_id,
4399*5113495bSYour Name 				 DP_MOD_ID_TX_PPDU_STATS);
4400*5113495bSYour Name 			/*
4401*5113495bSYour Name 			 * This check is to make sure peer is not deleted
4402*5113495bSYour Name 			 * after processing the TLVs.
4403*5113495bSYour Name 			 */
4404*5113495bSYour Name 			if (!peer)
4405*5113495bSYour Name 				continue;
4406*5113495bSYour Name 
4407*5113495bSYour Name 			if (!peer->monitor_peer) {
4408*5113495bSYour Name 				dp_peer_unref_delete(peer,
4409*5113495bSYour Name 						     DP_MOD_ID_TX_PPDU_STATS);
4410*5113495bSYour Name 				continue;
4411*5113495bSYour Name 			}
4412*5113495bSYour Name 
4413*5113495bSYour Name 			mon_peer = peer->monitor_peer;
4414*5113495bSYour Name 			delay_ppdu = &mon_peer->delayed_ba_ppdu_stats;
4415*5113495bSYour Name 			start_tsf = ppdu_desc->ppdu_start_timestamp;
4416*5113495bSYour Name 			end_tsf = ppdu_desc->ppdu_end_timestamp;
4417*5113495bSYour Name 			/*
4418*5113495bSYour Name 			 * save delayed ba user info
4419*5113495bSYour Name 			 */
4420*5113495bSYour Name 			if (ppdu_desc->user[i].delayed_ba) {
4421*5113495bSYour Name 				dp_peer_copy_delay_stats(peer,
4422*5113495bSYour Name 							 &ppdu_desc->user[i],
4423*5113495bSYour Name 							 ppdu_id);
4424*5113495bSYour Name 				mon_peer->last_delayed_ba_ppduid = ppdu_id;
4425*5113495bSYour Name 				delay_ppdu->ppdu_start_timestamp = start_tsf;
4426*5113495bSYour Name 				delay_ppdu->ppdu_end_timestamp = end_tsf;
4427*5113495bSYour Name 			}
4428*5113495bSYour Name 			ppdu_desc->user[i].peer_last_delayed_ba =
4429*5113495bSYour Name 				mon_peer->last_delayed_ba;
4430*5113495bSYour Name 
4431*5113495bSYour Name 			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
4432*5113495bSYour Name 
4433*5113495bSYour Name 			if (ppdu_desc->user[i].delayed_ba &&
4434*5113495bSYour Name 			    !ppdu_desc->user[i].debug_copied) {
4435*5113495bSYour Name 				QDF_TRACE(QDF_MODULE_ID_TXRX,
4436*5113495bSYour Name 					  QDF_TRACE_LEVEL_INFO_MED,
4437*5113495bSYour Name 					  "%s: %d ppdu_id[%d] bar_ppdu_id[%d] num_users[%d] usr[%d] htt_frame_type[%d]\n",
4438*5113495bSYour Name 					  __func__, __LINE__,
4439*5113495bSYour Name 					  ppdu_desc->ppdu_id,
4440*5113495bSYour Name 					  ppdu_desc->bar_ppdu_id,
4441*5113495bSYour Name 					  ppdu_desc->num_users,
4442*5113495bSYour Name 					  i,
4443*5113495bSYour Name 					  ppdu_desc->htt_frame_type);
4444*5113495bSYour Name 			}
4445*5113495bSYour Name 		}
4446*5113495bSYour Name 	}
4447*5113495bSYour Name 
4448*5113495bSYour Name 	/*
4449*5113495bSYour Name 	 * when frame type is BAR and STATS_COMMON_TLV is set
4450*5113495bSYour Name 	 * copy the store peer delayed info to BAR status
4451*5113495bSYour Name 	 */
4452*5113495bSYour Name 	if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) {
4453*5113495bSYour Name 		for (i = 0; i < ppdu_desc->bar_num_users; i++) {
4454*5113495bSYour Name 			struct cdp_delayed_tx_completion_ppdu_user *delay_ppdu;
4455*5113495bSYour Name 			uint64_t start_tsf;
4456*5113495bSYour Name 			uint64_t end_tsf;
4457*5113495bSYour Name 			struct dp_mon_peer *mon_peer;
4458*5113495bSYour Name 
4459*5113495bSYour Name 			peer = dp_peer_get_ref_by_id
4460*5113495bSYour Name 				(pdev->soc,
4461*5113495bSYour Name 				 ppdu_desc->user[i].peer_id,
4462*5113495bSYour Name 				 DP_MOD_ID_TX_PPDU_STATS);
4463*5113495bSYour Name 			/*
4464*5113495bSYour Name 			 * This check is to make sure peer is not deleted
4465*5113495bSYour Name 			 * after processing the TLVs.
4466*5113495bSYour Name 			 */
4467*5113495bSYour Name 			if (!peer)
4468*5113495bSYour Name 				continue;
4469*5113495bSYour Name 
4470*5113495bSYour Name 			if (!peer->monitor_peer) {
4471*5113495bSYour Name 				dp_peer_unref_delete(peer,
4472*5113495bSYour Name 						     DP_MOD_ID_TX_PPDU_STATS);
4473*5113495bSYour Name 				continue;
4474*5113495bSYour Name 			}
4475*5113495bSYour Name 
4476*5113495bSYour Name 			mon_peer = peer->monitor_peer;
4477*5113495bSYour Name 			if (ppdu_desc->user[i].completion_status !=
4478*5113495bSYour Name 			    HTT_PPDU_STATS_USER_STATUS_OK) {
4479*5113495bSYour Name 				dp_peer_unref_delete(peer,
4480*5113495bSYour Name 						     DP_MOD_ID_TX_PPDU_STATS);
4481*5113495bSYour Name 				continue;
4482*5113495bSYour Name 			}
4483*5113495bSYour Name 
4484*5113495bSYour Name 			delay_ppdu = &mon_peer->delayed_ba_ppdu_stats;
4485*5113495bSYour Name 			start_tsf = delay_ppdu->ppdu_start_timestamp;
4486*5113495bSYour Name 			end_tsf = delay_ppdu->ppdu_end_timestamp;
4487*5113495bSYour Name 
4488*5113495bSYour Name 			if (mon_peer->last_delayed_ba) {
4489*5113495bSYour Name 				dp_peer_copy_stats_to_bar(peer,
4490*5113495bSYour Name 							  &ppdu_desc->user[i]);
4491*5113495bSYour Name 				ppdu_desc->ppdu_id =
4492*5113495bSYour Name 					mon_peer->last_delayed_ba_ppduid;
4493*5113495bSYour Name 				ppdu_desc->ppdu_start_timestamp = start_tsf;
4494*5113495bSYour Name 				ppdu_desc->ppdu_end_timestamp = end_tsf;
4495*5113495bSYour Name 			}
4496*5113495bSYour Name 			ppdu_desc->user[i].peer_last_delayed_ba =
4497*5113495bSYour Name 						mon_peer->last_delayed_ba;
4498*5113495bSYour Name 			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
4499*5113495bSYour Name 		}
4500*5113495bSYour Name 	}
4501*5113495bSYour Name 
4502*5113495bSYour Name 	TAILQ_REMOVE(&mon_pdev->ppdu_info_list, ppdu_info, ppdu_info_list_elem);
4503*5113495bSYour Name 	mon_pdev->list_depth--;
4504*5113495bSYour Name 	TAILQ_INSERT_TAIL(&mon_pdev->sched_comp_ppdu_list, ppdu_info,
4505*5113495bSYour Name 			  ppdu_info_list_elem);
4506*5113495bSYour Name 	mon_pdev->sched_comp_list_depth++;
4507*5113495bSYour Name }
4508*5113495bSYour Name 
4509*5113495bSYour Name /**
4510*5113495bSYour Name  * dp_validate_fix_ppdu_tlv() - Function to validate the length of PPDU
4511*5113495bSYour Name  * @pdev: DP pdev handle
4512*5113495bSYour Name  * @tag_buf: TLV buffer
4513*5113495bSYour Name  * @tlv_expected_size: Expected size of Tag
4514*5113495bSYour Name  * @tlv_len: TLV length received from FW
4515*5113495bSYour Name  *
4516*5113495bSYour Name  * If the TLV length sent as part of PPDU TLV is less that expected size i.e
4517*5113495bSYour Name  * size of corresponding data structure, pad the remaining bytes with zeros
4518*5113495bSYour Name  * and continue processing the TLVs
4519*5113495bSYour Name  *
4520*5113495bSYour Name  * Return: Pointer to updated TLV
4521*5113495bSYour Name  */
dp_validate_fix_ppdu_tlv(struct dp_pdev * pdev,uint32_t * tag_buf,uint16_t tlv_expected_size,uint16_t tlv_len)4522*5113495bSYour Name static inline uint32_t *dp_validate_fix_ppdu_tlv(struct dp_pdev *pdev,
4523*5113495bSYour Name 						 uint32_t *tag_buf,
4524*5113495bSYour Name 						 uint16_t tlv_expected_size,
4525*5113495bSYour Name 						 uint16_t tlv_len)
4526*5113495bSYour Name {
4527*5113495bSYour Name 	uint32_t *tlv_desc = tag_buf;
4528*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
4529*5113495bSYour Name 
4530*5113495bSYour Name 	qdf_assert_always(tlv_len != 0);
4531*5113495bSYour Name 
4532*5113495bSYour Name 	if (tlv_len < tlv_expected_size) {
4533*5113495bSYour Name 		qdf_mem_zero(mon_pdev->ppdu_tlv_buf, tlv_expected_size);
4534*5113495bSYour Name 		qdf_mem_copy(mon_pdev->ppdu_tlv_buf, tag_buf, tlv_len);
4535*5113495bSYour Name 		tlv_desc = mon_pdev->ppdu_tlv_buf;
4536*5113495bSYour Name 	}
4537*5113495bSYour Name 
4538*5113495bSYour Name 	return tlv_desc;
4539*5113495bSYour Name }
4540*5113495bSYour Name 
4541*5113495bSYour Name /**
4542*5113495bSYour Name  * dp_process_ppdu_tag() - Function to process the PPDU TLVs
4543*5113495bSYour Name  * @pdev: DP pdev handle
4544*5113495bSYour Name  * @tag_buf: TLV buffer
4545*5113495bSYour Name  * @tlv_len: length of tlv
4546*5113495bSYour Name  * @ppdu_info: per ppdu tlv structure
4547*5113495bSYour Name  *
4548*5113495bSYour Name  * Return: void
4549*5113495bSYour Name  */
dp_process_ppdu_tag(struct dp_pdev * pdev,uint32_t * tag_buf,uint32_t tlv_len,struct ppdu_info * ppdu_info)4550*5113495bSYour Name static void dp_process_ppdu_tag(struct dp_pdev *pdev,
4551*5113495bSYour Name 				uint32_t *tag_buf,
4552*5113495bSYour Name 				uint32_t tlv_len,
4553*5113495bSYour Name 				struct ppdu_info *ppdu_info)
4554*5113495bSYour Name {
4555*5113495bSYour Name 	uint32_t tlv_type = HTT_STATS_TLV_TAG_GET(*tag_buf);
4556*5113495bSYour Name 	uint16_t tlv_expected_size;
4557*5113495bSYour Name 	uint32_t *tlv_desc;
4558*5113495bSYour Name 
4559*5113495bSYour Name 	switch (tlv_type) {
4560*5113495bSYour Name 	case HTT_PPDU_STATS_COMMON_TLV:
4561*5113495bSYour Name 		tlv_expected_size = sizeof(htt_ppdu_stats_common_tlv);
4562*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4563*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4564*5113495bSYour Name 		dp_process_ppdu_stats_common_tlv(pdev, tlv_desc, ppdu_info);
4565*5113495bSYour Name 		break;
4566*5113495bSYour Name 	case HTT_PPDU_STATS_USR_COMMON_TLV:
4567*5113495bSYour Name 		tlv_expected_size = sizeof(htt_ppdu_stats_user_common_tlv);
4568*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4569*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4570*5113495bSYour Name 		dp_process_ppdu_stats_user_common_tlv(pdev, tlv_desc,
4571*5113495bSYour Name 						      ppdu_info);
4572*5113495bSYour Name 		break;
4573*5113495bSYour Name 	case HTT_PPDU_STATS_USR_RATE_TLV:
4574*5113495bSYour Name 		tlv_expected_size = sizeof(htt_ppdu_stats_user_rate_tlv);
4575*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4576*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4577*5113495bSYour Name 		dp_process_ppdu_stats_user_rate_tlv(pdev, tlv_desc,
4578*5113495bSYour Name 						    ppdu_info);
4579*5113495bSYour Name 		break;
4580*5113495bSYour Name 	case HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_64_TLV:
4581*5113495bSYour Name 		tlv_expected_size =
4582*5113495bSYour Name 			sizeof(htt_ppdu_stats_enq_mpdu_bitmap_64_tlv);
4583*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4584*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4585*5113495bSYour Name 		dp_process_ppdu_stats_enq_mpdu_bitmap_64_tlv(
4586*5113495bSYour Name 				pdev, tlv_desc, ppdu_info);
4587*5113495bSYour Name 		break;
4588*5113495bSYour Name 	case HTT_PPDU_STATS_USR_MPDU_ENQ_BITMAP_256_TLV:
4589*5113495bSYour Name 		tlv_expected_size =
4590*5113495bSYour Name 			sizeof(htt_ppdu_stats_enq_mpdu_bitmap_256_tlv);
4591*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4592*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4593*5113495bSYour Name 		dp_process_ppdu_stats_enq_mpdu_bitmap_256_tlv(
4594*5113495bSYour Name 				pdev, tlv_desc, ppdu_info);
4595*5113495bSYour Name 		break;
4596*5113495bSYour Name 	case HTT_PPDU_STATS_USR_COMPLTN_COMMON_TLV:
4597*5113495bSYour Name 		tlv_expected_size =
4598*5113495bSYour Name 			sizeof(htt_ppdu_stats_user_cmpltn_common_tlv);
4599*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4600*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4601*5113495bSYour Name 		dp_process_ppdu_stats_user_cmpltn_common_tlv(
4602*5113495bSYour Name 				pdev, tlv_desc, ppdu_info);
4603*5113495bSYour Name 		break;
4604*5113495bSYour Name 	case HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_64_TLV:
4605*5113495bSYour Name 		tlv_expected_size =
4606*5113495bSYour Name 			sizeof(htt_ppdu_stats_user_compltn_ba_bitmap_64_tlv);
4607*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4608*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4609*5113495bSYour Name 		dp_process_ppdu_stats_user_compltn_ba_bitmap_64_tlv(
4610*5113495bSYour Name 				pdev, tlv_desc, ppdu_info);
4611*5113495bSYour Name 		break;
4612*5113495bSYour Name 	case HTT_PPDU_STATS_USR_COMPLTN_BA_BITMAP_256_TLV:
4613*5113495bSYour Name 		tlv_expected_size =
4614*5113495bSYour Name 			sizeof(htt_ppdu_stats_user_compltn_ba_bitmap_256_tlv);
4615*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4616*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4617*5113495bSYour Name 		dp_process_ppdu_stats_user_compltn_ba_bitmap_256_tlv(
4618*5113495bSYour Name 				pdev, tlv_desc, ppdu_info);
4619*5113495bSYour Name 		break;
4620*5113495bSYour Name 	case HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV:
4621*5113495bSYour Name 		tlv_expected_size =
4622*5113495bSYour Name 			sizeof(htt_ppdu_stats_user_compltn_ack_ba_status_tlv);
4623*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4624*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4625*5113495bSYour Name 		dp_process_ppdu_stats_user_compltn_ack_ba_status_tlv(
4626*5113495bSYour Name 				pdev, tlv_desc, ppdu_info);
4627*5113495bSYour Name 		break;
4628*5113495bSYour Name 	case HTT_PPDU_STATS_USR_COMMON_ARRAY_TLV:
4629*5113495bSYour Name 		tlv_expected_size =
4630*5113495bSYour Name 			sizeof(htt_ppdu_stats_usr_common_array_tlv_v);
4631*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4632*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4633*5113495bSYour Name 		dp_process_ppdu_stats_user_common_array_tlv(
4634*5113495bSYour Name 				pdev, tlv_desc, ppdu_info);
4635*5113495bSYour Name 		break;
4636*5113495bSYour Name 	case HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV:
4637*5113495bSYour Name 		tlv_expected_size = sizeof(htt_ppdu_stats_flush_tlv);
4638*5113495bSYour Name 		tlv_desc = dp_validate_fix_ppdu_tlv(pdev, tag_buf,
4639*5113495bSYour Name 						    tlv_expected_size, tlv_len);
4640*5113495bSYour Name 		dp_process_ppdu_stats_user_compltn_flush_tlv(pdev, tlv_desc,
4641*5113495bSYour Name 							     ppdu_info);
4642*5113495bSYour Name 		break;
4643*5113495bSYour Name 	case HTT_PPDU_STATS_SCH_CMD_STATUS_TLV:
4644*5113495bSYour Name 		dp_process_ppdu_stats_sch_cmd_status_tlv(pdev, ppdu_info);
4645*5113495bSYour Name 		break;
4646*5113495bSYour Name 	default:
4647*5113495bSYour Name 		break;
4648*5113495bSYour Name 	}
4649*5113495bSYour Name }
4650*5113495bSYour Name 
4651*5113495bSYour Name #ifdef WLAN_CONFIG_TELEMETRY_AGENT
4652*5113495bSYour Name static inline
dp_ppdu_desc_user_airtime_consumption_update(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * user)4653*5113495bSYour Name void dp_ppdu_desc_user_airtime_consumption_update(
4654*5113495bSYour Name 			struct dp_peer *peer,
4655*5113495bSYour Name 			struct cdp_tx_completion_ppdu_user *user)
4656*5113495bSYour Name {
4657*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
4658*5113495bSYour Name 	uint8_t ac = 0;
4659*5113495bSYour Name 
4660*5113495bSYour Name 	mon_peer = peer->monitor_peer;
4661*5113495bSYour Name 	if (qdf_unlikely(!mon_peer))
4662*5113495bSYour Name 		return;
4663*5113495bSYour Name 
4664*5113495bSYour Name 	ac = TID_TO_WME_AC(user->tid);
4665*5113495bSYour Name 	DP_STATS_INC(mon_peer, airtime_stats.tx_airtime_consumption[ac].consumption,
4666*5113495bSYour Name 		     user->phy_tx_time_us);
4667*5113495bSYour Name }
4668*5113495bSYour Name #else
4669*5113495bSYour Name static inline
dp_ppdu_desc_user_airtime_consumption_update(struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * user)4670*5113495bSYour Name void dp_ppdu_desc_user_airtime_consumption_update(
4671*5113495bSYour Name 			struct dp_peer *peer,
4672*5113495bSYour Name 			struct cdp_tx_completion_ppdu_user *user)
4673*5113495bSYour Name { }
4674*5113495bSYour Name #endif
4675*5113495bSYour Name 
4676*5113495bSYour Name #if defined(WLAN_ATF_ENABLE) || defined(WLAN_CONFIG_TELEMETRY_AGENT)
4677*5113495bSYour Name static void
dp_ppdu_desc_user_phy_tx_time_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu * ppdu_desc,struct cdp_tx_completion_ppdu_user * user)4678*5113495bSYour Name dp_ppdu_desc_user_phy_tx_time_update(struct dp_pdev *pdev,
4679*5113495bSYour Name 				     struct dp_peer *peer,
4680*5113495bSYour Name 				     struct cdp_tx_completion_ppdu *ppdu_desc,
4681*5113495bSYour Name 				     struct cdp_tx_completion_ppdu_user *user)
4682*5113495bSYour Name {
4683*5113495bSYour Name 	uint32_t nss_ru_width_sum = 0;
4684*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
4685*5113495bSYour Name 
4686*5113495bSYour Name 	if (!pdev || !ppdu_desc || !user || !peer)
4687*5113495bSYour Name 		return;
4688*5113495bSYour Name 
4689*5113495bSYour Name 	if (ppdu_desc->frame_type != CDP_PPDU_FTYPE_DATA)
4690*5113495bSYour Name 		return;
4691*5113495bSYour Name 
4692*5113495bSYour Name 	mon_peer = peer->monitor_peer;
4693*5113495bSYour Name 	if (qdf_unlikely(!mon_peer))
4694*5113495bSYour Name 		return;
4695*5113495bSYour Name 
4696*5113495bSYour Name 	nss_ru_width_sum = ppdu_desc->usr_nss_sum * ppdu_desc->usr_ru_tones_sum;
4697*5113495bSYour Name 	if (!nss_ru_width_sum)
4698*5113495bSYour Name 		nss_ru_width_sum = 1;
4699*5113495bSYour Name 
4700*5113495bSYour Name 	/*
4701*5113495bSYour Name 	 * For SU-MIMO PPDU phy Tx time is same for the single user.
4702*5113495bSYour Name 	 * For MU-MIMO phy Tx time is calculated per user as below
4703*5113495bSYour Name 	 *     user phy tx time =
4704*5113495bSYour Name 	 *           Entire PPDU duration * MU Ratio * OFDMA Ratio
4705*5113495bSYour Name 	 *     MU Ratio = usr_nss / Sum_of_nss_of_all_users
4706*5113495bSYour Name 	 *     OFDMA_ratio = usr_ru_width / Sum_of_ru_width_of_all_users
4707*5113495bSYour Name 	 *     usr_ru_widt = ru_end – ru_start + 1
4708*5113495bSYour Name 	 */
4709*5113495bSYour Name 	if (ppdu_desc->htt_frame_type == HTT_STATS_FTYPE_TIDQ_DATA_SU) {
4710*5113495bSYour Name 		user->phy_tx_time_us = ppdu_desc->phy_ppdu_tx_time_us;
4711*5113495bSYour Name 	} else {
4712*5113495bSYour Name 		user->phy_tx_time_us = (ppdu_desc->phy_ppdu_tx_time_us *
4713*5113495bSYour Name 				user->nss * user->ru_tones) / nss_ru_width_sum;
4714*5113495bSYour Name 	}
4715*5113495bSYour Name 
4716*5113495bSYour Name 	dp_ppdu_desc_user_airtime_consumption_update(peer, user);
4717*5113495bSYour Name }
4718*5113495bSYour Name #else
4719*5113495bSYour Name static void
dp_ppdu_desc_user_phy_tx_time_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu * ppdu_desc,struct cdp_tx_completion_ppdu_user * user)4720*5113495bSYour Name dp_ppdu_desc_user_phy_tx_time_update(struct dp_pdev *pdev,
4721*5113495bSYour Name 				     struct dp_peer *peer,
4722*5113495bSYour Name 				     struct cdp_tx_completion_ppdu *ppdu_desc,
4723*5113495bSYour Name 				     struct cdp_tx_completion_ppdu_user *user)
4724*5113495bSYour Name {
4725*5113495bSYour Name }
4726*5113495bSYour Name #endif
4727*5113495bSYour Name 
4728*5113495bSYour Name #ifdef WLAN_SUPPORT_CTRL_FRAME_STATS
4729*5113495bSYour Name static void
dp_tx_ctrl_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * user)4730*5113495bSYour Name dp_tx_ctrl_stats_update(struct dp_pdev *pdev, struct dp_peer *peer,
4731*5113495bSYour Name 			struct cdp_tx_completion_ppdu_user *user)
4732*5113495bSYour Name {
4733*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
4734*5113495bSYour Name 	uint16_t fc = 0;
4735*5113495bSYour Name 
4736*5113495bSYour Name 	if (!pdev || !peer || !user)
4737*5113495bSYour Name 		return;
4738*5113495bSYour Name 
4739*5113495bSYour Name 	mon_peer = peer->monitor_peer;
4740*5113495bSYour Name 	if (qdf_unlikely(!mon_peer))
4741*5113495bSYour Name 		return;
4742*5113495bSYour Name 
4743*5113495bSYour Name 	if (user->mprot_type) {
4744*5113495bSYour Name 		DP_STATS_INCC(mon_peer,
4745*5113495bSYour Name 			      tx.rts_success, 1, user->rts_success);
4746*5113495bSYour Name 		DP_STATS_INCC(mon_peer,
4747*5113495bSYour Name 			      tx.rts_failure, 1, user->rts_failure);
4748*5113495bSYour Name 	}
4749*5113495bSYour Name 	fc = user->frame_ctrl;
4750*5113495bSYour Name 	if ((qdf_cpu_to_le16(fc) & QDF_IEEE80211_FC0_TYPE_MASK) ==
4751*5113495bSYour Name 	    QDF_IEEE80211_FC0_TYPE_CTL) {
4752*5113495bSYour Name 		if ((qdf_cpu_to_le16(fc) & QDF_IEEE80211_FC0_SUBTYPE_MASK) ==
4753*5113495bSYour Name 		    QDF_IEEE80211_FC0_SUBTYPE_VHT_NDP_AN)
4754*5113495bSYour Name 			DP_STATS_INC(mon_peer, tx.ndpa_cnt, 1);
4755*5113495bSYour Name 		if ((qdf_cpu_to_le16(fc) & QDF_IEEE80211_FC0_SUBTYPE_MASK) ==
4756*5113495bSYour Name 		    QDF_IEEE80211_FC0_SUBTYPE_BAR)
4757*5113495bSYour Name 			DP_STATS_INC(mon_peer, tx.bar_cnt, 1);
4758*5113495bSYour Name 	}
4759*5113495bSYour Name }
4760*5113495bSYour Name #else
4761*5113495bSYour Name static void
dp_tx_ctrl_stats_update(struct dp_pdev * pdev,struct dp_peer * peer,struct cdp_tx_completion_ppdu_user * user)4762*5113495bSYour Name dp_tx_ctrl_stats_update(struct dp_pdev *pdev, struct dp_peer *peer,
4763*5113495bSYour Name 			struct cdp_tx_completion_ppdu_user *user)
4764*5113495bSYour Name {
4765*5113495bSYour Name }
4766*5113495bSYour Name #endif /* WLAN_SUPPORT_CTRL_FRAME_STATS */
4767*5113495bSYour Name 
4768*5113495bSYour Name void
dp_ppdu_desc_user_stats_update(struct dp_pdev * pdev,struct ppdu_info * ppdu_info)4769*5113495bSYour Name dp_ppdu_desc_user_stats_update(struct dp_pdev *pdev,
4770*5113495bSYour Name 			       struct ppdu_info *ppdu_info)
4771*5113495bSYour Name {
4772*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc = NULL;
4773*5113495bSYour Name 	struct dp_peer *peer = NULL;
4774*5113495bSYour Name 	uint32_t tlv_bitmap_expected;
4775*5113495bSYour Name 	uint32_t tlv_bitmap_default;
4776*5113495bSYour Name 	uint16_t i;
4777*5113495bSYour Name 	uint32_t num_users;
4778*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
4779*5113495bSYour Name 
4780*5113495bSYour Name 	ppdu_desc = (struct cdp_tx_completion_ppdu *)
4781*5113495bSYour Name 		qdf_nbuf_data(ppdu_info->nbuf);
4782*5113495bSYour Name 
4783*5113495bSYour Name 	if (ppdu_desc->frame_type != CDP_PPDU_FTYPE_BAR)
4784*5113495bSYour Name 		ppdu_desc->ppdu_id = ppdu_info->ppdu_id;
4785*5113495bSYour Name 
4786*5113495bSYour Name 	tlv_bitmap_expected = HTT_PPDU_DEFAULT_TLV_BITMAP;
4787*5113495bSYour Name 	if (mon_pdev->tx_sniffer_enable || mon_pdev->mcopy_mode ||
4788*5113495bSYour Name 	    mon_pdev->tx_capture_enabled) {
4789*5113495bSYour Name 		if (ppdu_info->is_ampdu)
4790*5113495bSYour Name 			tlv_bitmap_expected =
4791*5113495bSYour Name 				dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(
4792*5113495bSYour Name 					ppdu_info->tlv_bitmap);
4793*5113495bSYour Name 	}
4794*5113495bSYour Name 
4795*5113495bSYour Name 	tlv_bitmap_default = tlv_bitmap_expected;
4796*5113495bSYour Name 
4797*5113495bSYour Name 	if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) {
4798*5113495bSYour Name 		num_users = ppdu_desc->bar_num_users;
4799*5113495bSYour Name 		ppdu_desc->num_users = ppdu_desc->bar_num_users;
4800*5113495bSYour Name 	} else {
4801*5113495bSYour Name 		num_users = ppdu_desc->num_users;
4802*5113495bSYour Name 	}
4803*5113495bSYour Name 	qdf_assert_always(ppdu_desc->num_users <= ppdu_desc->max_users);
4804*5113495bSYour Name 
4805*5113495bSYour Name 	if (wlan_cfg_get_sawf_stats_config(pdev->soc->wlan_cfg_ctx)) {
4806*5113495bSYour Name 		dp_ppdu_desc_get_txmode(ppdu_desc);
4807*5113495bSYour Name 		dp_pdev_update_deter_stats(pdev, ppdu_desc);
4808*5113495bSYour Name 	}
4809*5113495bSYour Name 
4810*5113495bSYour Name 	for (i = 0; i < num_users; i++) {
4811*5113495bSYour Name 		ppdu_desc->num_mpdu += ppdu_desc->user[i].num_mpdu;
4812*5113495bSYour Name 		ppdu_desc->num_msdu += ppdu_desc->user[i].num_msdu;
4813*5113495bSYour Name 
4814*5113495bSYour Name 		peer = dp_peer_get_ref_by_id(pdev->soc,
4815*5113495bSYour Name 					     ppdu_desc->user[i].peer_id,
4816*5113495bSYour Name 					     DP_MOD_ID_TX_PPDU_STATS);
4817*5113495bSYour Name 		/*
4818*5113495bSYour Name 		 * This check is to make sure peer is not deleted
4819*5113495bSYour Name 		 * after processing the TLVs.
4820*5113495bSYour Name 		 */
4821*5113495bSYour Name 		if (!peer)
4822*5113495bSYour Name 			continue;
4823*5113495bSYour Name 
4824*5113495bSYour Name 		ppdu_desc->user[i].is_bss_peer = peer->bss_peer;
4825*5113495bSYour Name 
4826*5113495bSYour Name 		dp_ppdu_desc_user_phy_tx_time_update(pdev, peer, ppdu_desc,
4827*5113495bSYour Name 						     &ppdu_desc->user[i]);
4828*5113495bSYour Name 
4829*5113495bSYour Name 		dp_tx_ctrl_stats_update(pdev, peer, &ppdu_desc->user[i]);
4830*5113495bSYour Name 
4831*5113495bSYour Name 		if (wlan_cfg_get_sawf_stats_config(pdev->soc->wlan_cfg_ctx)) {
4832*5113495bSYour Name 			dp_ppdu_desc_user_deter_stats_update(pdev,
4833*5113495bSYour Name 							     peer,
4834*5113495bSYour Name 							     ppdu_desc,
4835*5113495bSYour Name 							     &ppdu_desc->user[i]);
4836*5113495bSYour Name 		}
4837*5113495bSYour Name 
4838*5113495bSYour Name 		/*
4839*5113495bSYour Name 		 * different frame like DATA, BAR or CTRL has different
4840*5113495bSYour Name 		 * tlv bitmap expected. Apart from ACK_BA_STATUS TLV, we
4841*5113495bSYour Name 		 * receive other tlv in-order/sequential from fw.
4842*5113495bSYour Name 		 * Since ACK_BA_STATUS TLV come from Hardware it is
4843*5113495bSYour Name 		 * asynchronous So we need to depend on some tlv to confirm
4844*5113495bSYour Name 		 * all tlv is received for a ppdu.
4845*5113495bSYour Name 		 * So we depend on both SCHED_CMD_STATUS_TLV and
4846*5113495bSYour Name 		 * ACK_BA_STATUS_TLV. for failure packet we won't get
4847*5113495bSYour Name 		 * ACK_BA_STATUS_TLV.
4848*5113495bSYour Name 		 */
4849*5113495bSYour Name 		if (!(ppdu_info->tlv_bitmap &
4850*5113495bSYour Name 		      (1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV)) ||
4851*5113495bSYour Name 		    (!(ppdu_info->tlv_bitmap &
4852*5113495bSYour Name 		       (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV)) &&
4853*5113495bSYour Name 		     (ppdu_desc->user[i].completion_status ==
4854*5113495bSYour Name 		      HTT_PPDU_STATS_USER_STATUS_OK))) {
4855*5113495bSYour Name 			dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
4856*5113495bSYour Name 			continue;
4857*5113495bSYour Name 		}
4858*5113495bSYour Name 
4859*5113495bSYour Name 		/*
4860*5113495bSYour Name 		 * Update tx stats for data frames having Qos as well as
4861*5113495bSYour Name 		 * non-Qos data tid
4862*5113495bSYour Name 		 */
4863*5113495bSYour Name 
4864*5113495bSYour Name 		if ((ppdu_desc->user[i].tid < CDP_DATA_TID_MAX ||
4865*5113495bSYour Name 		     (ppdu_desc->user[i].tid == CDP_DATA_NON_QOS_TID) ||
4866*5113495bSYour Name 		     (ppdu_desc->htt_frame_type ==
4867*5113495bSYour Name 		      HTT_STATS_FTYPE_SGEN_QOS_NULL) ||
4868*5113495bSYour Name 		     ((ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR) &&
4869*5113495bSYour Name 		      (ppdu_desc->num_mpdu > 1))) &&
4870*5113495bSYour Name 		      (ppdu_desc->frame_type != CDP_PPDU_FTYPE_CTRL)) {
4871*5113495bSYour Name 			dp_tx_stats_update(pdev, peer,
4872*5113495bSYour Name 					   &ppdu_desc->user[i],
4873*5113495bSYour Name 					   ppdu_desc);
4874*5113495bSYour Name 		}
4875*5113495bSYour Name 
4876*5113495bSYour Name 		dp_peer_unref_delete(peer, DP_MOD_ID_TX_PPDU_STATS);
4877*5113495bSYour Name 		tlv_bitmap_expected = tlv_bitmap_default;
4878*5113495bSYour Name 	}
4879*5113495bSYour Name }
4880*5113495bSYour Name 
4881*5113495bSYour Name #if !defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_PKT_CAPTURE_TX_2_0) || \
4882*5113495bSYour Name 	defined(WLAN_PKT_CAPTURE_RX_2_0)
4883*5113495bSYour Name /**
4884*5113495bSYour Name  * dp_tx_ppdu_desc_notify() - Notify to upper layer about PPDU via WDI
4885*5113495bSYour Name  *
4886*5113495bSYour Name  * @pdev: Datapath pdev handle
4887*5113495bSYour Name  * @nbuf: Buffer to be delivered to upper layer
4888*5113495bSYour Name  *
4889*5113495bSYour Name  * Return: void
4890*5113495bSYour Name  */
dp_tx_ppdu_desc_notify(struct dp_pdev * pdev,qdf_nbuf_t nbuf)4891*5113495bSYour Name static void dp_tx_ppdu_desc_notify(struct dp_pdev *pdev, qdf_nbuf_t nbuf)
4892*5113495bSYour Name {
4893*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
4894*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
4895*5113495bSYour Name 
4896*5113495bSYour Name 	mon_ops = dp_mon_ops_get(soc);
4897*5113495bSYour Name 	if (mon_ops && mon_ops->mon_ppdu_desc_notify)
4898*5113495bSYour Name 		mon_ops->mon_ppdu_desc_notify(pdev, nbuf);
4899*5113495bSYour Name 	else
4900*5113495bSYour Name 		qdf_nbuf_free(nbuf);
4901*5113495bSYour Name }
4902*5113495bSYour Name 
dp_ppdu_desc_deliver(struct dp_pdev * pdev,struct ppdu_info * ppdu_info)4903*5113495bSYour Name void dp_ppdu_desc_deliver(struct dp_pdev *pdev,
4904*5113495bSYour Name 			  struct ppdu_info *ppdu_info)
4905*5113495bSYour Name {
4906*5113495bSYour Name 	struct ppdu_info *s_ppdu_info = NULL;
4907*5113495bSYour Name 	struct ppdu_info *ppdu_info_next = NULL;
4908*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc = NULL;
4909*5113495bSYour Name 	qdf_nbuf_t nbuf;
4910*5113495bSYour Name 	uint32_t time_delta = 0;
4911*5113495bSYour Name 	bool starved = 0;
4912*5113495bSYour Name 	bool matched = 0;
4913*5113495bSYour Name 	bool recv_ack_ba_done = 0;
4914*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
4915*5113495bSYour Name 
4916*5113495bSYour Name 	if (ppdu_info->tlv_bitmap &
4917*5113495bSYour Name 	    (1 << HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) &&
4918*5113495bSYour Name 	    ppdu_info->done)
4919*5113495bSYour Name 		recv_ack_ba_done = 1;
4920*5113495bSYour Name 
4921*5113495bSYour Name 	mon_pdev->last_sched_cmdid = ppdu_info->sched_cmdid;
4922*5113495bSYour Name 
4923*5113495bSYour Name 	s_ppdu_info = TAILQ_FIRST(&mon_pdev->sched_comp_ppdu_list);
4924*5113495bSYour Name 
4925*5113495bSYour Name 	TAILQ_FOREACH_SAFE(s_ppdu_info, &mon_pdev->sched_comp_ppdu_list,
4926*5113495bSYour Name 			   ppdu_info_list_elem, ppdu_info_next) {
4927*5113495bSYour Name 		if (s_ppdu_info->tsf_l32 > ppdu_info->tsf_l32)
4928*5113495bSYour Name 			time_delta = (MAX_TSF_32 - s_ppdu_info->tsf_l32) +
4929*5113495bSYour Name 					ppdu_info->tsf_l32;
4930*5113495bSYour Name 		else
4931*5113495bSYour Name 			time_delta = ppdu_info->tsf_l32 - s_ppdu_info->tsf_l32;
4932*5113495bSYour Name 
4933*5113495bSYour Name 		if (!s_ppdu_info->done && !recv_ack_ba_done) {
4934*5113495bSYour Name 			if (time_delta < MAX_SCHED_STARVE) {
4935*5113495bSYour Name 				dp_mon_info("pdev[%d] ppdu_id[%d] sched_cmdid[%d] TLV_B[0x%x] TSF[%u] D[%d]",
4936*5113495bSYour Name 					    pdev->pdev_id,
4937*5113495bSYour Name 					    s_ppdu_info->ppdu_id,
4938*5113495bSYour Name 					    s_ppdu_info->sched_cmdid,
4939*5113495bSYour Name 					    s_ppdu_info->tlv_bitmap,
4940*5113495bSYour Name 					    s_ppdu_info->tsf_l32,
4941*5113495bSYour Name 					    s_ppdu_info->done);
4942*5113495bSYour Name 				break;
4943*5113495bSYour Name 			}
4944*5113495bSYour Name 			starved = 1;
4945*5113495bSYour Name 		}
4946*5113495bSYour Name 
4947*5113495bSYour Name 		mon_pdev->delivered_sched_cmdid = s_ppdu_info->sched_cmdid;
4948*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev->sched_comp_ppdu_list, s_ppdu_info,
4949*5113495bSYour Name 			     ppdu_info_list_elem);
4950*5113495bSYour Name 		mon_pdev->sched_comp_list_depth--;
4951*5113495bSYour Name 
4952*5113495bSYour Name 		nbuf = s_ppdu_info->nbuf;
4953*5113495bSYour Name 		qdf_assert_always(nbuf);
4954*5113495bSYour Name 		ppdu_desc = (struct cdp_tx_completion_ppdu *)
4955*5113495bSYour Name 				qdf_nbuf_data(nbuf);
4956*5113495bSYour Name 		ppdu_desc->tlv_bitmap = s_ppdu_info->tlv_bitmap;
4957*5113495bSYour Name 
4958*5113495bSYour Name 		if (starved) {
4959*5113495bSYour Name 			dp_mon_info("ppdu starved fc[0x%x] h_ftype[%d] tlv_bitmap[0x%x] cs[%d]\n",
4960*5113495bSYour Name 				    ppdu_desc->frame_ctrl,
4961*5113495bSYour Name 				    ppdu_desc->htt_frame_type,
4962*5113495bSYour Name 				    ppdu_desc->tlv_bitmap,
4963*5113495bSYour Name 				    ppdu_desc->user[0].completion_status);
4964*5113495bSYour Name 			starved = 0;
4965*5113495bSYour Name 		}
4966*5113495bSYour Name 
4967*5113495bSYour Name 		if (ppdu_info->ppdu_id == s_ppdu_info->ppdu_id &&
4968*5113495bSYour Name 		    ppdu_info->sched_cmdid == s_ppdu_info->sched_cmdid)
4969*5113495bSYour Name 			matched = 1;
4970*5113495bSYour Name 
4971*5113495bSYour Name 		dp_ppdu_desc_user_stats_update(pdev, s_ppdu_info);
4972*5113495bSYour Name 
4973*5113495bSYour Name 		qdf_mem_free(s_ppdu_info);
4974*5113495bSYour Name 
4975*5113495bSYour Name 		dp_tx_ppdu_desc_notify(pdev, nbuf);
4976*5113495bSYour Name 
4977*5113495bSYour Name 		if (matched)
4978*5113495bSYour Name 			break;
4979*5113495bSYour Name 	}
4980*5113495bSYour Name }
4981*5113495bSYour Name #endif
4982*5113495bSYour Name 
4983*5113495bSYour Name /**
4984*5113495bSYour Name  * dp_tx_ppdu_desc_deliver() - Deliver PPDU desc to upper layer
4985*5113495bSYour Name  * @pdev: Datapath pdev handle
4986*5113495bSYour Name  * @ppdu_info: per PPDU TLV descriptor
4987*5113495bSYour Name  *
4988*5113495bSYour Name  * Return: void
4989*5113495bSYour Name  */
dp_tx_ppdu_desc_deliver(struct dp_pdev * pdev,struct ppdu_info * ppdu_info)4990*5113495bSYour Name static void dp_tx_ppdu_desc_deliver(struct dp_pdev *pdev,
4991*5113495bSYour Name 				    struct ppdu_info *ppdu_info)
4992*5113495bSYour Name {
4993*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
4994*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
4995*5113495bSYour Name 
4996*5113495bSYour Name 	mon_ops = dp_mon_ops_get(soc);
4997*5113495bSYour Name 
4998*5113495bSYour Name 	if (mon_ops && mon_ops->mon_ppdu_desc_deliver) {
4999*5113495bSYour Name 		mon_ops->mon_ppdu_desc_deliver(pdev, ppdu_info);
5000*5113495bSYour Name 	} else {
5001*5113495bSYour Name 		qdf_nbuf_free(ppdu_info->nbuf);
5002*5113495bSYour Name 		ppdu_info->nbuf = NULL;
5003*5113495bSYour Name 		qdf_mem_free(ppdu_info);
5004*5113495bSYour Name 	}
5005*5113495bSYour Name }
5006*5113495bSYour Name 
5007*5113495bSYour Name /**
5008*5113495bSYour Name  * dp_get_ppdu_desc() - Function to allocate new PPDU status
5009*5113495bSYour Name  * desc for new ppdu id
5010*5113495bSYour Name  * @pdev: DP pdev handle
5011*5113495bSYour Name  * @ppdu_id: PPDU unique identifier
5012*5113495bSYour Name  * @tlv_type: TLV type received
5013*5113495bSYour Name  * @tsf_l32: timestamp received along with ppdu stats indication header
5014*5113495bSYour Name  * @max_users: Maximum user for that particular ppdu
5015*5113495bSYour Name  *
5016*5113495bSYour Name  * Return: ppdu_info per ppdu tlv structure
5017*5113495bSYour Name  */
5018*5113495bSYour Name static
dp_get_ppdu_desc(struct dp_pdev * pdev,uint32_t ppdu_id,uint8_t tlv_type,uint32_t tsf_l32,uint8_t max_users)5019*5113495bSYour Name struct ppdu_info *dp_get_ppdu_desc(struct dp_pdev *pdev, uint32_t ppdu_id,
5020*5113495bSYour Name 				   uint8_t tlv_type, uint32_t tsf_l32,
5021*5113495bSYour Name 				   uint8_t max_users)
5022*5113495bSYour Name {
5023*5113495bSYour Name 	struct ppdu_info *ppdu_info = NULL;
5024*5113495bSYour Name 	struct ppdu_info *s_ppdu_info = NULL;
5025*5113495bSYour Name 	struct ppdu_info *ppdu_info_next = NULL;
5026*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc = NULL;
5027*5113495bSYour Name 	uint32_t size = 0;
5028*5113495bSYour Name 	struct cdp_tx_completion_ppdu *tmp_ppdu_desc = NULL;
5029*5113495bSYour Name 	struct cdp_tx_completion_ppdu_user *tmp_user;
5030*5113495bSYour Name 	uint32_t time_delta;
5031*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
5032*5113495bSYour Name 
5033*5113495bSYour Name 	/*
5034*5113495bSYour Name 	 * Find ppdu_id node exists or not
5035*5113495bSYour Name 	 */
5036*5113495bSYour Name 	TAILQ_FOREACH_SAFE(ppdu_info, &mon_pdev->ppdu_info_list,
5037*5113495bSYour Name 			   ppdu_info_list_elem, ppdu_info_next) {
5038*5113495bSYour Name 		if (ppdu_info && (ppdu_info->ppdu_id == ppdu_id)) {
5039*5113495bSYour Name 			if (ppdu_info->tsf_l32 > tsf_l32)
5040*5113495bSYour Name 				time_delta  = (MAX_TSF_32 -
5041*5113495bSYour Name 					       ppdu_info->tsf_l32) + tsf_l32;
5042*5113495bSYour Name 			else
5043*5113495bSYour Name 				time_delta  = tsf_l32 - ppdu_info->tsf_l32;
5044*5113495bSYour Name 
5045*5113495bSYour Name 			if (time_delta > WRAP_DROP_TSF_DELTA) {
5046*5113495bSYour Name 				TAILQ_REMOVE(&mon_pdev->ppdu_info_list,
5047*5113495bSYour Name 					     ppdu_info, ppdu_info_list_elem);
5048*5113495bSYour Name 				mon_pdev->list_depth--;
5049*5113495bSYour Name 				pdev->stats.ppdu_wrap_drop++;
5050*5113495bSYour Name 				tmp_ppdu_desc =
5051*5113495bSYour Name 					(struct cdp_tx_completion_ppdu *)
5052*5113495bSYour Name 					qdf_nbuf_data(ppdu_info->nbuf);
5053*5113495bSYour Name 				tmp_user = &tmp_ppdu_desc->user[0];
5054*5113495bSYour Name 				dp_htt_tx_stats_info("S_PID [%d] S_TSF[%u] TLV_BITMAP[0x%x] [CMPLTN - %d ACK_BA - %d] CS[%d] - R_PID[%d] R_TSF[%u] R_TLV_TAG[0x%x]\n",
5055*5113495bSYour Name 						     ppdu_info->ppdu_id,
5056*5113495bSYour Name 						     ppdu_info->tsf_l32,
5057*5113495bSYour Name 						     ppdu_info->tlv_bitmap,
5058*5113495bSYour Name 						     tmp_user->completion_status,
5059*5113495bSYour Name 						     ppdu_info->compltn_common_tlv,
5060*5113495bSYour Name 						     ppdu_info->ack_ba_tlv,
5061*5113495bSYour Name 						     ppdu_id, tsf_l32,
5062*5113495bSYour Name 						     tlv_type);
5063*5113495bSYour Name 				qdf_nbuf_free(ppdu_info->nbuf);
5064*5113495bSYour Name 				ppdu_info->nbuf = NULL;
5065*5113495bSYour Name 				qdf_mem_free(ppdu_info);
5066*5113495bSYour Name 			} else {
5067*5113495bSYour Name 				break;
5068*5113495bSYour Name 			}
5069*5113495bSYour Name 		}
5070*5113495bSYour Name 	}
5071*5113495bSYour Name 
5072*5113495bSYour Name 	/*
5073*5113495bSYour Name 	 * check if it is ack ba tlv and if it is not there in ppdu info
5074*5113495bSYour Name 	 * list then check it in sched completion ppdu list
5075*5113495bSYour Name 	 */
5076*5113495bSYour Name 	if (!ppdu_info &&
5077*5113495bSYour Name 	    tlv_type == HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) {
5078*5113495bSYour Name 		TAILQ_FOREACH(s_ppdu_info,
5079*5113495bSYour Name 			      &mon_pdev->sched_comp_ppdu_list,
5080*5113495bSYour Name 			      ppdu_info_list_elem) {
5081*5113495bSYour Name 			if (s_ppdu_info && (s_ppdu_info->ppdu_id == ppdu_id)) {
5082*5113495bSYour Name 				if (s_ppdu_info->tsf_l32 > tsf_l32)
5083*5113495bSYour Name 					time_delta  = (MAX_TSF_32 -
5084*5113495bSYour Name 						       s_ppdu_info->tsf_l32) +
5085*5113495bSYour Name 							tsf_l32;
5086*5113495bSYour Name 				else
5087*5113495bSYour Name 					time_delta  = tsf_l32 -
5088*5113495bSYour Name 						s_ppdu_info->tsf_l32;
5089*5113495bSYour Name 				if (time_delta < WRAP_DROP_TSF_DELTA) {
5090*5113495bSYour Name 					ppdu_info = s_ppdu_info;
5091*5113495bSYour Name 					break;
5092*5113495bSYour Name 				}
5093*5113495bSYour Name 			} else {
5094*5113495bSYour Name 				/*
5095*5113495bSYour Name 				 * ACK BA STATUS TLV comes sequential order
5096*5113495bSYour Name 				 * if we received ack ba status tlv for second
5097*5113495bSYour Name 				 * ppdu and first ppdu is still waiting for
5098*5113495bSYour Name 				 * ACK BA STATUS TLV. Based on fw comment
5099*5113495bSYour Name 				 * we won't receive it tlv later. So we can
5100*5113495bSYour Name 				 * set ppdu info done.
5101*5113495bSYour Name 				 */
5102*5113495bSYour Name 				if (s_ppdu_info)
5103*5113495bSYour Name 					s_ppdu_info->done = 1;
5104*5113495bSYour Name 			}
5105*5113495bSYour Name 		}
5106*5113495bSYour Name 	}
5107*5113495bSYour Name 
5108*5113495bSYour Name 	if (ppdu_info) {
5109*5113495bSYour Name 		if (ppdu_info->tlv_bitmap & (1 << tlv_type)) {
5110*5113495bSYour Name 			/*
5111*5113495bSYour Name 			 * if we get tlv_type that is already been processed
5112*5113495bSYour Name 			 * for ppdu, that means we got a new ppdu with same
5113*5113495bSYour Name 			 * ppdu id. Hence Flush the older ppdu
5114*5113495bSYour Name 			 * for MUMIMO and OFDMA, In a PPDU we have
5115*5113495bSYour Name 			 * multiple user with same tlv types. tlv bitmap is
5116*5113495bSYour Name 			 * used to check whether SU or MU_MIMO/OFDMA
5117*5113495bSYour Name 			 */
5118*5113495bSYour Name 			if (!(ppdu_info->tlv_bitmap &
5119*5113495bSYour Name 			    (1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV)))
5120*5113495bSYour Name 				return ppdu_info;
5121*5113495bSYour Name 
5122*5113495bSYour Name 			ppdu_desc = (struct cdp_tx_completion_ppdu *)
5123*5113495bSYour Name 				qdf_nbuf_data(ppdu_info->nbuf);
5124*5113495bSYour Name 
5125*5113495bSYour Name 			/*
5126*5113495bSYour Name 			 * apart from ACK BA STATUS TLV rest all comes in order
5127*5113495bSYour Name 			 * so if tlv type not ACK BA STATUS TLV we can deliver
5128*5113495bSYour Name 			 * ppdu_info
5129*5113495bSYour Name 			 */
5130*5113495bSYour Name 			if ((tlv_type ==
5131*5113495bSYour Name 			     HTT_PPDU_STATS_USR_COMPLTN_ACK_BA_STATUS_TLV) &&
5132*5113495bSYour Name 			    ((ppdu_desc->htt_frame_type ==
5133*5113495bSYour Name 			     HTT_STATS_FTYPE_SGEN_MU_BAR) ||
5134*5113495bSYour Name 			    (ppdu_desc->htt_frame_type ==
5135*5113495bSYour Name 			     HTT_STATS_FTYPE_SGEN_BE_MU_BAR)))
5136*5113495bSYour Name 				return ppdu_info;
5137*5113495bSYour Name 
5138*5113495bSYour Name 			dp_tx_ppdu_desc_deliver(pdev, ppdu_info);
5139*5113495bSYour Name 		} else {
5140*5113495bSYour Name 			return ppdu_info;
5141*5113495bSYour Name 		}
5142*5113495bSYour Name 	}
5143*5113495bSYour Name 
5144*5113495bSYour Name 	/*
5145*5113495bSYour Name 	 * Flush the head ppdu descriptor if ppdu desc list reaches max
5146*5113495bSYour Name 	 * threshold
5147*5113495bSYour Name 	 */
5148*5113495bSYour Name 	if (mon_pdev->list_depth > HTT_PPDU_DESC_MAX_DEPTH) {
5149*5113495bSYour Name 		ppdu_info = TAILQ_FIRST(&mon_pdev->ppdu_info_list);
5150*5113495bSYour Name 		TAILQ_REMOVE(&mon_pdev->ppdu_info_list,
5151*5113495bSYour Name 			     ppdu_info, ppdu_info_list_elem);
5152*5113495bSYour Name 		mon_pdev->list_depth--;
5153*5113495bSYour Name 		pdev->stats.ppdu_drop++;
5154*5113495bSYour Name 		qdf_nbuf_free(ppdu_info->nbuf);
5155*5113495bSYour Name 		ppdu_info->nbuf = NULL;
5156*5113495bSYour Name 		qdf_mem_free(ppdu_info);
5157*5113495bSYour Name 	}
5158*5113495bSYour Name 
5159*5113495bSYour Name 	size = sizeof(struct cdp_tx_completion_ppdu) +
5160*5113495bSYour Name 		(max_users * sizeof(struct cdp_tx_completion_ppdu_user));
5161*5113495bSYour Name 
5162*5113495bSYour Name 	/*
5163*5113495bSYour Name 	 * Allocate new ppdu_info node
5164*5113495bSYour Name 	 */
5165*5113495bSYour Name 	ppdu_info = qdf_mem_malloc(sizeof(struct ppdu_info));
5166*5113495bSYour Name 	if (!ppdu_info)
5167*5113495bSYour Name 		return NULL;
5168*5113495bSYour Name 
5169*5113495bSYour Name 	ppdu_info->nbuf = qdf_nbuf_alloc(pdev->soc->osdev, size,
5170*5113495bSYour Name 					 0, 4, TRUE);
5171*5113495bSYour Name 	if (!ppdu_info->nbuf) {
5172*5113495bSYour Name 		qdf_mem_free(ppdu_info);
5173*5113495bSYour Name 		return NULL;
5174*5113495bSYour Name 	}
5175*5113495bSYour Name 
5176*5113495bSYour Name 	ppdu_info->ppdu_desc =
5177*5113495bSYour Name 		(struct cdp_tx_completion_ppdu *)qdf_nbuf_data(ppdu_info->nbuf);
5178*5113495bSYour Name 	qdf_mem_zero(qdf_nbuf_data(ppdu_info->nbuf), size);
5179*5113495bSYour Name 
5180*5113495bSYour Name 	if (!qdf_nbuf_put_tail(ppdu_info->nbuf, size)) {
5181*5113495bSYour Name 		dp_mon_err("No tailroom for HTT PPDU");
5182*5113495bSYour Name 		qdf_nbuf_free(ppdu_info->nbuf);
5183*5113495bSYour Name 		ppdu_info->nbuf = NULL;
5184*5113495bSYour Name 		ppdu_info->last_user = 0;
5185*5113495bSYour Name 		qdf_mem_free(ppdu_info);
5186*5113495bSYour Name 		return NULL;
5187*5113495bSYour Name 	}
5188*5113495bSYour Name 
5189*5113495bSYour Name 	ppdu_info->ppdu_desc->max_users = max_users;
5190*5113495bSYour Name 	ppdu_info->tsf_l32 = tsf_l32;
5191*5113495bSYour Name 	/*
5192*5113495bSYour Name 	 * No lock is needed because all PPDU TLVs are processed in
5193*5113495bSYour Name 	 * same context and this list is updated in same context
5194*5113495bSYour Name 	 */
5195*5113495bSYour Name 	TAILQ_INSERT_TAIL(&mon_pdev->ppdu_info_list, ppdu_info,
5196*5113495bSYour Name 			  ppdu_info_list_elem);
5197*5113495bSYour Name 	mon_pdev->list_depth++;
5198*5113495bSYour Name 	return ppdu_info;
5199*5113495bSYour Name }
5200*5113495bSYour Name 
5201*5113495bSYour Name #define DP_HTT_PPDU_ID_MASK 0x00FFFFFF
5202*5113495bSYour Name /**
5203*5113495bSYour Name  * dp_htt_mask_ppdu_id() - Function to mask ppdu_id
5204*5113495bSYour Name  * @ppdu_id: PPDU ID
5205*5113495bSYour Name  *
5206*5113495bSYour Name  * Return: Masked ppdu_id
5207*5113495bSYour Name  */
dp_htt_mask_ppdu_id(uint32_t ppdu_id)5208*5113495bSYour Name static inline uint32_t dp_htt_mask_ppdu_id(uint32_t ppdu_id)
5209*5113495bSYour Name {
5210*5113495bSYour Name 	return (ppdu_id & DP_HTT_PPDU_ID_MASK);
5211*5113495bSYour Name }
5212*5113495bSYour Name 
5213*5113495bSYour Name /**
5214*5113495bSYour Name  * dp_htt_process_tlv() - Function to process each PPDU TLVs
5215*5113495bSYour Name  * @pdev: DP pdev handle
5216*5113495bSYour Name  * @htt_t2h_msg: HTT target to host message
5217*5113495bSYour Name  *
5218*5113495bSYour Name  * Return: ppdu_info per ppdu tlv structure
5219*5113495bSYour Name  */
dp_htt_process_tlv(struct dp_pdev * pdev,qdf_nbuf_t htt_t2h_msg)5220*5113495bSYour Name static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev,
5221*5113495bSYour Name 					    qdf_nbuf_t htt_t2h_msg)
5222*5113495bSYour Name {
5223*5113495bSYour Name 	uint32_t length;
5224*5113495bSYour Name 	uint32_t ppdu_id;
5225*5113495bSYour Name 	uint8_t tlv_type;
5226*5113495bSYour Name 	uint32_t tlv_length, tlv_bitmap_expected;
5227*5113495bSYour Name 	uint8_t *tlv_buf;
5228*5113495bSYour Name 	struct ppdu_info *ppdu_info = NULL;
5229*5113495bSYour Name 	struct cdp_tx_completion_ppdu *ppdu_desc = NULL;
5230*5113495bSYour Name 	uint8_t max_users = CDP_MU_MAX_USERS;
5231*5113495bSYour Name 	uint32_t tsf_l32;
5232*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
5233*5113495bSYour Name 
5234*5113495bSYour Name 	uint32_t *msg_word = (uint32_t *)qdf_nbuf_data(htt_t2h_msg);
5235*5113495bSYour Name 
5236*5113495bSYour Name 	length = HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_GET(*msg_word);
5237*5113495bSYour Name 
5238*5113495bSYour Name 	msg_word = msg_word + 1;
5239*5113495bSYour Name 	ppdu_id = HTT_T2H_PPDU_STATS_PPDU_ID_GET(*msg_word);
5240*5113495bSYour Name 	ppdu_id = dp_htt_mask_ppdu_id(ppdu_id);
5241*5113495bSYour Name 
5242*5113495bSYour Name 	msg_word = msg_word + 1;
5243*5113495bSYour Name 	tsf_l32 = (uint32_t)(*msg_word);
5244*5113495bSYour Name 
5245*5113495bSYour Name 	msg_word = msg_word + 2;
5246*5113495bSYour Name 	while (length > 0) {
5247*5113495bSYour Name 		tlv_buf = (uint8_t *)msg_word;
5248*5113495bSYour Name 		tlv_type = HTT_STATS_TLV_TAG_GET(*msg_word);
5249*5113495bSYour Name 		tlv_length = HTT_STATS_TLV_LENGTH_GET(*msg_word);
5250*5113495bSYour Name 		if (qdf_likely(tlv_type < CDP_PPDU_STATS_MAX_TAG))
5251*5113495bSYour Name 			pdev->stats.ppdu_stats_counter[tlv_type]++;
5252*5113495bSYour Name 
5253*5113495bSYour Name 		if (tlv_length == 0)
5254*5113495bSYour Name 			break;
5255*5113495bSYour Name 
5256*5113495bSYour Name 		tlv_length += HTT_TLV_HDR_LEN;
5257*5113495bSYour Name 
5258*5113495bSYour Name 		/*
5259*5113495bSYour Name 		 * Not allocating separate ppdu descriptor for MGMT Payload
5260*5113495bSYour Name 		 * TLV as this is sent as separate WDI indication and it
5261*5113495bSYour Name 		 * doesn't contain any ppdu information
5262*5113495bSYour Name 		 */
5263*5113495bSYour Name 		if (tlv_type == HTT_PPDU_STATS_TX_MGMTCTRL_PAYLOAD_TLV) {
5264*5113495bSYour Name 			mon_pdev->mgmtctrl_frm_info.mgmt_buf = tlv_buf;
5265*5113495bSYour Name 			mon_pdev->mgmtctrl_frm_info.ppdu_id = ppdu_id;
5266*5113495bSYour Name 			mon_pdev->mgmtctrl_frm_info.mgmt_buf_len =
5267*5113495bSYour Name 				HTT_PPDU_STATS_TX_MGMTCTRL_TLV_FRAME_LENGTH_GET
5268*5113495bSYour Name 						(*(msg_word + 1));
5269*5113495bSYour Name 			msg_word =
5270*5113495bSYour Name 				(uint32_t *)((uint8_t *)tlv_buf + tlv_length);
5271*5113495bSYour Name 			length -= (tlv_length);
5272*5113495bSYour Name 			continue;
5273*5113495bSYour Name 		}
5274*5113495bSYour Name 
5275*5113495bSYour Name 		/*
5276*5113495bSYour Name 		 * retrieve max_users if it's USERS_INFO,
5277*5113495bSYour Name 		 * else, it's 1 for COMPLTN_FLUSH,
5278*5113495bSYour Name 		 * else, use CDP_MU_MAX_USERS
5279*5113495bSYour Name 		 */
5280*5113495bSYour Name 		if (tlv_type == HTT_PPDU_STATS_USERS_INFO_TLV) {
5281*5113495bSYour Name 			max_users =
5282*5113495bSYour Name 				HTT_PPDU_STATS_USERS_INFO_TLV_MAX_USERS_GET(*(msg_word + 1));
5283*5113495bSYour Name 		} else if (tlv_type == HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV) {
5284*5113495bSYour Name 			max_users = 1;
5285*5113495bSYour Name 		}
5286*5113495bSYour Name 
5287*5113495bSYour Name 		ppdu_info = dp_get_ppdu_desc(pdev, ppdu_id, tlv_type,
5288*5113495bSYour Name 					     tsf_l32, max_users);
5289*5113495bSYour Name 		if (!ppdu_info)
5290*5113495bSYour Name 			return NULL;
5291*5113495bSYour Name 
5292*5113495bSYour Name 		ppdu_info->ppdu_id = ppdu_id;
5293*5113495bSYour Name 		ppdu_info->tlv_bitmap |= (1 << tlv_type);
5294*5113495bSYour Name 
5295*5113495bSYour Name 		dp_process_ppdu_tag(pdev, msg_word, tlv_length, ppdu_info);
5296*5113495bSYour Name 
5297*5113495bSYour Name 		/*
5298*5113495bSYour Name 		 * Increment pdev level tlv count to monitor
5299*5113495bSYour Name 		 * missing TLVs
5300*5113495bSYour Name 		 */
5301*5113495bSYour Name 		mon_pdev->tlv_count++;
5302*5113495bSYour Name 		ppdu_info->last_tlv_cnt = mon_pdev->tlv_count;
5303*5113495bSYour Name 		msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length);
5304*5113495bSYour Name 		length -= (tlv_length);
5305*5113495bSYour Name 	}
5306*5113495bSYour Name 
5307*5113495bSYour Name 	if (!ppdu_info)
5308*5113495bSYour Name 		return NULL;
5309*5113495bSYour Name 
5310*5113495bSYour Name 	mon_pdev->last_ppdu_id = ppdu_id;
5311*5113495bSYour Name 
5312*5113495bSYour Name 	tlv_bitmap_expected = HTT_PPDU_DEFAULT_TLV_BITMAP;
5313*5113495bSYour Name 
5314*5113495bSYour Name 	if (mon_pdev->tx_sniffer_enable || mon_pdev->mcopy_mode ||
5315*5113495bSYour Name 	    mon_pdev->tx_capture_enabled) {
5316*5113495bSYour Name 		if (ppdu_info->is_ampdu)
5317*5113495bSYour Name 			tlv_bitmap_expected =
5318*5113495bSYour Name 				dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap(
5319*5113495bSYour Name 					ppdu_info->tlv_bitmap);
5320*5113495bSYour Name 	}
5321*5113495bSYour Name 
5322*5113495bSYour Name 	ppdu_desc = ppdu_info->ppdu_desc;
5323*5113495bSYour Name 
5324*5113495bSYour Name 	if (!ppdu_desc)
5325*5113495bSYour Name 		return NULL;
5326*5113495bSYour Name 
5327*5113495bSYour Name 	if (ppdu_desc->user[ppdu_desc->last_usr_index].completion_status !=
5328*5113495bSYour Name 	    HTT_PPDU_STATS_USER_STATUS_OK) {
5329*5113495bSYour Name 		tlv_bitmap_expected = tlv_bitmap_expected & 0xFF;
5330*5113495bSYour Name 	}
5331*5113495bSYour Name 
5332*5113495bSYour Name 	/*
5333*5113495bSYour Name 	 * for frame type DATA and BAR, we update stats based on MSDU,
5334*5113495bSYour Name 	 * successful msdu and mpdu are populate from ACK BA STATUS TLV
5335*5113495bSYour Name 	 * which comes out of order. successful mpdu also populated from
5336*5113495bSYour Name 	 * COMPLTN COMMON TLV which comes in order. for every ppdu_info
5337*5113495bSYour Name 	 * we store successful mpdu from both tlv and compare before delivering
5338*5113495bSYour Name 	 * to make sure we received ACK BA STATUS TLV. For some self generated
5339*5113495bSYour Name 	 * frame we won't get ack ba status tlv so no need to wait for
5340*5113495bSYour Name 	 * ack ba status tlv.
5341*5113495bSYour Name 	 */
5342*5113495bSYour Name 	if (ppdu_desc->frame_type != CDP_PPDU_FTYPE_CTRL &&
5343*5113495bSYour Name 	    ppdu_desc->htt_frame_type != HTT_STATS_FTYPE_SGEN_QOS_NULL) {
5344*5113495bSYour Name 		/*
5345*5113495bSYour Name 		 * most of the time bar frame will have duplicate ack ba
5346*5113495bSYour Name 		 * status tlv
5347*5113495bSYour Name 		 */
5348*5113495bSYour Name 		if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_BAR &&
5349*5113495bSYour Name 		    (ppdu_info->compltn_common_tlv != ppdu_info->ack_ba_tlv))
5350*5113495bSYour Name 			return NULL;
5351*5113495bSYour Name 		/*
5352*5113495bSYour Name 		 * For data frame, compltn common tlv should match ack ba status
5353*5113495bSYour Name 		 * tlv and completion status. Reason we are checking first user
5354*5113495bSYour Name 		 * for ofdma, completion seen at next MU BAR frm, for mimo
5355*5113495bSYour Name 		 * only for first user completion will be immediate.
5356*5113495bSYour Name 		 */
5357*5113495bSYour Name 		if (ppdu_desc->frame_type == CDP_PPDU_FTYPE_DATA &&
5358*5113495bSYour Name 		    (ppdu_desc->user[0].completion_status == 0 &&
5359*5113495bSYour Name 		     (ppdu_info->compltn_common_tlv != ppdu_info->ack_ba_tlv)))
5360*5113495bSYour Name 			return NULL;
5361*5113495bSYour Name 	}
5362*5113495bSYour Name 
5363*5113495bSYour Name 	/*
5364*5113495bSYour Name 	 * Once all the TLVs for a given PPDU has been processed,
5365*5113495bSYour Name 	 * return PPDU status to be delivered to higher layer.
5366*5113495bSYour Name 	 * tlv_bitmap_expected can't be available for different frame type.
5367*5113495bSYour Name 	 * But SCHED CMD STATS TLV is the last TLV from the FW for a ppdu.
5368*5113495bSYour Name 	 * apart from ACK BA TLV, FW sends other TLV in sequential order.
5369*5113495bSYour Name 	 * flush tlv comes separate.
5370*5113495bSYour Name 	 */
5371*5113495bSYour Name 	if ((ppdu_info->tlv_bitmap != 0 &&
5372*5113495bSYour Name 	     (ppdu_info->tlv_bitmap &
5373*5113495bSYour Name 	      (1 << HTT_PPDU_STATS_SCH_CMD_STATUS_TLV))) ||
5374*5113495bSYour Name 	    (ppdu_info->tlv_bitmap &
5375*5113495bSYour Name 	     (1 << HTT_PPDU_STATS_USR_COMPLTN_FLUSH_TLV))) {
5376*5113495bSYour Name 		ppdu_info->done = 1;
5377*5113495bSYour Name 		return ppdu_info;
5378*5113495bSYour Name 	}
5379*5113495bSYour Name 
5380*5113495bSYour Name 	return NULL;
5381*5113495bSYour Name }
5382*5113495bSYour Name #endif /* QCA_ENHANCED_STATS_SUPPORT */
5383*5113495bSYour Name 
5384*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
5385*5113495bSYour Name /**
5386*5113495bSYour Name  * dp_tx_ppdu_stats_feat_enable_check() - Check if feature(s) is enabled to
5387*5113495bSYour Name  *			consume stats received from FW via HTT
5388*5113495bSYour Name  * @pdev: Datapath pdev handle
5389*5113495bSYour Name  *
5390*5113495bSYour Name  * Return: void
5391*5113495bSYour Name  */
dp_tx_ppdu_stats_feat_enable_check(struct dp_pdev * pdev)5392*5113495bSYour Name static bool dp_tx_ppdu_stats_feat_enable_check(struct dp_pdev *pdev)
5393*5113495bSYour Name {
5394*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
5395*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
5396*5113495bSYour Name 
5397*5113495bSYour Name 	mon_ops = dp_mon_ops_get(soc);
5398*5113495bSYour Name 	if (mon_ops && mon_ops->mon_ppdu_stats_feat_enable_check)
5399*5113495bSYour Name 		return mon_ops->mon_ppdu_stats_feat_enable_check(pdev);
5400*5113495bSYour Name 	else
5401*5113495bSYour Name 		return false;
5402*5113495bSYour Name }
5403*5113495bSYour Name #endif
5404*5113495bSYour Name 
5405*5113495bSYour Name #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
dp_htt_process_smu_ppdu_stats_tlv(struct dp_soc * soc,qdf_nbuf_t htt_t2h_msg)5406*5113495bSYour Name static void dp_htt_process_smu_ppdu_stats_tlv(struct dp_soc *soc,
5407*5113495bSYour Name 					      qdf_nbuf_t htt_t2h_msg)
5408*5113495bSYour Name {
5409*5113495bSYour Name 	uint32_t length;
5410*5113495bSYour Name 	uint8_t tlv_type;
5411*5113495bSYour Name 	uint32_t tlv_length, tlv_expected_size;
5412*5113495bSYour Name 	uint8_t *tlv_buf;
5413*5113495bSYour Name 
5414*5113495bSYour Name 	uint32_t *msg_word = (uint32_t *)qdf_nbuf_data(htt_t2h_msg);
5415*5113495bSYour Name 
5416*5113495bSYour Name 	length = HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_GET(*msg_word);
5417*5113495bSYour Name 
5418*5113495bSYour Name 	msg_word = msg_word + 4;
5419*5113495bSYour Name 
5420*5113495bSYour Name 	while (length > 0) {
5421*5113495bSYour Name 		tlv_buf = (uint8_t *)msg_word;
5422*5113495bSYour Name 		tlv_type = HTT_STATS_TLV_TAG_GET(*msg_word);
5423*5113495bSYour Name 		tlv_length = HTT_STATS_TLV_LENGTH_GET(*msg_word);
5424*5113495bSYour Name 
5425*5113495bSYour Name 		if (tlv_length == 0)
5426*5113495bSYour Name 			break;
5427*5113495bSYour Name 
5428*5113495bSYour Name 		tlv_length += HTT_TLV_HDR_LEN;
5429*5113495bSYour Name 
5430*5113495bSYour Name 		if (tlv_type == HTT_PPDU_STATS_FOR_SMU_TLV) {
5431*5113495bSYour Name 			tlv_expected_size = sizeof(htt_ppdu_stats_for_smu_tlv);
5432*5113495bSYour Name 
5433*5113495bSYour Name 			if (tlv_length >= tlv_expected_size)
5434*5113495bSYour Name 				dp_wdi_event_handler(
5435*5113495bSYour Name 					WDI_EVENT_PKT_CAPTURE_PPDU_STATS,
5436*5113495bSYour Name 					soc, msg_word, HTT_INVALID_VDEV,
5437*5113495bSYour Name 					WDI_NO_VAL, 0);
5438*5113495bSYour Name 		}
5439*5113495bSYour Name 		msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length);
5440*5113495bSYour Name 		length -= (tlv_length);
5441*5113495bSYour Name 	}
5442*5113495bSYour Name }
5443*5113495bSYour Name #endif
5444*5113495bSYour Name 
5445*5113495bSYour Name #if defined(WDI_EVENT_ENABLE)
5446*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
5447*5113495bSYour Name /**
5448*5113495bSYour Name  * dp_txrx_ppdu_stats_handler() - Function to process HTT PPDU stats from FW
5449*5113495bSYour Name  * @soc: DP SOC handle
5450*5113495bSYour Name  * @pdev_id: pdev id
5451*5113495bSYour Name  * @htt_t2h_msg: HTT message nbuf
5452*5113495bSYour Name  *
5453*5113495bSYour Name  * Return: void
5454*5113495bSYour Name  */
dp_txrx_ppdu_stats_handler(struct dp_soc * soc,uint8_t pdev_id,qdf_nbuf_t htt_t2h_msg)5455*5113495bSYour Name static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
5456*5113495bSYour Name 				       uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg)
5457*5113495bSYour Name {
5458*5113495bSYour Name 	struct dp_pdev *pdev;
5459*5113495bSYour Name 	struct ppdu_info *ppdu_info = NULL;
5460*5113495bSYour Name 	bool free_buf = true;
5461*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
5462*5113495bSYour Name 
5463*5113495bSYour Name 	if (pdev_id >= MAX_PDEV_CNT)
5464*5113495bSYour Name 		return true;
5465*5113495bSYour Name 
5466*5113495bSYour Name 	pdev = soc->pdev_list[pdev_id];
5467*5113495bSYour Name 	if (!pdev)
5468*5113495bSYour Name 		return true;
5469*5113495bSYour Name 
5470*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
5471*5113495bSYour Name 	if (!mon_pdev)
5472*5113495bSYour Name 		return true;
5473*5113495bSYour Name 
5474*5113495bSYour Name 	if (!dp_tx_ppdu_stats_feat_enable_check(pdev))
5475*5113495bSYour Name 		return free_buf;
5476*5113495bSYour Name 
5477*5113495bSYour Name 	qdf_spin_lock_bh(&mon_pdev->ppdu_stats_lock);
5478*5113495bSYour Name 	ppdu_info = dp_htt_process_tlv(pdev, htt_t2h_msg);
5479*5113495bSYour Name 
5480*5113495bSYour Name 	if (mon_pdev->mgmtctrl_frm_info.mgmt_buf) {
5481*5113495bSYour Name 		if (dp_process_ppdu_stats_tx_mgmtctrl_payload_tlv
5482*5113495bSYour Name 		    (pdev, htt_t2h_msg, mon_pdev->mgmtctrl_frm_info.ppdu_id) !=
5483*5113495bSYour Name 		    QDF_STATUS_SUCCESS)
5484*5113495bSYour Name 			free_buf = false;
5485*5113495bSYour Name 	}
5486*5113495bSYour Name 
5487*5113495bSYour Name 	if (ppdu_info)
5488*5113495bSYour Name 		dp_tx_ppdu_desc_deliver(pdev, ppdu_info);
5489*5113495bSYour Name 
5490*5113495bSYour Name 	mon_pdev->mgmtctrl_frm_info.mgmt_buf = NULL;
5491*5113495bSYour Name 	mon_pdev->mgmtctrl_frm_info.mgmt_buf_len = 0;
5492*5113495bSYour Name 	mon_pdev->mgmtctrl_frm_info.ppdu_id = 0;
5493*5113495bSYour Name 
5494*5113495bSYour Name 	qdf_spin_unlock_bh(&mon_pdev->ppdu_stats_lock);
5495*5113495bSYour Name 
5496*5113495bSYour Name 	return free_buf;
5497*5113495bSYour Name }
5498*5113495bSYour Name #elif defined(WLAN_FEATURE_PKT_CAPTURE_V2)
dp_txrx_ppdu_stats_handler(struct dp_soc * soc,uint8_t pdev_id,qdf_nbuf_t htt_t2h_msg)5499*5113495bSYour Name static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
5500*5113495bSYour Name 				       uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg)
5501*5113495bSYour Name {
5502*5113495bSYour Name 	if (wlan_cfg_get_pkt_capture_mode(soc->wlan_cfg_ctx))
5503*5113495bSYour Name 		dp_htt_process_smu_ppdu_stats_tlv(soc, htt_t2h_msg);
5504*5113495bSYour Name 
5505*5113495bSYour Name 	return true;
5506*5113495bSYour Name }
5507*5113495bSYour Name #elif (!defined(REMOVE_PKT_LOG))
dp_txrx_ppdu_stats_handler(struct dp_soc * soc,uint8_t pdev_id,qdf_nbuf_t htt_t2h_msg)5508*5113495bSYour Name static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc,
5509*5113495bSYour Name 				       uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg)
5510*5113495bSYour Name {
5511*5113495bSYour Name 	return true;
5512*5113495bSYour Name }
5513*5113495bSYour Name #endif/* QCA_ENHANCED_STATS_SUPPORT */
5514*5113495bSYour Name #endif
5515*5113495bSYour Name 
5516*5113495bSYour Name #if defined(WDI_EVENT_ENABLE) &&\
5517*5113495bSYour Name 	(defined(QCA_ENHANCED_STATS_SUPPORT) || !defined(REMOVE_PKT_LOG) || \
5518*5113495bSYour Name 	 defined(WLAN_FEATURE_PKT_CAPTURE_V2))
5519*5113495bSYour Name bool
dp_ppdu_stats_ind_handler(struct htt_soc * soc,uint32_t * msg_word,qdf_nbuf_t htt_t2h_msg)5520*5113495bSYour Name dp_ppdu_stats_ind_handler(struct htt_soc *soc,
5521*5113495bSYour Name 			  uint32_t *msg_word,
5522*5113495bSYour Name 			  qdf_nbuf_t htt_t2h_msg)
5523*5113495bSYour Name {
5524*5113495bSYour Name 	u_int8_t pdev_id;
5525*5113495bSYour Name 	u_int8_t target_pdev_id;
5526*5113495bSYour Name 	bool free_buf;
5527*5113495bSYour Name 
5528*5113495bSYour Name 	target_pdev_id = HTT_T2H_PPDU_STATS_PDEV_ID_GET(*msg_word);
5529*5113495bSYour Name 	pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc->dp_soc,
5530*5113495bSYour Name 							 target_pdev_id);
5531*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_LITE_T2H, soc->dp_soc,
5532*5113495bSYour Name 			     htt_t2h_msg, HTT_INVALID_PEER, WDI_NO_VAL,
5533*5113495bSYour Name 			     pdev_id);
5534*5113495bSYour Name 
5535*5113495bSYour Name 	free_buf = dp_txrx_ppdu_stats_handler(soc->dp_soc, pdev_id,
5536*5113495bSYour Name 					      htt_t2h_msg);
5537*5113495bSYour Name 
5538*5113495bSYour Name 	return free_buf;
5539*5113495bSYour Name }
5540*5113495bSYour Name #endif
5541*5113495bSYour Name 
5542*5113495bSYour Name void
dp_mon_set_bsscolor(struct dp_pdev * pdev,uint8_t bsscolor)5543*5113495bSYour Name dp_mon_set_bsscolor(struct dp_pdev *pdev, uint8_t bsscolor)
5544*5113495bSYour Name {
5545*5113495bSYour Name 	pdev->monitor_pdev->rx_mon_recv_status.bsscolor = bsscolor;
5546*5113495bSYour Name }
5547*5113495bSYour Name 
dp_pdev_get_filter_ucast_data(struct cdp_pdev * pdev_handle)5548*5113495bSYour Name bool dp_pdev_get_filter_ucast_data(struct cdp_pdev *pdev_handle)
5549*5113495bSYour Name {
5550*5113495bSYour Name 	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
5551*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
5552*5113495bSYour Name 
5553*5113495bSYour Name 	if ((mon_pdev->fp_data_filter & FILTER_DATA_UCAST) ||
5554*5113495bSYour Name 	    (mon_pdev->mo_data_filter & FILTER_DATA_UCAST))
5555*5113495bSYour Name 		return true;
5556*5113495bSYour Name 
5557*5113495bSYour Name 	return false;
5558*5113495bSYour Name }
5559*5113495bSYour Name 
dp_pdev_get_filter_mcast_data(struct cdp_pdev * pdev_handle)5560*5113495bSYour Name bool dp_pdev_get_filter_mcast_data(struct cdp_pdev *pdev_handle)
5561*5113495bSYour Name {
5562*5113495bSYour Name 	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
5563*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
5564*5113495bSYour Name 
5565*5113495bSYour Name 	if ((mon_pdev->fp_data_filter & FILTER_DATA_MCAST) ||
5566*5113495bSYour Name 	    (mon_pdev->mo_data_filter & FILTER_DATA_MCAST))
5567*5113495bSYour Name 		return true;
5568*5113495bSYour Name 
5569*5113495bSYour Name 	return false;
5570*5113495bSYour Name }
5571*5113495bSYour Name 
dp_pdev_get_filter_non_data(struct cdp_pdev * pdev_handle)5572*5113495bSYour Name bool dp_pdev_get_filter_non_data(struct cdp_pdev *pdev_handle)
5573*5113495bSYour Name {
5574*5113495bSYour Name 	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
5575*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
5576*5113495bSYour Name 
5577*5113495bSYour Name 	if ((mon_pdev->fp_mgmt_filter & FILTER_MGMT_ALL) ||
5578*5113495bSYour Name 	    (mon_pdev->mo_mgmt_filter & FILTER_MGMT_ALL)) {
5579*5113495bSYour Name 		if ((mon_pdev->fp_ctrl_filter & FILTER_CTRL_ALL) ||
5580*5113495bSYour Name 		    (mon_pdev->mo_ctrl_filter & FILTER_CTRL_ALL)) {
5581*5113495bSYour Name 			return true;
5582*5113495bSYour Name 		}
5583*5113495bSYour Name 	}
5584*5113495bSYour Name 
5585*5113495bSYour Name 	return false;
5586*5113495bSYour Name }
5587*5113495bSYour Name 
dp_mon_soc_cfg_init(struct dp_soc * soc)5588*5113495bSYour Name QDF_STATUS dp_mon_soc_cfg_init(struct dp_soc *soc)
5589*5113495bSYour Name {
5590*5113495bSYour Name 	int target_type;
5591*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
5592*5113495bSYour Name 	struct cdp_mon_ops *cdp_ops;
5593*5113495bSYour Name 
5594*5113495bSYour Name 	cdp_ops = dp_mon_cdp_ops_get(soc);
5595*5113495bSYour Name 	target_type = hal_get_target_type(soc->hal_soc);
5596*5113495bSYour Name 	switch (target_type) {
5597*5113495bSYour Name 	case TARGET_TYPE_QCA6290:
5598*5113495bSYour Name 	case TARGET_TYPE_QCA6390:
5599*5113495bSYour Name 	case TARGET_TYPE_QCA6490:
5600*5113495bSYour Name 	case TARGET_TYPE_QCA6750:
5601*5113495bSYour Name 	case TARGET_TYPE_KIWI:
5602*5113495bSYour Name 	case TARGET_TYPE_MANGO:
5603*5113495bSYour Name 	case TARGET_TYPE_PEACH:
5604*5113495bSYour Name 	case TARGET_TYPE_WCN6450:
5605*5113495bSYour Name 		/* do nothing */
5606*5113495bSYour Name 		break;
5607*5113495bSYour Name 	case TARGET_TYPE_QCA8074:
5608*5113495bSYour Name 		wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx,
5609*5113495bSYour Name 							   MON_BUF_MIN_ENTRIES);
5610*5113495bSYour Name 		break;
5611*5113495bSYour Name 	case TARGET_TYPE_QCA8074V2:
5612*5113495bSYour Name 	case TARGET_TYPE_QCA6018:
5613*5113495bSYour Name 	case TARGET_TYPE_QCA9574:
5614*5113495bSYour Name 		wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx,
5615*5113495bSYour Name 							   MON_BUF_MIN_ENTRIES);
5616*5113495bSYour Name 		mon_soc->hw_nac_monitor_support = 1;
5617*5113495bSYour Name 		break;
5618*5113495bSYour Name 	case TARGET_TYPE_QCN9000:
5619*5113495bSYour Name 		wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx,
5620*5113495bSYour Name 							   MON_BUF_MIN_ENTRIES);
5621*5113495bSYour Name 		mon_soc->hw_nac_monitor_support = 1;
5622*5113495bSYour Name 		if (cfg_get(soc->ctrl_psoc, CFG_DP_FULL_MON_MODE)) {
5623*5113495bSYour Name 			if (cdp_ops  && cdp_ops->config_full_mon_mode)
5624*5113495bSYour Name 				cdp_ops->config_full_mon_mode((struct cdp_soc_t *)soc, 1);
5625*5113495bSYour Name 		}
5626*5113495bSYour Name 		break;
5627*5113495bSYour Name 	case TARGET_TYPE_QCA5018:
5628*5113495bSYour Name 	case TARGET_TYPE_QCN6122:
5629*5113495bSYour Name 	case TARGET_TYPE_QCN9160:
5630*5113495bSYour Name 		wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx,
5631*5113495bSYour Name 							   MON_BUF_MIN_ENTRIES);
5632*5113495bSYour Name 		mon_soc->hw_nac_monitor_support = 1;
5633*5113495bSYour Name 		break;
5634*5113495bSYour Name 	case TARGET_TYPE_QCN9224:
5635*5113495bSYour Name 	case TARGET_TYPE_QCA5332:
5636*5113495bSYour Name 	case TARGET_TYPE_QCN6432:
5637*5113495bSYour Name 		wlan_cfg_set_mon_delayed_replenish_entries(soc->wlan_cfg_ctx,
5638*5113495bSYour Name 							   MON_BUF_MIN_ENTRIES);
5639*5113495bSYour Name 		mon_soc->hw_nac_monitor_support = 1;
5640*5113495bSYour Name 		mon_soc->monitor_mode_v2 = 1;
5641*5113495bSYour Name 		break;
5642*5113495bSYour Name 	default:
5643*5113495bSYour Name 		dp_mon_info("%s: Unknown tgt type %d\n", __func__, target_type);
5644*5113495bSYour Name 		qdf_assert_always(0);
5645*5113495bSYour Name 		break;
5646*5113495bSYour Name 	}
5647*5113495bSYour Name 
5648*5113495bSYour Name 	dp_mon_info("hw_nac_monitor_support = %d",
5649*5113495bSYour Name 		    mon_soc->hw_nac_monitor_support);
5650*5113495bSYour Name 
5651*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5652*5113495bSYour Name }
5653*5113495bSYour Name 
5654*5113495bSYour Name /**
5655*5113495bSYour Name  * dp_mon_pdev_per_target_config() - Target specific monitor pdev configuration
5656*5113495bSYour Name  * @pdev: PDEV handle [Should be valid]
5657*5113495bSYour Name  *
5658*5113495bSYour Name  * Return: None
5659*5113495bSYour Name  */
dp_mon_pdev_per_target_config(struct dp_pdev * pdev)5660*5113495bSYour Name static void dp_mon_pdev_per_target_config(struct dp_pdev *pdev)
5661*5113495bSYour Name {
5662*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
5663*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
5664*5113495bSYour Name 	int target_type;
5665*5113495bSYour Name 
5666*5113495bSYour Name 	target_type = hal_get_target_type(soc->hal_soc);
5667*5113495bSYour Name 	switch (target_type) {
5668*5113495bSYour Name 	case TARGET_TYPE_KIWI:
5669*5113495bSYour Name 	case TARGET_TYPE_QCN9224:
5670*5113495bSYour Name 	case TARGET_TYPE_QCA5332:
5671*5113495bSYour Name 	case TARGET_TYPE_QCN6432:
5672*5113495bSYour Name 	case TARGET_TYPE_MANGO:
5673*5113495bSYour Name 		mon_pdev->is_tlv_hdr_64_bit = true;
5674*5113495bSYour Name 		mon_pdev->tlv_hdr_size = HAL_RX_TLV64_HDR_SIZE;
5675*5113495bSYour Name 		break;
5676*5113495bSYour Name 	case TARGET_TYPE_PEACH:
5677*5113495bSYour Name 	default:
5678*5113495bSYour Name 		mon_pdev->is_tlv_hdr_64_bit = false;
5679*5113495bSYour Name 		mon_pdev->tlv_hdr_size = HAL_RX_TLV32_HDR_SIZE;
5680*5113495bSYour Name 		break;
5681*5113495bSYour Name 	}
5682*5113495bSYour Name }
5683*5113495bSYour Name 
5684*5113495bSYour Name static
dp_mon_rings_alloc(struct dp_pdev * pdev)5685*5113495bSYour Name QDF_STATUS dp_mon_rings_alloc(struct dp_pdev *pdev)
5686*5113495bSYour Name {
5687*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5688*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
5689*5113495bSYour Name 
5690*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
5691*5113495bSYour Name 	if (!mon_ops) {
5692*5113495bSYour Name 		dp_mon_err("mon_ops is NULL");
5693*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5694*5113495bSYour Name 	}
5695*5113495bSYour Name 
5696*5113495bSYour Name 	if (mon_ops->mon_rings_alloc[0]) {
5697*5113495bSYour Name 		status = mon_ops->mon_rings_alloc[0](pdev);
5698*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
5699*5113495bSYour Name 			dp_mon_err("error: %d", status);
5700*5113495bSYour Name 			goto error;
5701*5113495bSYour Name 		}
5702*5113495bSYour Name 	}
5703*5113495bSYour Name 
5704*5113495bSYour Name 	if (mon_ops->mon_rings_alloc[1]) {
5705*5113495bSYour Name 		status = mon_ops->mon_rings_alloc[1](pdev);
5706*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
5707*5113495bSYour Name 			dp_mon_err("error: %d", status);
5708*5113495bSYour Name 			goto error;
5709*5113495bSYour Name 		}
5710*5113495bSYour Name 	}
5711*5113495bSYour Name 
5712*5113495bSYour Name error:
5713*5113495bSYour Name 	return status;
5714*5113495bSYour Name }
5715*5113495bSYour Name 
5716*5113495bSYour Name static
dp_mon_rings_free(struct dp_pdev * pdev)5717*5113495bSYour Name void dp_mon_rings_free(struct dp_pdev *pdev)
5718*5113495bSYour Name {
5719*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
5720*5113495bSYour Name 
5721*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
5722*5113495bSYour Name 	if (!mon_ops) {
5723*5113495bSYour Name 		dp_mon_err("mon_ops is NULL");
5724*5113495bSYour Name 		return;
5725*5113495bSYour Name 	}
5726*5113495bSYour Name 
5727*5113495bSYour Name 	if (mon_ops->mon_rings_free[0])
5728*5113495bSYour Name 		mon_ops->mon_rings_free[0](pdev);
5729*5113495bSYour Name 
5730*5113495bSYour Name 	if (mon_ops->mon_rings_free[1])
5731*5113495bSYour Name 		mon_ops->mon_rings_free[1](pdev);
5732*5113495bSYour Name }
5733*5113495bSYour Name 
5734*5113495bSYour Name static
dp_mon_rings_init(struct dp_pdev * pdev)5735*5113495bSYour Name QDF_STATUS dp_mon_rings_init(struct dp_pdev *pdev)
5736*5113495bSYour Name {
5737*5113495bSYour Name 	QDF_STATUS status = QDF_STATUS_SUCCESS;
5738*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
5739*5113495bSYour Name 
5740*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
5741*5113495bSYour Name 	if (!mon_ops) {
5742*5113495bSYour Name 		dp_mon_err("mon_ops is NULL");
5743*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5744*5113495bSYour Name 	}
5745*5113495bSYour Name 
5746*5113495bSYour Name 	if (mon_ops->mon_rings_init[0]) {
5747*5113495bSYour Name 		status = mon_ops->mon_rings_init[0](pdev);
5748*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
5749*5113495bSYour Name 			dp_mon_err("error: %d", status);
5750*5113495bSYour Name 			goto error;
5751*5113495bSYour Name 		}
5752*5113495bSYour Name 	}
5753*5113495bSYour Name 
5754*5113495bSYour Name 	if (mon_ops->mon_rings_init[1]) {
5755*5113495bSYour Name 		status = mon_ops->mon_rings_init[1](pdev);
5756*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status)) {
5757*5113495bSYour Name 			dp_mon_err("error: %d", status);
5758*5113495bSYour Name 			goto error;
5759*5113495bSYour Name 		}
5760*5113495bSYour Name 	}
5761*5113495bSYour Name 
5762*5113495bSYour Name error:
5763*5113495bSYour Name 	return status;
5764*5113495bSYour Name }
5765*5113495bSYour Name 
5766*5113495bSYour Name static
dp_mon_rings_deinit(struct dp_pdev * pdev)5767*5113495bSYour Name void dp_mon_rings_deinit(struct dp_pdev *pdev)
5768*5113495bSYour Name {
5769*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
5770*5113495bSYour Name 
5771*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
5772*5113495bSYour Name 	if (!mon_ops) {
5773*5113495bSYour Name 		dp_mon_err("mon_ops is NULL");
5774*5113495bSYour Name 		return;
5775*5113495bSYour Name 	}
5776*5113495bSYour Name 
5777*5113495bSYour Name 	if (mon_ops->mon_rings_deinit[0])
5778*5113495bSYour Name 		mon_ops->mon_rings_deinit[0](pdev);
5779*5113495bSYour Name 
5780*5113495bSYour Name 	if (mon_ops->mon_rings_deinit[1])
5781*5113495bSYour Name 		mon_ops->mon_rings_deinit[1](pdev);
5782*5113495bSYour Name }
5783*5113495bSYour Name 
dp_mon_pdev_attach(struct dp_pdev * pdev)5784*5113495bSYour Name QDF_STATUS dp_mon_pdev_attach(struct dp_pdev *pdev)
5785*5113495bSYour Name {
5786*5113495bSYour Name 	struct dp_soc *soc;
5787*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
5788*5113495bSYour Name 	struct dp_mon_ops *mon_ops;
5789*5113495bSYour Name 	qdf_size_t mon_pdev_context_size;
5790*5113495bSYour Name 
5791*5113495bSYour Name 	if (!pdev) {
5792*5113495bSYour Name 		dp_mon_err("pdev is NULL");
5793*5113495bSYour Name 		goto fail0;
5794*5113495bSYour Name 	}
5795*5113495bSYour Name 
5796*5113495bSYour Name 	soc = pdev->soc;
5797*5113495bSYour Name 
5798*5113495bSYour Name 	mon_pdev_context_size = soc->arch_ops.txrx_get_mon_context_size(DP_CONTEXT_TYPE_MON_PDEV);
5799*5113495bSYour Name 	mon_pdev = dp_context_alloc_mem(soc, DP_MON_PDEV_TYPE, mon_pdev_context_size);
5800*5113495bSYour Name 	if (!mon_pdev) {
5801*5113495bSYour Name 		dp_mon_err("%pK: MONITOR pdev allocation failed", pdev);
5802*5113495bSYour Name 		goto fail0;
5803*5113495bSYour Name 	}
5804*5113495bSYour Name 
5805*5113495bSYour Name 	pdev->monitor_pdev = mon_pdev;
5806*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
5807*5113495bSYour Name 	if (!mon_ops) {
5808*5113495bSYour Name 		dp_mon_err("%pK: Invalid monitor ops", pdev);
5809*5113495bSYour Name 		goto fail1;
5810*5113495bSYour Name 	}
5811*5113495bSYour Name 
5812*5113495bSYour Name 	if (mon_ops->mon_pdev_alloc) {
5813*5113495bSYour Name 		if (mon_ops->mon_pdev_alloc(pdev)) {
5814*5113495bSYour Name 			dp_mon_err("%pK: MONITOR pdev alloc failed", pdev);
5815*5113495bSYour Name 			goto fail1;
5816*5113495bSYour Name 		}
5817*5113495bSYour Name 	}
5818*5113495bSYour Name 
5819*5113495bSYour Name 	if (dp_mon_rings_alloc(pdev)) {
5820*5113495bSYour Name 		dp_mon_err("%pK: MONITOR rings setup failed", pdev);
5821*5113495bSYour Name 		goto fail2;
5822*5113495bSYour Name 	}
5823*5113495bSYour Name 
5824*5113495bSYour Name 	/* Rx monitor mode specific init */
5825*5113495bSYour Name 	if (mon_ops->rx_mon_desc_pool_alloc) {
5826*5113495bSYour Name 		if (mon_ops->rx_mon_desc_pool_alloc(pdev)) {
5827*5113495bSYour Name 			dp_mon_err("%pK: dp_rx_pdev_mon_attach failed", pdev);
5828*5113495bSYour Name 			goto fail3;
5829*5113495bSYour Name 		}
5830*5113495bSYour Name 	}
5831*5113495bSYour Name 
5832*5113495bSYour Name 	if (mon_ops->mon_rx_ppdu_info_cache_create) {
5833*5113495bSYour Name 		if (mon_ops->mon_rx_ppdu_info_cache_create(pdev)) {
5834*5113495bSYour Name 			dp_mon_err("%pK: dp_rx_pdev_mon_attach failed", pdev);
5835*5113495bSYour Name 			goto fail4;
5836*5113495bSYour Name 		}
5837*5113495bSYour Name 	}
5838*5113495bSYour Name 	pdev->monitor_pdev = mon_pdev;
5839*5113495bSYour Name 	dp_mon_pdev_per_target_config(pdev);
5840*5113495bSYour Name 
5841*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5842*5113495bSYour Name fail4:
5843*5113495bSYour Name 	if (mon_ops->rx_mon_desc_pool_free)
5844*5113495bSYour Name 		mon_ops->rx_mon_desc_pool_free(pdev);
5845*5113495bSYour Name fail3:
5846*5113495bSYour Name 	dp_mon_rings_free(pdev);
5847*5113495bSYour Name fail2:
5848*5113495bSYour Name 	if (mon_ops->mon_pdev_free)
5849*5113495bSYour Name 		mon_ops->mon_pdev_free(pdev);
5850*5113495bSYour Name fail1:
5851*5113495bSYour Name 	pdev->monitor_pdev = NULL;
5852*5113495bSYour Name 	dp_context_free_mem(soc, DP_MON_PDEV_TYPE, mon_pdev);
5853*5113495bSYour Name fail0:
5854*5113495bSYour Name 	return QDF_STATUS_E_NOMEM;
5855*5113495bSYour Name }
5856*5113495bSYour Name 
dp_mon_pdev_detach(struct dp_pdev * pdev)5857*5113495bSYour Name QDF_STATUS dp_mon_pdev_detach(struct dp_pdev *pdev)
5858*5113495bSYour Name {
5859*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
5860*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
5861*5113495bSYour Name 
5862*5113495bSYour Name 	if (!pdev) {
5863*5113495bSYour Name 		dp_mon_err("pdev is NULL");
5864*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5865*5113495bSYour Name 	}
5866*5113495bSYour Name 
5867*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
5868*5113495bSYour Name 	if (!mon_pdev) {
5869*5113495bSYour Name 		dp_mon_err("Monitor pdev is NULL");
5870*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5871*5113495bSYour Name 	}
5872*5113495bSYour Name 
5873*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
5874*5113495bSYour Name 	if (!mon_ops) {
5875*5113495bSYour Name 		dp_mon_err("Monitor ops is NULL");
5876*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5877*5113495bSYour Name 	}
5878*5113495bSYour Name 
5879*5113495bSYour Name 	if (mon_ops->mon_rx_ppdu_info_cache_destroy)
5880*5113495bSYour Name 		mon_ops->mon_rx_ppdu_info_cache_destroy(pdev);
5881*5113495bSYour Name 	if (mon_ops->rx_mon_desc_pool_free)
5882*5113495bSYour Name 		mon_ops->rx_mon_desc_pool_free(pdev);
5883*5113495bSYour Name 	dp_mon_rings_free(pdev);
5884*5113495bSYour Name 	if (mon_ops->mon_pdev_free)
5885*5113495bSYour Name 		mon_ops->mon_pdev_free(pdev);
5886*5113495bSYour Name 
5887*5113495bSYour Name 	dp_context_free_mem(pdev->soc, DP_MON_PDEV_TYPE, mon_pdev);
5888*5113495bSYour Name 	pdev->monitor_pdev = NULL;
5889*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5890*5113495bSYour Name }
5891*5113495bSYour Name 
5892*5113495bSYour Name #ifdef WLAN_TX_PKT_CAPTURE_ENH
dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops * mon_ops)5893*5113495bSYour Name void dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops *mon_ops)
5894*5113495bSYour Name {
5895*5113495bSYour Name 	mon_ops->mon_tx_ppdu_stats_attach = dp_tx_ppdu_stats_attach_1_0;
5896*5113495bSYour Name 	mon_ops->mon_tx_ppdu_stats_detach = dp_tx_ppdu_stats_detach_1_0;
5897*5113495bSYour Name 	mon_ops->mon_peer_tx_capture_filter_check =
5898*5113495bSYour Name 				dp_peer_tx_capture_filter_check_1_0;
5899*5113495bSYour Name }
5900*5113495bSYour Name #elif defined(WLAN_TX_PKT_CAPTURE_ENH_BE) && defined(WLAN_FEATURE_LOCAL_PKT_CAPTURE)
dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops * mon_ops)5901*5113495bSYour Name void dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops *mon_ops)
5902*5113495bSYour Name {
5903*5113495bSYour Name 	mon_ops->mon_tx_ppdu_stats_attach = dp_tx_ppdu_stats_attach_2_0;
5904*5113495bSYour Name 	mon_ops->mon_tx_ppdu_stats_detach = dp_tx_ppdu_stats_detach_2_0;
5905*5113495bSYour Name 	mon_ops->mon_peer_tx_capture_filter_check = NULL;
5906*5113495bSYour Name }
5907*5113495bSYour Name #elif (defined(WIFI_MONITOR_SUPPORT) && !defined(WLAN_TX_PKT_CAPTURE_ENH))
dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops * mon_ops)5908*5113495bSYour Name void dp_mon_register_tx_pkt_enh_ops_1_0(struct dp_mon_ops *mon_ops)
5909*5113495bSYour Name {
5910*5113495bSYour Name 	mon_ops->mon_tx_ppdu_stats_attach = NULL;
5911*5113495bSYour Name 	mon_ops->mon_tx_ppdu_stats_detach = NULL;
5912*5113495bSYour Name 	mon_ops->mon_peer_tx_capture_filter_check = NULL;
5913*5113495bSYour Name }
5914*5113495bSYour Name #endif
5915*5113495bSYour Name 
5916*5113495bSYour Name #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
5917*5113495bSYour Name #if !defined(DISABLE_MON_CONFIG)
dp_mon_config_register_ops(struct dp_mon_ops * mon_ops)5918*5113495bSYour Name static inline void dp_mon_config_register_ops(struct dp_mon_ops *mon_ops)
5919*5113495bSYour Name {
5920*5113495bSYour Name 	mon_ops->mon_pdev_htt_srng_setup[0] = dp_mon_htt_srng_setup_1_0;
5921*5113495bSYour Name 	mon_ops->mon_pdev_htt_srng_setup[1] = dp_mon_pdev_htt_srng_setup_2_0;
5922*5113495bSYour Name 	mon_ops->mon_soc_htt_srng_setup = dp_mon_soc_htt_srng_setup_2_0;
5923*5113495bSYour Name }
5924*5113495bSYour Name #else
dp_mon_config_register_ops(struct dp_mon_ops * mon_ops)5925*5113495bSYour Name static inline void dp_mon_config_register_ops(struct dp_mon_ops *mon_ops)
5926*5113495bSYour Name {
5927*5113495bSYour Name }
5928*5113495bSYour Name #endif
5929*5113495bSYour Name 
dp_mon_register_lpc_ops_1_0(struct dp_mon_ops * mon_ops)5930*5113495bSYour Name void dp_mon_register_lpc_ops_1_0(struct dp_mon_ops *mon_ops)
5931*5113495bSYour Name {
5932*5113495bSYour Name 	mon_ops->mon_soc_attach[0] = NULL;
5933*5113495bSYour Name 	mon_ops->mon_soc_detach[0] = NULL;
5934*5113495bSYour Name 	mon_ops->mon_soc_init[0] = NULL;
5935*5113495bSYour Name 	mon_ops->mon_soc_deinit[0] = NULL;
5936*5113495bSYour Name 	mon_ops->mon_soc_attach[1] = dp_mon_soc_attach_2_0;
5937*5113495bSYour Name 	mon_ops->mon_soc_detach[1] = dp_mon_soc_detach_2_0;
5938*5113495bSYour Name 	mon_ops->mon_soc_init[1] = dp_mon_soc_init_2_0;
5939*5113495bSYour Name 	mon_ops->mon_soc_deinit[1] = dp_mon_soc_deinit_2_0;
5940*5113495bSYour Name 
5941*5113495bSYour Name 	dp_mon_config_register_ops(mon_ops);
5942*5113495bSYour Name 
5943*5113495bSYour Name 	mon_ops->mon_rings_alloc[0] = dp_mon_rings_alloc_1_0;
5944*5113495bSYour Name 	mon_ops->mon_rings_free[0] = dp_mon_rings_free_1_0;
5945*5113495bSYour Name 	mon_ops->mon_rings_init[0] = dp_mon_rings_init_1_0;
5946*5113495bSYour Name 	mon_ops->mon_rings_deinit[0] = dp_mon_rings_deinit_1_0;
5947*5113495bSYour Name 	mon_ops->mon_rings_alloc[1] = dp_pdev_mon_rings_alloc_2_0;
5948*5113495bSYour Name 	mon_ops->mon_rings_free[1] = dp_pdev_mon_rings_free_2_0;
5949*5113495bSYour Name 	mon_ops->mon_rings_init[1] = dp_pdev_mon_rings_init_2_0;
5950*5113495bSYour Name 	mon_ops->mon_rings_deinit[1] = dp_pdev_mon_rings_deinit_2_0;
5951*5113495bSYour Name 
5952*5113495bSYour Name 	mon_ops->mon_filter_setup_tx_mon_mode =
5953*5113495bSYour Name 				dp_mon_filter_setup_local_pkt_capture_tx;
5954*5113495bSYour Name 	mon_ops->mon_filter_reset_tx_mon_mode =
5955*5113495bSYour Name 				dp_mon_filter_reset_local_pkt_capture_tx;
5956*5113495bSYour Name 	mon_ops->tx_mon_filter_update = dp_tx_mon_filter_update_2_0;
5957*5113495bSYour Name 
5958*5113495bSYour Name 	mon_ops->rx_hdr_length_set = dp_rx_mon_hdr_length_set;
5959*5113495bSYour Name 	dp_mon_register_tx_pkt_enh_ops_1_0(mon_ops);
5960*5113495bSYour Name }
5961*5113495bSYour Name #else
5962*5113495bSYour Name #if !defined(DISABLE_MON_CONFIG)
dp_mon_config_register_ops(struct dp_mon_ops * mon_ops)5963*5113495bSYour Name static inline void dp_mon_config_register_ops(struct dp_mon_ops *mon_ops)
5964*5113495bSYour Name {
5965*5113495bSYour Name 	mon_ops->mon_pdev_htt_srng_setup[0] = dp_mon_htt_srng_setup_1_0;
5966*5113495bSYour Name 	mon_ops->mon_pdev_htt_srng_setup[1] = NULL;
5967*5113495bSYour Name 	mon_ops->mon_soc_htt_srng_setup = NULL;
5968*5113495bSYour Name }
5969*5113495bSYour Name #else
dp_mon_config_register_ops(struct dp_mon_ops * mon_ops)5970*5113495bSYour Name static inline void dp_mon_config_register_ops(struct dp_mon_ops *mon_ops)
5971*5113495bSYour Name {
5972*5113495bSYour Name }
5973*5113495bSYour Name #endif
5974*5113495bSYour Name 
dp_mon_register_lpc_ops_1_0(struct dp_mon_ops * mon_ops)5975*5113495bSYour Name void dp_mon_register_lpc_ops_1_0(struct dp_mon_ops *mon_ops)
5976*5113495bSYour Name {
5977*5113495bSYour Name 	mon_ops->mon_soc_attach[0] = NULL;
5978*5113495bSYour Name 	mon_ops->mon_soc_detach[0] = NULL;
5979*5113495bSYour Name 	mon_ops->mon_soc_init[0] = NULL;
5980*5113495bSYour Name 	mon_ops->mon_soc_deinit[0] = NULL;
5981*5113495bSYour Name 	mon_ops->mon_soc_attach[1] = NULL;
5982*5113495bSYour Name 	mon_ops->mon_soc_detach[1] = NULL;
5983*5113495bSYour Name 	mon_ops->mon_soc_init[1] = NULL;
5984*5113495bSYour Name 	mon_ops->mon_soc_deinit[1] = NULL;
5985*5113495bSYour Name 
5986*5113495bSYour Name 	dp_mon_config_register_ops(mon_ops);
5987*5113495bSYour Name 
5988*5113495bSYour Name 	mon_ops->mon_rings_alloc[0] = dp_mon_rings_alloc_1_0;
5989*5113495bSYour Name 	mon_ops->mon_rings_free[0] = dp_mon_rings_free_1_0;
5990*5113495bSYour Name 	mon_ops->mon_rings_init[0] = dp_mon_rings_init_1_0;
5991*5113495bSYour Name 	mon_ops->mon_rings_deinit[0] = dp_mon_rings_deinit_1_0;
5992*5113495bSYour Name 	mon_ops->mon_rings_alloc[1] = NULL;
5993*5113495bSYour Name 	mon_ops->mon_rings_free[1] = NULL;
5994*5113495bSYour Name 	mon_ops->mon_rings_init[1] = NULL;
5995*5113495bSYour Name 	mon_ops->mon_rings_deinit[1] = NULL;
5996*5113495bSYour Name 
5997*5113495bSYour Name 	mon_ops->mon_filter_setup_tx_mon_mode = NULL;
5998*5113495bSYour Name 	mon_ops->mon_filter_reset_tx_mon_mode = NULL;
5999*5113495bSYour Name 	mon_ops->tx_mon_filter_update = NULL;
6000*5113495bSYour Name 
6001*5113495bSYour Name 	mon_ops->rx_hdr_length_set = NULL;
6002*5113495bSYour Name 	dp_mon_register_tx_pkt_enh_ops_1_0(mon_ops);
6003*5113495bSYour Name }
6004*5113495bSYour Name #endif
6005*5113495bSYour Name 
dp_mon_pdev_init(struct dp_pdev * pdev)6006*5113495bSYour Name QDF_STATUS dp_mon_pdev_init(struct dp_pdev *pdev)
6007*5113495bSYour Name {
6008*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
6009*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
6010*5113495bSYour Name 
6011*5113495bSYour Name 	if (!pdev) {
6012*5113495bSYour Name 		dp_mon_err("pdev is NULL");
6013*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6014*5113495bSYour Name 	}
6015*5113495bSYour Name 
6016*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
6017*5113495bSYour Name 
6018*5113495bSYour Name 	mon_pdev->invalid_mon_peer = qdf_mem_malloc(sizeof(struct dp_mon_peer));
6019*5113495bSYour Name 	if (!mon_pdev->invalid_mon_peer) {
6020*5113495bSYour Name 		dp_mon_err("%pK: Memory allocation failed for invalid "
6021*5113495bSYour Name 			   "monitor peer", pdev);
6022*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6023*5113495bSYour Name 	}
6024*5113495bSYour Name 
6025*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
6026*5113495bSYour Name 	if (!mon_ops) {
6027*5113495bSYour Name 		dp_mon_err("Monitor ops is NULL");
6028*5113495bSYour Name 		goto fail0;
6029*5113495bSYour Name 	}
6030*5113495bSYour Name 
6031*5113495bSYour Name 	mon_pdev->filter = dp_mon_filter_alloc(mon_pdev);
6032*5113495bSYour Name 	if (!mon_pdev->filter) {
6033*5113495bSYour Name 		dp_mon_err("%pK: Memory allocation failed for monitor filter",
6034*5113495bSYour Name 			   pdev);
6035*5113495bSYour Name 		goto fail0;
6036*5113495bSYour Name 	}
6037*5113495bSYour Name 
6038*5113495bSYour Name 	if (mon_ops->tx_mon_filter_alloc) {
6039*5113495bSYour Name 		if (mon_ops->tx_mon_filter_alloc(pdev)) {
6040*5113495bSYour Name 			dp_mon_err("%pK: Memory allocation failed for tx monitor "
6041*5113495bSYour Name 				   "filter", pdev);
6042*5113495bSYour Name 			goto fail1;
6043*5113495bSYour Name 		}
6044*5113495bSYour Name 	}
6045*5113495bSYour Name 
6046*5113495bSYour Name 	qdf_spinlock_create(&mon_pdev->ppdu_stats_lock);
6047*5113495bSYour Name 	qdf_spinlock_create(&mon_pdev->neighbour_peer_mutex);
6048*5113495bSYour Name 	mon_pdev->monitor_configured = false;
6049*5113495bSYour Name 	mon_pdev->mon_chan_band = REG_BAND_UNKNOWN;
6050*5113495bSYour Name 
6051*5113495bSYour Name 	TAILQ_INIT(&mon_pdev->neighbour_peers_list);
6052*5113495bSYour Name 	mon_pdev->neighbour_peers_added = false;
6053*5113495bSYour Name 	mon_pdev->monitor_configured = false;
6054*5113495bSYour Name 
6055*5113495bSYour Name 	dp_mon_pdev_filter_init(mon_pdev);
6056*5113495bSYour Name 	/*
6057*5113495bSYour Name 	 * initialize ppdu tlv list
6058*5113495bSYour Name 	 */
6059*5113495bSYour Name 	TAILQ_INIT(&mon_pdev->ppdu_info_list);
6060*5113495bSYour Name 	TAILQ_INIT(&mon_pdev->sched_comp_ppdu_list);
6061*5113495bSYour Name 
6062*5113495bSYour Name 	mon_pdev->list_depth = 0;
6063*5113495bSYour Name 	mon_pdev->tlv_count = 0;
6064*5113495bSYour Name 	/* initlialize cal client timer */
6065*5113495bSYour Name 	dp_cal_client_attach(&mon_pdev->cal_client_ctx,
6066*5113495bSYour Name 			     dp_pdev_to_cdp_pdev(pdev),
6067*5113495bSYour Name 			     pdev->soc->osdev,
6068*5113495bSYour Name 			     &dp_iterate_update_peer_list);
6069*5113495bSYour Name 	if (dp_htt_ppdu_stats_attach(pdev) != QDF_STATUS_SUCCESS)
6070*5113495bSYour Name 		goto fail2;
6071*5113495bSYour Name 
6072*5113495bSYour Name 	if (mon_ops->mon_lite_mon_alloc) {
6073*5113495bSYour Name 		if (mon_ops->mon_lite_mon_alloc(pdev) != QDF_STATUS_SUCCESS) {
6074*5113495bSYour Name 			dp_mon_err("%pK: lite mon alloc failed", pdev);
6075*5113495bSYour Name 			goto fail3;
6076*5113495bSYour Name 		}
6077*5113495bSYour Name 	}
6078*5113495bSYour Name 
6079*5113495bSYour Name 	if (dp_mon_rings_init(pdev)) {
6080*5113495bSYour Name 		dp_mon_err("%pK: MONITOR rings setup failed", pdev);
6081*5113495bSYour Name 		goto fail4;
6082*5113495bSYour Name 	}
6083*5113495bSYour Name 
6084*5113495bSYour Name 	/* initialize sw monitor rx descriptors */
6085*5113495bSYour Name 	if (mon_ops->rx_mon_desc_pool_init)
6086*5113495bSYour Name 		mon_ops->rx_mon_desc_pool_init(pdev);
6087*5113495bSYour Name 
6088*5113495bSYour Name 	/* allocate buffers and replenish the monitor RxDMA ring */
6089*5113495bSYour Name 	if (mon_ops->rx_mon_buffers_alloc) {
6090*5113495bSYour Name 		if (mon_ops->rx_mon_buffers_alloc(pdev)) {
6091*5113495bSYour Name 			dp_mon_err("%pK: rx mon buffers alloc failed", pdev);
6092*5113495bSYour Name 			goto fail5;
6093*5113495bSYour Name 		}
6094*5113495bSYour Name 	}
6095*5113495bSYour Name 
6096*5113495bSYour Name 	/* attach monitor function */
6097*5113495bSYour Name 	dp_monitor_tx_ppdu_stats_attach(pdev);
6098*5113495bSYour Name 
6099*5113495bSYour Name 	/* mon pdev extended init */
6100*5113495bSYour Name 	if (mon_ops->mon_pdev_ext_init)
6101*5113495bSYour Name 		mon_ops->mon_pdev_ext_init(pdev);
6102*5113495bSYour Name 
6103*5113495bSYour Name 	if (mon_ops->mon_rx_pdev_tlv_logger_init)
6104*5113495bSYour Name 		mon_ops->mon_rx_pdev_tlv_logger_init(pdev);
6105*5113495bSYour Name 
6106*5113495bSYour Name 	mon_pdev->is_dp_mon_pdev_initialized = true;
6107*5113495bSYour Name 	dp_mon_set_local_pkt_capture_running(mon_pdev, false);
6108*5113495bSYour Name 
6109*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6110*5113495bSYour Name 
6111*5113495bSYour Name fail5:
6112*5113495bSYour Name 	if (mon_ops->rx_mon_desc_pool_deinit)
6113*5113495bSYour Name 		mon_ops->rx_mon_desc_pool_deinit(pdev);
6114*5113495bSYour Name 
6115*5113495bSYour Name 	dp_mon_rings_deinit(pdev);
6116*5113495bSYour Name fail4:
6117*5113495bSYour Name 	if (mon_ops->mon_lite_mon_dealloc)
6118*5113495bSYour Name 		mon_ops->mon_lite_mon_dealloc(pdev);
6119*5113495bSYour Name fail3:
6120*5113495bSYour Name 	dp_htt_ppdu_stats_detach(pdev);
6121*5113495bSYour Name fail2:
6122*5113495bSYour Name 	qdf_spinlock_destroy(&mon_pdev->neighbour_peer_mutex);
6123*5113495bSYour Name 	qdf_spinlock_destroy(&mon_pdev->ppdu_stats_lock);
6124*5113495bSYour Name 	if (mon_ops->tx_mon_filter_dealloc)
6125*5113495bSYour Name 		mon_ops->tx_mon_filter_dealloc(pdev);
6126*5113495bSYour Name fail1:
6127*5113495bSYour Name 	dp_mon_filter_dealloc(mon_pdev);
6128*5113495bSYour Name fail0:
6129*5113495bSYour Name 	qdf_mem_free(mon_pdev->invalid_mon_peer);
6130*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
6131*5113495bSYour Name }
6132*5113495bSYour Name 
dp_mon_pdev_deinit(struct dp_pdev * pdev)6133*5113495bSYour Name QDF_STATUS dp_mon_pdev_deinit(struct dp_pdev *pdev)
6134*5113495bSYour Name {
6135*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
6136*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
6137*5113495bSYour Name 
6138*5113495bSYour Name 	mon_ops = dp_mon_ops_get(pdev->soc);
6139*5113495bSYour Name 	if (!mon_ops) {
6140*5113495bSYour Name 		dp_mon_err("Monitor ops is NULL");
6141*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6142*5113495bSYour Name 	}
6143*5113495bSYour Name 
6144*5113495bSYour Name 	if (!mon_pdev->is_dp_mon_pdev_initialized)
6145*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
6146*5113495bSYour Name 
6147*5113495bSYour Name 	dp_mon_filters_reset(pdev);
6148*5113495bSYour Name 
6149*5113495bSYour Name 	/* mon pdev extended deinit */
6150*5113495bSYour Name 	if (mon_ops->mon_pdev_ext_deinit)
6151*5113495bSYour Name 		mon_ops->mon_pdev_ext_deinit(pdev);
6152*5113495bSYour Name 
6153*5113495bSYour Name 	if (mon_ops->mon_rx_pdev_tlv_logger_deinit)
6154*5113495bSYour Name 		mon_ops->mon_rx_pdev_tlv_logger_deinit(pdev);
6155*5113495bSYour Name 
6156*5113495bSYour Name 	/* detach monitor function */
6157*5113495bSYour Name 	dp_monitor_tx_ppdu_stats_detach(pdev);
6158*5113495bSYour Name 
6159*5113495bSYour Name 	if (mon_ops->mon_lite_mon_dealloc)
6160*5113495bSYour Name 		mon_ops->mon_lite_mon_dealloc(pdev);
6161*5113495bSYour Name 
6162*5113495bSYour Name 	if (mon_ops->rx_mon_buffers_free)
6163*5113495bSYour Name 		mon_ops->rx_mon_buffers_free(pdev);
6164*5113495bSYour Name 	if (mon_ops->rx_mon_desc_pool_deinit)
6165*5113495bSYour Name 		mon_ops->rx_mon_desc_pool_deinit(pdev);
6166*5113495bSYour Name 	dp_mon_rings_deinit(pdev);
6167*5113495bSYour Name 	dp_cal_client_detach(&mon_pdev->cal_client_ctx);
6168*5113495bSYour Name 	dp_htt_ppdu_stats_detach(pdev);
6169*5113495bSYour Name 	qdf_spinlock_destroy(&mon_pdev->ppdu_stats_lock);
6170*5113495bSYour Name 	dp_neighbour_peers_detach(pdev);
6171*5113495bSYour Name 	dp_pktlogmod_exit(pdev);
6172*5113495bSYour Name 	if (mon_ops->tx_mon_filter_dealloc)
6173*5113495bSYour Name 		mon_ops->tx_mon_filter_dealloc(pdev);
6174*5113495bSYour Name 	if (mon_pdev->filter)
6175*5113495bSYour Name 		dp_mon_filter_dealloc(mon_pdev);
6176*5113495bSYour Name 	if (mon_pdev->invalid_mon_peer)
6177*5113495bSYour Name 		qdf_mem_free(mon_pdev->invalid_mon_peer);
6178*5113495bSYour Name 	mon_pdev->is_dp_mon_pdev_initialized = false;
6179*5113495bSYour Name 	dp_mon_set_local_pkt_capture_running(mon_pdev, false);
6180*5113495bSYour Name 
6181*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6182*5113495bSYour Name }
6183*5113495bSYour Name 
dp_mon_vdev_attach(struct dp_vdev * vdev)6184*5113495bSYour Name QDF_STATUS dp_mon_vdev_attach(struct dp_vdev *vdev)
6185*5113495bSYour Name {
6186*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev;
6187*5113495bSYour Name 	struct dp_pdev *pdev = vdev->pdev;
6188*5113495bSYour Name 
6189*5113495bSYour Name 	mon_vdev = (struct dp_mon_vdev *)qdf_mem_malloc(sizeof(*mon_vdev));
6190*5113495bSYour Name 	if (!mon_vdev) {
6191*5113495bSYour Name 		dp_mon_err("%pK: Monitor vdev allocation failed", vdev);
6192*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6193*5113495bSYour Name 	}
6194*5113495bSYour Name 
6195*5113495bSYour Name 	if (pdev && pdev->monitor_pdev &&
6196*5113495bSYour Name 	    pdev->monitor_pdev->scan_spcl_vap_configured)
6197*5113495bSYour Name 		dp_scan_spcl_vap_stats_attach(mon_vdev);
6198*5113495bSYour Name 
6199*5113495bSYour Name 	vdev->monitor_vdev = mon_vdev;
6200*5113495bSYour Name 
6201*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6202*5113495bSYour Name }
6203*5113495bSYour Name 
dp_mon_vdev_detach(struct dp_vdev * vdev)6204*5113495bSYour Name QDF_STATUS dp_mon_vdev_detach(struct dp_vdev *vdev)
6205*5113495bSYour Name {
6206*5113495bSYour Name 	struct dp_mon_vdev *mon_vdev = vdev->monitor_vdev;
6207*5113495bSYour Name 	struct dp_pdev *pdev = vdev->pdev;
6208*5113495bSYour Name 	struct dp_mon_ops *mon_ops = dp_mon_ops_get(pdev->soc);
6209*5113495bSYour Name 
6210*5113495bSYour Name 	if (!mon_ops)
6211*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6212*5113495bSYour Name 
6213*5113495bSYour Name 	if (!mon_vdev)
6214*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6215*5113495bSYour Name 
6216*5113495bSYour Name 	if (pdev->monitor_pdev->scan_spcl_vap_configured)
6217*5113495bSYour Name 		dp_scan_spcl_vap_stats_detach(mon_vdev);
6218*5113495bSYour Name 
6219*5113495bSYour Name 	qdf_mem_free(mon_vdev);
6220*5113495bSYour Name 	vdev->monitor_vdev = NULL;
6221*5113495bSYour Name 	/* set mvdev to NULL only if detach is called for monitor/special vap
6222*5113495bSYour Name 	 */
6223*5113495bSYour Name 	if (pdev->monitor_pdev->mvdev == vdev)
6224*5113495bSYour Name 		pdev->monitor_pdev->mvdev = NULL;
6225*5113495bSYour Name 
6226*5113495bSYour Name 	if (mon_ops->mon_lite_mon_vdev_delete)
6227*5113495bSYour Name 		mon_ops->mon_lite_mon_vdev_delete(pdev, vdev);
6228*5113495bSYour Name 
6229*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6230*5113495bSYour Name }
6231*5113495bSYour Name 
6232*5113495bSYour Name #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE
6233*5113495bSYour Name /**
6234*5113495bSYour Name  * dp_mon_peer_attach_notify() - Raise WDI event for peer create
6235*5113495bSYour Name  * @peer: DP Peer handle
6236*5113495bSYour Name  *
6237*5113495bSYour Name  * Return: none
6238*5113495bSYour Name  */
6239*5113495bSYour Name static inline
dp_mon_peer_attach_notify(struct dp_peer * peer)6240*5113495bSYour Name void dp_mon_peer_attach_notify(struct dp_peer *peer)
6241*5113495bSYour Name {
6242*5113495bSYour Name 	struct dp_mon_peer *mon_peer = peer->monitor_peer;
6243*5113495bSYour Name 	struct dp_pdev *pdev;
6244*5113495bSYour Name 	struct dp_soc *soc;
6245*5113495bSYour Name 	struct cdp_peer_cookie peer_cookie;
6246*5113495bSYour Name 
6247*5113495bSYour Name 	pdev = peer->vdev->pdev;
6248*5113495bSYour Name 	soc = pdev->soc;
6249*5113495bSYour Name 
6250*5113495bSYour Name 	qdf_mem_copy(peer_cookie.mac_addr, peer->mac_addr.raw,
6251*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
6252*5113495bSYour Name 
6253*5113495bSYour Name 	peer_cookie.ctx = NULL;
6254*5113495bSYour Name 	peer_cookie.pdev_id = pdev->pdev_id;
6255*5113495bSYour Name 	peer_cookie.cookie = pdev->next_peer_cookie++;
6256*5113495bSYour Name 
6257*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_PEER_CREATE, soc,
6258*5113495bSYour Name 			     (void *)&peer_cookie,
6259*5113495bSYour Name 			     peer->peer_id, WDI_NO_VAL, pdev->pdev_id);
6260*5113495bSYour Name 
6261*5113495bSYour Name 	if (soc->peerstats_enabled) {
6262*5113495bSYour Name 		if (!peer_cookie.ctx) {
6263*5113495bSYour Name 			pdev->next_peer_cookie--;
6264*5113495bSYour Name 			qdf_err("Failed to initialize peer rate stats");
6265*5113495bSYour Name 			mon_peer->peerstats_ctx = NULL;
6266*5113495bSYour Name 		} else {
6267*5113495bSYour Name 			mon_peer->peerstats_ctx =
6268*5113495bSYour Name 				(struct cdp_peer_rate_stats_ctx *)
6269*5113495bSYour Name 				 peer_cookie.ctx;
6270*5113495bSYour Name 		}
6271*5113495bSYour Name 	}
6272*5113495bSYour Name }
6273*5113495bSYour Name 
6274*5113495bSYour Name /**
6275*5113495bSYour Name  * dp_mon_peer_detach_notify() - Raise WDI event for peer destroy
6276*5113495bSYour Name  * @peer: DP Peer handle
6277*5113495bSYour Name  *
6278*5113495bSYour Name  * Return: none
6279*5113495bSYour Name  */
6280*5113495bSYour Name static inline
dp_mon_peer_detach_notify(struct dp_peer * peer)6281*5113495bSYour Name void dp_mon_peer_detach_notify(struct dp_peer *peer)
6282*5113495bSYour Name {
6283*5113495bSYour Name 	struct dp_mon_peer *mon_peer = peer->monitor_peer;
6284*5113495bSYour Name 	struct dp_pdev *pdev;
6285*5113495bSYour Name 	struct dp_soc *soc;
6286*5113495bSYour Name 	struct cdp_peer_cookie peer_cookie;
6287*5113495bSYour Name 
6288*5113495bSYour Name 	pdev = peer->vdev->pdev;
6289*5113495bSYour Name 	soc = pdev->soc;
6290*5113495bSYour Name 	/* send peer destroy event to upper layer */
6291*5113495bSYour Name 	qdf_mem_copy(peer_cookie.mac_addr, peer->mac_addr.raw,
6292*5113495bSYour Name 		     QDF_MAC_ADDR_SIZE);
6293*5113495bSYour Name 	peer_cookie.ctx = NULL;
6294*5113495bSYour Name 	peer_cookie.ctx = (struct cdp_stats_cookie *)mon_peer->peerstats_ctx;
6295*5113495bSYour Name 
6296*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_PEER_DESTROY,
6297*5113495bSYour Name 			     soc,
6298*5113495bSYour Name 			     (void *)&peer_cookie,
6299*5113495bSYour Name 			     peer->peer_id,
6300*5113495bSYour Name 			     WDI_NO_VAL,
6301*5113495bSYour Name 			     pdev->pdev_id);
6302*5113495bSYour Name 
6303*5113495bSYour Name 	mon_peer->peerstats_ctx = NULL;
6304*5113495bSYour Name }
6305*5113495bSYour Name #else
6306*5113495bSYour Name static inline
dp_mon_peer_attach_notify(struct dp_peer * peer)6307*5113495bSYour Name void dp_mon_peer_attach_notify(struct dp_peer *peer)
6308*5113495bSYour Name {
6309*5113495bSYour Name 	peer->monitor_peer->peerstats_ctx = NULL;
6310*5113495bSYour Name }
6311*5113495bSYour Name 
6312*5113495bSYour Name static inline
dp_mon_peer_detach_notify(struct dp_peer * peer)6313*5113495bSYour Name void dp_mon_peer_detach_notify(struct dp_peer *peer)
6314*5113495bSYour Name {
6315*5113495bSYour Name 	peer->monitor_peer->peerstats_ctx = NULL;
6316*5113495bSYour Name }
6317*5113495bSYour Name #endif
6318*5113495bSYour Name 
6319*5113495bSYour Name #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(FEATURE_PERPKT_INFO)
dp_mon_peer_attach(struct dp_peer * peer)6320*5113495bSYour Name QDF_STATUS dp_mon_peer_attach(struct dp_peer *peer)
6321*5113495bSYour Name {
6322*5113495bSYour Name 	struct dp_mon_peer *mon_peer;
6323*5113495bSYour Name 	struct dp_pdev *pdev;
6324*5113495bSYour Name 
6325*5113495bSYour Name 	mon_peer = (struct dp_mon_peer *)qdf_mem_malloc(sizeof(*mon_peer));
6326*5113495bSYour Name 	if (!mon_peer) {
6327*5113495bSYour Name 		dp_mon_err("%pK: MONITOR peer allocation failed", peer);
6328*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6329*5113495bSYour Name 	}
6330*5113495bSYour Name 
6331*5113495bSYour Name 	peer->monitor_peer = mon_peer;
6332*5113495bSYour Name 	pdev = peer->vdev->pdev;
6333*5113495bSYour Name 	/*
6334*5113495bSYour Name 	 * In tx_monitor mode, filter may be set for unassociated peer
6335*5113495bSYour Name 	 * when unassociated peer get associated peer need to
6336*5113495bSYour Name 	 * update tx_cap_enabled flag to support peer filter.
6337*5113495bSYour Name 	 */
6338*5113495bSYour Name 	dp_monitor_peer_tx_capture_filter_check(pdev, peer);
6339*5113495bSYour Name 
6340*5113495bSYour Name 	DP_STATS_INIT(mon_peer);
6341*5113495bSYour Name 	DP_STATS_UPD(mon_peer, rx.avg_snr, CDP_INVALID_SNR);
6342*5113495bSYour Name 
6343*5113495bSYour Name 	dp_mon_peer_attach_notify(peer);
6344*5113495bSYour Name 
6345*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6346*5113495bSYour Name }
6347*5113495bSYour Name #endif
6348*5113495bSYour Name 
dp_mon_peer_detach(struct dp_peer * peer)6349*5113495bSYour Name QDF_STATUS dp_mon_peer_detach(struct dp_peer *peer)
6350*5113495bSYour Name {
6351*5113495bSYour Name 	struct dp_mon_peer *mon_peer = peer->monitor_peer;
6352*5113495bSYour Name 
6353*5113495bSYour Name 	if (!mon_peer)
6354*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
6355*5113495bSYour Name 
6356*5113495bSYour Name 	dp_mon_peer_detach_notify(peer);
6357*5113495bSYour Name 
6358*5113495bSYour Name 	qdf_mem_free(mon_peer);
6359*5113495bSYour Name 	peer->monitor_peer = NULL;
6360*5113495bSYour Name 
6361*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6362*5113495bSYour Name }
6363*5113495bSYour Name 
6364*5113495bSYour Name #ifndef DISABLE_MON_CONFIG
dp_mon_register_intr_ops(struct dp_soc * soc)6365*5113495bSYour Name void dp_mon_register_intr_ops(struct dp_soc *soc)
6366*5113495bSYour Name {
6367*5113495bSYour Name 	struct dp_mon_ops *mon_ops = NULL;
6368*5113495bSYour Name 
6369*5113495bSYour Name 	mon_ops = dp_mon_ops_get(soc);
6370*5113495bSYour Name 	if (!mon_ops) {
6371*5113495bSYour Name 		dp_mon_err("Monitor ops is NULL");
6372*5113495bSYour Name 		return;
6373*5113495bSYour Name 	}
6374*5113495bSYour Name 	if (mon_ops->mon_register_intr_ops)
6375*5113495bSYour Name 		mon_ops->mon_register_intr_ops(soc);
6376*5113495bSYour Name }
6377*5113495bSYour Name #endif
6378*5113495bSYour Name 
dp_mon_peer_get_peerstats_ctx(struct dp_peer * peer)6379*5113495bSYour Name struct cdp_peer_rate_stats_ctx *dp_mon_peer_get_peerstats_ctx(struct
6380*5113495bSYour Name 							      dp_peer *peer)
6381*5113495bSYour Name {
6382*5113495bSYour Name 	struct dp_mon_peer *mon_peer = peer->monitor_peer;
6383*5113495bSYour Name 
6384*5113495bSYour Name 	if (mon_peer)
6385*5113495bSYour Name 		return mon_peer->peerstats_ctx;
6386*5113495bSYour Name 	else
6387*5113495bSYour Name 		return NULL;
6388*5113495bSYour Name }
6389*5113495bSYour Name 
6390*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
dp_mon_peer_reset_stats(struct dp_peer * peer)6391*5113495bSYour Name void dp_mon_peer_reset_stats(struct dp_peer *peer)
6392*5113495bSYour Name {
6393*5113495bSYour Name 	struct dp_mon_peer *mon_peer = NULL;
6394*5113495bSYour Name 
6395*5113495bSYour Name 	mon_peer = peer->monitor_peer;
6396*5113495bSYour Name 	if (!mon_peer)
6397*5113495bSYour Name 		return;
6398*5113495bSYour Name 
6399*5113495bSYour Name 	DP_STATS_CLR(mon_peer);
6400*5113495bSYour Name 	DP_STATS_UPD(mon_peer, rx.avg_snr, CDP_INVALID_SNR);
6401*5113495bSYour Name }
6402*5113495bSYour Name 
dp_mon_peer_get_stats(struct dp_peer * peer,void * arg,enum cdp_stat_update_type type)6403*5113495bSYour Name void dp_mon_peer_get_stats(struct dp_peer *peer, void *arg,
6404*5113495bSYour Name 			   enum cdp_stat_update_type type)
6405*5113495bSYour Name {
6406*5113495bSYour Name 	struct dp_mon_peer *mon_peer = peer->monitor_peer;
6407*5113495bSYour Name 	struct dp_mon_peer_stats *mon_peer_stats;
6408*5113495bSYour Name 
6409*5113495bSYour Name 	if (!mon_peer || !arg)
6410*5113495bSYour Name 		return;
6411*5113495bSYour Name 
6412*5113495bSYour Name 	mon_peer_stats = &mon_peer->stats;
6413*5113495bSYour Name 
6414*5113495bSYour Name 	switch (type) {
6415*5113495bSYour Name 	case UPDATE_PEER_STATS:
6416*5113495bSYour Name 	{
6417*5113495bSYour Name 		struct cdp_peer_stats *peer_stats =
6418*5113495bSYour Name 						(struct cdp_peer_stats *)arg;
6419*5113495bSYour Name 		DP_UPDATE_MON_STATS(peer_stats, mon_peer_stats);
6420*5113495bSYour Name 		break;
6421*5113495bSYour Name 	}
6422*5113495bSYour Name 	case UPDATE_VDEV_STATS_MLD:
6423*5113495bSYour Name 	{
6424*5113495bSYour Name 		struct cdp_vdev_stats *vdev_stats =
6425*5113495bSYour Name 						(struct cdp_vdev_stats *)arg;
6426*5113495bSYour Name 		DP_UPDATE_MON_STATS(vdev_stats, mon_peer_stats);
6427*5113495bSYour Name 		break;
6428*5113495bSYour Name 	}
6429*5113495bSYour Name 	case UPDATE_VDEV_STATS:
6430*5113495bSYour Name 	{
6431*5113495bSYour Name 		struct dp_vdev_stats *vdev_stats =
6432*5113495bSYour Name 						(struct dp_vdev_stats *)arg;
6433*5113495bSYour Name 		DP_UPDATE_MON_STATS(vdev_stats, mon_peer_stats);
6434*5113495bSYour Name 		break;
6435*5113495bSYour Name 	}
6436*5113495bSYour Name 	default:
6437*5113495bSYour Name 		dp_mon_err("Invalid stats_update_type: %u", type);
6438*5113495bSYour Name 	}
6439*5113495bSYour Name }
6440*5113495bSYour Name 
dp_mon_invalid_peer_update_pdev_stats(struct dp_pdev * pdev)6441*5113495bSYour Name void dp_mon_invalid_peer_update_pdev_stats(struct dp_pdev *pdev)
6442*5113495bSYour Name {
6443*5113495bSYour Name 	struct dp_mon_peer *mon_peer;
6444*5113495bSYour Name 	struct dp_mon_peer_stats *mon_peer_stats;
6445*5113495bSYour Name 	struct cdp_pdev_stats *pdev_stats;
6446*5113495bSYour Name 
6447*5113495bSYour Name 	if (!pdev || !pdev->monitor_pdev)
6448*5113495bSYour Name 		return;
6449*5113495bSYour Name 
6450*5113495bSYour Name 	mon_peer = pdev->monitor_pdev->invalid_mon_peer;
6451*5113495bSYour Name 	if (!mon_peer)
6452*5113495bSYour Name 		return;
6453*5113495bSYour Name 
6454*5113495bSYour Name 	mon_peer_stats = &mon_peer->stats;
6455*5113495bSYour Name 	pdev_stats = &pdev->stats;
6456*5113495bSYour Name 	DP_UPDATE_MON_STATS(pdev_stats, mon_peer_stats);
6457*5113495bSYour Name }
6458*5113495bSYour Name 
6459*5113495bSYour Name QDF_STATUS
dp_mon_peer_get_stats_param(struct dp_peer * peer,enum cdp_peer_stats_type type,cdp_peer_stats_param_t * buf)6460*5113495bSYour Name dp_mon_peer_get_stats_param(struct dp_peer *peer, enum cdp_peer_stats_type type,
6461*5113495bSYour Name 			    cdp_peer_stats_param_t *buf)
6462*5113495bSYour Name {
6463*5113495bSYour Name 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
6464*5113495bSYour Name 	struct dp_mon_peer *mon_peer;
6465*5113495bSYour Name 
6466*5113495bSYour Name 	mon_peer = peer->monitor_peer;
6467*5113495bSYour Name 	if (!mon_peer)
6468*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6469*5113495bSYour Name 
6470*5113495bSYour Name 	switch (type) {
6471*5113495bSYour Name 	case cdp_peer_tx_rate:
6472*5113495bSYour Name 		buf->tx_rate = mon_peer->stats.tx.tx_rate;
6473*5113495bSYour Name 		break;
6474*5113495bSYour Name 	case cdp_peer_tx_last_tx_rate:
6475*5113495bSYour Name 		buf->last_tx_rate = mon_peer->stats.tx.last_tx_rate;
6476*5113495bSYour Name 		break;
6477*5113495bSYour Name 	case cdp_peer_tx_ratecode:
6478*5113495bSYour Name 		buf->tx_ratecode = mon_peer->stats.tx.tx_ratecode;
6479*5113495bSYour Name 		break;
6480*5113495bSYour Name 	case cdp_peer_rx_rate:
6481*5113495bSYour Name 		buf->rx_rate = mon_peer->stats.rx.rx_rate;
6482*5113495bSYour Name 		break;
6483*5113495bSYour Name 	case cdp_peer_rx_last_rx_rate:
6484*5113495bSYour Name 		buf->last_rx_rate = mon_peer->stats.rx.last_rx_rate;
6485*5113495bSYour Name 		break;
6486*5113495bSYour Name 	case cdp_peer_rx_ratecode:
6487*5113495bSYour Name 		buf->rx_ratecode = mon_peer->stats.rx.rx_ratecode;
6488*5113495bSYour Name 		break;
6489*5113495bSYour Name 	case cdp_peer_rx_avg_snr:
6490*5113495bSYour Name 		buf->rx_avg_snr = mon_peer->stats.rx.avg_snr;
6491*5113495bSYour Name 		break;
6492*5113495bSYour Name 	case cdp_peer_rx_snr:
6493*5113495bSYour Name 		buf->rx_snr = mon_peer->stats.rx.snr;
6494*5113495bSYour Name 		break;
6495*5113495bSYour Name 	case cdp_peer_rx_avg_rate:
6496*5113495bSYour Name 		buf->rx_rate_avg = mon_peer->stats.rx.rnd_avg_rx_rate;
6497*5113495bSYour Name 		break;
6498*5113495bSYour Name 	case cdp_peer_tx_avg_rate:
6499*5113495bSYour Name 		buf->tx_rate_avg = mon_peer->stats.tx.rnd_avg_tx_rate;
6500*5113495bSYour Name 		break;
6501*5113495bSYour Name 	default:
6502*5113495bSYour Name 		dp_err("Invalid stats type: %u requested", type);
6503*5113495bSYour Name 		ret = QDF_STATUS_E_FAILURE;
6504*5113495bSYour Name 	}
6505*5113495bSYour Name 
6506*5113495bSYour Name 	return ret;
6507*5113495bSYour Name }
6508*5113495bSYour Name #endif
6509*5113495bSYour Name 
dp_mon_ops_register(struct dp_soc * soc)6510*5113495bSYour Name void dp_mon_ops_register(struct dp_soc *soc)
6511*5113495bSYour Name {
6512*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
6513*5113495bSYour Name 	uint32_t target_type;
6514*5113495bSYour Name 
6515*5113495bSYour Name 	target_type = hal_get_target_type(soc->hal_soc);
6516*5113495bSYour Name 	switch (target_type) {
6517*5113495bSYour Name 	case TARGET_TYPE_QCA6290:
6518*5113495bSYour Name 	case TARGET_TYPE_QCA6390:
6519*5113495bSYour Name 	case TARGET_TYPE_QCA6490:
6520*5113495bSYour Name 	case TARGET_TYPE_QCA6750:
6521*5113495bSYour Name 	case TARGET_TYPE_KIWI:
6522*5113495bSYour Name 	case TARGET_TYPE_MANGO:
6523*5113495bSYour Name 	case TARGET_TYPE_PEACH:
6524*5113495bSYour Name 	case TARGET_TYPE_QCA8074:
6525*5113495bSYour Name 	case TARGET_TYPE_QCA8074V2:
6526*5113495bSYour Name 	case TARGET_TYPE_QCA6018:
6527*5113495bSYour Name 	case TARGET_TYPE_QCA9574:
6528*5113495bSYour Name 	case TARGET_TYPE_QCN9160:
6529*5113495bSYour Name 	case TARGET_TYPE_QCN9000:
6530*5113495bSYour Name 	case TARGET_TYPE_QCA5018:
6531*5113495bSYour Name 	case TARGET_TYPE_QCN6122:
6532*5113495bSYour Name 	case TARGET_TYPE_WCN6450:
6533*5113495bSYour Name 		dp_mon_ops_register_1_0(mon_soc);
6534*5113495bSYour Name 		dp_mon_ops_register_cmn_2_0(mon_soc);
6535*5113495bSYour Name 		dp_mon_ops_register_tx_2_0(mon_soc);
6536*5113495bSYour Name 		break;
6537*5113495bSYour Name 	case TARGET_TYPE_QCN9224:
6538*5113495bSYour Name 	case TARGET_TYPE_QCA5332:
6539*5113495bSYour Name 	case TARGET_TYPE_QCN6432:
6540*5113495bSYour Name #if defined(WLAN_PKT_CAPTURE_TX_2_0) || defined(WLAN_PKT_CAPTURE_RX_2_0)
6541*5113495bSYour Name 		dp_mon_ops_register_2_0(mon_soc);
6542*5113495bSYour Name #endif
6543*5113495bSYour Name 		break;
6544*5113495bSYour Name 	default:
6545*5113495bSYour Name 		dp_mon_err("%s: Unknown tgt type %d", __func__, target_type);
6546*5113495bSYour Name 		qdf_assert_always(0);
6547*5113495bSYour Name 		break;
6548*5113495bSYour Name 	}
6549*5113495bSYour Name }
6550*5113495bSYour Name 
6551*5113495bSYour Name #ifdef QCA_MONITOR_OPS_PER_SOC_SUPPORT
dp_mon_ops_free(struct dp_soc * soc)6552*5113495bSYour Name void dp_mon_ops_free(struct dp_soc *soc)
6553*5113495bSYour Name {
6554*5113495bSYour Name 	struct cdp_ops *ops = soc->cdp_soc.ops;
6555*5113495bSYour Name 	struct cdp_mon_ops *cdp_mon_ops = ops->mon_ops;
6556*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
6557*5113495bSYour Name 	struct dp_mon_ops *mon_ops = mon_soc->mon_ops;
6558*5113495bSYour Name 
6559*5113495bSYour Name 	if (cdp_mon_ops)
6560*5113495bSYour Name 		qdf_mem_free(cdp_mon_ops);
6561*5113495bSYour Name 
6562*5113495bSYour Name 	if (mon_ops)
6563*5113495bSYour Name 		qdf_mem_free(mon_ops);
6564*5113495bSYour Name }
6565*5113495bSYour Name #else
dp_mon_ops_free(struct dp_soc * soc)6566*5113495bSYour Name void dp_mon_ops_free(struct dp_soc *soc)
6567*5113495bSYour Name {
6568*5113495bSYour Name }
6569*5113495bSYour Name #endif
6570*5113495bSYour Name 
dp_mon_cdp_ops_register(struct dp_soc * soc)6571*5113495bSYour Name void dp_mon_cdp_ops_register(struct dp_soc *soc)
6572*5113495bSYour Name {
6573*5113495bSYour Name 	struct cdp_ops *ops = soc->cdp_soc.ops;
6574*5113495bSYour Name 	uint32_t target_type;
6575*5113495bSYour Name 
6576*5113495bSYour Name 	if (!ops) {
6577*5113495bSYour Name 		dp_mon_err("cdp_ops is NULL");
6578*5113495bSYour Name 		return;
6579*5113495bSYour Name 	}
6580*5113495bSYour Name 
6581*5113495bSYour Name 	target_type = hal_get_target_type(soc->hal_soc);
6582*5113495bSYour Name 	switch (target_type) {
6583*5113495bSYour Name 	case TARGET_TYPE_QCA6290:
6584*5113495bSYour Name 	case TARGET_TYPE_QCA6390:
6585*5113495bSYour Name 	case TARGET_TYPE_QCA6490:
6586*5113495bSYour Name 	case TARGET_TYPE_QCA6750:
6587*5113495bSYour Name 	case TARGET_TYPE_KIWI:
6588*5113495bSYour Name 	case TARGET_TYPE_MANGO:
6589*5113495bSYour Name 	case TARGET_TYPE_PEACH:
6590*5113495bSYour Name 	case TARGET_TYPE_QCA8074:
6591*5113495bSYour Name 	case TARGET_TYPE_QCA8074V2:
6592*5113495bSYour Name 	case TARGET_TYPE_QCA6018:
6593*5113495bSYour Name 	case TARGET_TYPE_QCA9574:
6594*5113495bSYour Name 	case TARGET_TYPE_QCN9160:
6595*5113495bSYour Name 	case TARGET_TYPE_QCN9000:
6596*5113495bSYour Name 	case TARGET_TYPE_QCA5018:
6597*5113495bSYour Name 	case TARGET_TYPE_QCN6122:
6598*5113495bSYour Name 	case TARGET_TYPE_WCN6450:
6599*5113495bSYour Name 		dp_mon_cdp_ops_register_1_0(ops);
6600*5113495bSYour Name #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
6601*5113495bSYour Name 		dp_cfr_filter_register_1_0(ops);
6602*5113495bSYour Name #endif
6603*5113495bSYour Name 		if (target_type == TARGET_TYPE_QCN9000 ||
6604*5113495bSYour Name 		    target_type == TARGET_TYPE_QCN9160)
6605*5113495bSYour Name 			ops->mon_ops->txrx_update_mon_mac_filter =
6606*5113495bSYour Name 					dp_update_mon_mac_filter;
6607*5113495bSYour Name 		break;
6608*5113495bSYour Name 	case TARGET_TYPE_QCN9224:
6609*5113495bSYour Name 	case TARGET_TYPE_QCA5332:
6610*5113495bSYour Name 	case TARGET_TYPE_QCN6432:
6611*5113495bSYour Name #if defined(WLAN_PKT_CAPTURE_TX_2_0) || defined(WLAN_PKT_CAPTURE_RX_2_0)
6612*5113495bSYour Name 		dp_mon_cdp_ops_register_2_0(ops);
6613*5113495bSYour Name #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE)
6614*5113495bSYour Name 		dp_cfr_filter_register_2_0(ops);
6615*5113495bSYour Name #endif
6616*5113495bSYour Name #endif /* WLAN_PKT_CAPTURE_TX_2_0 && WLAN_PKT_CAPTURE_RX_2_0 */
6617*5113495bSYour Name 		break;
6618*5113495bSYour Name 	default:
6619*5113495bSYour Name 		dp_mon_err("%s: Unknown tgt type %d", __func__, target_type);
6620*5113495bSYour Name 		qdf_assert_always(0);
6621*5113495bSYour Name 		break;
6622*5113495bSYour Name 	}
6623*5113495bSYour Name 
6624*5113495bSYour Name 	ops->cmn_drv_ops->txrx_set_monitor_mode = dp_vdev_set_monitor_mode;
6625*5113495bSYour Name 	ops->cmn_drv_ops->txrx_get_mon_vdev_from_pdev =
6626*5113495bSYour Name 				dp_get_mon_vdev_from_pdev_wifi3;
6627*5113495bSYour Name #ifdef DP_PEER_EXTENDED_API
6628*5113495bSYour Name 	ops->misc_ops->pkt_log_init = dp_pkt_log_init;
6629*5113495bSYour Name 	ops->misc_ops->pkt_log_con_service = dp_pkt_log_con_service;
6630*5113495bSYour Name 	ops->misc_ops->pkt_log_exit = dp_pkt_log_exit;
6631*5113495bSYour Name #endif
6632*5113495bSYour Name 	ops->ctrl_ops->enable_peer_based_pktlog =
6633*5113495bSYour Name 				dp_enable_peer_based_pktlog;
6634*5113495bSYour Name #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH)
6635*5113495bSYour Name 	ops->ctrl_ops->txrx_update_peer_pkt_capture_params =
6636*5113495bSYour Name 				 dp_peer_update_pkt_capture_params;
6637*5113495bSYour Name #endif /* WLAN_TX_PKT_CAPTURE_ENH || WLAN_RX_PKT_CAPTURE_ENH */
6638*5113495bSYour Name #ifdef WDI_EVENT_ENABLE
6639*5113495bSYour Name 	ops->ctrl_ops->txrx_get_pldev = dp_get_pldev;
6640*5113495bSYour Name #endif
6641*5113495bSYour Name #ifdef QCA_SUPPORT_SCAN_SPCL_VAP_STATS
6642*5113495bSYour Name 	ops->host_stats_ops->txrx_get_scan_spcl_vap_stats =
6643*5113495bSYour Name 					dp_get_scan_spcl_vap_stats;
6644*5113495bSYour Name #endif
6645*5113495bSYour Name 	return;
6646*5113495bSYour Name }
6647*5113495bSYour Name 
6648*5113495bSYour Name #ifdef QCA_MONITOR_OPS_PER_SOC_SUPPORT
6649*5113495bSYour Name static inline void
dp_mon_cdp_mon_ops_deregister(struct cdp_ops * ops)6650*5113495bSYour Name dp_mon_cdp_mon_ops_deregister(struct cdp_ops *ops)
6651*5113495bSYour Name {
6652*5113495bSYour Name 	if (ops->mon_ops) {
6653*5113495bSYour Name 		qdf_mem_free(ops->mon_ops);
6654*5113495bSYour Name 		ops->mon_ops = NULL;
6655*5113495bSYour Name 	}
6656*5113495bSYour Name }
6657*5113495bSYour Name #else
6658*5113495bSYour Name static inline void
dp_mon_cdp_mon_ops_deregister(struct cdp_ops * ops)6659*5113495bSYour Name dp_mon_cdp_mon_ops_deregister(struct cdp_ops *ops)
6660*5113495bSYour Name {
6661*5113495bSYour Name 	ops->mon_ops = NULL;
6662*5113495bSYour Name }
6663*5113495bSYour Name #endif
6664*5113495bSYour Name 
dp_mon_cdp_ops_deregister(struct dp_soc * soc)6665*5113495bSYour Name void dp_mon_cdp_ops_deregister(struct dp_soc *soc)
6666*5113495bSYour Name {
6667*5113495bSYour Name 	struct cdp_ops *ops = soc->cdp_soc.ops;
6668*5113495bSYour Name 
6669*5113495bSYour Name 	if (!ops) {
6670*5113495bSYour Name 		dp_mon_err("cdp_ops is NULL");
6671*5113495bSYour Name 		return;
6672*5113495bSYour Name 	}
6673*5113495bSYour Name 
6674*5113495bSYour Name 	dp_mon_cdp_mon_ops_deregister(ops);
6675*5113495bSYour Name 
6676*5113495bSYour Name 	ops->cmn_drv_ops->txrx_set_monitor_mode = NULL;
6677*5113495bSYour Name 	ops->cmn_drv_ops->txrx_get_mon_vdev_from_pdev = NULL;
6678*5113495bSYour Name #ifdef DP_PEER_EXTENDED_API
6679*5113495bSYour Name 	ops->misc_ops->pkt_log_init = NULL;
6680*5113495bSYour Name 	ops->misc_ops->pkt_log_con_service = NULL;
6681*5113495bSYour Name 	ops->misc_ops->pkt_log_exit = NULL;
6682*5113495bSYour Name #endif
6683*5113495bSYour Name 	ops->ctrl_ops->enable_peer_based_pktlog = NULL;
6684*5113495bSYour Name #if defined(WLAN_TX_PKT_CAPTURE_ENH) || defined(WLAN_RX_PKT_CAPTURE_ENH)
6685*5113495bSYour Name 	ops->ctrl_ops->txrx_update_peer_pkt_capture_params = NULL;
6686*5113495bSYour Name #endif /* WLAN_TX_PKT_CAPTURE_ENH || WLAN_RX_PKT_CAPTURE_ENH */
6687*5113495bSYour Name #ifdef WDI_EVENT_ENABLE
6688*5113495bSYour Name 	ops->ctrl_ops->txrx_get_pldev = NULL;
6689*5113495bSYour Name #endif
6690*5113495bSYour Name 	return;
6691*5113495bSYour Name }
6692*5113495bSYour Name 
6693*5113495bSYour Name #if defined(WDI_EVENT_ENABLE) &&\
6694*5113495bSYour Name 	(defined(QCA_ENHANCED_STATS_SUPPORT) || !defined(REMOVE_PKT_LOG))
6695*5113495bSYour Name static inline
dp_mon_ppdu_stats_handler_deregister(struct dp_mon_soc * mon_soc)6696*5113495bSYour Name void dp_mon_ppdu_stats_handler_deregister(struct dp_mon_soc *mon_soc)
6697*5113495bSYour Name {
6698*5113495bSYour Name 	mon_soc->mon_ops->mon_ppdu_stats_ind_handler = NULL;
6699*5113495bSYour Name }
6700*5113495bSYour Name #else
6701*5113495bSYour Name static inline
dp_mon_ppdu_stats_handler_deregister(struct dp_mon_soc * mon_soc)6702*5113495bSYour Name void dp_mon_ppdu_stats_handler_deregister(struct dp_mon_soc *mon_soc)
6703*5113495bSYour Name {
6704*5113495bSYour Name }
6705*5113495bSYour Name #endif
6706*5113495bSYour Name 
6707*5113495bSYour Name #ifdef QCA_RSSI_DB2DBM
6708*5113495bSYour Name /**
6709*5113495bSYour Name  * dp_mon_compute_min_nf() - calculate the min nf value in the
6710*5113495bSYour Name  *                      active chains 20 MHz subbands.
6711*5113495bSYour Name  * @conv_params: cdp_rssi_dbm_conv_param_dp structure value
6712*5113495bSYour Name  * @min_nf: location to store min NF value
6713*5113495bSYour Name  * @chain_idx: active chain index in nfHwdbm array
6714*5113495bSYour Name  *
6715*5113495bSYour Name  * computation: Need to calculate nfInDbm[][] to A_MIN(nfHwDbm[][])
6716*5113495bSYour Name  *              considering row index as active chains and column
6717*5113495bSYour Name  *              index as 20MHZ subbands per chain.
6718*5113495bSYour Name  * example: chain_mask = 0x07 (consider 3 active chains 0,1,2 index)
6719*5113495bSYour Name  *          BandWidth = 40MHZ (40MHZ includes two 20MHZ subbands so need to
6720*5113495bSYour Name  *                      consider 0,1 index calculate min_nf value)
6721*5113495bSYour Name  *
6722*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS if value set successfully
6723*5113495bSYour Name  *         QDF_STATUS_E_INVAL false if error
6724*5113495bSYour Name  */
6725*5113495bSYour Name static QDF_STATUS
dp_mon_compute_min_nf(struct cdp_rssi_dbm_conv_param_dp * conv_params,int8_t * min_nf,int chain_idx)6726*5113495bSYour Name dp_mon_compute_min_nf(struct cdp_rssi_dbm_conv_param_dp *conv_params,
6727*5113495bSYour Name 		      int8_t *min_nf, int chain_idx)
6728*5113495bSYour Name {
6729*5113495bSYour Name 	int j;
6730*5113495bSYour Name 	*min_nf = conv_params->nf_hw_dbm[chain_idx][0];
6731*5113495bSYour Name 
6732*5113495bSYour Name 	switch (conv_params->curr_bw) {
6733*5113495bSYour Name 	case CHAN_WIDTH_20:
6734*5113495bSYour Name 	case CHAN_WIDTH_5:
6735*5113495bSYour Name 	case CHAN_WIDTH_10:
6736*5113495bSYour Name 		break;
6737*5113495bSYour Name 	case CHAN_WIDTH_40:
6738*5113495bSYour Name 		for (j = 1; j < SUB40BW; j++) {
6739*5113495bSYour Name 			if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf)
6740*5113495bSYour Name 				*min_nf = conv_params->nf_hw_dbm[chain_idx][j];
6741*5113495bSYour Name 		}
6742*5113495bSYour Name 		break;
6743*5113495bSYour Name 	case CHAN_WIDTH_80:
6744*5113495bSYour Name 		for (j = 1; j < SUB80BW; j++) {
6745*5113495bSYour Name 			if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf)
6746*5113495bSYour Name 				*min_nf = conv_params->nf_hw_dbm[chain_idx][j];
6747*5113495bSYour Name 		}
6748*5113495bSYour Name 		break;
6749*5113495bSYour Name 	case CHAN_WIDTH_160:
6750*5113495bSYour Name 	case CHAN_WIDTH_80P80:
6751*5113495bSYour Name 	case CHAN_WIDTH_165:
6752*5113495bSYour Name 		for (j = 1; j < SUB160BW; j++) {
6753*5113495bSYour Name 			if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf)
6754*5113495bSYour Name 				*min_nf = conv_params->nf_hw_dbm[chain_idx][j];
6755*5113495bSYour Name 		}
6756*5113495bSYour Name 		break;
6757*5113495bSYour Name 	case CHAN_WIDTH_160P160:
6758*5113495bSYour Name 	case CHAN_WIDTH_320:
6759*5113495bSYour Name 		for (j = 1; j < SUB320BW; j++) {
6760*5113495bSYour Name 			if (conv_params->nf_hw_dbm[chain_idx][j] < *min_nf)
6761*5113495bSYour Name 				*min_nf = conv_params->nf_hw_dbm[chain_idx][j];
6762*5113495bSYour Name 		}
6763*5113495bSYour Name 		break;
6764*5113495bSYour Name 	default:
6765*5113495bSYour Name 		dp_cdp_err("Invalid bandwidth %u", conv_params->curr_bw);
6766*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
6767*5113495bSYour Name 	}
6768*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6769*5113495bSYour Name }
6770*5113495bSYour Name 
6771*5113495bSYour Name /**
6772*5113495bSYour Name  * dp_mon_pdev_params_rssi_dbm_conv() - to set rssi in dbm conversion
6773*5113495bSYour Name  *                                      params into monitor pdev.
6774*5113495bSYour Name  * @cdp_soc: dp soc handle.
6775*5113495bSYour Name  * @params: cdp_rssi_db2dbm_param_dp structure value.
6776*5113495bSYour Name  *
6777*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS if value set successfully
6778*5113495bSYour Name  *         QDF_STATUS_E_INVAL false if error
6779*5113495bSYour Name  */
6780*5113495bSYour Name QDF_STATUS
dp_mon_pdev_params_rssi_dbm_conv(struct cdp_soc_t * cdp_soc,struct cdp_rssi_db2dbm_param_dp * params)6781*5113495bSYour Name dp_mon_pdev_params_rssi_dbm_conv(struct cdp_soc_t *cdp_soc,
6782*5113495bSYour Name 				 struct cdp_rssi_db2dbm_param_dp *params)
6783*5113495bSYour Name {
6784*5113495bSYour Name 	struct cdp_rssi_db2dbm_param_dp *dp_rssi_params = params;
6785*5113495bSYour Name 	uint8_t pdev_id = params->pdev_id;
6786*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
6787*5113495bSYour Name 	struct dp_pdev *pdev =
6788*5113495bSYour Name 		dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
6789*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
6790*5113495bSYour Name 	struct cdp_rssi_temp_off_param_dp temp_off_param;
6791*5113495bSYour Name 	struct cdp_rssi_dbm_conv_param_dp conv_params;
6792*5113495bSYour Name 	int8_t min_nf = 0;
6793*5113495bSYour Name 	int i;
6794*5113495bSYour Name 
6795*5113495bSYour Name 	if (!soc->features.rssi_dbm_conv_support) {
6796*5113495bSYour Name 		dp_cdp_err("rssi dbm conversion support is false");
6797*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
6798*5113495bSYour Name 	}
6799*5113495bSYour Name 	if (!pdev || !pdev->monitor_pdev) {
6800*5113495bSYour Name 		dp_cdp_err("Invalid pdev_id %u", pdev_id);
6801*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6802*5113495bSYour Name 	}
6803*5113495bSYour Name 
6804*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
6805*5113495bSYour Name 	mon_pdev->rssi_dbm_conv_support =
6806*5113495bSYour Name 				soc->features.rssi_dbm_conv_support;
6807*5113495bSYour Name 
6808*5113495bSYour Name 	if (dp_rssi_params->rssi_temp_off_present) {
6809*5113495bSYour Name 		temp_off_param = dp_rssi_params->temp_off_param;
6810*5113495bSYour Name 		mon_pdev->rssi_offsets.rssi_temp_offset =
6811*5113495bSYour Name 				temp_off_param.rssi_temp_offset;
6812*5113495bSYour Name 	}
6813*5113495bSYour Name 	if (dp_rssi_params->rssi_dbm_info_present) {
6814*5113495bSYour Name 		conv_params = dp_rssi_params->rssi_dbm_param;
6815*5113495bSYour Name 		for (i = 0; i < CDP_MAX_NUM_ANTENNA; i++) {
6816*5113495bSYour Name 			if (conv_params.curr_rx_chainmask & (0x01 << i)) {
6817*5113495bSYour Name 				if (QDF_STATUS_E_INVAL == dp_mon_compute_min_nf
6818*5113495bSYour Name 						(&conv_params, &min_nf, i))
6819*5113495bSYour Name 					return QDF_STATUS_E_INVAL;
6820*5113495bSYour Name 			} else {
6821*5113495bSYour Name 				continue;
6822*5113495bSYour Name 			}
6823*5113495bSYour Name 		}
6824*5113495bSYour Name 		mon_pdev->rssi_offsets.xlna_bypass_offset =
6825*5113495bSYour Name 					conv_params.xlna_bypass_offset;
6826*5113495bSYour Name 		mon_pdev->rssi_offsets.xlna_bypass_threshold =
6827*5113495bSYour Name 					conv_params.xlna_bypass_threshold;
6828*5113495bSYour Name 		mon_pdev->rssi_offsets.xbar_config = conv_params.xbar_config;
6829*5113495bSYour Name 		mon_pdev->rssi_offsets.min_nf_dbm = min_nf;
6830*5113495bSYour Name 		mon_pdev->rssi_offsets.rssi_offset =
6831*5113495bSYour Name 					mon_pdev->rssi_offsets.min_nf_dbm +
6832*5113495bSYour Name 				     mon_pdev->rssi_offsets.rssi_temp_offset;
6833*5113495bSYour Name 	}
6834*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6835*5113495bSYour Name }
6836*5113495bSYour Name #endif
6837*5113495bSYour Name 
dp_mon_intr_ops_deregister(struct dp_soc * soc)6838*5113495bSYour Name void dp_mon_intr_ops_deregister(struct dp_soc *soc)
6839*5113495bSYour Name {
6840*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
6841*5113495bSYour Name 
6842*5113495bSYour Name 	mon_soc->mon_rx_process = NULL;
6843*5113495bSYour Name 	dp_mon_ppdu_stats_handler_deregister(mon_soc);
6844*5113495bSYour Name }
6845*5113495bSYour Name 
dp_mon_feature_ops_deregister(struct dp_soc * soc)6846*5113495bSYour Name void dp_mon_feature_ops_deregister(struct dp_soc *soc)
6847*5113495bSYour Name {
6848*5113495bSYour Name 	struct dp_mon_ops *mon_ops = dp_mon_ops_get(soc);
6849*5113495bSYour Name 
6850*5113495bSYour Name 	if (!mon_ops) {
6851*5113495bSYour Name 		dp_err("mon_ops is NULL");
6852*5113495bSYour Name 		return;
6853*5113495bSYour Name 	}
6854*5113495bSYour Name 
6855*5113495bSYour Name 	mon_ops->mon_config_debug_sniffer = NULL;
6856*5113495bSYour Name 	mon_ops->mon_peer_tx_init = NULL;
6857*5113495bSYour Name 	mon_ops->mon_peer_tx_cleanup = NULL;
6858*5113495bSYour Name 	mon_ops->mon_htt_ppdu_stats_attach = NULL;
6859*5113495bSYour Name 	mon_ops->mon_htt_ppdu_stats_detach = NULL;
6860*5113495bSYour Name 	mon_ops->mon_print_pdev_rx_mon_stats = NULL;
6861*5113495bSYour Name 	mon_ops->mon_set_bsscolor = NULL;
6862*5113495bSYour Name 	mon_ops->mon_pdev_get_filter_ucast_data = NULL;
6863*5113495bSYour Name 	mon_ops->mon_pdev_get_filter_mcast_data = NULL;
6864*5113495bSYour Name 	mon_ops->mon_pdev_get_filter_non_data = NULL;
6865*5113495bSYour Name 	mon_ops->mon_neighbour_peer_add_ast = NULL;
6866*5113495bSYour Name #ifdef WLAN_TX_PKT_CAPTURE_ENH
6867*5113495bSYour Name 	mon_ops->mon_peer_tid_peer_id_update = NULL;
6868*5113495bSYour Name 	mon_ops->mon_tx_ppdu_stats_attach = NULL;
6869*5113495bSYour Name 	mon_ops->mon_tx_ppdu_stats_detach = NULL;
6870*5113495bSYour Name 	mon_ops->mon_tx_capture_debugfs_init = NULL;
6871*5113495bSYour Name 	mon_ops->mon_tx_add_to_comp_queue = NULL;
6872*5113495bSYour Name 	mon_ops->mon_peer_tx_capture_filter_check = NULL;
6873*5113495bSYour Name 	mon_ops->mon_print_pdev_tx_capture_stats = NULL;
6874*5113495bSYour Name 	mon_ops->mon_config_enh_tx_capture = NULL;
6875*5113495bSYour Name #endif
6876*5113495bSYour Name #ifdef WLAN_RX_PKT_CAPTURE_ENH
6877*5113495bSYour Name 	mon_ops->mon_config_enh_rx_capture = NULL;
6878*5113495bSYour Name #endif
6879*5113495bSYour Name #ifdef QCA_SUPPORT_BPR
6880*5113495bSYour Name 	mon_ops->mon_set_bpr_enable = NULL;
6881*5113495bSYour Name #endif
6882*5113495bSYour Name #ifdef ATH_SUPPORT_NAC
6883*5113495bSYour Name 	mon_ops->mon_set_filter_neigh_peers = NULL;
6884*5113495bSYour Name #endif
6885*5113495bSYour Name #ifdef WLAN_ATF_ENABLE
6886*5113495bSYour Name 	mon_ops->mon_set_atf_stats_enable = NULL;
6887*5113495bSYour Name #endif
6888*5113495bSYour Name #ifdef FEATURE_NAC_RSSI
6889*5113495bSYour Name 	mon_ops->mon_filter_neighbour_peer = NULL;
6890*5113495bSYour Name #endif
6891*5113495bSYour Name #ifdef QCA_MCOPY_SUPPORT
6892*5113495bSYour Name 	mon_ops->mon_filter_setup_mcopy_mode = NULL;
6893*5113495bSYour Name 	mon_ops->mon_filter_reset_mcopy_mode = NULL;
6894*5113495bSYour Name 	mon_ops->mon_mcopy_check_deliver = NULL;
6895*5113495bSYour Name #endif
6896*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
6897*5113495bSYour Name 	mon_ops->mon_filter_setup_enhanced_stats = NULL;
6898*5113495bSYour Name 	mon_ops->mon_tx_enable_enhanced_stats = NULL;
6899*5113495bSYour Name 	mon_ops->mon_tx_disable_enhanced_stats = NULL;
6900*5113495bSYour Name 	mon_ops->mon_ppdu_desc_deliver = NULL;
6901*5113495bSYour Name 	mon_ops->mon_ppdu_desc_notify = NULL;
6902*5113495bSYour Name 	mon_ops->mon_ppdu_stats_feat_enable_check = NULL;
6903*5113495bSYour Name #ifdef WLAN_FEATURE_11BE
6904*5113495bSYour Name 	mon_ops->mon_tx_stats_update = NULL;
6905*5113495bSYour Name #endif
6906*5113495bSYour Name #endif
6907*5113495bSYour Name #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
6908*5113495bSYour Name 	mon_ops->mon_filter_setup_smart_monitor = NULL;
6909*5113495bSYour Name #endif
6910*5113495bSYour Name 	mon_ops->mon_filter_set_reset_mon_mac_filter = NULL;
6911*5113495bSYour Name #ifdef WLAN_RX_PKT_CAPTURE_ENH
6912*5113495bSYour Name 	mon_ops->mon_filter_setup_rx_enh_capture = NULL;
6913*5113495bSYour Name #endif
6914*5113495bSYour Name #ifdef WDI_EVENT_ENABLE
6915*5113495bSYour Name 	mon_ops->mon_set_pktlog_wifi3 = NULL;
6916*5113495bSYour Name 	mon_ops->mon_filter_setup_rx_pkt_log_full = NULL;
6917*5113495bSYour Name 	mon_ops->mon_filter_reset_rx_pkt_log_full = NULL;
6918*5113495bSYour Name 	mon_ops->mon_filter_setup_rx_pkt_log_lite = NULL;
6919*5113495bSYour Name 	mon_ops->mon_filter_reset_rx_pkt_log_lite = NULL;
6920*5113495bSYour Name 	mon_ops->mon_filter_setup_rx_pkt_log_cbf = NULL;
6921*5113495bSYour Name 	mon_ops->mon_filter_reset_rx_pkt_log_cbf = NULL;
6922*5113495bSYour Name #ifdef BE_PKTLOG_SUPPORT
6923*5113495bSYour Name 	mon_ops->mon_filter_setup_pktlog_hybrid = NULL;
6924*5113495bSYour Name 	mon_ops->mon_filter_reset_pktlog_hybrid = NULL;
6925*5113495bSYour Name #endif
6926*5113495bSYour Name #endif
6927*5113495bSYour Name #if defined(DP_CON_MON) && !defined(REMOVE_PKT_LOG)
6928*5113495bSYour Name 	mon_ops->mon_pktlogmod_exit = NULL;
6929*5113495bSYour Name #endif
6930*5113495bSYour Name 	mon_ops->rx_hdr_length_set = NULL;
6931*5113495bSYour Name 	mon_ops->rx_packet_length_set = NULL;
6932*5113495bSYour Name 	mon_ops->rx_wmask_subscribe = NULL;
6933*5113495bSYour Name 	mon_ops->rx_pkt_tlv_offset = NULL;
6934*5113495bSYour Name 	mon_ops->rx_enable_mpdu_logging = NULL;
6935*5113495bSYour Name 	mon_ops->rx_enable_fpmo = NULL;
6936*5113495bSYour Name 	mon_ops->mon_neighbour_peers_detach = NULL;
6937*5113495bSYour Name 	mon_ops->mon_vdev_set_monitor_mode_buf_rings = NULL;
6938*5113495bSYour Name 	mon_ops->mon_vdev_set_monitor_mode_rings = NULL;
6939*5113495bSYour Name #ifdef QCA_ENHANCED_STATS_SUPPORT
6940*5113495bSYour Name 	mon_ops->mon_rx_stats_update = NULL;
6941*5113495bSYour Name 	mon_ops->mon_rx_populate_ppdu_usr_info = NULL;
6942*5113495bSYour Name 	mon_ops->mon_rx_populate_ppdu_info = NULL;
6943*5113495bSYour Name #endif
6944*5113495bSYour Name }
6945*5113495bSYour Name 
dp_mon_soc_attach(struct dp_soc * soc)6946*5113495bSYour Name QDF_STATUS dp_mon_soc_attach(struct dp_soc *soc)
6947*5113495bSYour Name {
6948*5113495bSYour Name 	struct dp_mon_soc *mon_soc;
6949*5113495bSYour Name 	qdf_size_t soc_context_size;
6950*5113495bSYour Name 
6951*5113495bSYour Name 	if (!soc) {
6952*5113495bSYour Name 		dp_mon_err("dp_soc is NULL");
6953*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6954*5113495bSYour Name 	}
6955*5113495bSYour Name 
6956*5113495bSYour Name 	if (soc->arch_ops.txrx_get_mon_context_size) {
6957*5113495bSYour Name 		soc_context_size = soc->arch_ops.txrx_get_mon_context_size(DP_CONTEXT_TYPE_MON_SOC);
6958*5113495bSYour Name 		mon_soc = dp_context_alloc_mem(soc, DP_MON_SOC_TYPE,
6959*5113495bSYour Name 					       soc_context_size);
6960*5113495bSYour Name 	} else {
6961*5113495bSYour Name 		mon_soc = (struct dp_mon_soc *)qdf_mem_malloc(sizeof(*mon_soc));
6962*5113495bSYour Name 	}
6963*5113495bSYour Name 	if (!mon_soc) {
6964*5113495bSYour Name 		dp_mon_err("%pK: mem allocation failed", soc);
6965*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
6966*5113495bSYour Name 	}
6967*5113495bSYour Name 	/* register monitor ops */
6968*5113495bSYour Name 	soc->monitor_soc = mon_soc;
6969*5113495bSYour Name 	dp_mon_ops_register(soc);
6970*5113495bSYour Name 	dp_mon_register_intr_ops(soc);
6971*5113495bSYour Name 
6972*5113495bSYour Name 	dp_mon_cdp_ops_register(soc);
6973*5113495bSYour Name 	dp_monitor_soc_attach(soc);
6974*5113495bSYour Name 	dp_mon_register_feature_ops(soc);
6975*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6976*5113495bSYour Name }
6977*5113495bSYour Name 
dp_mon_soc_detach(struct dp_soc * soc)6978*5113495bSYour Name QDF_STATUS dp_mon_soc_detach(struct dp_soc *soc)
6979*5113495bSYour Name {
6980*5113495bSYour Name 	struct dp_mon_soc *mon_soc;
6981*5113495bSYour Name 
6982*5113495bSYour Name 	if (!soc) {
6983*5113495bSYour Name 		dp_mon_err("dp_soc is NULL");
6984*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
6985*5113495bSYour Name 	}
6986*5113495bSYour Name 
6987*5113495bSYour Name 	mon_soc = soc->monitor_soc;
6988*5113495bSYour Name 	dp_monitor_vdev_timer_deinit(soc);
6989*5113495bSYour Name 	dp_mon_cdp_ops_deregister(soc);
6990*5113495bSYour Name 	dp_monitor_soc_detach(soc);
6991*5113495bSYour Name 	soc->monitor_soc = NULL;
6992*5113495bSYour Name 	qdf_mem_free(mon_soc);
6993*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
6994*5113495bSYour Name }
6995*5113495bSYour Name 
6996*5113495bSYour Name #ifdef QCA_SUPPORT_FULL_MON
print_ring_tracker_stats(struct dp_mon_pdev * mon_pdev,uint8_t target)6997*5113495bSYour Name static void print_ring_tracker_stats(struct dp_mon_pdev *mon_pdev,
6998*5113495bSYour Name 				     uint8_t target)
6999*5113495bSYour Name {
7000*5113495bSYour Name 	struct dp_ring_ppdu_id_tracker *tracker;
7001*5113495bSYour Name 	uint8_t i;
7002*5113495bSYour Name 
7003*5113495bSYour Name 	if (target)
7004*5113495bSYour Name 		tracker = mon_pdev->hist_ppdu_id_mon_s;
7005*5113495bSYour Name 	else
7006*5113495bSYour Name 		tracker = mon_pdev->hist_ppdu_id_mon_d;
7007*5113495bSYour Name 
7008*5113495bSYour Name 	for (i = 0; i < DP_HIST_TRACK_SIZE; i++) {
7009*5113495bSYour Name 		qdf_print("idx: %d dest_ppdu_id: %d dest_time: %lld d_hp: %d ",
7010*5113495bSYour Name 			  i, tracker[i].ppdu_id_mon_dest,
7011*5113495bSYour Name 			  tracker[i].time_ppdu_id_mon_dest,
7012*5113495bSYour Name 			  tracker[i].dest_hp);
7013*5113495bSYour Name 		qdf_print("d_tp: %d d_hw_hp: %d d_hw_tp: %d status_ppdu_id: %d",
7014*5113495bSYour Name 			  tracker[i].dest_tp,
7015*5113495bSYour Name 			  tracker[i].dest_hw_hp,
7016*5113495bSYour Name 			  tracker[i].dest_hw_tp,
7017*5113495bSYour Name 			  tracker[i].ppdu_id_mon_status);
7018*5113495bSYour Name 		qdf_print(" status_time: %lld s_hp: %d s_tp: %d s_hw_hp: %d ",
7019*5113495bSYour Name 			  tracker[i].time_ppdu_id_mon_status,
7020*5113495bSYour Name 			  tracker[i].status_hp,
7021*5113495bSYour Name 			  tracker[i].status_tp,
7022*5113495bSYour Name 			  tracker[i].status_hw_hp);
7023*5113495bSYour Name 		qdf_print("s_hw_tp: %d\n",
7024*5113495bSYour Name 			  tracker[i].status_hw_tp);
7025*5113495bSYour Name 	}
7026*5113495bSYour Name }
7027*5113495bSYour Name #else
print_ring_tracker_stats(struct dp_mon_pdev * mon_pdev,uint8_t target)7028*5113495bSYour Name static void print_ring_tracker_stats(struct dp_mon_pdev *mon_pdev,
7029*5113495bSYour Name 				     uint8_t target)
7030*5113495bSYour Name {
7031*5113495bSYour Name }
7032*5113495bSYour Name #endif
7033*5113495bSYour Name 
7034*5113495bSYour Name void
dp_check_and_dump_full_mon_info(struct dp_soc * soc,struct dp_pdev * pdev,int mac_id,int war)7035*5113495bSYour Name dp_check_and_dump_full_mon_info(struct dp_soc *soc, struct dp_pdev *pdev,
7036*5113495bSYour Name 				int mac_id, int war)
7037*5113495bSYour Name {
7038*5113495bSYour Name 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
7039*5113495bSYour Name 	struct dp_mon_pdev *mon_pdev;
7040*5113495bSYour Name 	hal_soc_handle_t hal_soc;
7041*5113495bSYour Name 	uint64_t buf_addr;
7042*5113495bSYour Name 	void *mon_status_srng;
7043*5113495bSYour Name 	void *rxdma_mon_status_ring_entry;
7044*5113495bSYour Name 	struct hal_buf_info hbi;
7045*5113495bSYour Name 	hal_ring_handle_t mon_dest_srng;
7046*5113495bSYour Name 	void *ring_desc;
7047*5113495bSYour Name 	struct hal_rx_mon_desc_info desc_info = {0};
7048*5113495bSYour Name 	struct dp_rx_desc *rx_desc;
7049*5113495bSYour Name 	uint64_t ppdu_id = 0;
7050*5113495bSYour Name 
7051*5113495bSYour Name 	if (!mon_soc) {
7052*5113495bSYour Name 		dp_err("Monitor soc is NULL\n");
7053*5113495bSYour Name 		return;
7054*5113495bSYour Name 	}
7055*5113495bSYour Name 
7056*5113495bSYour Name 	if (!mon_soc->full_mon_mode) {
7057*5113495bSYour Name 		dp_err("Full monitor mode is disable\n");
7058*5113495bSYour Name 		return;
7059*5113495bSYour Name 	}
7060*5113495bSYour Name 
7061*5113495bSYour Name 	/**
7062*5113495bSYour Name 	 * As rx_mon_ring_mask is set but workdone is 0
7063*5113495bSYour Name 	 * there is a more chance backpressure can happen.
7064*5113495bSYour Name 	 * dump the content of rx monitor status and destination ring
7065*5113495bSYour Name 	 * and move to next pointers.
7066*5113495bSYour Name 	 */
7067*5113495bSYour Name 	mon_pdev = pdev->monitor_pdev;
7068*5113495bSYour Name 	if (!mon_pdev) {
7069*5113495bSYour Name 		dp_err("mon_pdev is NULL\n");
7070*5113495bSYour Name 		return;
7071*5113495bSYour Name 	}
7072*5113495bSYour Name 
7073*5113495bSYour Name 	hal_soc = soc->hal_soc;
7074*5113495bSYour Name 
7075*5113495bSYour Name 	if (!war)
7076*5113495bSYour Name 		qdf_spin_lock_bh(&mon_pdev->mon_lock);
7077*5113495bSYour Name 
7078*5113495bSYour Name 	mon_status_srng = soc->rxdma_mon_status_ring[mac_id].hal_srng;
7079*5113495bSYour Name 	if (!mon_status_srng)
7080*5113495bSYour Name 		goto unlock_monitor;
7081*5113495bSYour Name 
7082*5113495bSYour Name 	dp_print_ring_stat_from_hal(soc, &soc->rxdma_mon_status_ring[mac_id],
7083*5113495bSYour Name 				    RXDMA_MONITOR_STATUS);
7084*5113495bSYour Name 	rxdma_mon_status_ring_entry =
7085*5113495bSYour Name 		hal_srng_src_peek_n_get_next(hal_soc, mon_status_srng);
7086*5113495bSYour Name 
7087*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7088*5113495bSYour Name 		  "hold_mon_dest_ring: %d\n", mon_pdev->hold_mon_dest_ring);
7089*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7090*5113495bSYour Name 		  "mon_pdev last_ppdu_id: %d\n", mon_pdev->last_ppdu_id);
7091*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7092*5113495bSYour Name 		  "soc: %d\n", hal_get_target_type(hal_soc));
7093*5113495bSYour Name 
7094*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7095*5113495bSYour Name 		  "reap_status:\n");
7096*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7097*5113495bSYour Name 		  "\t DP_MON_STATUS_NO_DMA : %lld\n",
7098*5113495bSYour Name 		  mon_pdev->reap_status[DP_MON_STATUS_NO_DMA]);
7099*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7100*5113495bSYour Name 		  "\t DP_MON_STATUS_MATCH : %lld\n",
7101*5113495bSYour Name 		  mon_pdev->reap_status[DP_MON_STATUS_MATCH]);
7102*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7103*5113495bSYour Name 		  "\t DP_MON_STATUS_LAG : %lld\n",
7104*5113495bSYour Name 		  mon_pdev->reap_status[DP_MON_STATUS_LAG]);
7105*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7106*5113495bSYour Name 		  "\t DP_MON_STATUS_LEAD : %lld\n",
7107*5113495bSYour Name 		  mon_pdev->reap_status[DP_MON_STATUS_LEAD]);
7108*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7109*5113495bSYour Name 		  "\t DP_MON_STATUS_REPLENISH : %lld\n",
7110*5113495bSYour Name 		  mon_pdev->reap_status[DP_MON_STATUS_REPLENISH]);
7111*5113495bSYour Name 
7112*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7113*5113495bSYour Name 		  "prev_status:\n");
7114*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7115*5113495bSYour Name 		  "\t DP_MON_STATUS_NO_DMA : %lld\n",
7116*5113495bSYour Name 		  mon_pdev->prev_status[DP_MON_STATUS_NO_DMA]);
7117*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7118*5113495bSYour Name 		  "\t DP_MON_STATUS_MATCH : %lld\n",
7119*5113495bSYour Name 		  mon_pdev->prev_status[DP_MON_STATUS_MATCH]);
7120*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7121*5113495bSYour Name 		  "\t DP_MON_STATUS_LAG : %lld\n",
7122*5113495bSYour Name 		  mon_pdev->prev_status[DP_MON_STATUS_LAG]);
7123*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7124*5113495bSYour Name 		  "\t DP_MON_STATUS_LEAD : %lld\n",
7125*5113495bSYour Name 		  mon_pdev->prev_status[DP_MON_STATUS_LEAD]);
7126*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7127*5113495bSYour Name 		  "\t DP_MON_STATUS_REPLENISH : %lld\n",
7128*5113495bSYour Name 		  mon_pdev->prev_status[DP_MON_STATUS_REPLENISH]);
7129*5113495bSYour Name 
7130*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7131*5113495bSYour Name 		  "match_stats:\n");
7132*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7133*5113495bSYour Name 		  "\t DP_MON_STATUS_LAG : %lld\n",
7134*5113495bSYour Name 		  mon_pdev->status_match[DP_MON_STATUS_LAG]);
7135*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7136*5113495bSYour Name 		  "\t DP_MON_STATUS_LEAD : %lld\n",
7137*5113495bSYour Name 		  mon_pdev->status_match[DP_MON_STATUS_LEAD]);
7138*5113495bSYour Name 
7139*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7140*5113495bSYour Name 		  "mismatch: %d\n",
7141*5113495bSYour Name 		  mon_pdev->rx_mon_stats.ppdu_id_mismatch);
7142*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7143*5113495bSYour Name 		  "status_ppdu_drop: %d\n",
7144*5113495bSYour Name 		  mon_pdev->rx_mon_stats.status_ppdu_drop);
7145*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7146*5113495bSYour Name 		  "dest_ppdu_drop: %d\n",
7147*5113495bSYour Name 		  mon_pdev->rx_mon_stats.dest_ppdu_drop);
7148*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7149*5113495bSYour Name 		  "tlv_tag_status_err: %d\n",
7150*5113495bSYour Name 		  mon_pdev->rx_mon_stats.tlv_tag_status_err);
7151*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7152*5113495bSYour Name 		  "status_buf_done_war: %d\n",
7153*5113495bSYour Name 		  mon_pdev->rx_mon_stats.status_buf_done_war);
7154*5113495bSYour Name 
7155*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7156*5113495bSYour Name 		  "soc[%pK] pdev[%pK] mac_id[%d]\n",
7157*5113495bSYour Name 		  soc, pdev, mac_id);
7158*5113495bSYour Name 
7159*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7160*5113495bSYour Name 		  "MON DEST TRACKER STATS:\n");
7161*5113495bSYour Name 	print_ring_tracker_stats(mon_pdev, 0);
7162*5113495bSYour Name 
7163*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7164*5113495bSYour Name 		  "MON STA TRACKER STATS:\n");
7165*5113495bSYour Name 	print_ring_tracker_stats(mon_pdev, 1);
7166*5113495bSYour Name 
7167*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7168*5113495bSYour Name 		  "rxdma_mon_status_ring:\n");
7169*5113495bSYour Name 	if (!rxdma_mon_status_ring_entry) {
7170*5113495bSYour Name 		dp_err("rxdma_mon_status_ring_entry NULL\n");
7171*5113495bSYour Name 		goto dump_mon_destination_ring;
7172*5113495bSYour Name 	}
7173*5113495bSYour Name 
7174*5113495bSYour Name 	buf_addr =
7175*5113495bSYour Name 		(HAL_RX_BUFFER_ADDR_31_0_GET(rxdma_mon_status_ring_entry) |
7176*5113495bSYour Name 		 ((uint64_t)
7177*5113495bSYour Name 		  (HAL_RX_BUFFER_ADDR_39_32_GET(rxdma_mon_status_ring_entry))
7178*5113495bSYour Name 		  << 32));
7179*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7180*5113495bSYour Name 		  "Buffer address : %llx\n", buf_addr);
7181*5113495bSYour Name 	if (!buf_addr)
7182*5113495bSYour Name 		goto dump_mon_destination_ring;
7183*5113495bSYour Name 
7184*5113495bSYour Name 	hal_rx_buf_cookie_rbm_get(soc->hal_soc,
7185*5113495bSYour Name 				  (uint32_t *)rxdma_mon_status_ring_entry,
7186*5113495bSYour Name 				  &hbi);
7187*5113495bSYour Name 
7188*5113495bSYour Name 	print_hex_dump(KERN_ERR, "\tHAL_BUF_INFO: ", DUMP_PREFIX_NONE, 32, 4,
7189*5113495bSYour Name 		       &hbi, sizeof(struct hal_buf_info), false);
7190*5113495bSYour Name 
7191*5113495bSYour Name 	rx_desc = dp_rx_cookie_2_va_mon_status(soc, hbi.sw_cookie);
7192*5113495bSYour Name 	if (!rx_desc) {
7193*5113495bSYour Name 		dp_err("rx_desc is NULL\n");
7194*5113495bSYour Name 		goto dump_mon_destination_ring;
7195*5113495bSYour Name 	}
7196*5113495bSYour Name 
7197*5113495bSYour Name 	print_hex_dump(KERN_ERR, "\tRX_DESC: ", DUMP_PREFIX_NONE, 32, 4,
7198*5113495bSYour Name 		       rx_desc, sizeof(struct dp_rx_desc), false);
7199*5113495bSYour Name 
7200*5113495bSYour Name dump_mon_destination_ring:
7201*5113495bSYour Name 
7202*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7203*5113495bSYour Name 		  "rxdma_mon_destination_ring:\n");
7204*5113495bSYour Name 	mon_dest_srng = pdev->soc->rxdma_mon_dst_ring[mac_id].hal_srng;
7205*5113495bSYour Name 
7206*5113495bSYour Name 	if (!mon_dest_srng) {
7207*5113495bSYour Name 		dp_err("rxdma_mon_dst_ring hal_srng is NULL\n");
7208*5113495bSYour Name 		goto unlock_monitor;
7209*5113495bSYour Name 	}
7210*5113495bSYour Name 
7211*5113495bSYour Name 	dp_print_ring_stat_from_hal(soc, &soc->rxdma_mon_dst_ring[mac_id],
7212*5113495bSYour Name 				    RXDMA_MONITOR_DST);
7213*5113495bSYour Name 
7214*5113495bSYour Name 	ring_desc = hal_srng_dst_peek(hal_soc, mon_dest_srng);
7215*5113495bSYour Name 	if (!ring_desc)
7216*5113495bSYour Name 		goto unlock_monitor;
7217*5113495bSYour Name 
7218*5113495bSYour Name 	ppdu_id = hal_rx_hw_desc_get_ppduid_get(hal_soc, NULL, ring_desc);
7219*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7220*5113495bSYour Name 		  "Next dest ring ppdu id: %lld\n", ppdu_id);
7221*5113495bSYour Name 	hal_rx_sw_mon_desc_info_get((struct hal_soc *)soc->hal_soc,
7222*5113495bSYour Name 				    ring_desc, &desc_info);
7223*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
7224*5113495bSYour Name 		  "Next desc_info ppdu_id: %d\n", desc_info.ppdu_id);
7225*5113495bSYour Name 
7226*5113495bSYour Name 	print_hex_dump(KERN_ERR, "\tDESC_INFO: ", DUMP_PREFIX_NONE, 32, 4,
7227*5113495bSYour Name 		       &desc_info, sizeof(struct hal_rx_mon_desc_info), false);
7228*5113495bSYour Name 
7229*5113495bSYour Name unlock_monitor:
7230*5113495bSYour Name 	if (!war)
7231*5113495bSYour Name 		qdf_spin_unlock_bh(&mon_pdev->mon_lock);
7232*5113495bSYour Name }
7233