xref: /wlan-dirver/qca-wifi-host-cmn/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c (revision 65fdbbce9a41477a87bd5ec4e372ee54e2b62087)
1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 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_peer.h"
20 #include <dp_htt.h>
21 #include <dp_mon_filter.h>
22 #include <dp_mon.h>
23 #include <dp_rx_mon.h>
24 #include <dp_rx_mon_1.0.h>
25 #include <dp_mon_1.0.h>
26 #include <dp_mon_filter_1.0.h>
27 
28 #include "htt_ppdu_stats.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 
39 #ifdef WLAN_TX_PKT_CAPTURE_ENH
40 #include "dp_tx_capture.h"
41 #endif
42 
43 extern QDF_STATUS dp_srng_alloc(struct dp_soc *soc, struct dp_srng *srng,
44 				int ring_type, uint32_t num_entries,
45 				bool cached);
46 extern void dp_srng_free(struct dp_soc *soc, struct dp_srng *srng);
47 extern QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng,
48 			       int ring_type, int ring_num, int mac_id);
49 extern void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng,
50 			   int ring_type, int ring_num);
51 
52 extern enum timer_yield_status
53 dp_should_timer_irq_yield(struct dp_soc *soc, uint32_t work_done,
54 			  uint64_t start_time);
55 
56 #ifdef QCA_ENHANCED_STATS_SUPPORT
57 void
58 dp_mon_populate_ppdu_info_1_0(struct hal_rx_ppdu_info *hal_ppdu_info,
59 			      struct cdp_rx_indication_ppdu *ppdu)
60 {
61 	ppdu->u.preamble = hal_ppdu_info->rx_status.preamble_type;
62 	ppdu->u.bw = hal_ppdu_info->rx_status.bw;
63 	ppdu->punc_bw = 0;
64 }
65 
66 /**
67  * is_ppdu_txrx_capture_enabled() - API to check both pktlog and debug_sniffer
68  *                              modes are enabled or not.
69  * @pdev: dp pdev handle.
70  *
71  * Return: bool
72  */
73 static inline bool is_ppdu_txrx_capture_enabled(struct dp_pdev *pdev)
74 {
75 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
76 
77 	if (!mon_pdev->pktlog_ppdu_stats && !mon_pdev->tx_sniffer_enable &&
78 	    !mon_pdev->mcopy_mode)
79 		return true;
80 	else
81 		return false;
82 }
83 
84 /**
85  * dp_mon_tx_enable_enhanced_stats_1_0() - Send HTT cmd to FW to enable stats
86  * @pdev: Datapath pdev handle
87  *
88  * Return: none
89  */
90 static void dp_mon_tx_enable_enhanced_stats_1_0(struct dp_pdev *pdev)
91 {
92 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
93 
94 	if (is_ppdu_txrx_capture_enabled(pdev) && !mon_pdev->bpr_enable) {
95 		dp_h2t_cfg_stats_msg_send(pdev, DP_PPDU_STATS_CFG_ENH_STATS,
96 					  pdev->pdev_id);
97 	} else if (is_ppdu_txrx_capture_enabled(pdev) &&
98 		   mon_pdev->bpr_enable) {
99 		dp_h2t_cfg_stats_msg_send(pdev,
100 					  DP_PPDU_STATS_CFG_BPR_ENH,
101 					  pdev->pdev_id);
102 	}
103 }
104 
105 /**
106  * dp_mon_tx_disable_enhanced_stats_1_0() - Send HTT cmd to FW to disable stats
107  * @pdev: Datapath pdev handle
108  *
109  * Return: none
110  */
111 static void dp_mon_tx_disable_enhanced_stats_1_0(struct dp_pdev *pdev)
112 {
113 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
114 
115 	if (is_ppdu_txrx_capture_enabled(pdev) && !mon_pdev->bpr_enable) {
116 		dp_h2t_cfg_stats_msg_send(pdev, 0, pdev->pdev_id);
117 	} else if (is_ppdu_txrx_capture_enabled(pdev) && mon_pdev->bpr_enable) {
118 		dp_h2t_cfg_stats_msg_send(pdev,
119 					  DP_PPDU_STATS_CFG_BPR,
120 					  pdev->pdev_id);
121 	}
122 }
123 #endif
124 
125 #ifdef QCA_SUPPORT_FULL_MON
126 static QDF_STATUS
127 dp_config_full_mon_mode(struct cdp_soc_t *soc_handle,
128 			uint8_t val)
129 {
130 	struct dp_soc *soc = (struct dp_soc *)soc_handle;
131 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
132 
133 	mon_soc->full_mon_mode = val;
134 	dp_cdp_err("Configure full monitor mode val: %d ", val);
135 
136 	return QDF_STATUS_SUCCESS;
137 }
138 
139 static QDF_STATUS
140 dp_soc_config_full_mon_mode(struct cdp_pdev *cdp_pdev, uint8_t val)
141 {
142 	struct dp_pdev *pdev = (struct dp_pdev *)cdp_pdev;
143 	struct dp_soc *soc = pdev->soc;
144 	QDF_STATUS status = QDF_STATUS_SUCCESS;
145 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
146 
147 	if (!mon_soc->full_mon_mode)
148 		return QDF_STATUS_SUCCESS;
149 
150 	if ((htt_h2t_full_mon_cfg(soc->htt_handle,
151 				  pdev->pdev_id,
152 				  val)) != QDF_STATUS_SUCCESS) {
153 		status = QDF_STATUS_E_FAILURE;
154 	}
155 
156 	return status;
157 }
158 #else
159 static inline QDF_STATUS
160 dp_config_full_mon_mode(struct cdp_soc_t *soc_handle,
161 			uint8_t val)
162 {
163 	return 0;
164 }
165 
166 static inline QDF_STATUS
167 dp_soc_config_full_mon_mode(struct cdp_pdev *cdp_pdev,
168 			    uint8_t val)
169 {
170 	return 0;
171 }
172 #endif
173 
174 #if !defined(DISABLE_MON_CONFIG)
175 void dp_flush_monitor_rings(struct dp_soc *soc)
176 {
177 	struct dp_pdev *pdev = soc->pdev_list[0];
178 	hal_soc_handle_t hal_soc = soc->hal_soc;
179 	uint32_t lmac_id;
180 	uint32_t hp, tp;
181 	int budget;
182 	void *mon_dst_srng;
183 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
184 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
185 
186 	if (qdf_unlikely(mon_soc->full_mon_mode))
187 		return;
188 
189 	/* Reset monitor filters before reaping the ring*/
190 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
191 	dp_mon_filter_reset_mon_mode(pdev);
192 	if (dp_mon_filter_update(pdev) != QDF_STATUS_SUCCESS)
193 		dp_info("failed to reset monitor filters");
194 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
195 
196 	if (qdf_unlikely(mon_pdev->mon_chan_band >= REG_BAND_UNKNOWN))
197 		return;
198 
199 	lmac_id = pdev->ch_band_lmac_id_mapping[mon_pdev->mon_chan_band];
200 	if (qdf_unlikely(lmac_id == DP_MON_INVALID_LMAC_ID))
201 		return;
202 
203 	mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, lmac_id);
204 
205 	/* reap full ring */
206 	budget = wlan_cfg_get_dma_mon_stat_ring_size(pdev->wlan_cfg_ctx);
207 
208 	hal_get_sw_hptp(hal_soc, mon_dst_srng, &tp, &hp);
209 	dp_info("Before flush: Monitor DST ring HP %u TP %u", hp, tp);
210 
211 	dp_mon_drop_packets_for_mac(pdev, lmac_id, budget, true);
212 
213 	hal_get_sw_hptp(hal_soc, mon_dst_srng, &tp, &hp);
214 	dp_info("After flush: Monitor DST ring HP %u TP %u", hp, tp);
215 }
216 
217 void dp_mon_rings_deinit_1_0(struct dp_pdev *pdev)
218 {
219 	int mac_id = 0;
220 	struct dp_soc *soc = pdev->soc;
221 
222 	for (mac_id = 0;
223 	     mac_id  < soc->wlan_cfg_ctx->num_rxdma_status_rings_per_pdev;
224 	     mac_id++) {
225 		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id,
226 							 pdev->pdev_id);
227 
228 		dp_srng_deinit(soc, &soc->rxdma_mon_status_ring[lmac_id],
229 			       RXDMA_MONITOR_STATUS, 0);
230 		dp_srng_deinit(soc, &soc->sw2rxdma_link_ring[lmac_id],
231 			       SW2RXDMA_LINK_RELEASE, 0);
232 
233 		dp_mon_dest_rings_deinit(pdev, lmac_id);
234 	}
235 }
236 
237 void dp_mon_rings_free_1_0(struct dp_pdev *pdev)
238 {
239 	int mac_id = 0;
240 	struct dp_soc *soc = pdev->soc;
241 
242 
243 	for (mac_id = 0;
244 	     mac_id  < soc->wlan_cfg_ctx->num_rxdma_status_rings_per_pdev;
245 	     mac_id++) {
246 		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id,
247 							 pdev->pdev_id);
248 
249 		dp_srng_free(soc, &soc->rxdma_mon_status_ring[lmac_id]);
250 		dp_srng_free(soc, &soc->sw2rxdma_link_ring[lmac_id]);
251 
252 		dp_mon_dest_rings_free(pdev, lmac_id);
253 	}
254 }
255 
256 #ifdef WLAN_SOFTUMAC_SUPPORT
257 static QDF_STATUS
258 dp_mon_sw2rxdma_link_ring_alloc(struct dp_pdev *pdev, int lmac_id)
259 {
260 	struct dp_soc *soc = pdev->soc;
261 	struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx = pdev->wlan_cfg_ctx;
262 	int entries;
263 
264 	entries = wlan_cfg_get_dma_sw2rxdma_link_ring_size(pdev_cfg_ctx);
265 
266 	return dp_srng_alloc(soc, &soc->sw2rxdma_link_ring[lmac_id],
267 			     SW2RXDMA_LINK_RELEASE, entries, 0);
268 }
269 
270 static QDF_STATUS
271 dp_mon_sw2rxdma_link_ring_init(struct dp_soc *soc, int lmac_id)
272 {
273 	return dp_srng_init(soc, &soc->sw2rxdma_link_ring[lmac_id],
274 			    SW2RXDMA_LINK_RELEASE, 0, lmac_id);
275 }
276 #else
277 static QDF_STATUS
278 dp_mon_sw2rxdma_link_ring_alloc(struct dp_pdev *pdev, int lmac_id)
279 {
280 	return QDF_STATUS_SUCCESS;
281 }
282 
283 static QDF_STATUS
284 dp_mon_sw2rxdma_link_ring_init(struct dp_soc *soc, int lmac_id)
285 {
286 	return QDF_STATUS_SUCCESS;
287 }
288 #endif
289 
290 QDF_STATUS dp_mon_rings_init_1_0(struct dp_pdev *pdev)
291 {
292 	struct dp_soc *soc = pdev->soc;
293 	int mac_id = 0;
294 
295 	for (mac_id = 0;
296 	     mac_id  < soc->wlan_cfg_ctx->num_rxdma_status_rings_per_pdev;
297 	     mac_id++) {
298 		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id,
299 							 pdev->pdev_id);
300 
301 		if (dp_srng_init(soc, &soc->rxdma_mon_status_ring[lmac_id],
302 				 RXDMA_MONITOR_STATUS, 0, lmac_id)) {
303 			dp_mon_err("%pK: " RNG_ERR "rxdma_mon_status_ring",
304 				   soc);
305 			goto fail1;
306 		}
307 
308 		if (dp_mon_sw2rxdma_link_ring_init(soc, lmac_id)) {
309 			dp_mon_err("%pK: " RNG_ERR "sw2rxdma_link_ring", soc);
310 			goto fail1;
311 		}
312 
313 		if (dp_mon_dest_rings_init(pdev, lmac_id))
314 			goto fail1;
315 	}
316 	return QDF_STATUS_SUCCESS;
317 
318 fail1:
319 	dp_mon_rings_deinit_1_0(pdev);
320 	return QDF_STATUS_E_NOMEM;
321 }
322 
323 QDF_STATUS dp_mon_rings_alloc_1_0(struct dp_pdev *pdev)
324 {
325 	struct dp_soc *soc = pdev->soc;
326 	int mac_id = 0;
327 	int entries;
328 	struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx;
329 
330 	pdev_cfg_ctx = pdev->wlan_cfg_ctx;
331 
332 	for (mac_id = 0;
333 	     mac_id  < soc->wlan_cfg_ctx->num_rxdma_status_rings_per_pdev;
334 	     mac_id++) {
335 		int lmac_id =
336 		dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id);
337 		entries = wlan_cfg_get_dma_mon_stat_ring_size(pdev_cfg_ctx);
338 		if (dp_srng_alloc(soc, &soc->rxdma_mon_status_ring[lmac_id],
339 				  RXDMA_MONITOR_STATUS, entries, 0)) {
340 			dp_mon_err("%pK: " RNG_ERR "rxdma_mon_status_ring",
341 				   soc);
342 			goto fail1;
343 		}
344 
345 		if (dp_mon_sw2rxdma_link_ring_alloc(pdev, lmac_id)) {
346 			dp_mon_err("%pK: " RNG_ERR "sw2rxdma_link_ring", soc);
347 			goto fail1;
348 		}
349 
350 		if (dp_mon_dest_rings_alloc(pdev, lmac_id))
351 			goto fail1;
352 	}
353 	return QDF_STATUS_SUCCESS;
354 
355 fail1:
356 	dp_mon_rings_free_1_0(pdev);
357 	return QDF_STATUS_E_NOMEM;
358 }
359 #else
360 inline
361 void dp_flush_monitor_rings(struct dp_soc *soc)
362 {
363 }
364 
365 #endif
366 
367 #ifdef QCA_MONITOR_PKT_SUPPORT
368 QDF_STATUS dp_vdev_set_monitor_mode_buf_rings(struct dp_pdev *pdev)
369 {
370 	uint32_t mac_id;
371 	uint32_t mac_for_pdev;
372 	struct dp_srng *mon_buf_ring;
373 	uint32_t num_entries;
374 	struct dp_soc *soc = pdev->soc;
375 
376 	/* If delay monitor replenish is disabled, allocate link descriptor
377 	 * monitor ring buffers of ring size.
378 	 */
379 	if (!wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) {
380 		dp_vdev_set_monitor_mode_rings(pdev, false);
381 	} else {
382 		for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
383 			mac_for_pdev =
384 				dp_get_lmac_id_for_pdev_id(pdev->soc,
385 							   mac_id,
386 							   pdev->pdev_id);
387 
388 			dp_rx_pdev_mon_buf_buffers_alloc(pdev, mac_for_pdev,
389 							 FALSE);
390 			mon_buf_ring =
391 				&pdev->soc->rxdma_mon_buf_ring[mac_for_pdev];
392 			/*
393 			 * Configure low interrupt threshld when monitor mode is
394 			 * configured.
395 			 */
396 			if (mon_buf_ring->hal_srng) {
397 				num_entries = mon_buf_ring->num_entries;
398 				hal_set_low_threshold(mon_buf_ring->hal_srng,
399 						      num_entries >> 3);
400 				htt_srng_setup(pdev->soc->htt_handle,
401 					       pdev->pdev_id,
402 					       mon_buf_ring->hal_srng,
403 					       RXDMA_MONITOR_BUF);
404 			}
405 		}
406 	}
407 	return QDF_STATUS_SUCCESS;
408 }
409 #endif
410 
411 #ifdef QCA_MONITOR_PKT_SUPPORT
412 QDF_STATUS dp_vdev_set_monitor_mode_rings(struct dp_pdev *pdev,
413 					  uint8_t delayed_replenish)
414 {
415 	uint32_t mac_id;
416 	uint32_t mac_for_pdev;
417 	struct dp_soc *soc = pdev->soc;
418 	QDF_STATUS status = QDF_STATUS_SUCCESS;
419 	struct dp_srng *mon_buf_ring;
420 	uint32_t num_entries;
421 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
422 	uint32_t target_type = hal_get_target_type(soc->hal_soc);
423 
424 	/* If monitor rings are already initialized, return from here */
425 	if (mon_pdev->pdev_mon_init)
426 		return QDF_STATUS_SUCCESS;
427 
428 	if (target_type == TARGET_TYPE_QCN9160) {
429 		dp_alert("Mon SOC:%pK config, skip desc pool alloc", soc);
430 		goto pass;
431 	}
432 
433 	for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) {
434 		mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id,
435 							  pdev->pdev_id);
436 
437 		/* Allocate sw rx descriptor pool for mon RxDMA buffer ring */
438 		status = dp_rx_pdev_mon_buf_desc_pool_alloc(pdev, mac_for_pdev);
439 		if (!QDF_IS_STATUS_SUCCESS(status)) {
440 			dp_err("%s: dp_rx_pdev_mon_buf_desc_pool_alloc() failed",
441 			       __func__);
442 			goto fail0;
443 		}
444 
445 		dp_rx_pdev_mon_buf_desc_pool_init(pdev, mac_for_pdev);
446 
447 		/* If monitor buffers are already allocated,
448 		 * do not allocate.
449 		 */
450 		status = dp_rx_pdev_mon_buf_buffers_alloc(pdev, mac_for_pdev,
451 							  delayed_replenish);
452 
453 		mon_buf_ring = &pdev->soc->rxdma_mon_buf_ring[mac_for_pdev];
454 		/*
455 		 * Configure low interrupt threshld when monitor mode is
456 		 * configured.
457 		 */
458 		if (mon_buf_ring->hal_srng) {
459 			num_entries = mon_buf_ring->num_entries;
460 			hal_set_low_threshold(mon_buf_ring->hal_srng,
461 					      num_entries >> 3);
462 			htt_srng_setup(pdev->soc->htt_handle,
463 				       pdev->pdev_id,
464 				       mon_buf_ring->hal_srng,
465 				       RXDMA_MONITOR_BUF);
466 		}
467 
468 		/* Allocate link descriptors for the mon link descriptor ring */
469 		status = dp_hw_link_desc_pool_banks_alloc(soc, mac_for_pdev);
470 		if (!QDF_IS_STATUS_SUCCESS(status)) {
471 			dp_err("%s: dp_hw_link_desc_pool_banks_alloc() failed",
472 			       __func__);
473 			goto fail0;
474 		}
475 		dp_link_desc_ring_replenish(soc, mac_for_pdev);
476 
477 		htt_srng_setup(soc->htt_handle, pdev->pdev_id,
478 			       soc->rxdma_mon_desc_ring[mac_for_pdev].hal_srng,
479 			       RXDMA_MONITOR_DESC);
480 		htt_srng_setup(soc->htt_handle, pdev->pdev_id,
481 			       soc->rxdma_mon_dst_ring[mac_for_pdev].hal_srng,
482 			       RXDMA_MONITOR_DST);
483 	}
484 pass:
485 	mon_pdev->pdev_mon_init = 1;
486 	return QDF_STATUS_SUCCESS;
487 
488 fail0:
489 	return QDF_STATUS_E_FAILURE;
490 }
491 #endif
492 
493 /* dp_mon_vdev_timer()- timer poll for interrupts
494  *
495  * @arg: SoC Handle
496  *
497  * Return:
498  *
499  */
500 static void dp_mon_vdev_timer(void *arg)
501 {
502 	struct dp_soc *soc = (struct dp_soc *)arg;
503 	struct dp_pdev *pdev = soc->pdev_list[0];
504 	enum timer_yield_status yield = DP_TIMER_NO_YIELD;
505 	uint32_t work_done  = 0, total_work_done = 0;
506 	int budget = 0xffff;
507 	uint32_t remaining_quota = budget;
508 	uint64_t start_time;
509 	uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
510 	uint32_t lmac_iter;
511 	int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
512 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
513 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
514 
515 	if (!qdf_atomic_read(&soc->cmn_init_done))
516 		return;
517 
518 	if (mon_pdev->mon_chan_band != REG_BAND_UNKNOWN)
519 		lmac_id = pdev->ch_band_lmac_id_mapping[mon_pdev->mon_chan_band];
520 
521 	start_time = qdf_get_log_timestamp();
522 	dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings);
523 
524 	while (yield == DP_TIMER_NO_YIELD) {
525 		for (lmac_iter = 0; lmac_iter < max_mac_rings; lmac_iter++) {
526 			if (lmac_iter == lmac_id)
527 				work_done = dp_monitor_process(
528 						    soc, NULL,
529 						    lmac_iter, remaining_quota);
530 			else
531 				work_done =
532 					dp_monitor_drop_packets_for_mac(pdev,
533 								     lmac_iter,
534 								     remaining_quota);
535 			if (work_done) {
536 				budget -=  work_done;
537 				if (budget <= 0) {
538 					yield = DP_TIMER_WORK_EXHAUST;
539 					goto budget_done;
540 				}
541 				remaining_quota = budget;
542 				total_work_done += work_done;
543 			}
544 		}
545 
546 		yield = dp_should_timer_irq_yield(soc, total_work_done,
547 						  start_time);
548 		total_work_done = 0;
549 	}
550 
551 budget_done:
552 	if (yield == DP_TIMER_WORK_EXHAUST ||
553 	    yield == DP_TIMER_TIME_EXHAUST)
554 		qdf_timer_mod(&mon_soc->mon_vdev_timer, 1);
555 	else
556 		qdf_timer_mod(&mon_soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
557 }
558 
559 /* MCL specific functions */
560 #if defined(DP_CON_MON)
561 /**
562  * dp_mon_reap_timer_handler()- timer to reap monitor rings
563  * reqd as we are not getting ppdu end interrupts
564  * @arg: SoC Handle
565  *
566  * Return:
567  *
568  */
569 static void dp_mon_reap_timer_handler(void *arg)
570 {
571 	struct dp_soc *soc = (struct dp_soc *)arg;
572 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
573 
574 	dp_service_mon_rings(soc, QCA_NAPI_BUDGET);
575 
576 	qdf_timer_mod(&mon_soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
577 }
578 
579 static void dp_mon_reap_timer_init(struct dp_soc *soc)
580 {
581 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
582 
583 	qdf_spinlock_create(&mon_soc->reap_timer_lock);
584 	qdf_timer_init(soc->osdev, &mon_soc->mon_reap_timer,
585 		       dp_mon_reap_timer_handler, (void *)soc,
586 		       QDF_TIMER_TYPE_WAKE_APPS);
587 	qdf_mem_zero(mon_soc->mon_reap_src_bitmap,
588 		     sizeof(mon_soc->mon_reap_src_bitmap));
589 	mon_soc->reap_timer_init = 1;
590 }
591 #else
592 static void dp_mon_reap_timer_init(struct dp_soc *soc)
593 {
594 }
595 #endif
596 
597 static void dp_mon_reap_timer_deinit(struct dp_soc *soc)
598 {
599 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
600         if (mon_soc->reap_timer_init) {
601 		mon_soc->reap_timer_init = 0;
602 		qdf_timer_free(&mon_soc->mon_reap_timer);
603 		qdf_spinlock_destroy(&mon_soc->reap_timer_lock);
604         }
605 }
606 
607 /**
608  * dp_mon_is_irq_enabled() - check if DP monitor status srng irq enabled
609  * @soc: point to soc
610  *
611  * Return: true if irq enabled, false if not.
612  */
613 static bool
614 dp_mon_is_irq_enabled(struct dp_soc *soc)
615 {
616 	void *mon_status_srng;
617 
618 	mon_status_srng = soc->rxdma_mon_status_ring[0].hal_srng;
619 
620 	if (!mon_status_srng)
621 		return false;
622 
623 	return hal_srng_batch_threshold_irq_enabled(mon_status_srng);
624 }
625 
626 /**
627  * dp_mon_reap_timer_start() - start reap timer of monitor status ring
628  * @soc: point to soc
629  * @source: trigger source
630  *
631  * If the source is CDP_MON_REAP_SOURCE_ANY, skip bit set, and start timer
632  * if any bit has been set in the bitmap; while for the other sources, set
633  * the bit and start timer if the bitmap is empty before that.
634  *
635  * Return: true if timer-start is performed, false otherwise.
636  */
637 static bool
638 dp_mon_reap_timer_start(struct dp_soc *soc, enum cdp_mon_reap_source source)
639 {
640 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
641 	bool do_start;
642 
643 	/* if monitor status ring irq enabled, no need to start timer */
644 	if (!mon_soc->reap_timer_init || dp_mon_is_irq_enabled(soc))
645 		return false;
646 
647 	qdf_spin_lock_bh(&mon_soc->reap_timer_lock);
648 	do_start = qdf_bitmap_empty(mon_soc->mon_reap_src_bitmap,
649 				    CDP_MON_REAP_SOURCE_NUM);
650 	if (source == CDP_MON_REAP_SOURCE_ANY)
651 		do_start = !do_start;
652 	else
653 		qdf_set_bit(source, mon_soc->mon_reap_src_bitmap);
654 	qdf_spin_unlock_bh(&mon_soc->reap_timer_lock);
655 
656 	if (do_start)
657 		qdf_timer_mod(&mon_soc->mon_reap_timer, DP_INTR_POLL_TIMER_MS);
658 
659 	return do_start;
660 }
661 
662 /**
663  * dp_mon_reap_timer_stop() - stop reap timer of monitor status ring
664  * @soc: point to soc
665  * @source: trigger source
666  *
667  * If the source is CDP_MON_REAP_SOURCE_ANY, skip bit clear, and stop timer
668  * if any bit has been set in the bitmap; while for the other sources, clear
669  * the bit and stop the timer if the bitmap is empty after that.
670  *
671  * Return: true if timer-stop is performed, false otherwise.
672  */
673 static bool
674 dp_mon_reap_timer_stop(struct dp_soc *soc, enum cdp_mon_reap_source source)
675 {
676 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
677 	bool do_stop;
678 
679 	if (!mon_soc->reap_timer_init || dp_mon_is_irq_enabled(soc))
680 		return false;
681 
682 	qdf_spin_lock_bh(&mon_soc->reap_timer_lock);
683 	if (source != CDP_MON_REAP_SOURCE_ANY)
684 		qdf_clear_bit(source, mon_soc->mon_reap_src_bitmap);
685 
686 	do_stop = qdf_bitmap_empty(mon_soc->mon_reap_src_bitmap,
687 				   CDP_MON_REAP_SOURCE_NUM);
688 	if (source == CDP_MON_REAP_SOURCE_ANY)
689 		do_stop = !do_stop;
690 	qdf_spin_unlock_bh(&mon_soc->reap_timer_lock);
691 
692 	if (do_stop)
693 		qdf_timer_sync_cancel(&mon_soc->mon_reap_timer);
694 
695 	return do_stop;
696 }
697 
698 static void dp_mon_vdev_timer_init(struct dp_soc *soc)
699 {
700 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
701 
702         qdf_timer_init(soc->osdev, &mon_soc->mon_vdev_timer,
703                        dp_mon_vdev_timer, (void *)soc,
704                        QDF_TIMER_TYPE_WAKE_APPS);
705         mon_soc->mon_vdev_timer_state |= MON_VDEV_TIMER_INIT;
706 }
707 
708 static void dp_mon_vdev_timer_deinit(struct dp_soc *soc)
709 {
710 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
711         if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
712                 qdf_timer_free(&mon_soc->mon_vdev_timer);
713                 mon_soc->mon_vdev_timer_state = 0;
714         }
715 }
716 
717 static void dp_mon_vdev_timer_start(struct dp_soc *soc)
718 {
719 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
720         if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_INIT) {
721                 qdf_timer_mod(&mon_soc->mon_vdev_timer, DP_INTR_POLL_TIMER_MS);
722                 mon_soc->mon_vdev_timer_state |= MON_VDEV_TIMER_RUNNING;
723         }
724 }
725 
726 static bool dp_mon_vdev_timer_stop(struct dp_soc *soc)
727 {
728 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
729         if (mon_soc->mon_vdev_timer_state & MON_VDEV_TIMER_RUNNING) {
730                 qdf_timer_sync_cancel(&mon_soc->mon_vdev_timer);
731                 mon_soc->mon_vdev_timer_state &= ~MON_VDEV_TIMER_RUNNING;
732 		return true;
733         }
734 
735 	return false;
736 }
737 
738 static void dp_mon_neighbour_peer_add_ast(struct dp_pdev *pdev,
739 					  struct dp_peer *ta_peer,
740 					  uint8_t *mac_addr,
741 					  qdf_nbuf_t nbuf,
742 					  uint32_t flags)
743 {
744 	struct dp_neighbour_peer *neighbour_peer = NULL;
745 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
746 	struct dp_soc *soc = pdev->soc;
747 
748 	if (mon_pdev->neighbour_peers_added) {
749 		qdf_mem_copy(mac_addr,
750 			     (qdf_nbuf_data(nbuf) +
751 			      QDF_MAC_ADDR_SIZE),
752 			      QDF_MAC_ADDR_SIZE);
753 
754 		qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex);
755 		TAILQ_FOREACH(neighbour_peer,
756 			      &mon_pdev->neighbour_peers_list,
757 			      neighbour_peer_list_elem) {
758 			if (!qdf_mem_cmp(&neighbour_peer->neighbour_peers_macaddr,
759 					 mac_addr,
760 					 QDF_MAC_ADDR_SIZE)) {
761 				dp_peer_add_ast(soc,
762 						ta_peer,
763 						mac_addr,
764 						CDP_TXRX_AST_TYPE_WDS,
765 						flags);
766 				QDF_TRACE(QDF_MODULE_ID_DP,
767 					  QDF_TRACE_LEVEL_INFO,
768 					  "sa valid and nac roamed to wds");
769 				break;
770 			}
771 		}
772 		qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex);
773 	}
774 }
775 
776 #if !defined(DISABLE_MON_CONFIG)
777 #if defined(DP_CON_MON)
778 QDF_STATUS dp_mon_htt_srng_setup_1_0(struct dp_soc *soc,
779 				     struct dp_pdev *pdev,
780 				     int mac_id,
781 				     int mac_for_pdev)
782 {
783 	QDF_STATUS status = QDF_STATUS_SUCCESS;
784 
785 	status = dp_mon_htt_dest_srng_setup(soc, pdev, mac_id, mac_for_pdev);
786 	if (status != QDF_STATUS_SUCCESS)
787 		return status;
788 
789 	if (!soc->rxdma_mon_status_ring[mac_id].hal_srng)
790 		return QDF_STATUS_SUCCESS;
791 
792 	status = htt_srng_setup(soc->htt_handle, mac_for_pdev,
793 				soc->rxdma_mon_status_ring[mac_id]
794 				.hal_srng,
795 				RXDMA_MONITOR_STATUS);
796 
797 	if (status != QDF_STATUS_SUCCESS) {
798 		dp_mon_err("Failed to send htt srng setup message for Rxdma mon status ring");
799 		return status;
800 	}
801 
802 	if (!soc->sw2rxdma_link_ring[mac_id].hal_srng)
803 		return QDF_STATUS_SUCCESS;
804 
805 	status = htt_srng_setup(soc->htt_handle, mac_for_pdev,
806 				soc->sw2rxdma_link_ring[mac_id].hal_srng,
807 				SW2RXDMA_LINK_RELEASE);
808 
809 	if (status != QDF_STATUS_SUCCESS) {
810 		dp_mon_err("Failed to send htt srng setup message for sw2rxdma link ring");
811 		return status;
812 	}
813 
814 	return status;
815 }
816 #else
817 /* This is only for WIN */
818 QDF_STATUS dp_mon_htt_srng_setup_1_0(struct dp_soc *soc,
819 				     struct dp_pdev *pdev,
820 				     int mac_id,
821 				     int mac_for_pdev)
822 {
823 	QDF_STATUS status = QDF_STATUS_SUCCESS;
824 	struct dp_mon_soc *mon_soc;
825 
826 	mon_soc = soc->monitor_soc;
827 	if(!mon_soc) {
828 		dp_mon_err("%pK: monitor SOC not initialized", soc);
829 		return status;
830 	}
831 
832 	if (mon_soc->monitor_mode_v2)
833 		return status;
834 
835 	if (wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) {
836 		status = dp_mon_htt_dest_srng_setup(soc, pdev,
837 						    mac_id, mac_for_pdev);
838 		if (status != QDF_STATUS_SUCCESS)
839 			return status;
840 	}
841 
842 	if (!soc->rxdma_mon_status_ring[mac_id].hal_srng)
843 		return QDF_STATUS_SUCCESS;
844 
845 	status = htt_srng_setup(soc->htt_handle, mac_for_pdev,
846 				soc->rxdma_mon_status_ring[mac_id]
847 				.hal_srng,
848 				RXDMA_MONITOR_STATUS);
849 
850 	if (status != QDF_STATUS_SUCCESS) {
851 		dp_mon_err("Failed to send htt srng setup msg for Rxdma mon status ring");
852 		return status;
853 	}
854 
855 	return status;
856 }
857 #endif
858 #endif
859 
860 /* MCL specific functions */
861 #if defined(DP_CON_MON)
862 
863 /**
864  * dp_service_mon_rings() - service monitor rings
865  * @soc: soc dp handle
866  * @quota: number of ring entry that can be serviced
867  *
868  * Return: None
869  *
870  */
871 void dp_service_mon_rings(struct  dp_soc *soc, uint32_t quota)
872 {
873 	int ring = 0, work_done;
874 	struct dp_pdev *pdev = NULL;
875 
876 	for (ring = 0 ; ring < MAX_NUM_LMAC_HW; ring++) {
877 		pdev = dp_get_pdev_for_lmac_id(soc, ring);
878 		if (!pdev)
879 			continue;
880 		work_done = dp_mon_process(soc, NULL, ring, quota);
881 
882 		dp_rx_mon_dest_debug("Reaped %d descs from Monitor rings",
883 				     work_done);
884 	}
885 }
886 #endif
887 
888 /**
889  * dp_mon_peer_tx_init() - Initialize receive TID state in monitor peer
890  * @pdev: Datapath pdev
891  * @peer: Datapath peer
892  *
893  */
894 static void
895 dp_mon_peer_tx_init(struct dp_pdev *pdev, struct dp_peer *peer)
896 {
897 	if (!peer->monitor_peer)
898 		return;
899 
900 	dp_peer_tid_queue_init(peer);
901 	dp_peer_update_80211_hdr(peer->vdev, peer);
902 }
903 
904 /**
905  * dp_mon_peer_tx_cleanup() - Deinitialize receive TID state in monitor peer
906  * @vdev: Datapath vdev
907  * @peer: Datapath peer
908  *
909  */
910 static void
911 dp_mon_peer_tx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
912 {
913 	if (!peer->monitor_peer)
914 		return;
915 
916 	dp_peer_tid_queue_cleanup(peer);
917 }
918 
919 #ifdef QCA_SUPPORT_BPR
920 static QDF_STATUS
921 dp_set_bpr_enable_1_0(struct dp_pdev *pdev, int val)
922 {
923 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
924 
925 	switch (val) {
926 	case CDP_BPR_DISABLE:
927 		mon_pdev->bpr_enable = CDP_BPR_DISABLE;
928 		if (!mon_pdev->pktlog_ppdu_stats &&
929 		    !mon_pdev->enhanced_stats_en &&
930 		    !mon_pdev->tx_sniffer_enable && !mon_pdev->mcopy_mode) {
931 			dp_h2t_cfg_stats_msg_send(pdev, 0, pdev->pdev_id);
932 		} else if (mon_pdev->enhanced_stats_en &&
933 			   !mon_pdev->tx_sniffer_enable &&
934 			   !mon_pdev->mcopy_mode &&
935 			   !mon_pdev->pktlog_ppdu_stats) {
936 			dp_h2t_cfg_stats_msg_send(pdev,
937 						  DP_PPDU_STATS_CFG_ENH_STATS,
938 						  pdev->pdev_id);
939 		}
940 		break;
941 	case CDP_BPR_ENABLE:
942 		mon_pdev->bpr_enable = CDP_BPR_ENABLE;
943 		if (!mon_pdev->enhanced_stats_en &&
944 		    !mon_pdev->tx_sniffer_enable &&
945 		    !mon_pdev->mcopy_mode && !mon_pdev->pktlog_ppdu_stats) {
946 			dp_h2t_cfg_stats_msg_send(pdev,
947 						  DP_PPDU_STATS_CFG_BPR,
948 						  pdev->pdev_id);
949 		} else if (mon_pdev->enhanced_stats_en &&
950 			   !mon_pdev->tx_sniffer_enable &&
951 			   !mon_pdev->mcopy_mode &&
952 			   !mon_pdev->pktlog_ppdu_stats) {
953 			dp_h2t_cfg_stats_msg_send(pdev,
954 						  DP_PPDU_STATS_CFG_BPR_ENH,
955 						  pdev->pdev_id);
956 		} else if (mon_pdev->pktlog_ppdu_stats) {
957 			dp_h2t_cfg_stats_msg_send(pdev,
958 						  DP_PPDU_STATS_CFG_BPR_PKTLOG,
959 						  pdev->pdev_id);
960 		}
961 		break;
962 	default:
963 		break;
964 	}
965 
966 	return QDF_STATUS_SUCCESS;
967 }
968 #endif
969 
970 #ifdef QCA_ENHANCED_STATS_SUPPORT
971 #if defined(WDI_EVENT_ENABLE) && !defined(WLAN_TX_PKT_CAPTURE_ENH)
972 /**
973  * dp_ppdu_desc_notify_1_0 - Notify upper layer for PPDU indication via WDI
974  *
975  * @pdev: Datapath pdev handle
976  * @nbuf: Buffer to be shipped
977  *
978  * Return: void
979  */
980 static void dp_ppdu_desc_notify_1_0(struct dp_pdev *pdev, qdf_nbuf_t nbuf)
981 {
982 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
983 	struct cdp_tx_completion_ppdu *ppdu_desc = NULL;
984 
985 	ppdu_desc = (struct cdp_tx_completion_ppdu *)qdf_nbuf_data(nbuf);
986 
987 	/*
988 	 * Deliver PPDU stats only for valid (acked) data
989 	 * frames if sniffer mode is not enabled.
990 	 * If sniffer mode is enabled, PPDU stats
991 	 * for all frames including mgmt/control
992 	 * frames should be delivered to upper layer
993 	 */
994 	if (mon_pdev->tx_sniffer_enable || mon_pdev->mcopy_mode) {
995 		dp_wdi_event_handler(WDI_EVENT_TX_PPDU_DESC,
996 				     pdev->soc,
997 				     nbuf, HTT_INVALID_PEER,
998 				     WDI_NO_VAL,
999 				     pdev->pdev_id);
1000 	} else {
1001 		if (ppdu_desc->num_mpdu != 0 &&
1002 		    ppdu_desc->num_users != 0 &&
1003 		    ppdu_desc->frame_ctrl &
1004 		    HTT_FRAMECTRL_DATATYPE) {
1005 			dp_wdi_event_handler(WDI_EVENT_TX_PPDU_DESC,
1006 					     pdev->soc,
1007 					     nbuf, HTT_INVALID_PEER,
1008 					     WDI_NO_VAL,
1009 					     pdev->pdev_id);
1010 		} else {
1011 			qdf_nbuf_free(nbuf);
1012 		}
1013 	}
1014 }
1015 #endif
1016 
1017 /**
1018  * dp_ppdu_stats_feat_enable_check_1_0() - Check if feature(s) is enabled to
1019  *				consume ppdu stats from FW
1020  *
1021  * @pdev: Datapath pdev handle
1022  *
1023  * Return: true if enabled, else return false
1024  */
1025 static bool dp_ppdu_stats_feat_enable_check_1_0(struct dp_pdev *pdev)
1026 {
1027 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
1028 
1029 	if (!mon_pdev->enhanced_stats_en && !mon_pdev->tx_sniffer_enable &&
1030 	    !mon_pdev->mcopy_mode && !mon_pdev->bpr_enable)
1031 		return false;
1032 	else
1033 		return true;
1034 }
1035 
1036 /**
1037  * dp_mon_tx_stats_update_1_0() - Update Tx stats from HTT PPDU completion path
1038  *
1039  * @mon_peer: Monitor peer
1040  * @ppdu: Tx PPDU user completion info
1041  */
1042 static void
1043 dp_mon_tx_stats_update_1_0(struct dp_mon_peer *mon_peer,
1044 			   struct cdp_tx_completion_ppdu_user *ppdu)
1045 {
1046 	ppdu->punc_mode = NO_PUNCTURE;
1047 }
1048 #endif
1049 
1050 #ifndef QCA_SUPPORT_FULL_MON
1051 /**
1052  * dp_rx_mon_process() - Core brain processing for monitor mode
1053  *
1054  * This API processes monitor destination ring followed by monitor status ring
1055  * Called from bottom half (tasklet/NET_RX_SOFTIRQ)
1056  *
1057  * @soc: datapath soc context
1058  * @int_ctx: interrupt context
1059  * @mac_id: mac_id on which interrupt is received
1060  * @quota: Number of status ring entry that can be serviced in one shot.
1061  *
1062  * Return: Number of reaped status ring entries
1063  */
1064 static inline uint32_t
1065 dp_rx_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx,
1066 		  uint32_t mac_id, uint32_t quota)
1067 {
1068 	return quota;
1069 }
1070 #endif
1071 
1072 #ifndef DISABLE_MON_CONFIG
1073 static uint32_t
1074 dp_rx_mon_process_1_0(struct dp_soc *soc, struct dp_intr *int_ctx,
1075 	              uint32_t mac_id, uint32_t quota)
1076 {
1077 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1078 
1079 	if (qdf_unlikely(mon_soc->full_mon_mode))
1080 		return dp_rx_mon_process(soc, int_ctx, mac_id, quota);
1081 
1082 	return dp_rx_mon_status_process(soc, int_ctx, mac_id, quota);
1083 }
1084 
1085 #if defined(WDI_EVENT_ENABLE) &&\
1086 	(defined(QCA_ENHANCED_STATS_SUPPORT) || !defined(REMOVE_PKT_LOG) ||\
1087 	 defined(WLAN_FEATURE_PKT_CAPTURE_V2))
1088 static inline
1089 void dp_mon_ppdu_stats_handler_register(struct dp_mon_soc *mon_soc)
1090 {
1091 	mon_soc->mon_ops->mon_ppdu_stats_ind_handler =
1092 					dp_ppdu_stats_ind_handler;
1093 }
1094 #else
1095 static inline
1096 void dp_mon_ppdu_stats_handler_register(struct dp_mon_soc *mon_soc)
1097 {
1098 }
1099 #endif
1100 
1101 static void dp_mon_register_intr_ops_1_0(struct dp_soc *soc)
1102 {
1103 	struct dp_mon_soc *mon_soc = soc->monitor_soc;
1104 
1105 	mon_soc->mon_rx_process = dp_rx_mon_process_1_0;
1106 	dp_mon_ppdu_stats_handler_register(mon_soc);
1107 }
1108 #endif
1109 
1110 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
1111 /*
1112  * dp_update_filter_neighbour_peers() - set neighbour peers(nac clients)
1113  * address for smart mesh filtering
1114  * @txrx_soc: cdp soc handle
1115  * @vdev_id: id of virtual device object
1116  * @cmd: Add/Del command
1117  * @macaddr: nac client mac address
1118  *
1119  * Return: success/failure
1120  */
1121 static int dp_update_filter_neighbour_peers(struct cdp_soc_t *soc_hdl,
1122 					    uint8_t vdev_id,
1123 					    uint32_t cmd, uint8_t *macaddr)
1124 {
1125 	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
1126 	struct dp_pdev *pdev;
1127 	struct dp_neighbour_peer *peer = NULL;
1128 	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
1129 						     DP_MOD_ID_CDP);
1130 	struct dp_mon_pdev *mon_pdev;
1131 
1132 	if (!vdev || !macaddr)
1133 		goto fail0;
1134 
1135 	pdev = vdev->pdev;
1136 
1137 	if (!pdev)
1138 		goto fail0;
1139 
1140 	mon_pdev = pdev->monitor_pdev;
1141 
1142 	/* Store address of NAC (neighbour peer) which will be checked
1143 	 * against TA of received packets.
1144 	 */
1145 	if (cmd == DP_NAC_PARAM_ADD) {
1146 		peer = (struct dp_neighbour_peer *)qdf_mem_malloc(
1147 				sizeof(*peer));
1148 
1149 		if (!peer) {
1150 			dp_cdp_err("%pK: DP neighbour peer node memory allocation failed"
1151 				   , soc);
1152 			goto fail0;
1153 		}
1154 
1155 		qdf_mem_copy(&peer->neighbour_peers_macaddr.raw[0],
1156 			     macaddr, QDF_MAC_ADDR_SIZE);
1157 		peer->vdev = vdev;
1158 
1159 		qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex);
1160 
1161 		/* add this neighbour peer into the list */
1162 		TAILQ_INSERT_TAIL(&mon_pdev->neighbour_peers_list, peer,
1163 				  neighbour_peer_list_elem);
1164 		qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex);
1165 
1166 		/* first neighbour */
1167 		if (!mon_pdev->neighbour_peers_added) {
1168 			QDF_STATUS status = QDF_STATUS_SUCCESS;
1169 
1170 			mon_pdev->neighbour_peers_added = true;
1171 			dp_mon_filter_setup_smart_monitor(pdev);
1172 			status = dp_mon_filter_update(pdev);
1173 			if (status != QDF_STATUS_SUCCESS) {
1174 				dp_cdp_err("%pK: smart mon filter setup failed",
1175 					   soc);
1176 				dp_mon_filter_reset_smart_monitor(pdev);
1177 				mon_pdev->neighbour_peers_added = false;
1178 			}
1179 		}
1180 
1181 	} else if (cmd == DP_NAC_PARAM_DEL) {
1182 		qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex);
1183 		TAILQ_FOREACH(peer, &mon_pdev->neighbour_peers_list,
1184 			      neighbour_peer_list_elem) {
1185 			if (!qdf_mem_cmp(&peer->neighbour_peers_macaddr.raw[0],
1186 					 macaddr, QDF_MAC_ADDR_SIZE)) {
1187 				/* delete this peer from the list */
1188 				TAILQ_REMOVE(&mon_pdev->neighbour_peers_list,
1189 					     peer, neighbour_peer_list_elem);
1190 				qdf_mem_free(peer);
1191 				break;
1192 			}
1193 		}
1194 		/* last neighbour deleted */
1195 		if (TAILQ_EMPTY(&mon_pdev->neighbour_peers_list)) {
1196 			QDF_STATUS status = QDF_STATUS_SUCCESS;
1197 
1198 			dp_mon_filter_reset_smart_monitor(pdev);
1199 			status = dp_mon_filter_update(pdev);
1200 			if (status != QDF_STATUS_SUCCESS) {
1201 				dp_cdp_err("%pK: smart mon filter clear failed",
1202 					   soc);
1203 			}
1204 			mon_pdev->neighbour_peers_added = false;
1205 		}
1206 		qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex);
1207 	}
1208 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
1209 	return 1;
1210 
1211 fail0:
1212 	if (vdev)
1213 		dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
1214 	return 0;
1215 }
1216 #endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
1217 
1218 #ifdef ATH_SUPPORT_NAC_RSSI
1219 /**
1220  * dp_vdev_get_neighbour_rssi(): Store RSSI for configured NAC
1221  * @soc_hdl: DP soc handle
1222  * @vdev_id: id of DP vdev handle
1223  * @mac_addr: neighbour mac
1224  * @rssi: rssi value
1225  *
1226  * Return: 0 for success. nonzero for failure.
1227  */
1228 static QDF_STATUS  dp_vdev_get_neighbour_rssi(struct cdp_soc_t *soc_hdl,
1229 					      uint8_t vdev_id,
1230 					      char *mac_addr,
1231 					      uint8_t *rssi)
1232 {
1233 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
1234 	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
1235 						     DP_MOD_ID_CDP);
1236 	struct dp_pdev *pdev;
1237 	struct dp_neighbour_peer *peer = NULL;
1238 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
1239 	struct dp_mon_pdev *mon_pdev;
1240 
1241 	if (!vdev)
1242 		return status;
1243 
1244 	pdev = vdev->pdev;
1245 	mon_pdev = pdev->monitor_pdev;
1246 
1247 	*rssi = 0;
1248 	qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex);
1249 	TAILQ_FOREACH(peer, &mon_pdev->neighbour_peers_list,
1250 		      neighbour_peer_list_elem) {
1251 		if (qdf_mem_cmp(&peer->neighbour_peers_macaddr.raw[0],
1252 				mac_addr, QDF_MAC_ADDR_SIZE) == 0) {
1253 			*rssi = peer->rssi;
1254 			status = QDF_STATUS_SUCCESS;
1255 			break;
1256 		}
1257 	}
1258 	qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex);
1259 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
1260 	return status;
1261 }
1262 
1263 static QDF_STATUS
1264 dp_config_for_nac_rssi(struct cdp_soc_t *cdp_soc,
1265 		       uint8_t vdev_id,
1266 		       enum cdp_nac_param_cmd cmd, char *bssid,
1267 		       char *client_macaddr,
1268 		       uint8_t chan_num)
1269 {
1270 	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
1271 	struct dp_vdev *vdev = dp_vdev_get_ref_by_id(soc, vdev_id,
1272 						     DP_MOD_ID_CDP);
1273 	struct dp_pdev *pdev;
1274 	struct dp_mon_pdev *mon_pdev;
1275 
1276 	if (!vdev)
1277 		return QDF_STATUS_E_FAILURE;
1278 
1279 	pdev = (struct dp_pdev *)vdev->pdev;
1280 
1281 	mon_pdev = pdev->monitor_pdev;
1282 	mon_pdev->nac_rssi_filtering = 1;
1283 	/* Store address of NAC (neighbour peer) which will be checked
1284 	 * against TA of received packets.
1285 	 */
1286 
1287 	if (cmd == CDP_NAC_PARAM_ADD) {
1288 		dp_update_filter_neighbour_peers(cdp_soc, vdev->vdev_id,
1289 						 DP_NAC_PARAM_ADD,
1290 						 (uint8_t *)client_macaddr);
1291 	} else if (cmd == CDP_NAC_PARAM_DEL) {
1292 		dp_update_filter_neighbour_peers(cdp_soc, vdev->vdev_id,
1293 						 DP_NAC_PARAM_DEL,
1294 						 (uint8_t *)client_macaddr);
1295 	}
1296 
1297 	if (soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi)
1298 		soc->cdp_soc.ol_ops->config_bssid_in_fw_for_nac_rssi
1299 			(soc->ctrl_psoc, pdev->pdev_id,
1300 			 vdev->vdev_id, cmd, bssid, client_macaddr);
1301 
1302 	dp_vdev_unref_delete(soc, vdev, DP_MOD_ID_CDP);
1303 	return QDF_STATUS_SUCCESS;
1304 }
1305 #endif
1306 
1307 /**
1308  * dp_mon_register_feature_ops_1_0() - register feature ops
1309  *
1310  * @soc: dp soc context
1311  *
1312  * @return: void
1313  */
1314 static void
1315 dp_mon_register_feature_ops_1_0(struct dp_soc *soc)
1316 {
1317 	struct dp_mon_ops *mon_ops = dp_mon_ops_get(soc);
1318 
1319 	if (!mon_ops) {
1320 		dp_err("mon_ops is NULL, feature ops registration failed");
1321 		return;
1322 	}
1323 
1324 	mon_ops->mon_config_debug_sniffer = dp_config_debug_sniffer;
1325 	mon_ops->mon_peer_tx_init = dp_mon_peer_tx_init;
1326 	mon_ops->mon_peer_tx_cleanup = dp_mon_peer_tx_cleanup;
1327 	mon_ops->mon_htt_ppdu_stats_attach = dp_htt_ppdu_stats_attach;
1328 	mon_ops->mon_htt_ppdu_stats_detach = dp_htt_ppdu_stats_detach;
1329 	mon_ops->mon_print_pdev_rx_mon_stats = dp_print_pdev_rx_mon_stats;
1330 	mon_ops->mon_set_bsscolor = dp_mon_set_bsscolor;
1331 	mon_ops->mon_pdev_get_filter_ucast_data =
1332 				dp_pdev_get_filter_ucast_data;
1333 	mon_ops->mon_pdev_get_filter_mcast_data =
1334 				dp_pdev_get_filter_mcast_data;
1335 	mon_ops->mon_pdev_get_filter_non_data = dp_pdev_get_filter_non_data;
1336 	mon_ops->mon_neighbour_peer_add_ast = dp_mon_neighbour_peer_add_ast;
1337 #ifdef WLAN_TX_PKT_CAPTURE_ENH
1338 	mon_ops->mon_peer_tid_peer_id_update = dp_peer_tid_peer_id_update_1_0;
1339 	mon_ops->mon_tx_capture_debugfs_init = dp_tx_capture_debugfs_init_1_0;
1340 	mon_ops->mon_tx_add_to_comp_queue = dp_tx_add_to_comp_queue_1_0;
1341 	mon_ops->mon_print_pdev_tx_capture_stats =
1342 				dp_print_pdev_tx_capture_stats_1_0;
1343 	mon_ops->mon_config_enh_tx_capture = dp_config_enh_tx_capture_1_0;
1344 	mon_ops->mon_tx_peer_filter = dp_peer_set_tx_capture_enabled_1_0;
1345 	mon_ops->mon_peer_tx_capture_get_stats = dp_get_peer_tx_capture_stats;
1346 	mon_ops->mon_pdev_tx_capture_get_stats = dp_get_pdev_tx_capture_stats;
1347 #endif
1348 #if (defined(WIFI_MONITOR_SUPPORT) && !defined(WLAN_TX_PKT_CAPTURE_ENH))
1349 	mon_ops->mon_peer_tid_peer_id_update = NULL;
1350 	mon_ops->mon_tx_capture_debugfs_init = NULL;
1351 	mon_ops->mon_tx_add_to_comp_queue = NULL;
1352 	mon_ops->mon_print_pdev_tx_capture_stats = NULL;
1353 	mon_ops->mon_config_enh_tx_capture = NULL;
1354 	mon_ops->mon_tx_peer_filter = NULL;
1355 #endif
1356 #ifdef WLAN_RX_PKT_CAPTURE_ENH
1357 	mon_ops->mon_config_enh_rx_capture = dp_config_enh_rx_capture;
1358 #endif
1359 #ifdef QCA_SUPPORT_BPR
1360 	mon_ops->mon_set_bpr_enable = dp_set_bpr_enable_1_0;
1361 #endif
1362 #ifdef ATH_SUPPORT_NAC
1363 	mon_ops->mon_set_filter_neigh_peers = dp_set_filter_neigh_peers;
1364 #endif
1365 #ifdef WLAN_ATF_ENABLE
1366 	mon_ops->mon_set_atf_stats_enable = dp_set_atf_stats_enable;
1367 #endif
1368 #ifdef FEATURE_NAC_RSSI
1369 	mon_ops->mon_filter_neighbour_peer = dp_filter_neighbour_peer;
1370 #endif
1371 #ifdef QCA_MCOPY_SUPPORT
1372 	mon_ops->mon_filter_setup_mcopy_mode =
1373 				dp_mon_filter_setup_mcopy_mode_1_0;
1374 	mon_ops->mon_filter_reset_mcopy_mode =
1375 				dp_mon_filter_reset_mcopy_mode_1_0;
1376 	mon_ops->mon_mcopy_check_deliver = dp_mcopy_check_deliver;
1377 #endif
1378 #ifdef QCA_ENHANCED_STATS_SUPPORT
1379 	mon_ops->mon_filter_setup_enhanced_stats =
1380 				dp_mon_filter_setup_enhanced_stats_1_0;
1381 	mon_ops->mon_filter_reset_enhanced_stats =
1382 				dp_mon_filter_reset_enhanced_stats_1_0;
1383 	mon_ops->mon_tx_enable_enhanced_stats =
1384 				dp_mon_tx_enable_enhanced_stats_1_0;
1385 	mon_ops->mon_tx_disable_enhanced_stats =
1386 				dp_mon_tx_disable_enhanced_stats_1_0;
1387 	mon_ops->mon_ppdu_stats_feat_enable_check =
1388 				dp_ppdu_stats_feat_enable_check_1_0;
1389 #ifndef WLAN_TX_PKT_CAPTURE_ENH
1390 	mon_ops->mon_ppdu_desc_deliver = dp_ppdu_desc_deliver;
1391 #ifdef WDI_EVENT_ENABLE
1392 	mon_ops->mon_ppdu_desc_notify = dp_ppdu_desc_notify_1_0;
1393 #endif
1394 #else
1395 	mon_ops->mon_ppdu_desc_deliver = dp_ppdu_desc_deliver_1_0;
1396 #endif
1397 	mon_ops->mon_tx_stats_update = dp_mon_tx_stats_update_1_0;
1398 #endif
1399 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
1400 	mon_ops->mon_filter_setup_smart_monitor =
1401 				dp_mon_filter_setup_smart_monitor_1_0;
1402 	mon_ops->mon_filter_reset_smart_monitor =
1403 				dp_mon_filter_reset_smart_monitor_1_0;
1404 #endif
1405 	mon_ops->mon_filter_set_reset_mon_mac_filter =
1406 				dp_mon_set_reset_mon_mac_filter_1_0;
1407 #ifdef WLAN_RX_PKT_CAPTURE_ENH
1408 	mon_ops->mon_filter_setup_rx_enh_capture =
1409 				dp_mon_filter_setup_rx_enh_capture_1_0;
1410 #endif
1411 #ifdef WDI_EVENT_ENABLE
1412 	mon_ops->mon_set_pktlog_wifi3 = dp_set_pktlog_wifi3;
1413 	mon_ops->mon_filter_setup_rx_pkt_log_full =
1414 				dp_mon_filter_setup_rx_pkt_log_full_1_0;
1415 	mon_ops->mon_filter_reset_rx_pkt_log_full =
1416 				dp_mon_filter_reset_rx_pkt_log_full_1_0;
1417 	mon_ops->mon_filter_setup_rx_pkt_log_lite =
1418 				dp_mon_filter_setup_rx_pkt_log_lite_1_0;
1419 	mon_ops->mon_filter_reset_rx_pkt_log_lite =
1420 				dp_mon_filter_reset_rx_pkt_log_lite_1_0;
1421 	mon_ops->mon_filter_setup_rx_pkt_log_cbf =
1422 				dp_mon_filter_setup_rx_pkt_log_cbf_1_0;
1423 	mon_ops->mon_filter_reset_rx_pkt_log_cbf =
1424 				dp_mon_filter_reset_rx_pktlog_cbf_1_0;
1425 #ifdef BE_PKTLOG_SUPPORT
1426 	mon_ops->mon_filter_setup_pktlog_hybrid = NULL;
1427 	mon_ops->mon_filter_reset_pktlog_hybrid = NULL;
1428 #endif
1429 #endif
1430 #if defined(DP_CON_MON) && !defined(REMOVE_PKT_LOG)
1431 	mon_ops->mon_pktlogmod_exit = dp_pktlogmod_exit;
1432 #endif
1433 	mon_ops->rx_packet_length_set = NULL;
1434 	mon_ops->rx_mon_enable = NULL;
1435 	mon_ops->rx_wmask_subscribe = NULL;
1436 	mon_ops->rx_pkt_tlv_offset = NULL;
1437 	mon_ops->rx_enable_mpdu_logging = NULL;
1438 	mon_ops->rx_enable_fpmo = NULL;
1439 	mon_ops->mon_neighbour_peers_detach = dp_neighbour_peers_detach;
1440 	mon_ops->mon_vdev_set_monitor_mode_buf_rings =
1441 				dp_vdev_set_monitor_mode_buf_rings;
1442 	mon_ops->mon_vdev_set_monitor_mode_rings =
1443 				dp_vdev_set_monitor_mode_rings;
1444 #ifdef QCA_ENHANCED_STATS_SUPPORT
1445 	mon_ops->mon_rx_stats_update = NULL;
1446 	mon_ops->mon_rx_populate_ppdu_usr_info = NULL;
1447 	mon_ops->mon_rx_populate_ppdu_info = dp_mon_populate_ppdu_info_1_0;
1448 #endif
1449 #ifdef QCA_UNDECODED_METADATA_SUPPORT
1450 	mon_ops->mon_config_undecoded_metadata_capture =
1451 		dp_mon_config_undecoded_metadata_capture;
1452 	mon_ops->mon_filter_setup_undecoded_metadata_capture =
1453 		dp_mon_filter_setup_undecoded_metadata_capture_1_0;
1454 	mon_ops->mon_filter_reset_undecoded_metadata_capture =
1455 		dp_mon_filter_reset_undecoded_metadata_capture_1_0;
1456 #endif
1457 	mon_ops->mon_rx_print_advanced_stats = NULL;
1458 	mon_ops->mon_mac_filter_set = dp_mon_mac_filter_set;
1459 }
1460 
1461 struct dp_mon_ops monitor_ops_1_0 = {
1462 	.mon_soc_cfg_init = dp_mon_soc_cfg_init,
1463 
1464 	.mon_pdev_alloc = NULL,
1465 	.mon_pdev_free = NULL,
1466 	.mon_pdev_attach = dp_mon_pdev_attach,
1467 	.mon_pdev_detach = dp_mon_pdev_detach,
1468 	.mon_pdev_init = dp_mon_pdev_init,
1469 	.mon_pdev_deinit = dp_mon_pdev_deinit,
1470 	.mon_vdev_attach = dp_mon_vdev_attach,
1471 	.mon_vdev_detach = dp_mon_vdev_detach,
1472 	.mon_peer_attach = dp_mon_peer_attach,
1473 	.mon_peer_detach = dp_mon_peer_detach,
1474 	.mon_peer_get_peerstats_ctx = dp_mon_peer_get_peerstats_ctx,
1475 	.mon_peer_reset_stats = dp_mon_peer_reset_stats,
1476 	.mon_peer_get_stats = dp_mon_peer_get_stats,
1477 	.mon_invalid_peer_update_pdev_stats =
1478 				dp_mon_invalid_peer_update_pdev_stats,
1479 	.mon_peer_get_stats_param = dp_mon_peer_get_stats_param,
1480 	.mon_flush_rings = dp_flush_monitor_rings,
1481 #if defined(DP_CON_MON)
1482 	.mon_service_rings = dp_service_mon_rings,
1483 #endif
1484 #ifndef DISABLE_MON_CONFIG
1485 	.mon_rx_process = NULL,
1486 #endif
1487 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC)
1488 	.mon_drop_packets_for_mac = dp_mon_drop_packets_for_mac,
1489 #endif
1490 	.mon_vdev_timer_init = dp_mon_vdev_timer_init,
1491 	.mon_vdev_timer_start = dp_mon_vdev_timer_start,
1492 	.mon_vdev_timer_stop = dp_mon_vdev_timer_stop,
1493 	.mon_vdev_timer_deinit = dp_mon_vdev_timer_deinit,
1494 	.mon_reap_timer_init = dp_mon_reap_timer_init,
1495 	.mon_reap_timer_start = dp_mon_reap_timer_start,
1496 	.mon_reap_timer_stop = dp_mon_reap_timer_stop,
1497 	.mon_reap_timer_deinit = dp_mon_reap_timer_deinit,
1498 	.mon_filter_setup_rx_mon_mode = dp_mon_filter_setup_mon_mode_1_0,
1499 	.mon_filter_reset_rx_mon_mode = dp_mon_filter_reset_mon_mode_1_0,
1500 	.rx_mon_filter_update = dp_mon_filter_update_1_0,
1501 	.set_mon_mode_buf_rings_tx = NULL,
1502 	.rx_mon_desc_pool_init = dp_rx_pdev_mon_desc_pool_init,
1503 	.rx_mon_desc_pool_deinit = dp_rx_pdev_mon_desc_pool_deinit,
1504 	.rx_mon_desc_pool_alloc = dp_rx_pdev_mon_desc_pool_alloc,
1505 	.rx_mon_desc_pool_free = dp_rx_pdev_mon_desc_pool_free,
1506 	.rx_mon_buffers_alloc = dp_rx_pdev_mon_buffers_alloc,
1507 	.rx_mon_buffers_free = dp_rx_pdev_mon_buffers_free,
1508 	.tx_mon_desc_pool_init = NULL,
1509 	.tx_mon_desc_pool_deinit = NULL,
1510 	.tx_mon_desc_pool_alloc = NULL,
1511 	.tx_mon_desc_pool_free = NULL,
1512 	.tx_mon_filter_alloc = NULL,
1513 #if !defined(DISABLE_MON_CONFIG)
1514 	.mon_register_intr_ops = dp_mon_register_intr_ops_1_0,
1515 #endif
1516 	.mon_register_feature_ops = dp_mon_register_feature_ops_1_0,
1517 	.mon_lite_mon_alloc = NULL,
1518 	.mon_lite_mon_dealloc = NULL,
1519 	.mon_lite_mon_vdev_delete = NULL,
1520 	.mon_lite_mon_disable_rx = NULL,
1521 	.mon_lite_mon_is_rx_adv_filter_enable = NULL,
1522 };
1523 
1524 struct cdp_mon_ops dp_ops_mon_1_0 = {
1525 	.txrx_reset_monitor_mode = dp_reset_monitor_mode,
1526 	/* Added support for HK advance filter */
1527 	.txrx_set_advance_monitor_filter = dp_pdev_set_advance_monitor_filter,
1528 	.txrx_deliver_tx_mgmt = dp_deliver_tx_mgmt,
1529 	.config_full_mon_mode = dp_config_full_mon_mode,
1530 	.soc_config_full_mon_mode = dp_soc_config_full_mon_mode,
1531 	.get_mon_pdev_rx_stats = dp_pdev_get_rx_mon_stats,
1532 	.txrx_enable_mon_reap_timer = dp_enable_mon_reap_timer,
1533 #ifdef QCA_ENHANCED_STATS_SUPPORT
1534 	.txrx_enable_enhanced_stats = dp_enable_enhanced_stats,
1535 	.txrx_disable_enhanced_stats = dp_disable_enhanced_stats,
1536 #endif /* QCA_ENHANCED_STATS_SUPPORT */
1537 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
1538 	.txrx_update_filter_neighbour_peers = dp_update_filter_neighbour_peers,
1539 #endif
1540 #ifdef ATH_SUPPORT_NAC_RSSI
1541 	.txrx_vdev_config_for_nac_rssi = dp_config_for_nac_rssi,
1542 	.txrx_vdev_get_neighbour_rssi = dp_vdev_get_neighbour_rssi,
1543 #endif
1544 #ifdef QCA_SUPPORT_LITE_MONITOR
1545 	.txrx_set_lite_mon_config = NULL,
1546 	.txrx_get_lite_mon_config = NULL,
1547 	.txrx_set_lite_mon_peer_config = NULL,
1548 	.txrx_get_lite_mon_peer_config = NULL,
1549 	.txrx_is_lite_mon_enabled = NULL,
1550 	.txrx_get_lite_mon_legacy_feature_enabled = NULL,
1551 #endif
1552 	.txrx_set_mon_pdev_params_rssi_dbm_conv =
1553 				dp_mon_pdev_params_rssi_dbm_conv,
1554 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
1555 	.start_local_pkt_capture = dp_mon_start_local_pkt_capture,
1556 	.stop_local_pkt_capture = dp_mon_stop_local_pkt_capture,
1557 	.is_local_pkt_capture_running = dp_mon_get_is_local_pkt_capture_running,
1558 #endif /* WLAN_FEATURE_LOCAL_PKT_CAPTURE */
1559 };
1560 
1561 #ifdef QCA_MONITOR_OPS_PER_SOC_SUPPORT
1562 void dp_mon_ops_register_1_0(struct dp_mon_soc *mon_soc)
1563 {
1564 	struct dp_mon_ops *mon_ops = NULL;
1565 
1566 	if (mon_soc->mon_ops) {
1567 		dp_mon_err("monitor ops is allocated");
1568 		return;
1569 	}
1570 
1571 	mon_ops = qdf_mem_malloc(sizeof(struct dp_mon_ops));
1572 	if (!mon_ops) {
1573 		dp_mon_err("Failed to allocate memory for mon ops");
1574 		return;
1575 	}
1576 
1577 	qdf_mem_copy(mon_ops, &monitor_ops_1_0, sizeof(struct dp_mon_ops));
1578 	mon_soc->mon_ops = mon_ops;
1579 	dp_mon_register_lpc_ops_1_0(mon_ops);
1580 }
1581 
1582 void dp_mon_cdp_ops_register_1_0(struct cdp_ops *ops)
1583 {
1584 	struct cdp_mon_ops *mon_ops = NULL;
1585 
1586 	if (ops->mon_ops) {
1587 		dp_mon_err("cdp monitor ops is allocated");
1588 		return;
1589 	}
1590 
1591 	mon_ops = qdf_mem_malloc(sizeof(struct cdp_mon_ops));
1592 	if (!mon_ops) {
1593 		dp_mon_err("Failed to allocate memory for cdp mon ops");
1594 		return;
1595 	}
1596 
1597 	qdf_mem_copy(mon_ops, &dp_ops_mon_1_0, sizeof(struct cdp_mon_ops));
1598 	ops->mon_ops = mon_ops;
1599 }
1600 #else
1601 void dp_mon_ops_register_1_0(struct dp_mon_soc *mon_soc)
1602 {
1603 	mon_soc->mon_ops = &monitor_ops_1_0;
1604 	dp_mon_register_lpc_ops_1_0(mon_soc->mon_ops);
1605 }
1606 
1607 void dp_mon_cdp_ops_register_1_0(struct cdp_ops *ops)
1608 {
1609 	ops->mon_ops = &dp_ops_mon_1_0;
1610 }
1611 #endif
1612