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
dp_mon_populate_ppdu_info_1_0(struct hal_rx_ppdu_info * hal_ppdu_info,struct cdp_rx_indication_ppdu * ppdu)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 */
is_ppdu_txrx_capture_enabled(struct dp_pdev * pdev)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 */
dp_mon_tx_enable_enhanced_stats_1_0(struct dp_pdev * pdev)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 */
dp_mon_tx_disable_enhanced_stats_1_0(struct dp_pdev * pdev)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
dp_config_full_mon_mode(struct cdp_soc_t * soc_handle,uint8_t val)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
dp_soc_config_full_mon_mode(struct cdp_pdev * cdp_pdev,uint8_t val)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
dp_config_full_mon_mode(struct cdp_soc_t * soc_handle,uint8_t val)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
dp_soc_config_full_mon_mode(struct cdp_pdev * cdp_pdev,uint8_t val)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)
dp_flush_monitor_rings(struct dp_soc * soc)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
dp_mon_rings_deinit_1_0(struct dp_pdev * pdev)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
dp_mon_rings_free_1_0(struct dp_pdev * pdev)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
dp_mon_sw2rxdma_link_ring_alloc(struct dp_pdev * pdev,int lmac_id)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
dp_mon_sw2rxdma_link_ring_init(struct dp_soc * soc,int lmac_id)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
dp_mon_sw2rxdma_link_ring_alloc(struct dp_pdev * pdev,int lmac_id)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
dp_mon_sw2rxdma_link_ring_init(struct dp_soc * soc,int lmac_id)284 dp_mon_sw2rxdma_link_ring_init(struct dp_soc *soc, int lmac_id)
285 {
286 return QDF_STATUS_SUCCESS;
287 }
288 #endif
289
dp_mon_rings_init_1_0(struct dp_pdev * pdev)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
dp_mon_rings_alloc_1_0(struct dp_pdev * pdev)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
dp_flush_monitor_rings(struct dp_soc * soc)361 void dp_flush_monitor_rings(struct dp_soc *soc)
362 {
363 }
364
365 #endif
366
367 #ifdef QCA_MONITOR_PKT_SUPPORT
dp_vdev_set_monitor_mode_buf_rings(struct dp_pdev * pdev)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
dp_vdev_set_monitor_mode_rings(struct dp_pdev * pdev,uint8_t delayed_replenish)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 */
dp_mon_vdev_timer(void * arg)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 */
dp_mon_reap_timer_handler(void * arg)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
dp_mon_reap_timer_init(struct dp_soc * soc)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
dp_mon_reap_timer_init(struct dp_soc * soc)592 static void dp_mon_reap_timer_init(struct dp_soc *soc)
593 {
594 }
595 #endif
596
dp_mon_reap_timer_deinit(struct dp_soc * soc)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
dp_mon_is_irq_enabled(struct dp_soc * soc)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
dp_mon_reap_timer_start(struct dp_soc * soc,enum cdp_mon_reap_source source)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
dp_mon_reap_timer_stop(struct dp_soc * soc,enum cdp_mon_reap_source source)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
dp_mon_vdev_timer_init(struct dp_soc * soc)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
dp_mon_vdev_timer_deinit(struct dp_soc * soc)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
dp_mon_vdev_timer_start(struct dp_soc * soc)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
dp_mon_vdev_timer_stop(struct dp_soc * soc)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
dp_mon_neighbour_peer_add_ast(struct dp_pdev * pdev,struct dp_peer * ta_peer,uint8_t * mac_addr,qdf_nbuf_t nbuf,uint32_t flags)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)
dp_mon_htt_srng_setup_1_0(struct dp_soc * soc,struct dp_pdev * pdev,int mac_id,int mac_for_pdev)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 */
dp_mon_htt_srng_setup_1_0(struct dp_soc * soc,struct dp_pdev * pdev,int mac_id,int mac_for_pdev)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 */
dp_service_mon_rings(struct dp_soc * soc,uint32_t quota)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
dp_mon_peer_tx_init(struct dp_pdev * pdev,struct dp_peer * peer)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
dp_mon_peer_tx_cleanup(struct dp_vdev * vdev,struct dp_peer * peer)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
dp_set_bpr_enable_1_0(struct dp_pdev * pdev,int val)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 */
dp_ppdu_desc_notify_1_0(struct dp_pdev * pdev,qdf_nbuf_t nbuf)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 */
dp_ppdu_stats_feat_enable_check_1_0(struct dp_pdev * pdev)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
dp_mon_tx_stats_update_1_0(struct dp_mon_peer * mon_peer,struct cdp_tx_completion_ppdu_user * ppdu)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
dp_rx_mon_process(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)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
dp_rx_mon_process_1_0(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)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
dp_mon_ppdu_stats_handler_register(struct dp_mon_soc * mon_soc)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
dp_mon_ppdu_stats_handler_register(struct dp_mon_soc * mon_soc)1096 void dp_mon_ppdu_stats_handler_register(struct dp_mon_soc *mon_soc)
1097 {
1098 }
1099 #endif
1100
dp_mon_register_intr_ops_1_0(struct dp_soc * soc)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 */
dp_update_filter_neighbour_peers(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,uint32_t cmd,uint8_t * macaddr)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 */
dp_vdev_get_neighbour_rssi(struct cdp_soc_t * soc_hdl,uint8_t vdev_id,char * mac_addr,uint8_t * rssi)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
dp_config_for_nac_rssi(struct cdp_soc_t * cdp_soc,uint8_t vdev_id,enum cdp_nac_param_cmd cmd,char * bssid,char * client_macaddr,uint8_t chan_num)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
dp_mon_register_feature_ops_1_0(struct dp_soc * soc)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
dp_mon_ops_register_1_0(struct dp_mon_soc * mon_soc)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
dp_mon_cdp_ops_register_1_0(struct cdp_ops * ops)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
dp_mon_ops_register_1_0(struct dp_mon_soc * mon_soc)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
dp_mon_cdp_ops_register_1_0(struct cdp_ops * ops)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