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