1 /*
2 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include "hal_hw_headers.h"
19 #include "dp_types.h"
20 #include "dp_rx.h"
21 #include "dp_peer.h"
22 #include "hal_rx.h"
23 #include "hal_api.h"
24 #include "qdf_trace.h"
25 #include "qdf_nbuf.h"
26 #include "hal_api_mon.h"
27 #include "dp_htt.h"
28 #include "dp_mon.h"
29 #include "dp_rx_mon.h"
30 #include "wlan_cfg.h"
31 #include "dp_internal.h"
32 #include "dp_rx_buffer_pool.h"
33 #include <dp_mon_1.0.h>
34 #include <dp_rx_mon_1.0.h>
35
36 #ifdef WLAN_TX_PKT_CAPTURE_ENH
37 #include "dp_rx_mon_feature.h"
38 #endif
39
40 /*
41 * PPDU id is from 0 to 64k-1. PPDU id read from status ring and PPDU id
42 * read from destination ring shall track each other. If the distance of
43 * two ppdu id is less than 20000. It is assume no wrap around. Otherwise,
44 * It is assume wrap around.
45 */
46 #define NOT_PPDU_ID_WRAP_AROUND 20000
47 /*
48 * The destination ring processing is stuck if the destrination is not
49 * moving while status ring moves 16 ppdu. the destination ring processing
50 * skips this destination ring ppdu as walkaround
51 */
52 #define MON_DEST_RING_STUCK_MAX_CNT 16
53
54 #ifdef WLAN_TX_PKT_CAPTURE_ENH
55 void
dp_handle_tx_capture(struct dp_soc * soc,struct dp_pdev * pdev,qdf_nbuf_t mon_mpdu)56 dp_handle_tx_capture(struct dp_soc *soc, struct dp_pdev *pdev,
57 qdf_nbuf_t mon_mpdu)
58 {
59 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
60 struct hal_rx_ppdu_info *ppdu_info = &mon_pdev->ppdu_info;
61
62 if (mon_pdev->tx_capture_enabled
63 == CDP_TX_ENH_CAPTURE_DISABLED)
64 return;
65
66 if ((ppdu_info->sw_frame_group_id ==
67 HAL_MPDU_SW_FRAME_GROUP_CTRL_NDPA) ||
68 (ppdu_info->sw_frame_group_id ==
69 HAL_MPDU_SW_FRAME_GROUP_CTRL_BAR))
70 dp_handle_tx_capture_from_dest(soc, pdev, mon_mpdu);
71 }
72
73 #ifdef QCA_MONITOR_PKT_SUPPORT
74 static void
dp_tx_capture_get_user_id(struct dp_pdev * dp_pdev,void * rx_desc_tlv)75 dp_tx_capture_get_user_id(struct dp_pdev *dp_pdev, void *rx_desc_tlv)
76 {
77 struct dp_mon_pdev *mon_pdev = dp_pdev->monitor_pdev;
78
79 if (mon_pdev->tx_capture_enabled
80 != CDP_TX_ENH_CAPTURE_DISABLED)
81 mon_pdev->ppdu_info.rx_info.user_id =
82 hal_rx_hw_desc_mpdu_user_id(dp_pdev->soc->hal_soc,
83 rx_desc_tlv);
84 }
85 #endif
86 #else
87 static void
dp_tx_capture_get_user_id(struct dp_pdev * dp_pdev,void * rx_desc_tlv)88 dp_tx_capture_get_user_id(struct dp_pdev *dp_pdev, void *rx_desc_tlv)
89 {
90 }
91 #endif
92
93 #ifdef QCA_MONITOR_PKT_SUPPORT
94 /**
95 * dp_rx_mon_link_desc_return() - Return a MPDU link descriptor to HW
96 * (WBM), following error handling
97 *
98 * @dp_pdev: core txrx pdev context
99 * @buf_addr_info: void pointer to monitor link descriptor buf addr info
100 * @mac_id: mac_id for which the link desc is released.
101 *
102 * Return: QDF_STATUS
103 */
104 QDF_STATUS
dp_rx_mon_link_desc_return(struct dp_pdev * dp_pdev,hal_buff_addrinfo_t buf_addr_info,int mac_id)105 dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev,
106 hal_buff_addrinfo_t buf_addr_info, int mac_id)
107 {
108 hal_ring_handle_t hal_ring_hdl;
109 hal_soc_handle_t hal_soc;
110 QDF_STATUS status = QDF_STATUS_E_FAILURE;
111 void *src_srng_desc;
112
113 hal_soc = dp_pdev->soc->hal_soc;
114
115 hal_ring_hdl = dp_monitor_get_link_desc_ring(dp_pdev->soc, mac_id);
116
117 qdf_assert(hal_ring_hdl);
118
119 if (qdf_unlikely(hal_srng_access_start(hal_soc, hal_ring_hdl))) {
120
121 /* TODO */
122 /*
123 * Need API to convert from hal_ring pointer to
124 * Ring Type / Ring Id combo
125 */
126 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
127 "%s %d : \
128 HAL RING Access For WBM Release SRNG Failed -- %pK",
129 __func__, __LINE__, hal_ring_hdl);
130 goto done;
131 }
132
133 src_srng_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl);
134
135 if (qdf_likely(src_srng_desc)) {
136 /* Return link descriptor through WBM ring (SW2WBM)*/
137 hal_rx_mon_msdu_link_desc_set(hal_soc,
138 src_srng_desc, buf_addr_info);
139 status = QDF_STATUS_SUCCESS;
140 } else {
141 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
142 "%s %d -- Monitor Link Desc WBM Release Ring Full",
143 __func__, __LINE__);
144 }
145 done:
146 hal_srng_access_end(hal_soc, hal_ring_hdl);
147 return status;
148 }
149
150 /**
151 * dp_rx_mon_mpdu_pop() - Return a MPDU link descriptor to HW
152 * (WBM), following error handling
153 *
154 * @soc: core DP main context
155 * @mac_id: mac id which is one of 3 mac_ids
156 * @rxdma_dst_ring_desc: void pointer to monitor link descriptor buf addr info
157 * @head_msdu: head of msdu to be popped
158 * @tail_msdu: tail of msdu to be popped
159 * @npackets: number of packet to be popped
160 * @ppdu_id: ppdu id of processing ppdu
161 * @head: head of descs list to be freed
162 * @tail: tail of decs list to be freed
163 *
164 * Return: number of msdu in MPDU to be popped
165 */
166 static inline uint32_t
dp_rx_mon_mpdu_pop(struct dp_soc * soc,uint32_t mac_id,hal_rxdma_desc_t rxdma_dst_ring_desc,qdf_nbuf_t * head_msdu,qdf_nbuf_t * tail_msdu,uint32_t * npackets,uint32_t * ppdu_id,union dp_rx_desc_list_elem_t ** head,union dp_rx_desc_list_elem_t ** tail)167 dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
168 hal_rxdma_desc_t rxdma_dst_ring_desc, qdf_nbuf_t *head_msdu,
169 qdf_nbuf_t *tail_msdu, uint32_t *npackets, uint32_t *ppdu_id,
170 union dp_rx_desc_list_elem_t **head,
171 union dp_rx_desc_list_elem_t **tail)
172 {
173 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
174 void *rx_desc_tlv, *first_rx_desc_tlv = NULL;
175 void *rx_msdu_link_desc;
176 qdf_nbuf_t msdu;
177 qdf_nbuf_t last;
178 struct hal_rx_msdu_list msdu_list;
179 uint16_t num_msdus;
180 uint32_t rx_buf_size, rx_pkt_offset;
181 struct hal_buf_info buf_info;
182 uint32_t rx_bufs_used = 0;
183 uint32_t msdu_ppdu_id, msdu_cnt;
184 uint8_t *data = NULL;
185 uint32_t i;
186 uint32_t total_frag_len = 0, frag_len = 0;
187 bool is_frag, is_first_msdu;
188 bool drop_mpdu = false, is_frag_non_raw = false;
189 uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
190 qdf_dma_addr_t buf_paddr = 0;
191 uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS];
192 struct cdp_mon_status *rs;
193 struct dp_mon_pdev *mon_pdev;
194
195 if (qdf_unlikely(!dp_pdev)) {
196 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", soc, mac_id);
197 return rx_bufs_used;
198 }
199
200 mon_pdev = dp_pdev->monitor_pdev;
201 msdu = 0;
202
203 last = NULL;
204
205 hal_rx_reo_ent_buf_paddr_get(soc->hal_soc, rxdma_dst_ring_desc,
206 &buf_info, &msdu_cnt);
207
208 rs = &mon_pdev->rx_mon_recv_status;
209 rs->cdp_rs_rxdma_err = false;
210 if ((hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc) ==
211 HAL_RX_WBM_RXDMA_PSH_RSN_ERROR)) {
212 uint8_t rxdma_err =
213 hal_rx_reo_ent_rxdma_error_code_get(
214 rxdma_dst_ring_desc);
215 if (qdf_unlikely((rxdma_err == HAL_RXDMA_ERR_FLUSH_REQUEST) ||
216 (rxdma_err == HAL_RXDMA_ERR_MPDU_LENGTH) ||
217 (rxdma_err == HAL_RXDMA_ERR_OVERFLOW) ||
218 (rxdma_err == HAL_RXDMA_ERR_FCS && mon_pdev->mcopy_mode) ||
219 (rxdma_err == HAL_RXDMA_ERR_FCS &&
220 mon_pdev->rx_pktlog_cbf))) {
221 drop_mpdu = true;
222 mon_pdev->rx_mon_stats.dest_mpdu_drop++;
223 }
224 rs->cdp_rs_rxdma_err = true;
225 }
226
227 is_frag = false;
228 is_first_msdu = true;
229
230 do {
231 if (!msdu_cnt) {
232 drop_mpdu = true;
233 DP_STATS_INC(dp_pdev, invalid_msdu_cnt, 1);
234 }
235
236 /* WAR for duplicate link descriptors received from HW */
237 if (qdf_unlikely(mon_pdev->mon_last_linkdesc_paddr ==
238 buf_info.paddr)) {
239 mon_pdev->rx_mon_stats.dup_mon_linkdesc_cnt++;
240 return rx_bufs_used;
241 }
242
243 rx_msdu_link_desc =
244 dp_rx_cookie_2_mon_link_desc(dp_pdev,
245 &buf_info, mac_id);
246
247 qdf_assert_always(rx_msdu_link_desc);
248
249 hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc,
250 &msdu_list, &num_msdus);
251
252 for (i = 0; i < num_msdus; i++) {
253 uint16_t l2_hdr_offset;
254 struct dp_rx_desc *rx_desc = NULL;
255 struct rx_desc_pool *rx_desc_pool;
256
257 rx_desc = dp_rx_get_mon_desc(soc,
258 msdu_list.sw_cookie[i]);
259
260 qdf_assert_always(rx_desc);
261
262 msdu = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc);
263 buf_paddr = dp_rx_mon_get_paddr_from_desc(rx_desc);
264
265 /* WAR for duplicate buffers received from HW */
266 if (qdf_unlikely(mon_pdev->mon_last_buf_cookie ==
267 msdu_list.sw_cookie[i] ||
268 DP_RX_MON_IS_BUFFER_ADDR_NULL(rx_desc) ||
269 msdu_list.paddr[i] != buf_paddr ||
270 !rx_desc->in_use)) {
271 /* Skip duplicate buffer and drop subsequent
272 * buffers in this MPDU
273 */
274 drop_mpdu = true;
275 mon_pdev->rx_mon_stats.dup_mon_buf_cnt++;
276 mon_pdev->mon_last_linkdesc_paddr =
277 buf_info.paddr;
278 continue;
279 }
280
281 if (rx_desc->unmapped == 0) {
282 rx_desc_pool = dp_rx_get_mon_desc_pool(soc,
283 mac_id,
284 dp_pdev->pdev_id);
285 dp_rx_mon_buffer_unmap(soc, rx_desc,
286 rx_desc_pool->buf_size);
287 rx_desc->unmapped = 1;
288 }
289
290 if (dp_rx_buffer_pool_refill(soc, msdu,
291 rx_desc->pool_id)) {
292 drop_mpdu = true;
293 msdu = NULL;
294 mon_pdev->mon_last_linkdesc_paddr =
295 buf_info.paddr;
296 goto next_msdu;
297 }
298
299 if (drop_mpdu) {
300 mon_pdev->mon_last_linkdesc_paddr =
301 buf_info.paddr;
302 dp_rx_mon_buffer_free(rx_desc);
303 msdu = NULL;
304 goto next_msdu;
305 }
306
307 data = dp_rx_mon_get_buffer_data(rx_desc);
308 rx_desc_tlv = HAL_RX_MON_DEST_GET_DESC(data);
309
310 dp_rx_mon_dest_debug("%pK: i=%d, ppdu_id=%x, num_msdus = %u",
311 soc, i, *ppdu_id, num_msdus);
312
313 if (is_first_msdu) {
314 if (!hal_rx_mpdu_start_tlv_tag_valid(
315 soc->hal_soc,
316 rx_desc_tlv)) {
317 drop_mpdu = true;
318 dp_rx_mon_buffer_free(rx_desc);
319 msdu = NULL;
320 mon_pdev->mon_last_linkdesc_paddr =
321 buf_info.paddr;
322 goto next_msdu;
323 }
324
325 msdu_ppdu_id = hal_rx_hw_desc_get_ppduid_get(
326 soc->hal_soc,
327 rx_desc_tlv,
328 rxdma_dst_ring_desc);
329 is_first_msdu = false;
330
331 dp_rx_mon_dest_debug("%pK: msdu_ppdu_id=%x",
332 soc, msdu_ppdu_id);
333
334 if (*ppdu_id > msdu_ppdu_id)
335 dp_rx_mon_dest_debug("%pK: ppdu_id=%d "
336 "msdu_ppdu_id=%d", soc,
337 *ppdu_id, msdu_ppdu_id);
338
339 if ((*ppdu_id < msdu_ppdu_id) && (
340 (msdu_ppdu_id - *ppdu_id) <
341 NOT_PPDU_ID_WRAP_AROUND)) {
342 *ppdu_id = msdu_ppdu_id;
343 return rx_bufs_used;
344 } else if ((*ppdu_id > msdu_ppdu_id) && (
345 (*ppdu_id - msdu_ppdu_id) >
346 NOT_PPDU_ID_WRAP_AROUND)) {
347 *ppdu_id = msdu_ppdu_id;
348 return rx_bufs_used;
349 }
350
351 dp_tx_capture_get_user_id(dp_pdev,
352 rx_desc_tlv);
353
354 if (*ppdu_id == msdu_ppdu_id)
355 mon_pdev->rx_mon_stats.ppdu_id_match++;
356 else
357 mon_pdev->rx_mon_stats.ppdu_id_mismatch
358 ++;
359
360 mon_pdev->mon_last_linkdesc_paddr =
361 buf_info.paddr;
362
363 if (dp_rx_mon_alloc_parent_buffer(head_msdu)
364 != QDF_STATUS_SUCCESS) {
365 DP_STATS_INC(dp_pdev,
366 replenish.nbuf_alloc_fail,
367 1);
368 qdf_frag_free(rx_desc_tlv);
369 dp_rx_mon_dest_debug("failed to allocate parent buffer to hold all frag");
370 drop_mpdu = true;
371 goto next_msdu;
372 }
373 }
374
375 if (hal_rx_desc_is_first_msdu(soc->hal_soc,
376 rx_desc_tlv))
377 hal_rx_mon_hw_desc_get_mpdu_status(soc->hal_soc,
378 rx_desc_tlv,
379 &mon_pdev->ppdu_info.rx_status);
380
381 dp_rx_mon_parse_desc_buffer(soc,
382 &(msdu_list.msdu_info[i]),
383 &is_frag,
384 &total_frag_len,
385 &frag_len,
386 &l2_hdr_offset,
387 rx_desc_tlv,
388 &first_rx_desc_tlv,
389 &is_frag_non_raw, data);
390 if (!is_frag && msdu_cnt)
391 msdu_cnt--;
392
393 dp_rx_mon_dest_debug("total_len %u frag_len %u flags %u",
394 total_frag_len, frag_len,
395 msdu_list.msdu_info[i].msdu_flags);
396
397 rx_pkt_offset = dp_rx_mon_get_rx_pkt_tlv_size(soc);
398
399 rx_buf_size = rx_pkt_offset + l2_hdr_offset
400 + frag_len;
401
402 dp_rx_mon_buffer_set_pktlen(msdu, rx_buf_size);
403 #if 0
404 /* Disable it.see packet on msdu done set to 0 */
405 /*
406 * Check if DMA completed -- msdu_done is the
407 * last bit to be written
408 */
409 if (!hal_rx_attn_msdu_done_get(rx_desc_tlv)) {
410
411 QDF_TRACE(QDF_MODULE_ID_DP,
412 QDF_TRACE_LEVEL_ERROR,
413 "%s:%d: Pkt Desc",
414 __func__, __LINE__);
415
416 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP,
417 QDF_TRACE_LEVEL_ERROR,
418 rx_desc_tlv, 128);
419
420 qdf_assert_always(0);
421 }
422 #endif
423 dp_rx_mon_dest_debug("%pK: rx_pkt_offset=%d, l2_hdr_offset=%d, msdu_len=%d, frag_len %u",
424 soc, rx_pkt_offset, l2_hdr_offset,
425 msdu_list.msdu_info[i].msdu_len,
426 frag_len);
427
428 if (dp_rx_mon_add_msdu_to_list(soc, head_msdu, msdu,
429 &last, rx_desc_tlv,
430 frag_len, l2_hdr_offset)
431 != QDF_STATUS_SUCCESS) {
432 dp_rx_mon_add_msdu_to_list_failure_handler(rx_desc_tlv,
433 dp_pdev, &last, head_msdu,
434 tail_msdu, __func__);
435 drop_mpdu = true;
436 goto next_msdu;
437 }
438
439 next_msdu:
440 mon_pdev->mon_last_buf_cookie = msdu_list.sw_cookie[i];
441 rx_bufs_used++;
442 dp_rx_add_to_free_desc_list(head,
443 tail, rx_desc);
444 }
445
446 /*
447 * Store the current link buffer into to the local
448 * structure to be used for release purpose.
449 */
450 hal_rxdma_buff_addr_info_set(soc->hal_soc, rx_link_buf_info,
451 buf_info.paddr,
452 buf_info.sw_cookie, buf_info.rbm);
453
454 hal_rx_mon_next_link_desc_get(soc->hal_soc, rx_msdu_link_desc,
455 &buf_info);
456 if (dp_rx_monitor_link_desc_return(dp_pdev,
457 (hal_buff_addrinfo_t)
458 rx_link_buf_info,
459 mac_id,
460 bm_action)
461 != QDF_STATUS_SUCCESS)
462 dp_err_rl("monitor link desc return failed");
463 } while (buf_info.paddr);
464
465 dp_rx_mon_init_tail_msdu(head_msdu, msdu, last, tail_msdu);
466 dp_rx_mon_remove_raw_frame_fcs_len(soc, head_msdu, tail_msdu);
467
468 return rx_bufs_used;
469 }
470
471 #if !defined(DISABLE_MON_CONFIG) && \
472 (defined(MON_ENABLE_DROP_FOR_NON_MON_PMAC) || \
473 defined(MON_ENABLE_DROP_FOR_MAC))
474 /**
475 * dp_rx_mon_drop_one_mpdu() - Drop one mpdu from one rxdma monitor destination
476 * ring.
477 * @pdev: DP pdev handle
478 * @mac_id: MAC id which is being currently processed
479 * @rxdma_dst_ring_desc: RXDMA monitor destination ring entry
480 * @head: HEAD if the rx_desc list to be freed
481 * @tail: TAIL of the rx_desc list to be freed
482 *
483 * Return: Number of msdus which are dropped.
484 */
dp_rx_mon_drop_one_mpdu(struct dp_pdev * pdev,uint32_t mac_id,hal_rxdma_desc_t rxdma_dst_ring_desc,union dp_rx_desc_list_elem_t ** head,union dp_rx_desc_list_elem_t ** tail)485 static int dp_rx_mon_drop_one_mpdu(struct dp_pdev *pdev,
486 uint32_t mac_id,
487 hal_rxdma_desc_t rxdma_dst_ring_desc,
488 union dp_rx_desc_list_elem_t **head,
489 union dp_rx_desc_list_elem_t **tail)
490 {
491 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
492 struct dp_soc *soc = pdev->soc;
493 hal_soc_handle_t hal_soc = soc->hal_soc;
494 struct hal_buf_info buf_info;
495 uint32_t msdu_count = 0;
496 uint32_t rx_bufs_used = 0;
497 void *rx_msdu_link_desc;
498 struct hal_rx_msdu_list msdu_list;
499 uint16_t num_msdus;
500 qdf_nbuf_t nbuf;
501 uint32_t i;
502 uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
503 uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS];
504 struct rx_desc_pool *rx_desc_pool;
505
506 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id);
507 hal_rx_reo_ent_buf_paddr_get(hal_soc, rxdma_dst_ring_desc,
508 &buf_info, &msdu_count);
509
510 do {
511 rx_msdu_link_desc = dp_rx_cookie_2_mon_link_desc(pdev,
512 &buf_info,
513 mac_id);
514 if (qdf_unlikely(!rx_msdu_link_desc)) {
515 mon_pdev->rx_mon_stats.mon_link_desc_invalid++;
516 return rx_bufs_used;
517 }
518
519 hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc,
520 &msdu_list, &num_msdus);
521
522 for (i = 0; i < num_msdus; i++) {
523 struct dp_rx_desc *rx_desc;
524 qdf_dma_addr_t buf_paddr;
525
526 rx_desc = dp_rx_get_mon_desc(soc,
527 msdu_list.sw_cookie[i]);
528
529 if (qdf_unlikely(!rx_desc)) {
530 mon_pdev->rx_mon_stats.
531 mon_rx_desc_invalid++;
532 continue;
533 }
534
535 nbuf = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc);
536 buf_paddr =
537 dp_rx_mon_get_paddr_from_desc(rx_desc);
538
539 if (qdf_unlikely(!rx_desc->in_use || !nbuf ||
540 msdu_list.paddr[i] !=
541 buf_paddr)) {
542 mon_pdev->rx_mon_stats.
543 mon_nbuf_sanity_err++;
544 continue;
545 }
546 rx_bufs_used++;
547
548 if (!rx_desc->unmapped) {
549 dp_rx_mon_buffer_unmap(soc, rx_desc,
550 rx_desc_pool->buf_size);
551 rx_desc->unmapped = 1;
552 }
553
554 qdf_nbuf_free(nbuf);
555 dp_rx_add_to_free_desc_list(head, tail, rx_desc);
556
557 if (!(msdu_list.msdu_info[i].msdu_flags &
558 HAL_MSDU_F_MSDU_CONTINUATION))
559 msdu_count--;
560 }
561
562 /*
563 * Store the current link buffer into to the local
564 * structure to be used for release purpose.
565 */
566 hal_rxdma_buff_addr_info_set(soc->hal_soc,
567 rx_link_buf_info,
568 buf_info.paddr,
569 buf_info.sw_cookie,
570 buf_info.rbm);
571
572 hal_rx_mon_next_link_desc_get(soc->hal_soc,
573 rx_msdu_link_desc,
574 &buf_info);
575 if (dp_rx_monitor_link_desc_return(pdev,
576 (hal_buff_addrinfo_t)
577 rx_link_buf_info,
578 mac_id, bm_action) !=
579 QDF_STATUS_SUCCESS)
580 dp_info_rl("monitor link desc return failed");
581 } while (buf_info.paddr && msdu_count);
582
583 return rx_bufs_used;
584 }
585 #endif
586
587 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_NON_MON_PMAC)
588 /**
589 * dp_rx_mon_check_n_drop_mpdu() - Check if the current MPDU is not from the
590 * PMAC which is being currently processed, and
591 * if yes, drop the MPDU.
592 * @pdev: DP pdev handle
593 * @mac_id: MAC id which is being currently processed
594 * @rxdma_dst_ring_desc: RXDMA monitor destination ring entry
595 * @head: HEAD if the rx_desc list to be freed
596 * @tail: TAIL of the rx_desc list to be freed
597 * @rx_bufs_dropped: Number of msdus dropped
598 *
599 * Return: QDF_STATUS_SUCCESS, if the mpdu was to be dropped
600 * QDF_STATUS_E_INVAL/QDF_STATUS_E_FAILURE, if the mdpu was not dropped
601 */
602 static QDF_STATUS
dp_rx_mon_check_n_drop_mpdu(struct dp_pdev * pdev,uint32_t mac_id,hal_rxdma_desc_t rxdma_dst_ring_desc,union dp_rx_desc_list_elem_t ** head,union dp_rx_desc_list_elem_t ** tail,uint32_t * rx_bufs_dropped)603 dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id,
604 hal_rxdma_desc_t rxdma_dst_ring_desc,
605 union dp_rx_desc_list_elem_t **head,
606 union dp_rx_desc_list_elem_t **tail,
607 uint32_t *rx_bufs_dropped)
608 {
609 struct dp_soc *soc = pdev->soc;
610 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
611 uint32_t lmac_id = DP_MON_INVALID_LMAC_ID;
612 uint8_t src_link_id;
613 QDF_STATUS status;
614
615 if (mon_pdev->mon_chan_band == REG_BAND_UNKNOWN)
616 goto drop_mpdu;
617
618 lmac_id = pdev->ch_band_lmac_id_mapping[mon_pdev->mon_chan_band];
619
620 status = hal_rx_reo_ent_get_src_link_id(soc->hal_soc,
621 rxdma_dst_ring_desc,
622 &src_link_id);
623 if (QDF_IS_STATUS_ERROR(status))
624 return QDF_STATUS_E_INVAL;
625
626 if (src_link_id == lmac_id)
627 return QDF_STATUS_E_INVAL;
628
629 drop_mpdu:
630 *rx_bufs_dropped = dp_rx_mon_drop_one_mpdu(pdev, mac_id,
631 rxdma_dst_ring_desc,
632 head, tail);
633
634 return QDF_STATUS_SUCCESS;
635 }
636 #else
637 static inline QDF_STATUS
dp_rx_mon_check_n_drop_mpdu(struct dp_pdev * pdev,uint32_t mac_id,hal_rxdma_desc_t rxdma_dst_ring_desc,union dp_rx_desc_list_elem_t ** head,union dp_rx_desc_list_elem_t ** tail,uint32_t * rx_bufs_dropped)638 dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id,
639 hal_rxdma_desc_t rxdma_dst_ring_desc,
640 union dp_rx_desc_list_elem_t **head,
641 union dp_rx_desc_list_elem_t **tail,
642 uint32_t *rx_bufs_dropped)
643 {
644 return QDF_STATUS_E_FAILURE;
645 }
646 #endif
647
dp_rx_mon_dest_process(struct dp_soc * soc,struct dp_intr * int_ctx,uint32_t mac_id,uint32_t quota)648 void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx,
649 uint32_t mac_id, uint32_t quota)
650 {
651 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
652 uint8_t pdev_id;
653 hal_rxdma_desc_t rxdma_dst_ring_desc;
654 hal_soc_handle_t hal_soc;
655 void *mon_dst_srng;
656 union dp_rx_desc_list_elem_t *head = NULL;
657 union dp_rx_desc_list_elem_t *tail = NULL;
658 uint32_t ppdu_id;
659 uint32_t rx_bufs_used;
660 uint32_t mpdu_rx_bufs_used;
661 int mac_for_pdev = mac_id;
662 struct cdp_pdev_mon_stats *rx_mon_stats;
663 struct dp_mon_pdev *mon_pdev;
664
665 if (!pdev) {
666 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", soc, mac_id);
667 return;
668 }
669
670 mon_pdev = pdev->monitor_pdev;
671 mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_for_pdev);
672
673 if (!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)) {
674 dp_rx_mon_dest_err("%pK: : HAL Monitor Destination Ring Init Failed -- %pK",
675 soc, mon_dst_srng);
676 return;
677 }
678
679 hal_soc = soc->hal_soc;
680
681 qdf_assert((hal_soc && pdev));
682
683 qdf_spin_lock_bh(&mon_pdev->mon_lock);
684
685 if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_dst_srng))) {
686 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
687 "%s %d : HAL Mon Dest Ring access Failed -- %pK",
688 __func__, __LINE__, mon_dst_srng);
689 qdf_spin_unlock_bh(&mon_pdev->mon_lock);
690 return;
691 }
692
693 pdev_id = pdev->pdev_id;
694 ppdu_id = mon_pdev->ppdu_info.com_info.ppdu_id;
695 rx_bufs_used = 0;
696 rx_mon_stats = &mon_pdev->rx_mon_stats;
697
698 while (qdf_likely(rxdma_dst_ring_desc =
699 hal_srng_dst_peek(hal_soc, mon_dst_srng))) {
700 qdf_nbuf_t head_msdu, tail_msdu;
701 uint32_t npackets;
702 uint32_t rx_bufs_dropped;
703
704 rx_bufs_dropped = 0;
705 head_msdu = (qdf_nbuf_t)NULL;
706 tail_msdu = (qdf_nbuf_t)NULL;
707
708 if (QDF_STATUS_SUCCESS ==
709 dp_rx_mon_check_n_drop_mpdu(pdev, mac_id,
710 rxdma_dst_ring_desc,
711 &head, &tail,
712 &rx_bufs_dropped)) {
713 /* Increment stats */
714 rx_bufs_used += rx_bufs_dropped;
715 hal_srng_dst_get_next(hal_soc, mon_dst_srng);
716 continue;
717 }
718
719 mpdu_rx_bufs_used =
720 dp_rx_mon_mpdu_pop(soc, mac_id,
721 rxdma_dst_ring_desc,
722 &head_msdu, &tail_msdu,
723 &npackets, &ppdu_id,
724 &head, &tail);
725
726 rx_bufs_used += mpdu_rx_bufs_used;
727
728 if (mpdu_rx_bufs_used)
729 mon_pdev->mon_dest_ring_stuck_cnt = 0;
730 else
731 mon_pdev->mon_dest_ring_stuck_cnt++;
732
733 if (mon_pdev->mon_dest_ring_stuck_cnt >
734 MON_DEST_RING_STUCK_MAX_CNT) {
735 dp_info("destination ring stuck");
736 dp_info("ppdu_id status=%d dest=%d",
737 mon_pdev->ppdu_info.com_info.ppdu_id, ppdu_id);
738 rx_mon_stats->mon_rx_dest_stuck++;
739 mon_pdev->ppdu_info.com_info.ppdu_id = ppdu_id;
740 continue;
741 }
742
743 if (ppdu_id != mon_pdev->ppdu_info.com_info.ppdu_id) {
744 rx_mon_stats->stat_ring_ppdu_id_hist[
745 rx_mon_stats->ppdu_id_hist_idx] =
746 mon_pdev->ppdu_info.com_info.ppdu_id;
747 rx_mon_stats->dest_ring_ppdu_id_hist[
748 rx_mon_stats->ppdu_id_hist_idx] = ppdu_id;
749 rx_mon_stats->ppdu_id_hist_idx =
750 (rx_mon_stats->ppdu_id_hist_idx + 1) &
751 (MAX_PPDU_ID_HIST - 1);
752 dp_rx_mon_dest_debug("%pK: ppdu_id %x != ppdu_info.com_info.ppdu_id %x",
753 soc, ppdu_id,
754 mon_pdev->ppdu_info.com_info.ppdu_id);
755 break;
756 }
757
758 if (qdf_likely((head_msdu) && (tail_msdu))) {
759 rx_mon_stats->dest_mpdu_done++;
760 dp_rx_mon_deliver(soc, mac_id, head_msdu, tail_msdu);
761 }
762
763 rxdma_dst_ring_desc =
764 hal_srng_dst_get_next(hal_soc,
765 mon_dst_srng);
766 }
767
768 dp_srng_access_end(int_ctx, soc, mon_dst_srng);
769
770 qdf_spin_unlock_bh(&mon_pdev->mon_lock);
771
772 if (rx_bufs_used) {
773 rx_mon_stats->dest_ppdu_done++;
774 dp_rx_buffers_replenish(soc, mac_id,
775 dp_rxdma_get_mon_buf_ring(pdev,
776 mac_for_pdev),
777 dp_rx_get_mon_desc_pool(soc, mac_id,
778 pdev_id),
779 rx_bufs_used, &head, &tail, false);
780 }
781 }
782
783 QDF_STATUS
dp_rx_pdev_mon_buf_buffers_alloc(struct dp_pdev * pdev,uint32_t mac_id,bool delayed_replenish)784 dp_rx_pdev_mon_buf_buffers_alloc(struct dp_pdev *pdev, uint32_t mac_id,
785 bool delayed_replenish)
786 {
787 uint8_t pdev_id = pdev->pdev_id;
788 struct dp_soc *soc = pdev->soc;
789 struct dp_srng *mon_buf_ring;
790 uint32_t num_entries;
791 struct rx_desc_pool *rx_desc_pool;
792 QDF_STATUS status = QDF_STATUS_SUCCESS;
793 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
794
795 mon_buf_ring = dp_rxdma_get_mon_buf_ring(pdev, mac_id);
796
797 num_entries = mon_buf_ring->num_entries;
798
799 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev_id);
800
801 dp_debug("Mon RX Desc Pool[%d] entries=%u", pdev_id, num_entries);
802
803 /* Replenish RXDMA monitor buffer ring with 8 buffers only
804 * delayed_replenish_entries is actually 8 but when we call
805 * dp_pdev_rx_buffers_attach() we pass 1 less than 8, hence
806 * added 1 to delayed_replenish_entries to ensure we have 8
807 * entries. Once the monitor VAP is configured we replenish
808 * the complete RXDMA monitor buffer ring.
809 */
810 if (delayed_replenish) {
811 num_entries = soc_cfg_ctx->delayed_replenish_entries + 1;
812 status = dp_pdev_rx_buffers_attach(soc, mac_id, mon_buf_ring,
813 rx_desc_pool,
814 num_entries - 1);
815 } else {
816 union dp_rx_desc_list_elem_t *tail = NULL;
817 union dp_rx_desc_list_elem_t *desc_list = NULL;
818
819 status = dp_rx_buffers_replenish(soc, mac_id,
820 mon_buf_ring,
821 rx_desc_pool,
822 num_entries,
823 &desc_list,
824 &tail, false);
825 }
826
827 return status;
828 }
829
830 void
dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev * pdev,uint32_t mac_id)831 dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id)
832 {
833 uint8_t pdev_id = pdev->pdev_id;
834 struct dp_soc *soc = pdev->soc;
835 struct dp_srng *mon_buf_ring;
836 uint32_t num_entries;
837 struct rx_desc_pool *rx_desc_pool;
838 uint32_t rx_desc_pool_size;
839 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
840 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
841
842 mon_buf_ring = &soc->rxdma_mon_buf_ring[mac_id];
843
844 num_entries = mon_buf_ring->num_entries;
845
846 rx_desc_pool = &soc->rx_desc_mon[mac_id];
847
848 /* If descriptor pool is already initialized, do not initialize it */
849 if (rx_desc_pool->freelist)
850 return;
851
852 dp_debug("Mon RX Desc buf Pool[%d] init entries=%u",
853 pdev_id, num_entries);
854
855 rx_desc_pool_size = wlan_cfg_get_dp_soc_rx_sw_desc_weight(soc_cfg_ctx) *
856 num_entries;
857
858 rx_desc_pool->owner = HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id);
859 rx_desc_pool->buf_size = RX_MONITOR_BUFFER_SIZE;
860 rx_desc_pool->buf_alignment = RX_MONITOR_BUFFER_ALIGNMENT;
861 /* Enable frag processing if feature is enabled */
862 dp_rx_enable_mon_dest_frag(rx_desc_pool, true);
863
864 dp_rx_desc_pool_init(soc, mac_id, rx_desc_pool_size, rx_desc_pool);
865
866 mon_pdev->mon_last_linkdesc_paddr = 0;
867
868 mon_pdev->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1;
869
870 /* Attach full monitor mode resources */
871 dp_full_mon_attach(pdev);
872 }
873
874 static void
dp_rx_pdev_mon_buf_desc_pool_deinit(struct dp_pdev * pdev,uint32_t mac_id)875 dp_rx_pdev_mon_buf_desc_pool_deinit(struct dp_pdev *pdev, uint32_t mac_id)
876 {
877 uint8_t pdev_id = pdev->pdev_id;
878 struct dp_soc *soc = pdev->soc;
879 struct rx_desc_pool *rx_desc_pool;
880
881 rx_desc_pool = &soc->rx_desc_mon[mac_id];
882
883 dp_debug("Mon RX Desc buf Pool[%d] deinit", pdev_id);
884
885 dp_rx_desc_pool_deinit(soc, rx_desc_pool, mac_id);
886
887 /* Detach full monitor mode resources */
888 dp_full_mon_detach(pdev);
889 }
890
891 static void
dp_rx_pdev_mon_buf_desc_pool_free(struct dp_pdev * pdev,uint32_t mac_id)892 dp_rx_pdev_mon_buf_desc_pool_free(struct dp_pdev *pdev, uint32_t mac_id)
893 {
894 uint8_t pdev_id = pdev->pdev_id;
895 struct dp_soc *soc = pdev->soc;
896 struct rx_desc_pool *rx_desc_pool;
897
898 rx_desc_pool = &soc->rx_desc_mon[mac_id];
899
900 dp_debug("Mon RX Buf Desc Pool Free pdev[%d]", pdev_id);
901
902 dp_rx_desc_pool_free(soc, rx_desc_pool);
903 }
904
dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev * pdev,uint32_t mac_id)905 void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id)
906 {
907 uint8_t pdev_id = pdev->pdev_id;
908 struct dp_soc *soc = pdev->soc;
909 struct rx_desc_pool *rx_desc_pool;
910
911 rx_desc_pool = &soc->rx_desc_mon[mac_id];
912
913 dp_debug("Mon RX Buf buffers Free pdev[%d]", pdev_id);
914
915 if (rx_desc_pool->rx_mon_dest_frag_enable)
916 dp_rx_desc_frag_free(soc, rx_desc_pool);
917 else
918 dp_rx_desc_nbuf_free(soc, rx_desc_pool, true);
919 }
920
921 QDF_STATUS
dp_rx_pdev_mon_buf_desc_pool_alloc(struct dp_pdev * pdev,uint32_t mac_id)922 dp_rx_pdev_mon_buf_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_id)
923 {
924 uint8_t pdev_id = pdev->pdev_id;
925 struct dp_soc *soc = pdev->soc;
926 struct dp_srng *mon_buf_ring;
927 uint32_t num_entries;
928 struct rx_desc_pool *rx_desc_pool;
929 uint32_t rx_desc_pool_size;
930 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
931
932 mon_buf_ring = &soc->rxdma_mon_buf_ring[mac_id];
933
934 num_entries = mon_buf_ring->num_entries;
935
936 rx_desc_pool = &soc->rx_desc_mon[mac_id];
937
938 dp_debug("Mon RX Desc Pool[%d] entries=%u",
939 pdev_id, num_entries);
940
941 rx_desc_pool_size = wlan_cfg_get_dp_soc_rx_sw_desc_weight(soc_cfg_ctx) *
942 num_entries;
943
944 if (dp_rx_desc_pool_is_allocated(rx_desc_pool) == QDF_STATUS_SUCCESS)
945 return QDF_STATUS_SUCCESS;
946
947 return dp_rx_desc_pool_alloc(soc, rx_desc_pool_size, rx_desc_pool);
948 }
949
950 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC)
951 uint32_t
dp_mon_dest_srng_drop_for_mac(struct dp_pdev * pdev,uint32_t mac_id,bool force_flush)952 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id,
953 bool force_flush)
954 {
955 struct dp_soc *soc = pdev->soc;
956 hal_rxdma_desc_t rxdma_dst_ring_desc;
957 hal_soc_handle_t hal_soc;
958 void *mon_dst_srng;
959 union dp_rx_desc_list_elem_t *head = NULL;
960 union dp_rx_desc_list_elem_t *tail = NULL;
961 uint32_t rx_bufs_used = 0;
962 struct rx_desc_pool *rx_desc_pool;
963 uint32_t reap_cnt = 0;
964 uint32_t rx_bufs_dropped;
965 struct dp_mon_pdev *mon_pdev;
966 bool is_rxdma_dst_ring_common;
967
968 if (qdf_unlikely(!soc || !soc->hal_soc))
969 return reap_cnt;
970
971 mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_id);
972
973 if (qdf_unlikely(!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)))
974 return reap_cnt;
975
976 hal_soc = soc->hal_soc;
977 mon_pdev = pdev->monitor_pdev;
978
979 qdf_spin_lock_bh(&mon_pdev->mon_lock);
980
981 if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_dst_srng))) {
982 qdf_spin_unlock_bh(&mon_pdev->mon_lock);
983 return reap_cnt;
984 }
985
986 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id);
987 is_rxdma_dst_ring_common = dp_is_rxdma_dst_ring_common(pdev);
988
989 while ((rxdma_dst_ring_desc =
990 hal_srng_dst_peek(hal_soc, mon_dst_srng)) &&
991 (reap_cnt < MON_DROP_REAP_LIMIT || force_flush)) {
992 if (is_rxdma_dst_ring_common && !force_flush) {
993 if (QDF_STATUS_SUCCESS ==
994 dp_rx_mon_check_n_drop_mpdu(pdev, mac_id,
995 rxdma_dst_ring_desc,
996 &head, &tail,
997 &rx_bufs_dropped)) {
998 /* Increment stats */
999 rx_bufs_used += rx_bufs_dropped;
1000 } else {
1001 /*
1002 * If the mpdu was not dropped, we need to
1003 * wait for the entry to be processed, along
1004 * with the status ring entry for the other
1005 * mac. Hence we bail out here.
1006 */
1007 break;
1008 }
1009 } else {
1010 rx_bufs_used += dp_rx_mon_drop_one_mpdu(pdev, mac_id,
1011 rxdma_dst_ring_desc,
1012 &head, &tail);
1013 }
1014 reap_cnt++;
1015 rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc,
1016 mon_dst_srng);
1017 }
1018
1019 hal_srng_access_end(hal_soc, mon_dst_srng);
1020
1021 qdf_spin_unlock_bh(&mon_pdev->mon_lock);
1022
1023 if (rx_bufs_used) {
1024 dp_rx_buffers_replenish(soc, mac_id,
1025 dp_rxdma_get_mon_buf_ring(pdev, mac_id),
1026 rx_desc_pool,
1027 rx_bufs_used, &head, &tail, false);
1028 }
1029
1030 return reap_cnt;
1031 }
1032 #else
1033 #if defined(QCA_SUPPORT_FULL_MON) && defined(WIFI_MONITOR_SUPPORT)
1034 uint32_t
dp_mon_dest_srng_drop_for_mac(struct dp_pdev * pdev,uint32_t mac_id)1035 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id)
1036 {
1037 struct dp_soc *soc = pdev->soc;
1038 hal_rxdma_desc_t rxdma_dst_ring_desc;
1039 hal_soc_handle_t hal_soc;
1040 void *mon_dst_srng;
1041 union dp_rx_desc_list_elem_t *head = NULL;
1042 union dp_rx_desc_list_elem_t *tail = NULL;
1043 uint32_t rx_bufs_used = 0;
1044 void *rx_msdu_link_desc;
1045 uint16_t num_msdus;
1046 struct hal_rx_msdu_list msdu_list;
1047 qdf_nbuf_t nbuf = NULL;
1048 uint32_t i;
1049 uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST;
1050 uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS];
1051 struct rx_desc_pool *rx_desc_pool = NULL;
1052 uint32_t reap_cnt = 0;
1053 struct dp_mon_pdev *mon_pdev;
1054 struct hal_rx_mon_desc_info *desc_info;
1055
1056 if (qdf_unlikely(!soc || !soc->hal_soc))
1057 return reap_cnt;
1058
1059 mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_id);
1060
1061 if (qdf_unlikely(!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)))
1062 return reap_cnt;
1063
1064 hal_soc = soc->hal_soc;
1065 mon_pdev = pdev->monitor_pdev;
1066 desc_info = mon_pdev->mon_desc;
1067
1068 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id);
1069
1070 while ((rxdma_dst_ring_desc =
1071 hal_srng_dst_peek(hal_soc, mon_dst_srng))) {
1072 qdf_mem_zero(desc_info, sizeof(struct hal_rx_mon_desc_info));
1073 hal_rx_sw_mon_desc_info_get((struct hal_soc *)soc->hal_soc,
1074 (void *)rxdma_dst_ring_desc,
1075 (void *)desc_info);
1076
1077 if (desc_info->end_of_ppdu) {
1078 rxdma_dst_ring_desc =
1079 hal_srng_dst_get_next(hal_soc, mon_dst_srng);
1080 continue;
1081 }
1082
1083 do {
1084 rx_msdu_link_desc =
1085 dp_rx_cookie_2_mon_link_desc(pdev,
1086 &desc_info->
1087 link_desc,
1088 mac_id);
1089
1090 if (qdf_unlikely(!rx_msdu_link_desc)) {
1091 mon_pdev->rx_mon_stats.mon_link_desc_invalid++;
1092 goto next_entry;
1093 }
1094
1095 hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc,
1096 &msdu_list, &num_msdus);
1097
1098 for (i = 0; i < num_msdus; i++) {
1099 struct dp_rx_desc *rx_desc;
1100 qdf_dma_addr_t buf_paddr;
1101
1102 rx_desc =
1103 dp_rx_get_mon_desc(soc, msdu_list.
1104 sw_cookie[i]);
1105
1106 if (qdf_unlikely(!rx_desc)) {
1107 mon_pdev->rx_mon_stats.
1108 mon_rx_desc_invalid++;
1109 continue;
1110 }
1111
1112 nbuf = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc);
1113 buf_paddr =
1114 dp_rx_mon_get_paddr_from_desc(rx_desc);
1115
1116 if (qdf_unlikely(!rx_desc->in_use || !nbuf ||
1117 msdu_list.paddr[i] !=
1118 buf_paddr)) {
1119 mon_pdev->rx_mon_stats.
1120 mon_nbuf_sanity_err++;
1121 continue;
1122 }
1123 rx_bufs_used++;
1124
1125 if (!rx_desc->unmapped) {
1126 dp_rx_mon_buffer_unmap(soc, rx_desc,
1127 rx_desc_pool->
1128 buf_size);
1129 rx_desc->unmapped = 1;
1130 }
1131
1132 dp_rx_mon_buffer_free(rx_desc);
1133 dp_rx_add_to_free_desc_list(&head, &tail,
1134 rx_desc);
1135
1136 if (!(msdu_list.msdu_info[i].msdu_flags &
1137 HAL_MSDU_F_MSDU_CONTINUATION))
1138 desc_info->msdu_count--;
1139 }
1140
1141 /*
1142 * Store the current link buffer into to the local
1143 * structure to be used for release purpose.
1144 */
1145 hal_rxdma_buff_addr_info_set(soc->hal_soc,
1146 rx_link_buf_info,
1147 desc_info->link_desc.paddr,
1148 desc_info->link_desc.
1149 sw_cookie,
1150 desc_info->link_desc.rbm);
1151
1152 hal_rx_mon_next_link_desc_get(soc->hal_soc,
1153 rx_msdu_link_desc,
1154 &desc_info->link_desc);
1155 if (dp_rx_monitor_link_desc_return(pdev,
1156 (hal_buff_addrinfo_t)
1157 rx_link_buf_info,
1158 mac_id, bm_action) !=
1159 QDF_STATUS_SUCCESS)
1160 dp_info_rl("monitor link desc return failed");
1161 } while (desc_info->link_desc.paddr);
1162
1163 next_entry:
1164 reap_cnt++;
1165 rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc,
1166 mon_dst_srng);
1167 }
1168
1169 if (rx_bufs_used) {
1170 dp_rx_buffers_replenish(soc, mac_id,
1171 dp_rxdma_get_mon_buf_ring(pdev, mac_id),
1172 rx_desc_pool,
1173 rx_bufs_used, &head, &tail, false);
1174 }
1175
1176 return reap_cnt;
1177 }
1178 #else
1179 uint32_t
dp_mon_dest_srng_drop_for_mac(struct dp_pdev * pdev,uint32_t mac_id)1180 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id)
1181 {
1182 return 0;
1183 }
1184 #endif
1185 #endif
1186
1187 static void
dp_rx_pdev_mon_dest_desc_pool_free(struct dp_pdev * pdev,int mac_for_pdev)1188 dp_rx_pdev_mon_dest_desc_pool_free(struct dp_pdev *pdev, int mac_for_pdev)
1189 {
1190 struct dp_soc *soc = pdev->soc;
1191
1192 dp_rx_pdev_mon_buf_desc_pool_free(pdev, mac_for_pdev);
1193 dp_hw_link_desc_pool_banks_free(soc, mac_for_pdev);
1194 }
1195
1196 static void
dp_rx_pdev_mon_dest_desc_pool_deinit(struct dp_pdev * pdev,int mac_for_pdev)1197 dp_rx_pdev_mon_dest_desc_pool_deinit(struct dp_pdev *pdev, int mac_for_pdev)
1198 {
1199 struct dp_soc *soc = pdev->soc;
1200
1201 if (!soc->wlan_cfg_ctx->rxdma1_enable)
1202 return;
1203
1204 dp_rx_pdev_mon_buf_desc_pool_deinit(pdev, mac_for_pdev);
1205 }
1206
1207 static void
dp_rx_pdev_mon_dest_desc_pool_init(struct dp_pdev * pdev,uint32_t mac_for_pdev)1208 dp_rx_pdev_mon_dest_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_for_pdev)
1209 {
1210 struct dp_soc *soc = pdev->soc;
1211
1212 if (!soc->wlan_cfg_ctx->rxdma1_enable ||
1213 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx))
1214 return;
1215
1216 dp_rx_pdev_mon_buf_desc_pool_init(pdev, mac_for_pdev);
1217 dp_link_desc_ring_replenish(soc, mac_for_pdev);
1218 }
1219
1220 static void
dp_rx_pdev_mon_dest_buffers_free(struct dp_pdev * pdev,int mac_for_pdev)1221 dp_rx_pdev_mon_dest_buffers_free(struct dp_pdev *pdev, int mac_for_pdev)
1222 {
1223 struct dp_soc *soc = pdev->soc;
1224
1225 if (!soc->wlan_cfg_ctx->rxdma1_enable)
1226 return;
1227
1228 dp_rx_pdev_mon_buf_buffers_free(pdev, mac_for_pdev);
1229 }
1230
1231 static QDF_STATUS
dp_rx_pdev_mon_dest_buffers_alloc(struct dp_pdev * pdev,int mac_for_pdev)1232 dp_rx_pdev_mon_dest_buffers_alloc(struct dp_pdev *pdev, int mac_for_pdev)
1233 {
1234 struct dp_soc *soc = pdev->soc;
1235 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx;
1236 bool delayed_replenish;
1237 QDF_STATUS status = QDF_STATUS_SUCCESS;
1238
1239 delayed_replenish = soc_cfg_ctx->delayed_replenish_entries ? 1 : 0;
1240 if (!soc->wlan_cfg_ctx->rxdma1_enable ||
1241 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx))
1242 return status;
1243
1244 status = dp_rx_pdev_mon_buf_buffers_alloc(pdev, mac_for_pdev,
1245 delayed_replenish);
1246 if (!QDF_IS_STATUS_SUCCESS(status))
1247 dp_err("dp_rx_pdev_mon_buf_desc_pool_alloc() failed");
1248
1249 return status;
1250 }
1251
1252 static QDF_STATUS
dp_rx_pdev_mon_dest_desc_pool_alloc(struct dp_pdev * pdev,uint32_t mac_for_pdev)1253 dp_rx_pdev_mon_dest_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_for_pdev)
1254 {
1255 struct dp_soc *soc = pdev->soc;
1256 QDF_STATUS status = QDF_STATUS_SUCCESS;
1257
1258 if (!soc->wlan_cfg_ctx->rxdma1_enable ||
1259 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx))
1260 return status;
1261
1262 /* Allocate sw rx descriptor pool for monitor RxDMA buffer ring */
1263 status = dp_rx_pdev_mon_buf_desc_pool_alloc(pdev, mac_for_pdev);
1264 if (!QDF_IS_STATUS_SUCCESS(status)) {
1265 dp_err("dp_rx_pdev_mon_buf_desc_pool_alloc() failed");
1266 goto fail;
1267 }
1268
1269 /* Allocate link descriptors for the monitor link descriptor ring */
1270 status = dp_hw_link_desc_pool_banks_alloc(soc, mac_for_pdev);
1271 if (!QDF_IS_STATUS_SUCCESS(status)) {
1272 dp_err("dp_hw_link_desc_pool_banks_alloc() failed");
1273 goto mon_buf_dealloc;
1274 }
1275
1276 return status;
1277
1278 mon_buf_dealloc:
1279 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev);
1280 fail:
1281 return status;
1282 }
1283 #else
1284 static void
dp_rx_pdev_mon_dest_desc_pool_free(struct dp_pdev * pdev,int mac_for_pdev)1285 dp_rx_pdev_mon_dest_desc_pool_free(struct dp_pdev *pdev, int mac_for_pdev)
1286 {
1287 }
1288
1289 static void
dp_rx_pdev_mon_dest_desc_pool_deinit(struct dp_pdev * pdev,int mac_for_pdev)1290 dp_rx_pdev_mon_dest_desc_pool_deinit(struct dp_pdev *pdev, int mac_for_pdev)
1291 {
1292 }
1293
1294 static void
dp_rx_pdev_mon_dest_desc_pool_init(struct dp_pdev * pdev,uint32_t mac_for_pdev)1295 dp_rx_pdev_mon_dest_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_for_pdev)
1296 {
1297 }
1298
1299 static void
dp_rx_pdev_mon_dest_buffers_free(struct dp_pdev * pdev,int mac_for_pdev)1300 dp_rx_pdev_mon_dest_buffers_free(struct dp_pdev *pdev, int mac_for_pdev)
1301 {
1302 }
1303
1304 static QDF_STATUS
dp_rx_pdev_mon_dest_buffers_alloc(struct dp_pdev * pdev,int mac_for_pdev)1305 dp_rx_pdev_mon_dest_buffers_alloc(struct dp_pdev *pdev, int mac_for_pdev)
1306 {
1307 return QDF_STATUS_SUCCESS;
1308 }
1309
1310 static QDF_STATUS
dp_rx_pdev_mon_dest_desc_pool_alloc(struct dp_pdev * pdev,uint32_t mac_for_pdev)1311 dp_rx_pdev_mon_dest_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_for_pdev)
1312 {
1313 return QDF_STATUS_SUCCESS;
1314 }
1315
1316 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC)
1317 uint32_t
dp_mon_dest_srng_drop_for_mac(struct dp_pdev * pdev,uint32_t mac_id)1318 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id)
1319 {
1320 return 0;
1321 }
1322 #endif
1323
1324 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_NON_MON_PMAC)
1325 static QDF_STATUS
dp_rx_mon_check_n_drop_mpdu(struct dp_pdev * pdev,uint32_t mac_id,hal_rxdma_desc_t rxdma_dst_ring_desc,union dp_rx_desc_list_elem_t ** head,union dp_rx_desc_list_elem_t ** tail,uint32_t * rx_bufs_dropped)1326 dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id,
1327 hal_rxdma_desc_t rxdma_dst_ring_desc,
1328 union dp_rx_desc_list_elem_t **head,
1329 union dp_rx_desc_list_elem_t **tail,
1330 uint32_t *rx_bufs_dropped)
1331 {
1332 return QDF_STATUS_E_FAILURE;
1333 }
1334 #endif
1335 #endif
1336
1337 #ifdef WLAN_SOFTUMAC_SUPPORT
dp_mon_hw_link_desc_bank_free(struct dp_soc * soc,uint32_t mac_id)1338 static void dp_mon_hw_link_desc_bank_free(struct dp_soc *soc, uint32_t mac_id)
1339 {
1340 struct qdf_mem_multi_page_t *pages;
1341
1342 pages = dp_monitor_get_link_desc_pages(soc, mac_id);
1343 if (!pages) {
1344 dp_err("can not get mon link desc pages");
1345 QDF_ASSERT(0);
1346 return;
1347 }
1348
1349 if (pages->dma_pages) {
1350 wlan_minidump_remove((void *)
1351 pages->dma_pages->page_v_addr_start,
1352 pages->num_pages * pages->page_size,
1353 soc->ctrl_psoc,
1354 WLAN_MD_DP_SRNG_SW2RXDMA_LINK_RING,
1355 "mon hw_link_desc_bank");
1356 dp_desc_multi_pages_mem_free(soc, QDF_DP_HW_LINK_DESC_TYPE,
1357 pages, 0, false);
1358 }
1359 }
1360
1361 static QDF_STATUS
dp_mon_hw_link_desc_bank_alloc(struct dp_soc * soc,uint32_t mac_id)1362 dp_mon_hw_link_desc_bank_alloc(struct dp_soc *soc, uint32_t mac_id)
1363 {
1364 struct qdf_mem_multi_page_t *pages;
1365 uint32_t *total_link_descs, total_mem_size;
1366 uint32_t num_entries;
1367 uint32_t max_alloc_size = wlan_cfg_max_alloc_size(soc->wlan_cfg_ctx);
1368 int link_desc_size = hal_get_link_desc_size(soc->hal_soc);
1369 int link_desc_align = hal_get_link_desc_align(soc->hal_soc);
1370 uint8_t minidump_str[MINIDUMP_STR_SIZE];
1371
1372 pages = dp_monitor_get_link_desc_pages(soc, mac_id);
1373 if (!pages) {
1374 dp_err("can not get mon link desc pages");
1375 QDF_ASSERT(0);
1376 return QDF_STATUS_E_FAULT;
1377 }
1378
1379 /* If link descriptor banks are allocated, return from here */
1380 if (pages->num_pages)
1381 return QDF_STATUS_SUCCESS;
1382
1383 num_entries = dp_monitor_get_num_link_desc_ring_entries(soc, mac_id);
1384 total_link_descs = dp_monitor_get_total_link_descs(soc, mac_id);
1385 qdf_str_lcopy(minidump_str, "mon_link_desc_bank",
1386 MINIDUMP_STR_SIZE);
1387
1388 /* Round up to power of 2 */
1389 *total_link_descs = 1;
1390 while (*total_link_descs < num_entries)
1391 *total_link_descs <<= 1;
1392
1393 dp_init_info("%pK: total_link_descs: %u, link_desc_size: %d",
1394 soc, *total_link_descs, link_desc_size);
1395
1396 total_mem_size = *total_link_descs * link_desc_size;
1397 total_mem_size += link_desc_align;
1398
1399 dp_init_info("%pK: total_mem_size: %d", soc, total_mem_size);
1400
1401 dp_set_max_page_size(pages, max_alloc_size);
1402 dp_desc_multi_pages_mem_alloc(soc, QDF_DP_HW_LINK_DESC_TYPE,
1403 pages, link_desc_size,
1404 *total_link_descs, 0, false);
1405
1406 if (!pages->num_pages) {
1407 dp_err("Multi page alloc fail for mon hw link desc pool");
1408 return QDF_STATUS_E_FAULT;
1409 }
1410
1411 wlan_minidump_log(pages->dma_pages->page_v_addr_start,
1412 pages->num_pages * pages->page_size,
1413 soc->ctrl_psoc,
1414 WLAN_MD_DP_SRNG_SW2RXDMA_LINK_RING,
1415 "mon hw_link_desc_bank");
1416
1417 return QDF_STATUS_SUCCESS;
1418 }
1419
1420 static void
dp_mon_link_desc_ring_replenish(struct dp_soc * soc,int mac_id)1421 dp_mon_link_desc_ring_replenish(struct dp_soc *soc, int mac_id)
1422 {
1423 dp_link_desc_ring_replenish(soc, mac_id);
1424 }
1425 #else
1426 static QDF_STATUS
dp_mon_hw_link_desc_bank_alloc(struct dp_soc * soc,uint32_t mac_id)1427 dp_mon_hw_link_desc_bank_alloc(struct dp_soc *soc, uint32_t mac_id)
1428 {
1429 return QDF_STATUS_SUCCESS;
1430 }
1431
1432 static void
dp_mon_hw_link_desc_bank_free(struct dp_soc * soc,uint32_t mac_id)1433 dp_mon_hw_link_desc_bank_free(struct dp_soc *soc, uint32_t mac_id) {}
1434
1435 static void
dp_mon_link_desc_ring_replenish(struct dp_soc * soc,int mac_id)1436 dp_mon_link_desc_ring_replenish(struct dp_soc *soc, int mac_id) {}
1437 #endif
1438
1439 static void
dp_rx_pdev_mon_cmn_desc_pool_free(struct dp_pdev * pdev,int mac_id)1440 dp_rx_pdev_mon_cmn_desc_pool_free(struct dp_pdev *pdev, int mac_id)
1441 {
1442 struct dp_soc *soc = pdev->soc;
1443 uint8_t pdev_id = pdev->pdev_id;
1444 int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id);
1445
1446 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev);
1447 dp_mon_hw_link_desc_bank_free(soc, mac_for_pdev);
1448 dp_rx_pdev_mon_dest_desc_pool_free(pdev, mac_for_pdev);
1449 }
1450
dp_rx_pdev_mon_desc_pool_free(struct dp_pdev * pdev)1451 void dp_rx_pdev_mon_desc_pool_free(struct dp_pdev *pdev)
1452 {
1453 int mac_id;
1454
1455 for (mac_id = 0; mac_id < NUM_RXDMA_STATUS_RINGS_PER_PDEV; mac_id++)
1456 dp_rx_pdev_mon_cmn_desc_pool_free(pdev, mac_id);
1457 }
1458
1459 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
1460 static inline void
dp_rx_lpc_lock_create(struct dp_mon_pdev * mon_pdev)1461 dp_rx_lpc_lock_create(struct dp_mon_pdev *mon_pdev)
1462 {
1463 qdf_spinlock_create(&mon_pdev->lpc_lock);
1464 }
1465
1466 static inline void
dp_rx_lpc_lock_destroy(struct dp_mon_pdev * mon_pdev)1467 dp_rx_lpc_lock_destroy(struct dp_mon_pdev *mon_pdev)
1468 {
1469 qdf_spinlock_destroy(&mon_pdev->lpc_lock);
1470 }
1471 #else
1472 static inline void
dp_rx_lpc_lock_create(struct dp_mon_pdev * mon_pdev)1473 dp_rx_lpc_lock_create(struct dp_mon_pdev *mon_pdev)
1474 {
1475 }
1476
1477 static inline void
dp_rx_lpc_lock_destroy(struct dp_mon_pdev * mon_pdev)1478 dp_rx_lpc_lock_destroy(struct dp_mon_pdev *mon_pdev)
1479 {
1480 }
1481 #endif
1482
1483 static void
dp_rx_pdev_mon_cmn_desc_pool_deinit(struct dp_pdev * pdev,int mac_id)1484 dp_rx_pdev_mon_cmn_desc_pool_deinit(struct dp_pdev *pdev, int mac_id)
1485 {
1486 struct dp_soc *soc = pdev->soc;
1487 uint8_t pdev_id = pdev->pdev_id;
1488 int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id);
1489
1490 dp_rx_pdev_mon_status_desc_pool_deinit(pdev, mac_for_pdev);
1491
1492 dp_rx_pdev_mon_dest_desc_pool_deinit(pdev, mac_for_pdev);
1493 }
1494
1495 void
dp_rx_pdev_mon_desc_pool_deinit(struct dp_pdev * pdev)1496 dp_rx_pdev_mon_desc_pool_deinit(struct dp_pdev *pdev)
1497 {
1498 int mac_id;
1499
1500 for (mac_id = 0; mac_id < NUM_RXDMA_STATUS_RINGS_PER_PDEV; mac_id++)
1501 dp_rx_pdev_mon_cmn_desc_pool_deinit(pdev, mac_id);
1502 qdf_spinlock_destroy(&pdev->monitor_pdev->mon_lock);
1503 dp_rx_lpc_lock_destroy(pdev->monitor_pdev);
1504 }
1505
1506 static void
dp_rx_pdev_mon_cmn_desc_pool_init(struct dp_pdev * pdev,int mac_id)1507 dp_rx_pdev_mon_cmn_desc_pool_init(struct dp_pdev *pdev, int mac_id)
1508 {
1509 struct dp_soc *soc = pdev->soc;
1510 uint32_t mac_for_pdev;
1511
1512 mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id);
1513 dp_rx_pdev_mon_status_desc_pool_init(pdev, mac_for_pdev);
1514 dp_mon_link_desc_ring_replenish(soc, mac_for_pdev);
1515
1516 dp_rx_pdev_mon_dest_desc_pool_init(pdev, mac_for_pdev);
1517 }
1518
1519 void
dp_rx_pdev_mon_desc_pool_init(struct dp_pdev * pdev)1520 dp_rx_pdev_mon_desc_pool_init(struct dp_pdev *pdev)
1521 {
1522 int mac_id;
1523
1524 for (mac_id = 0; mac_id < NUM_RXDMA_STATUS_RINGS_PER_PDEV; mac_id++)
1525 dp_rx_pdev_mon_cmn_desc_pool_init(pdev, mac_id);
1526 qdf_spinlock_create(&pdev->monitor_pdev->mon_lock);
1527 dp_rx_lpc_lock_create(pdev->monitor_pdev);
1528 }
1529
1530 void
dp_rx_pdev_mon_buffers_free(struct dp_pdev * pdev)1531 dp_rx_pdev_mon_buffers_free(struct dp_pdev *pdev)
1532 {
1533 int mac_id;
1534 int mac_for_pdev;
1535 uint8_t pdev_id = pdev->pdev_id;
1536 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = pdev->soc->wlan_cfg_ctx;
1537
1538 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_status_rings_per_pdev;
1539 mac_id++) {
1540 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id,
1541 pdev_id);
1542 dp_rx_pdev_mon_status_buffers_free(pdev, mac_for_pdev);
1543 }
1544
1545 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_dst_rings_per_pdev;
1546 mac_id++) {
1547 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id,
1548 pdev_id);
1549 dp_rx_pdev_mon_dest_buffers_free(pdev, mac_for_pdev);
1550 }
1551 pdev->monitor_pdev->pdev_mon_init = 0;
1552 }
1553
1554 QDF_STATUS
dp_rx_pdev_mon_buffers_alloc(struct dp_pdev * pdev)1555 dp_rx_pdev_mon_buffers_alloc(struct dp_pdev *pdev)
1556 {
1557 int mac_id;
1558 int mac_for_pdev;
1559 QDF_STATUS status = QDF_STATUS_SUCCESS;
1560 uint8_t pdev_id = pdev->pdev_id;
1561 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = pdev->soc->wlan_cfg_ctx;
1562
1563 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_status_rings_per_pdev;
1564 mac_id++) {
1565 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id,
1566 pdev_id);
1567 status = dp_rx_pdev_mon_status_buffers_alloc(pdev,
1568 mac_for_pdev);
1569 if (!QDF_IS_STATUS_SUCCESS(status)) {
1570 dp_err("dp_rx_pdev_mon_status_desc_pool_alloc() failed");
1571 goto mon_status_buf_fail;
1572 }
1573 }
1574
1575 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_dst_rings_per_pdev;
1576 mac_id++) {
1577 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id,
1578 pdev_id);
1579 status = dp_rx_pdev_mon_dest_buffers_alloc(pdev, mac_for_pdev);
1580 if (!QDF_IS_STATUS_SUCCESS(status))
1581 goto mon_stat_buf_dealloc;
1582 }
1583
1584 return status;
1585
1586 mon_stat_buf_dealloc:
1587 dp_rx_pdev_mon_status_buffers_free(pdev, mac_for_pdev);
1588 mon_status_buf_fail:
1589 return status;
1590 }
1591
1592 static QDF_STATUS
dp_rx_pdev_mon_cmn_desc_pool_alloc(struct dp_pdev * pdev,int mac_id)1593 dp_rx_pdev_mon_cmn_desc_pool_alloc(struct dp_pdev *pdev, int mac_id)
1594 {
1595 struct dp_soc *soc = pdev->soc;
1596 uint8_t pdev_id = pdev->pdev_id;
1597 uint32_t mac_for_pdev;
1598 QDF_STATUS status;
1599
1600 mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id);
1601
1602 /* Allocate sw rx descriptor pool for monitor status ring */
1603 status = dp_rx_pdev_mon_status_desc_pool_alloc(pdev, mac_for_pdev);
1604 if (!QDF_IS_STATUS_SUCCESS(status)) {
1605 dp_err("dp_rx_pdev_mon_status_desc_pool_alloc() failed");
1606 goto fail;
1607 }
1608
1609 /* Allocate hw link desc bank for monitor mode for
1610 * SOFTUMAC architecture.
1611 */
1612 status = dp_mon_hw_link_desc_bank_alloc(soc, mac_for_pdev);
1613 if (!QDF_IS_STATUS_SUCCESS(status)) {
1614 dp_err("dp_mon_hw_link_desc_bank_alloc() failed");
1615 goto mon_status_dealloc;
1616 }
1617
1618 status = dp_rx_pdev_mon_dest_desc_pool_alloc(pdev, mac_for_pdev);
1619 if (!QDF_IS_STATUS_SUCCESS(status))
1620 goto link_desc_bank_free;
1621
1622 return status;
1623
1624 link_desc_bank_free:
1625 dp_mon_hw_link_desc_bank_free(soc, mac_for_pdev);
1626 mon_status_dealloc:
1627 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev);
1628 fail:
1629 return status;
1630 }
1631
1632 QDF_STATUS
dp_rx_pdev_mon_desc_pool_alloc(struct dp_pdev * pdev)1633 dp_rx_pdev_mon_desc_pool_alloc(struct dp_pdev *pdev)
1634 {
1635 QDF_STATUS status;
1636 int mac_id, count;
1637
1638 for (mac_id = 0; mac_id < NUM_RXDMA_STATUS_RINGS_PER_PDEV; mac_id++) {
1639 status = dp_rx_pdev_mon_cmn_desc_pool_alloc(pdev, mac_id);
1640 if (!QDF_IS_STATUS_SUCCESS(status)) {
1641 dp_rx_mon_dest_err("%pK: %d failed",
1642 pdev->soc, mac_id);
1643
1644 for (count = 0; count < mac_id; count++)
1645 dp_rx_pdev_mon_cmn_desc_pool_free(pdev, count);
1646
1647 return status;
1648 }
1649 }
1650 return status;
1651 }
1652
1653 #ifdef QCA_WIFI_MONITOR_MODE_NO_MSDU_START_TLV_SUPPORT
1654 static inline void
hal_rx_populate_buf_info(struct dp_soc * soc,struct hal_rx_mon_dest_buf_info * buf_info,void * rx_desc)1655 hal_rx_populate_buf_info(struct dp_soc *soc,
1656 struct hal_rx_mon_dest_buf_info *buf_info,
1657 void *rx_desc)
1658 {
1659 hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_desc,
1660 (uint8_t *)buf_info,
1661 sizeof(*buf_info));
1662 }
1663
1664 static inline uint8_t
hal_rx_frag_msdu_get_l2_hdr_offset(struct dp_soc * soc,struct hal_rx_mon_dest_buf_info * buf_info,void * rx_desc,bool is_first_frag)1665 hal_rx_frag_msdu_get_l2_hdr_offset(struct dp_soc *soc,
1666 struct hal_rx_mon_dest_buf_info *buf_info,
1667 void *rx_desc, bool is_first_frag)
1668 {
1669 if (is_first_frag)
1670 return buf_info->l2_hdr_pad;
1671 else
1672 return DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
1673 }
1674 #else
1675 static inline void
hal_rx_populate_buf_info(struct dp_soc * soc,struct hal_rx_mon_dest_buf_info * buf_info,void * rx_desc)1676 hal_rx_populate_buf_info(struct dp_soc *soc,
1677 struct hal_rx_mon_dest_buf_info *buf_info,
1678 void *rx_desc)
1679 {
1680 if (hal_rx_tlv_decap_format_get(soc->hal_soc, rx_desc) ==
1681 HAL_HW_RX_DECAP_FORMAT_RAW)
1682 buf_info->is_decap_raw = 1;
1683
1684 if (hal_rx_tlv_mpdu_len_err_get(soc->hal_soc, rx_desc))
1685 buf_info->mpdu_len_err = 1;
1686 }
1687
1688 static inline uint8_t
hal_rx_frag_msdu_get_l2_hdr_offset(struct dp_soc * soc,struct hal_rx_mon_dest_buf_info * buf_info,void * rx_desc,bool is_first_frag)1689 hal_rx_frag_msdu_get_l2_hdr_offset(struct dp_soc *soc,
1690 struct hal_rx_mon_dest_buf_info *buf_info,
1691 void *rx_desc, bool is_first_frag)
1692 {
1693 return hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, rx_desc);
1694 }
1695 #endif
1696
1697 static inline
dp_rx_msdus_set_payload(struct dp_soc * soc,qdf_nbuf_t msdu,uint8_t l2_hdr_offset)1698 void dp_rx_msdus_set_payload(struct dp_soc *soc, qdf_nbuf_t msdu,
1699 uint8_t l2_hdr_offset)
1700 {
1701 uint8_t *data;
1702 uint32_t rx_pkt_offset;
1703
1704 data = qdf_nbuf_data(msdu);
1705 rx_pkt_offset = dp_rx_mon_get_rx_pkt_tlv_size(soc);
1706 qdf_nbuf_pull_head(msdu, rx_pkt_offset + l2_hdr_offset);
1707 }
1708
1709 static inline qdf_nbuf_t
dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc * soc,uint32_t mac_id,qdf_nbuf_t head_msdu,qdf_nbuf_t last_msdu,struct cdp_mon_status * rx_status)1710 dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc,
1711 uint32_t mac_id,
1712 qdf_nbuf_t head_msdu,
1713 qdf_nbuf_t last_msdu,
1714 struct cdp_mon_status *rx_status)
1715 {
1716 qdf_nbuf_t msdu, mpdu_buf, prev_buf, msdu_orig, head_frag_list;
1717 uint32_t wifi_hdr_len, sec_hdr_len, msdu_llc_len,
1718 mpdu_buf_len, decap_hdr_pull_bytes, frag_list_sum_len, dir,
1719 is_amsdu, is_first_frag, amsdu_pad;
1720 void *rx_desc;
1721 char *hdr_desc;
1722 unsigned char *dest;
1723 struct ieee80211_frame *wh;
1724 struct ieee80211_qoscntl *qos;
1725 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
1726 struct dp_mon_pdev *mon_pdev;
1727 struct hal_rx_mon_dest_buf_info buf_info;
1728 uint8_t l2_hdr_offset;
1729
1730 head_frag_list = NULL;
1731 mpdu_buf = NULL;
1732
1733 if (qdf_unlikely(!dp_pdev)) {
1734 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d",
1735 soc, mac_id);
1736 return NULL;
1737 }
1738
1739 mon_pdev = dp_pdev->monitor_pdev;
1740
1741 /* The nbuf has been pulled just beyond the status and points to the
1742 * payload
1743 */
1744 if (!head_msdu)
1745 goto mpdu_stitch_fail;
1746
1747 msdu_orig = head_msdu;
1748
1749 rx_desc = qdf_nbuf_data(msdu_orig);
1750 qdf_mem_zero(&buf_info, sizeof(buf_info));
1751 hal_rx_populate_buf_info(soc, &buf_info, rx_desc);
1752
1753 if (buf_info.mpdu_len_err) {
1754 /* It looks like there is some issue on MPDU len err */
1755 /* Need further investigate if drop the packet */
1756 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1);
1757 return NULL;
1758 }
1759
1760 rx_desc = qdf_nbuf_data(last_msdu);
1761
1762 rx_status->cdp_rs_fcs_err = hal_rx_tlv_mpdu_fcs_err_get(soc->hal_soc,
1763 rx_desc);
1764 mon_pdev->ppdu_info.rx_status.rs_fcs_err = rx_status->cdp_rs_fcs_err;
1765
1766 /* Fill out the rx_status from the PPDU start and end fields */
1767 /* HAL_RX_GET_PPDU_STATUS(soc, mac_id, rx_status); */
1768
1769 rx_desc = qdf_nbuf_data(head_msdu);
1770
1771 /* Easy case - The MSDU status indicates that this is a non-decapped
1772 * packet in RAW mode.
1773 */
1774 if (buf_info.is_decap_raw) {
1775 /* Note that this path might suffer from headroom unavailabilty
1776 * - but the RX status is usually enough
1777 */
1778
1779 l2_hdr_offset = hal_rx_frag_msdu_get_l2_hdr_offset(soc,
1780 &buf_info,
1781 rx_desc,
1782 true);
1783 dp_rx_msdus_set_payload(soc, head_msdu, l2_hdr_offset);
1784
1785 dp_rx_mon_dest_debug("%pK: decap format raw head %pK head->next %pK last_msdu %pK last_msdu->next %pK",
1786 soc, head_msdu, head_msdu->next,
1787 last_msdu, last_msdu->next);
1788
1789 mpdu_buf = head_msdu;
1790
1791 prev_buf = mpdu_buf;
1792
1793 frag_list_sum_len = 0;
1794 msdu = qdf_nbuf_next(head_msdu);
1795 is_first_frag = 1;
1796
1797 while (msdu) {
1798 l2_hdr_offset = hal_rx_frag_msdu_get_l2_hdr_offset(
1799 soc, &buf_info,
1800 rx_desc, false);
1801 dp_rx_msdus_set_payload(soc, msdu, l2_hdr_offset);
1802
1803 if (is_first_frag) {
1804 is_first_frag = 0;
1805 head_frag_list = msdu;
1806 }
1807
1808 frag_list_sum_len += qdf_nbuf_len(msdu);
1809
1810 /* Maintain the linking of the cloned MSDUS */
1811 qdf_nbuf_set_next_ext(prev_buf, msdu);
1812
1813 /* Move to the next */
1814 prev_buf = msdu;
1815 msdu = qdf_nbuf_next(msdu);
1816 }
1817
1818 qdf_nbuf_trim_tail(prev_buf, HAL_RX_FCS_LEN);
1819
1820 /* If there were more fragments to this RAW frame */
1821 if (head_frag_list) {
1822 if (frag_list_sum_len <
1823 sizeof(struct ieee80211_frame_min_one)) {
1824 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1);
1825 return NULL;
1826 }
1827 frag_list_sum_len -= HAL_RX_FCS_LEN;
1828 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list,
1829 frag_list_sum_len);
1830 qdf_nbuf_set_next(mpdu_buf, NULL);
1831 }
1832
1833 goto mpdu_stitch_done;
1834 }
1835
1836 /* Decap mode:
1837 * Calculate the amount of header in decapped packet to knock off based
1838 * on the decap type and the corresponding number of raw bytes to copy
1839 * status header
1840 */
1841 rx_desc = qdf_nbuf_data(head_msdu);
1842
1843 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, rx_desc);
1844
1845 dp_rx_mon_dest_debug("%pK: decap format not raw", soc);
1846
1847 /* Base size */
1848 wifi_hdr_len = sizeof(struct ieee80211_frame);
1849 wh = (struct ieee80211_frame *)hdr_desc;
1850
1851 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1852
1853 if (dir == IEEE80211_FC1_DIR_DSTODS)
1854 wifi_hdr_len += 6;
1855
1856 is_amsdu = 0;
1857 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) {
1858 qos = (struct ieee80211_qoscntl *)
1859 (hdr_desc + wifi_hdr_len);
1860 wifi_hdr_len += 2;
1861
1862 is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU);
1863 }
1864
1865 /* Calculate security header length based on 'Protected'
1866 * and 'EXT_IV' flag
1867 */
1868 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1869 char *iv = (char *)wh + wifi_hdr_len;
1870
1871 if (iv[3] & KEY_EXTIV)
1872 sec_hdr_len = 8;
1873 else
1874 sec_hdr_len = 4;
1875 } else {
1876 sec_hdr_len = 0;
1877 }
1878 wifi_hdr_len += sec_hdr_len;
1879
1880 /* MSDU related stuff LLC - AMSDU subframe header etc */
1881 msdu_llc_len = is_amsdu ? (14 + 8) : 8;
1882
1883 mpdu_buf_len = wifi_hdr_len + msdu_llc_len;
1884
1885 /* "Decap" header to remove from MSDU buffer */
1886 decap_hdr_pull_bytes = 14;
1887
1888 /* Allocate a new nbuf for holding the 802.11 header retrieved from the
1889 * status of the now decapped first msdu. Leave enough headroom for
1890 * accommodating any radio-tap /prism like PHY header
1891 */
1892 mpdu_buf = qdf_nbuf_alloc(soc->osdev,
1893 MAX_MONITOR_HEADER + mpdu_buf_len,
1894 MAX_MONITOR_HEADER, 4, FALSE);
1895
1896 if (!mpdu_buf)
1897 goto mpdu_stitch_done;
1898
1899 /* Copy the MPDU related header and enc headers into the first buffer
1900 * - Note that there can be a 2 byte pad between heaader and enc header
1901 */
1902
1903 prev_buf = mpdu_buf;
1904 dest = qdf_nbuf_put_tail(prev_buf, wifi_hdr_len);
1905 if (!dest)
1906 goto mpdu_stitch_fail;
1907
1908 qdf_mem_copy(dest, hdr_desc, wifi_hdr_len);
1909 hdr_desc += wifi_hdr_len;
1910
1911 #if 0
1912 dest = qdf_nbuf_put_tail(prev_buf, sec_hdr_len);
1913 adf_os_mem_copy(dest, hdr_desc, sec_hdr_len);
1914 hdr_desc += sec_hdr_len;
1915 #endif
1916
1917 /* The first LLC len is copied into the MPDU buffer */
1918 frag_list_sum_len = 0;
1919
1920 msdu_orig = head_msdu;
1921 is_first_frag = 1;
1922 amsdu_pad = 0;
1923
1924 while (msdu_orig) {
1925
1926 /* TODO: intra AMSDU padding - do we need it ??? */
1927
1928 msdu = msdu_orig;
1929
1930 if (is_first_frag) {
1931 head_frag_list = msdu;
1932 } else {
1933 /* Reload the hdr ptr only on non-first MSDUs */
1934 rx_desc = qdf_nbuf_data(msdu_orig);
1935 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc,
1936 rx_desc);
1937 }
1938
1939 /* Copy this buffers MSDU related status into the prev buffer */
1940
1941 if (is_first_frag)
1942 is_first_frag = 0;
1943
1944 /* Update protocol and flow tag for MSDU */
1945 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev,
1946 msdu_orig, rx_desc);
1947
1948 dest = qdf_nbuf_put_tail(prev_buf,
1949 msdu_llc_len + amsdu_pad);
1950
1951 if (!dest)
1952 goto mpdu_stitch_fail;
1953
1954 dest += amsdu_pad;
1955 qdf_mem_copy(dest, hdr_desc, msdu_llc_len);
1956
1957 l2_hdr_offset = hal_rx_frag_msdu_get_l2_hdr_offset(soc,
1958 &buf_info,
1959 rx_desc,
1960 true);
1961 dp_rx_msdus_set_payload(soc, msdu, l2_hdr_offset);
1962
1963 /* Push the MSDU buffer beyond the decap header */
1964 qdf_nbuf_pull_head(msdu, decap_hdr_pull_bytes);
1965 frag_list_sum_len += msdu_llc_len + qdf_nbuf_len(msdu)
1966 + amsdu_pad;
1967
1968 /* Set up intra-AMSDU pad to be added to start of next buffer -
1969 * AMSDU pad is 4 byte pad on AMSDU subframe
1970 */
1971 amsdu_pad = (msdu_llc_len + qdf_nbuf_len(msdu)) & 0x3;
1972 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
1973
1974 /* TODO FIXME How do we handle MSDUs that have fraglist - Should
1975 * probably iterate all the frags cloning them along the way and
1976 * and also updating the prev_buf pointer
1977 */
1978
1979 /* Move to the next */
1980 prev_buf = msdu;
1981 msdu_orig = qdf_nbuf_next(msdu_orig);
1982 }
1983
1984 #if 0
1985 /* Add in the trailer section - encryption trailer + FCS */
1986 qdf_nbuf_put_tail(prev_buf, HAL_RX_FCS_LEN);
1987 frag_list_sum_len += HAL_RX_FCS_LEN;
1988 #endif
1989
1990 frag_list_sum_len -= msdu_llc_len;
1991
1992 /* TODO: Convert this to suitable adf routines */
1993 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list,
1994 frag_list_sum_len);
1995
1996 dp_rx_mon_dest_debug("%pK: mpdu_buf %pK mpdu_buf->len %u",
1997 soc, mpdu_buf, mpdu_buf->len);
1998
1999 mpdu_stitch_done:
2000 /* Check if this buffer contains the PPDU end status for TSF */
2001 /* Need revist this code to see where we can get tsf timestamp */
2002 #if 0
2003 /* PPDU end TLV will be retrieved from monitor status ring */
2004 last_mpdu =
2005 (*(((u_int32_t *)&rx_desc->attention)) &
2006 RX_ATTENTION_0_LAST_MPDU_MASK) >>
2007 RX_ATTENTION_0_LAST_MPDU_LSB;
2008
2009 if (last_mpdu)
2010 rx_status->rs_tstamp.tsf = rx_desc->ppdu_end.tsf_timestamp;
2011
2012 #endif
2013 return mpdu_buf;
2014
2015 mpdu_stitch_fail:
2016 if ((mpdu_buf) && !buf_info.is_decap_raw) {
2017 dp_rx_mon_dest_err("%pK: mpdu_stitch_fail mpdu_buf %pK",
2018 soc, mpdu_buf);
2019 /* Free the head buffer */
2020 qdf_nbuf_free(mpdu_buf);
2021 }
2022 return NULL;
2023 }
2024
2025 #ifdef DP_RX_MON_MEM_FRAG
2026 /**
2027 * dp_rx_mon_fraglist_prepare() - Prepare nbuf fraglist from chained skb
2028 *
2029 * @head_msdu: Parent SKB
2030 * @tail_msdu: Last skb in the chained list
2031 *
2032 * Return: Void
2033 */
dp_rx_mon_fraglist_prepare(qdf_nbuf_t head_msdu,qdf_nbuf_t tail_msdu)2034 void dp_rx_mon_fraglist_prepare(qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu)
2035 {
2036 qdf_nbuf_t msdu, mpdu_buf, head_frag_list;
2037 uint32_t frag_list_sum_len;
2038
2039 dp_err("[%s][%d] decap format raw head %pK head->next %pK last_msdu %pK last_msdu->next %pK",
2040 __func__, __LINE__, head_msdu, head_msdu->next,
2041 tail_msdu, tail_msdu->next);
2042
2043 /* Single skb accommodating MPDU worth Data */
2044 if (tail_msdu == head_msdu)
2045 return;
2046
2047 mpdu_buf = head_msdu;
2048 frag_list_sum_len = 0;
2049
2050 msdu = qdf_nbuf_next(head_msdu);
2051 /* msdu can't be NULL here as it is multiple skb case here */
2052
2053 /* Head frag list to point to second skb */
2054 head_frag_list = msdu;
2055
2056 while (msdu) {
2057 frag_list_sum_len += qdf_nbuf_len(msdu);
2058 msdu = qdf_nbuf_next(msdu);
2059 }
2060
2061 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list, frag_list_sum_len);
2062
2063 /* Make Parent skb next to NULL */
2064 qdf_nbuf_set_next(mpdu_buf, NULL);
2065 }
2066
2067 /**
2068 * dp_rx_mon_frag_restitch_mpdu_from_msdus() - Restitch logic to
2069 * convert to 802.3 header and adjust frag memory pointing to
2070 * dot3 header and payload in case of Non-Raw frame.
2071 *
2072 * @soc: struct dp_soc *
2073 * @mac_id: MAC id
2074 * @head_msdu: MPDU containing all MSDU as a frag
2075 * @tail_msdu: last skb which accommodate MPDU info
2076 * @rx_status: struct cdp_mon_status *
2077 *
2078 * Return: Adjusted nbuf containing MPDU worth info.
2079 */
2080 static inline qdf_nbuf_t
dp_rx_mon_frag_restitch_mpdu_from_msdus(struct dp_soc * soc,uint32_t mac_id,qdf_nbuf_t head_msdu,qdf_nbuf_t tail_msdu,struct cdp_mon_status * rx_status)2081 dp_rx_mon_frag_restitch_mpdu_from_msdus(struct dp_soc *soc,
2082 uint32_t mac_id,
2083 qdf_nbuf_t head_msdu,
2084 qdf_nbuf_t tail_msdu,
2085 struct cdp_mon_status *rx_status)
2086 {
2087 uint32_t wifi_hdr_len, sec_hdr_len, msdu_llc_len,
2088 mpdu_buf_len, decap_hdr_pull_bytes, dir,
2089 is_amsdu, amsdu_pad, frag_size, tot_msdu_len;
2090 qdf_frag_t rx_desc, rx_src_desc, rx_dest_desc, frag_addr;
2091 char *hdr_desc;
2092 uint8_t num_frags, frags_iter, l2_hdr_offset;
2093 struct ieee80211_frame *wh;
2094 struct ieee80211_qoscntl *qos;
2095 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id);
2096 int16_t frag_page_offset = 0;
2097 struct hal_rx_mon_dest_buf_info buf_info;
2098 uint32_t pad_byte_pholder = 0;
2099 qdf_nbuf_t msdu_curr;
2100 uint16_t rx_mon_tlv_size = soc->rx_mon_pkt_tlv_size;
2101 struct dp_mon_pdev *mon_pdev;
2102
2103 if (qdf_unlikely(!dp_pdev)) {
2104 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d",
2105 soc, mac_id);
2106 return NULL;
2107 }
2108
2109 mon_pdev = dp_pdev->monitor_pdev;
2110 qdf_mem_zero(&buf_info, sizeof(struct hal_rx_mon_dest_buf_info));
2111
2112 if (!head_msdu || !tail_msdu)
2113 goto mpdu_stitch_fail;
2114
2115 rx_desc = qdf_nbuf_get_frag_addr(head_msdu, 0) - rx_mon_tlv_size;
2116
2117 if (hal_rx_tlv_mpdu_len_err_get(soc->hal_soc, rx_desc)) {
2118 /* It looks like there is some issue on MPDU len err */
2119 /* Need further investigate if drop the packet */
2120 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1);
2121 return NULL;
2122 }
2123
2124 /* Look for FCS error */
2125 num_frags = qdf_nbuf_get_nr_frags(tail_msdu);
2126 rx_desc = qdf_nbuf_get_frag_addr(tail_msdu, num_frags - 1) -
2127 rx_mon_tlv_size;
2128 rx_status->cdp_rs_fcs_err = hal_rx_tlv_mpdu_fcs_err_get(soc->hal_soc,
2129 rx_desc);
2130 mon_pdev->ppdu_info.rx_status.rs_fcs_err = rx_status->cdp_rs_fcs_err;
2131
2132 rx_desc = qdf_nbuf_get_frag_addr(head_msdu, 0) - rx_mon_tlv_size;
2133 hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_desc,
2134 (uint8_t *)&buf_info,
2135 sizeof(buf_info));
2136
2137 /* Easy case - The MSDU status indicates that this is a non-decapped
2138 * packet in RAW mode.
2139 */
2140 if (buf_info.is_decap_raw == 1) {
2141 if (qdf_unlikely(mon_pdev->ppdu_info.rx_status.rs_fcs_err)) {
2142 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, rx_desc);
2143 wh = (struct ieee80211_frame *)hdr_desc;
2144 if ((wh->i_fc[0] & QDF_IEEE80211_FC0_VERSION_MASK) !=
2145 QDF_IEEE80211_FC0_VERSION_0) {
2146 DP_STATS_INC(dp_pdev, dropped.mon_ver_err, 1);
2147 return NULL;
2148 }
2149 }
2150 dp_rx_mon_fraglist_prepare(head_msdu, tail_msdu);
2151 goto mpdu_stitch_done;
2152 }
2153
2154 l2_hdr_offset = DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE;
2155
2156 /* Decap mode:
2157 * Calculate the amount of header in decapped packet to knock off based
2158 * on the decap type and the corresponding number of raw bytes to copy
2159 * status header
2160 */
2161 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, rx_desc);
2162
2163 dp_rx_mon_dest_debug("%pK: decap format not raw", soc);
2164
2165 /* Base size */
2166 wifi_hdr_len = sizeof(struct ieee80211_frame);
2167 wh = (struct ieee80211_frame *)hdr_desc;
2168
2169 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
2170
2171 if (dir == IEEE80211_FC1_DIR_DSTODS)
2172 wifi_hdr_len += 6;
2173
2174 is_amsdu = 0;
2175 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) {
2176 qos = (struct ieee80211_qoscntl *)
2177 (hdr_desc + wifi_hdr_len);
2178 wifi_hdr_len += 2;
2179
2180 is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU);
2181 }
2182
2183 /*Calculate security header length based on 'Protected'
2184 * and 'EXT_IV' flag
2185 */
2186 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2187 char *iv = (char *)wh + wifi_hdr_len;
2188
2189 if (iv[3] & KEY_EXTIV)
2190 sec_hdr_len = 8;
2191 else
2192 sec_hdr_len = 4;
2193 } else {
2194 sec_hdr_len = 0;
2195 }
2196 wifi_hdr_len += sec_hdr_len;
2197
2198 /* MSDU related stuff LLC - AMSDU subframe header etc */
2199 msdu_llc_len = is_amsdu ? (14 + 8) : 8;
2200
2201 mpdu_buf_len = wifi_hdr_len + msdu_llc_len;
2202
2203 /* "Decap" header to remove from MSDU buffer */
2204 decap_hdr_pull_bytes = 14;
2205
2206 amsdu_pad = 0;
2207 tot_msdu_len = 0;
2208
2209 /*
2210 * keeping first MSDU ops outside of loop to avoid multiple
2211 * check handling
2212 */
2213
2214 /* Construct src header */
2215 rx_src_desc = hdr_desc;
2216
2217 /*
2218 * Update protocol and flow tag for MSDU
2219 * update frag index in ctx_idx field.
2220 * Reset head pointer data of nbuf before updating.
2221 */
2222 QDF_NBUF_CB_RX_CTX_ID(head_msdu) = 0;
2223 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev, head_msdu, rx_desc);
2224
2225 /* Construct destination address */
2226 frag_addr = qdf_nbuf_get_frag_addr(head_msdu, 0);
2227 frag_size = qdf_nbuf_get_frag_size_by_idx(head_msdu, 0);
2228 /* We will come here in 2 scenario:
2229 * 1. First MSDU of MPDU with single buffer
2230 * 2. First buffer of First MSDU of MPDU with continuation
2231 *
2232 * ------------------------------------------------------------
2233 * | SINGLE BUFFER (<= RX_MONITOR_BUFFER_SIZE - RX_PKT_TLVS_LEN)|
2234 * ------------------------------------------------------------
2235 *
2236 * ------------------------------------------------------------
2237 * | First BUFFER with Continuation | ... |
2238 * | (RX_MONITOR_BUFFER_SIZE - RX_PKT_TLVS_LEN) | |
2239 * ------------------------------------------------------------
2240 */
2241 pad_byte_pholder =
2242 (RX_MONITOR_BUFFER_SIZE - soc->rx_mon_pkt_tlv_size) - frag_size;
2243 /* Construct destination address
2244 * --------------------------------------------------------------
2245 * | RX_PKT_TLV | L2_HDR_PAD | Decap HDR | Payload |
2246 * | | / |
2247 * | >Frag address points here / |
2248 * | \ / |
2249 * | \ This bytes needs to / |
2250 * | \ removed to frame pkt / |
2251 * | ----------------------- |
2252 * | | |
2253 * | | |
2254 * | WIFI +LLC HDR will be added here <-| |
2255 * | | | |
2256 * | >Dest addr will point | |
2257 * | somewhere in this area | |
2258 * --------------------------------------------------------------
2259 */
2260 rx_dest_desc =
2261 (frag_addr + decap_hdr_pull_bytes + l2_hdr_offset) -
2262 mpdu_buf_len;
2263 /* Add WIFI and LLC header for 1st MSDU of MPDU */
2264 qdf_mem_copy(rx_dest_desc, rx_src_desc, mpdu_buf_len);
2265
2266 frag_page_offset =
2267 (decap_hdr_pull_bytes + l2_hdr_offset) - mpdu_buf_len;
2268
2269 qdf_nbuf_move_frag_page_offset(head_msdu, 0, frag_page_offset);
2270
2271 frag_size = qdf_nbuf_get_frag_size_by_idx(head_msdu, 0);
2272
2273 if (buf_info.first_buffer && buf_info.last_buffer) {
2274 /* MSDU with single buffer */
2275 amsdu_pad = frag_size & 0x3;
2276 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
2277 if (amsdu_pad && (amsdu_pad <= pad_byte_pholder)) {
2278 char *frag_addr_temp;
2279
2280 qdf_nbuf_trim_add_frag_size(head_msdu, 0, amsdu_pad,
2281 0);
2282 frag_addr_temp =
2283 (char *)qdf_nbuf_get_frag_addr(head_msdu, 0);
2284 frag_addr_temp = (frag_addr_temp +
2285 qdf_nbuf_get_frag_size_by_idx(head_msdu, 0)) -
2286 amsdu_pad;
2287 qdf_mem_zero(frag_addr_temp, amsdu_pad);
2288 amsdu_pad = 0;
2289 }
2290 } else {
2291 /*
2292 * First buffer of Continuation frame and hence
2293 * amsdu_padding doesn't need to be added
2294 * Increase tot_msdu_len so that amsdu_pad byte
2295 * will be calculated for last frame of MSDU
2296 */
2297 tot_msdu_len = frag_size;
2298 amsdu_pad = 0;
2299 }
2300
2301 /* Here amsdu_pad byte will have some value if 1sf buffer was
2302 * Single buffer MSDU and dint had pholder to adjust amsdu padding
2303 * byte in the end
2304 * So dont initialize to ZERO here
2305 */
2306 pad_byte_pholder = 0;
2307 for (msdu_curr = head_msdu; msdu_curr;) {
2308 /* frag_iter will start from 0 for second skb onwards */
2309 if (msdu_curr == head_msdu)
2310 frags_iter = 1;
2311 else
2312 frags_iter = 0;
2313
2314 num_frags = qdf_nbuf_get_nr_frags(msdu_curr);
2315
2316 for (; frags_iter < num_frags; frags_iter++) {
2317 /* Construct destination address
2318 * ----------------------------------------------------------
2319 * | RX_PKT_TLV | L2_HDR_PAD | Decap HDR | Payload | Pad |
2320 * | | (First buffer) | | |
2321 * | | / / |
2322 * | >Frag address points here / / |
2323 * | \ / / |
2324 * | \ This bytes needs to / / |
2325 * | \ removed to frame pkt/ / |
2326 * | ---------------------- / |
2327 * | | / Add |
2328 * | | / amsdu pad |
2329 * | LLC HDR will be added here <-| | Byte for |
2330 * | | | | last frame |
2331 * | >Dest addr will point | | if space |
2332 * | somewhere in this area | | available |
2333 * | And amsdu_pad will be created if | | |
2334 * | dint get added in last buffer | | |
2335 * | (First Buffer) | | |
2336 * ----------------------------------------------------------
2337 */
2338 frag_addr =
2339 qdf_nbuf_get_frag_addr(msdu_curr, frags_iter);
2340 rx_desc = frag_addr - rx_mon_tlv_size;
2341
2342 /*
2343 * Update protocol and flow tag for MSDU
2344 * update frag index in ctx_idx field
2345 */
2346 QDF_NBUF_CB_RX_CTX_ID(msdu_curr) = frags_iter;
2347 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev,
2348 msdu_curr, rx_desc);
2349
2350 /* Read buffer info from stored data in tlvs */
2351 hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_desc,
2352 (uint8_t *)&buf_info,
2353 sizeof(buf_info));
2354
2355 frag_size = qdf_nbuf_get_frag_size_by_idx(msdu_curr,
2356 frags_iter);
2357
2358 /* If Middle buffer, dont add any header */
2359 if ((!buf_info.first_buffer) &&
2360 (!buf_info.last_buffer)) {
2361 tot_msdu_len += frag_size;
2362 amsdu_pad = 0;
2363 pad_byte_pholder = 0;
2364 continue;
2365 }
2366
2367 /* Calculate if current buffer has placeholder
2368 * to accommodate amsdu pad byte
2369 */
2370 pad_byte_pholder =
2371 (RX_MONITOR_BUFFER_SIZE - soc->rx_mon_pkt_tlv_size)
2372 - frag_size;
2373 /*
2374 * We will come here only only three condition:
2375 * 1. Msdu with single Buffer
2376 * 2. First buffer in case MSDU is spread in multiple
2377 * buffer
2378 * 3. Last buffer in case MSDU is spread in multiple
2379 * buffer
2380 *
2381 * First buffER | Last buffer
2382 * Case 1: 1 | 1
2383 * Case 2: 1 | 0
2384 * Case 3: 0 | 1
2385 *
2386 * In 3rd case only l2_hdr_padding byte will be Zero and
2387 * in other case, It will be 2 Bytes.
2388 */
2389 if (buf_info.first_buffer)
2390 l2_hdr_offset =
2391 DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE;
2392 else
2393 l2_hdr_offset = DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
2394
2395 if (buf_info.first_buffer) {
2396 /* Src addr from where llc header needs to be copied */
2397 rx_src_desc =
2398 hal_rx_desc_get_80211_hdr(soc->hal_soc,
2399 rx_desc);
2400
2401 /* Size of buffer with llc header */
2402 frag_size = frag_size -
2403 (l2_hdr_offset + decap_hdr_pull_bytes);
2404 frag_size += msdu_llc_len;
2405
2406 /* Construct destination address */
2407 rx_dest_desc = frag_addr +
2408 decap_hdr_pull_bytes + l2_hdr_offset;
2409 rx_dest_desc = rx_dest_desc - (msdu_llc_len);
2410
2411 qdf_mem_copy(rx_dest_desc, rx_src_desc,
2412 msdu_llc_len);
2413
2414 /*
2415 * Calculate new page offset and create hole
2416 * if amsdu_pad required.
2417 */
2418 frag_page_offset = l2_hdr_offset +
2419 decap_hdr_pull_bytes;
2420 frag_page_offset = frag_page_offset -
2421 (msdu_llc_len + amsdu_pad);
2422
2423 qdf_nbuf_move_frag_page_offset(msdu_curr,
2424 frags_iter,
2425 frag_page_offset);
2426
2427 tot_msdu_len = frag_size;
2428 /*
2429 * No amsdu padding required for first frame of
2430 * continuation buffer
2431 */
2432 if (!buf_info.last_buffer) {
2433 amsdu_pad = 0;
2434 continue;
2435 }
2436 } else {
2437 tot_msdu_len += frag_size;
2438 }
2439
2440 /* Will reach to this place in only two case:
2441 * 1. Single buffer MSDU
2442 * 2. Last buffer of MSDU in case of multiple buf MSDU
2443 */
2444
2445 /* Check size of buffer if amsdu padding required */
2446 amsdu_pad = tot_msdu_len & 0x3;
2447 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0;
2448
2449 /* Create placeholder if current buffer can
2450 * accommodate padding.
2451 */
2452 if (amsdu_pad && (amsdu_pad <= pad_byte_pholder)) {
2453 char *frag_addr_temp;
2454
2455 qdf_nbuf_trim_add_frag_size(msdu_curr,
2456 frags_iter,
2457 amsdu_pad, 0);
2458 frag_addr_temp = (char *)qdf_nbuf_get_frag_addr(msdu_curr,
2459 frags_iter);
2460 frag_addr_temp = (frag_addr_temp +
2461 qdf_nbuf_get_frag_size_by_idx(msdu_curr, frags_iter)) -
2462 amsdu_pad;
2463 qdf_mem_zero(frag_addr_temp, amsdu_pad);
2464 amsdu_pad = 0;
2465 }
2466
2467 /* reset tot_msdu_len */
2468 tot_msdu_len = 0;
2469 }
2470 msdu_curr = qdf_nbuf_next(msdu_curr);
2471 }
2472
2473 dp_rx_mon_fraglist_prepare(head_msdu, tail_msdu);
2474
2475 dp_rx_mon_dest_debug("%pK: head_msdu %pK head_msdu->len %u",
2476 soc, head_msdu, head_msdu->len);
2477
2478 mpdu_stitch_done:
2479 return head_msdu;
2480
2481 mpdu_stitch_fail:
2482 dp_rx_mon_dest_err("%pK: mpdu_stitch_fail head_msdu %pK",
2483 soc, head_msdu);
2484 return NULL;
2485 }
2486 #endif
2487
2488 #ifdef DP_RX_MON_MEM_FRAG
dp_rx_mon_restitch_mpdu(struct dp_soc * soc,uint32_t mac_id,qdf_nbuf_t head_msdu,qdf_nbuf_t tail_msdu,struct cdp_mon_status * rs)2489 qdf_nbuf_t dp_rx_mon_restitch_mpdu(struct dp_soc *soc, uint32_t mac_id,
2490 qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu,
2491 struct cdp_mon_status *rs)
2492 {
2493 if (qdf_nbuf_get_nr_frags(head_msdu))
2494 return dp_rx_mon_frag_restitch_mpdu_from_msdus(soc, mac_id,
2495 head_msdu,
2496 tail_msdu, rs);
2497 else
2498 return dp_rx_mon_restitch_mpdu_from_msdus(soc, mac_id,
2499 head_msdu,
2500 tail_msdu, rs);
2501 }
2502 #else
dp_rx_mon_restitch_mpdu(struct dp_soc * soc,uint32_t mac_id,qdf_nbuf_t head_msdu,qdf_nbuf_t tail_msdu,struct cdp_mon_status * rs)2503 qdf_nbuf_t dp_rx_mon_restitch_mpdu(struct dp_soc *soc, uint32_t mac_id,
2504 qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu,
2505 struct cdp_mon_status *rs)
2506 {
2507 return dp_rx_mon_restitch_mpdu_from_msdus(soc, mac_id, head_msdu,
2508 tail_msdu, rs);
2509 }
2510 #endif
2511
2512 #ifdef DP_RX_MON_MEM_FRAG
2513 #if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) ||\
2514 defined(WLAN_SUPPORT_RX_FLOW_TAG)
dp_rx_mon_update_pf_tag_to_buf_headroom(struct dp_soc * soc,qdf_nbuf_t nbuf)2515 void dp_rx_mon_update_pf_tag_to_buf_headroom(struct dp_soc *soc,
2516 qdf_nbuf_t nbuf)
2517 {
2518 qdf_nbuf_t ext_list;
2519
2520 if (qdf_unlikely(!soc)) {
2521 dp_err("Soc[%pK] Null. Can't update pftag to nbuf headroom",
2522 soc);
2523 qdf_assert_always(0);
2524 }
2525
2526 if (!wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(soc->wlan_cfg_ctx))
2527 return;
2528
2529 if (qdf_unlikely(!nbuf))
2530 return;
2531
2532 /* Return if it dint came from mon Path */
2533 if (!qdf_nbuf_get_nr_frags(nbuf))
2534 return;
2535
2536 /* Headroom must be double of PF_TAG_SIZE as we copy it 1stly to head */
2537 if (qdf_unlikely(qdf_nbuf_headroom(nbuf) < (DP_RX_MON_TOT_PF_TAG_LEN * 2))) {
2538 dp_err("Nbuf avail Headroom[%d] < 2 * DP_RX_MON_PF_TAG_TOT_LEN[%lu]",
2539 qdf_nbuf_headroom(nbuf), DP_RX_MON_TOT_PF_TAG_LEN);
2540 return;
2541 }
2542
2543 qdf_nbuf_push_head(nbuf, DP_RX_MON_TOT_PF_TAG_LEN);
2544 qdf_mem_copy(qdf_nbuf_data(nbuf), qdf_nbuf_head(nbuf),
2545 DP_RX_MON_TOT_PF_TAG_LEN);
2546 qdf_nbuf_pull_head(nbuf, DP_RX_MON_TOT_PF_TAG_LEN);
2547
2548 ext_list = qdf_nbuf_get_ext_list(nbuf);
2549 while (ext_list) {
2550 /* Headroom must be double of PF_TAG_SIZE
2551 * as we copy it 1stly to head
2552 */
2553 if (qdf_unlikely(qdf_nbuf_headroom(ext_list) < (DP_RX_MON_TOT_PF_TAG_LEN * 2))) {
2554 dp_err("Fraglist Nbuf avail Headroom[%d] < 2 * DP_RX_MON_PF_TAG_TOT_LEN[%lu]",
2555 qdf_nbuf_headroom(ext_list),
2556 DP_RX_MON_TOT_PF_TAG_LEN);
2557 ext_list = qdf_nbuf_queue_next(ext_list);
2558 continue;
2559 }
2560 qdf_nbuf_push_head(ext_list, DP_RX_MON_TOT_PF_TAG_LEN);
2561 qdf_mem_copy(qdf_nbuf_data(ext_list), qdf_nbuf_head(ext_list),
2562 DP_RX_MON_TOT_PF_TAG_LEN);
2563 qdf_nbuf_pull_head(ext_list, DP_RX_MON_TOT_PF_TAG_LEN);
2564 ext_list = qdf_nbuf_queue_next(ext_list);
2565 }
2566 }
2567 #endif
2568 #endif
2569
2570 #ifdef QCA_MONITOR_PKT_SUPPORT
dp_mon_htt_dest_srng_setup(struct dp_soc * soc,struct dp_pdev * pdev,int mac_id,int mac_for_pdev)2571 QDF_STATUS dp_mon_htt_dest_srng_setup(struct dp_soc *soc,
2572 struct dp_pdev *pdev,
2573 int mac_id,
2574 int mac_for_pdev)
2575 {
2576 QDF_STATUS status = QDF_STATUS_SUCCESS;
2577
2578 if (soc->wlan_cfg_ctx->rxdma1_enable) {
2579 status = htt_srng_setup(soc->htt_handle, mac_for_pdev,
2580 soc->rxdma_mon_buf_ring[mac_id]
2581 .hal_srng,
2582 RXDMA_MONITOR_BUF);
2583
2584 if (status != QDF_STATUS_SUCCESS) {
2585 dp_mon_err("Failed to send htt srng setup message for Rxdma mon buf ring");
2586 return status;
2587 }
2588
2589 status = htt_srng_setup(soc->htt_handle, mac_for_pdev,
2590 soc->rxdma_mon_dst_ring[mac_id]
2591 .hal_srng,
2592 RXDMA_MONITOR_DST);
2593
2594 if (status != QDF_STATUS_SUCCESS) {
2595 dp_mon_err("Failed to send htt srng setup message for Rxdma mon dst ring");
2596 return status;
2597 }
2598
2599 status = htt_srng_setup(soc->htt_handle, mac_for_pdev,
2600 soc->rxdma_mon_desc_ring[mac_id]
2601 .hal_srng,
2602 RXDMA_MONITOR_DESC);
2603
2604 if (status != QDF_STATUS_SUCCESS) {
2605 dp_mon_err("Failed to send htt srng message for Rxdma mon desc ring");
2606 return status;
2607 }
2608 }
2609
2610 return status;
2611 }
2612 #endif /* QCA_MONITOR_PKT_SUPPORT */
2613
2614 #ifdef QCA_MONITOR_PKT_SUPPORT
dp_mon_dest_rings_deinit(struct dp_pdev * pdev,int lmac_id)2615 void dp_mon_dest_rings_deinit(struct dp_pdev *pdev, int lmac_id)
2616 {
2617 struct dp_soc *soc = pdev->soc;
2618
2619 if (soc->wlan_cfg_ctx->rxdma1_enable) {
2620 dp_srng_deinit(soc, &soc->rxdma_mon_buf_ring[lmac_id],
2621 RXDMA_MONITOR_BUF, 0);
2622 dp_srng_deinit(soc, &soc->rxdma_mon_dst_ring[lmac_id],
2623 RXDMA_MONITOR_DST, 0);
2624 dp_srng_deinit(soc, &soc->rxdma_mon_desc_ring[lmac_id],
2625 RXDMA_MONITOR_DESC, 0);
2626 }
2627 }
2628
dp_mon_dest_rings_free(struct dp_pdev * pdev,int lmac_id)2629 void dp_mon_dest_rings_free(struct dp_pdev *pdev, int lmac_id)
2630 {
2631 struct dp_soc *soc = pdev->soc;
2632
2633 if (soc->wlan_cfg_ctx->rxdma1_enable) {
2634 dp_srng_free(soc, &soc->rxdma_mon_buf_ring[lmac_id]);
2635 dp_srng_free(soc, &soc->rxdma_mon_dst_ring[lmac_id]);
2636 dp_srng_free(soc, &soc->rxdma_mon_desc_ring[lmac_id]);
2637 }
2638 }
2639
dp_mon_dest_rings_init(struct dp_pdev * pdev,int lmac_id)2640 QDF_STATUS dp_mon_dest_rings_init(struct dp_pdev *pdev, int lmac_id)
2641 {
2642 struct dp_soc *soc = pdev->soc;
2643
2644 if (soc->wlan_cfg_ctx->rxdma1_enable) {
2645 if (dp_srng_init(soc, &soc->rxdma_mon_buf_ring[lmac_id],
2646 RXDMA_MONITOR_BUF, 0, lmac_id)) {
2647 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_buf_ring ", soc);
2648 goto fail1;
2649 }
2650
2651 if (dp_srng_init(soc, &soc->rxdma_mon_dst_ring[lmac_id],
2652 RXDMA_MONITOR_DST, 0, lmac_id)) {
2653 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_dst_ring", soc);
2654 goto fail1;
2655 }
2656
2657 if (dp_srng_init(soc, &soc->rxdma_mon_desc_ring[lmac_id],
2658 RXDMA_MONITOR_DESC, 0, lmac_id)) {
2659 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_desc_ring", soc);
2660 goto fail1;
2661 }
2662 }
2663 return QDF_STATUS_SUCCESS;
2664
2665 fail1:
2666 return QDF_STATUS_E_NOMEM;
2667 }
2668
dp_mon_dest_rings_alloc(struct dp_pdev * pdev,int lmac_id)2669 QDF_STATUS dp_mon_dest_rings_alloc(struct dp_pdev *pdev, int lmac_id)
2670 {
2671 int entries;
2672 struct dp_soc *soc = pdev->soc;
2673 struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx = pdev->wlan_cfg_ctx;
2674
2675 if (soc->wlan_cfg_ctx->rxdma1_enable) {
2676 entries = wlan_cfg_get_dma_mon_buf_ring_size(pdev_cfg_ctx);
2677 if (dp_srng_alloc(soc, &soc->rxdma_mon_buf_ring[lmac_id],
2678 RXDMA_MONITOR_BUF, entries, 0)) {
2679 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_buf_ring ", soc);
2680 goto fail1;
2681 }
2682 entries = wlan_cfg_get_dma_rx_mon_dest_ring_size(pdev_cfg_ctx);
2683 if (dp_srng_alloc(soc, &soc->rxdma_mon_dst_ring[lmac_id],
2684 RXDMA_MONITOR_DST, entries, 0)) {
2685 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_dst_ring", soc);
2686 goto fail1;
2687 }
2688 entries = wlan_cfg_get_dma_mon_desc_ring_size(pdev_cfg_ctx);
2689 if (dp_srng_alloc(soc, &soc->rxdma_mon_desc_ring[lmac_id],
2690 RXDMA_MONITOR_DESC, entries, 0)) {
2691 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_desc_ring", soc);
2692 goto fail1;
2693 }
2694 }
2695 return QDF_STATUS_SUCCESS;
2696
2697 fail1:
2698 return QDF_STATUS_E_NOMEM;
2699 }
2700 #endif
2701