xref: /wlan-dirver/qca-wifi-host-cmn/dp/wifi3.0/monitor/1.0/dp_rx_mon_1.0.h (revision 901120c066e139c7f8a2c8e4820561fdd83c67ef)
1 /*
2  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2022 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 #ifndef _DP_RX_MON_1_0_H_
18 #define _DP_RX_MON_1_0_H_
19 
20 #include <dp_rx.h>
21 /*
22  * MON_BUF_MIN_ENTRIES macro defines minimum number of network buffers
23  * to be refilled in the RXDMA monitor buffer ring at init, remaining
24  * buffers are replenished at the time of monitor vap creation
25  */
26 #define MON_BUF_MIN_ENTRIES 64
27 
28 /*
29  * The below macro defines the maximum number of ring entries that would
30  * be processed in a single instance when processing each of the non-monitoring
31  * RXDMA2SW ring.
32  */
33 #define MON_DROP_REAP_LIMIT 64
34 
35 QDF_STATUS dp_rx_pdev_mon_status_buffers_alloc(struct dp_pdev *pdev,
36 					       uint32_t mac_id);
37 QDF_STATUS dp_rx_pdev_mon_status_desc_pool_alloc(struct dp_pdev *pdev,
38 						 uint32_t mac_id);
39 void dp_rx_pdev_mon_status_desc_pool_init(struct dp_pdev *pdev,
40 					  uint32_t mac_id);
41 void dp_rx_pdev_mon_status_desc_pool_deinit(struct dp_pdev *pdev,
42 					    uint32_t mac_id);
43 void dp_rx_pdev_mon_status_desc_pool_free(struct dp_pdev *pdev,
44 					  uint32_t mac_id);
45 void dp_rx_pdev_mon_status_buffers_free(struct dp_pdev *pdev, uint32_t mac_id);
46 
47 QDF_STATUS dp_rx_pdev_mon_desc_pool_alloc(struct dp_pdev *pdev);
48 QDF_STATUS dp_rx_pdev_mon_buffers_alloc(struct dp_pdev *pdev);
49 void dp_rx_pdev_mon_buffers_free(struct dp_pdev *pdev);
50 void dp_rx_pdev_mon_desc_pool_init(struct dp_pdev *pdev);
51 void dp_rx_pdev_mon_desc_pool_deinit(struct dp_pdev *pdev);
52 void dp_rx_pdev_mon_desc_pool_free(struct dp_pdev *pdev);
53 
54 /**
55  * dp_rx_mon_dest_process() - Brain of the Rx processing functionality
56  *	Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
57  * @soc: core txrx main context
58  * @int_ctx: interrupt context
59  * @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced
60  * @quota: No. of units (packets) that can be serviced in one shot.
61  *
62  * This function implements the core of Rx functionality. This is
63  * expected to handle only non-error frames.
64  *
65  * Return: none
66  */
67 #ifdef QCA_MONITOR_PKT_SUPPORT
68 void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx,
69 			    uint32_t mac_id, uint32_t quota);
70 
71 void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id);
72 QDF_STATUS
73 dp_rx_pdev_mon_buf_buffers_alloc(struct dp_pdev *pdev, uint32_t mac_id,
74 				 bool delayed_replenish);
75 QDF_STATUS
76 dp_rx_pdev_mon_buf_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_id);
77 void
78 dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id);
79 #else
80 static inline
81 void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx,
82 			    uint32_t mac_id, uint32_t quota)
83 {
84 }
85 
86 static inline
87 void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id)
88 {
89 }
90 
91 static inline QDF_STATUS
92 dp_rx_pdev_mon_buf_buffers_alloc(struct dp_pdev *pdev, uint32_t mac_id,
93 				 bool delayed_replenish)
94 {
95 	return QDF_STATUS_SUCCESS;
96 }
97 
98 static inline QDF_STATUS
99 dp_rx_pdev_mon_buf_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_id)
100 {
101 	return QDF_STATUS_SUCCESS;
102 }
103 
104 static inline void
105 dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id)
106 {
107 }
108 #endif
109 
110 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC)
111 /**
112  * dp_mon_dest_srng_drop_for_mac() - Drop the mon dest ring packets for
113  *  a given mac
114  * @pdev: DP pdev
115  * @mac_id: mac id
116  *
117  * Return: None
118  */
119 uint32_t
120 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id);
121 #endif
122 
123 /**
124  * dp_rxdma_err_process() - RxDMA error processing functionality
125  * @soc: core txrx main context
126  * @mac_id: mac id which is one of 3 mac_ids
127  * @hal_ring: opaque pointer to the HAL Rx Ring, which will be serviced
128  * @quota: No. of units (packets) that can be serviced in one shot.
129  *
130  * Return: num of buffers processed
131  */
132 uint32_t dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
133 			      uint32_t mac_id, uint32_t quota);
134 
135 /**
136  * dp_mon_buf_delayed_replenish() - Helper routine to replenish monitor dest buf
137  * @pdev: DP pdev object
138  *
139  * Return: None
140  */
141 void dp_mon_buf_delayed_replenish(struct dp_pdev *pdev);
142 
143 #ifdef QCA_MONITOR_PKT_SUPPORT
144 /**
145  * dp_rx_mon_link_desc_return() - Return a MPDU link descriptor to HW
146  *			      (WBM), following error handling
147  *
148  * @dp_pdev: core txrx pdev context
149  * @buf_addr_info: void pointer to monitor link descriptor buf addr info
150  * Return: QDF_STATUS
151  */
152 QDF_STATUS
153 dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev,
154 			   hal_buff_addrinfo_t buf_addr_info,
155 			   int mac_id);
156 #else
157 static inline QDF_STATUS
158 dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev,
159 			   hal_buff_addrinfo_t buf_addr_info,
160 			   int mac_id)
161 {
162 	return QDF_STATUS_SUCCESS;
163 }
164 #endif
165 
166 /**
167  * dp_mon_adjust_frag_len() - MPDU and MSDU may spread across
168  *				multiple nbufs. This function
169  *                              is to return data length in
170  *				fragmented buffer
171  * @soc: Datapath soc handle
172  * @total_len: pointer to remaining data length.
173  * @frag_len: pointer to data length in this fragment.
174  * @l2_hdr_pad: l2 header padding
175  */
176 static inline void dp_mon_adjust_frag_len(struct dp_soc *soc,
177 					  uint32_t *total_len,
178 					  uint32_t *frag_len,
179 					  uint16_t l2_hdr_pad)
180 {
181 	uint32_t rx_pkt_tlv_len = soc->rx_pkt_tlv_size;
182 
183 	if (*total_len >= (RX_MONITOR_BUFFER_SIZE - rx_pkt_tlv_len)) {
184 		*frag_len = RX_MONITOR_BUFFER_SIZE - rx_pkt_tlv_len -
185 					l2_hdr_pad;
186 		*total_len -= *frag_len;
187 	} else {
188 		*frag_len = *total_len;
189 		*total_len = 0;
190 	}
191 }
192 
193 /**
194  * dp_rx_mon_frag_adjust_frag_len() - MPDU and MSDU may spread across
195  * multiple nbufs. This function is to return data length in
196  * fragmented buffer.
197  * It takes input as max_limit for any buffer(as it changes based
198  * on decap type and buffer sequence in MSDU.
199  *
200  * If MSDU is divided into multiple buffer then below format will
201  * be max limit.
202  * Decap type Non-Raw
203  *--------------------------------
204  *|  1st  |  2nd  | ...  | Last   |
205  *| 1662  |  1664 | 1664 | <=1664 |
206  *--------------------------------
207  * Decap type Raw
208  *--------------------------------
209  *|  1st  |  2nd  | ...  | Last   |
210  *| 1664  |  1664 | 1664 | <=1664 |
211  *--------------------------------
212  *
213  * It also calculate if current buffer has placeholder to keep padding byte.
214  *  --------------------------------
215  * |       MAX LIMIT(1662/1664)     |
216  *  --------------------------------
217  * | Actual Data | Pad byte Pholder |
218  *  --------------------------------
219  *
220  * @total_len: Remaining data length.
221  * @frag_len:  Data length in this fragment.
222  * @max_limit: Max limit of current buffer/MSDU.
223  */
224 #ifdef DP_RX_MON_MEM_FRAG
225 static inline
226 void dp_rx_mon_frag_adjust_frag_len(uint32_t *total_len, uint32_t *frag_len,
227 				    uint32_t max_limit)
228 {
229 	if (*total_len >= max_limit) {
230 		*frag_len = max_limit;
231 		*total_len -= *frag_len;
232 	} else {
233 		*frag_len = *total_len;
234 		*total_len = 0;
235 	}
236 }
237 
238 /**
239  * DP_RX_MON_GET_NBUF_FROM_DESC() - Get nbuf from desc
240  */
241 #define DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc) \
242 	NULL
243 
244 /**
245  * dp_rx_mon_add_msdu_to_list_failure_handler() - Handler for nbuf buffer
246  *                                                  attach failure
247  *
248  * @rx_tlv_hdr: rx_tlv_hdr
249  * @pdev: struct dp_pdev *
250  * @last: skb pointing to last skb in chained list at any moment
251  * @head_msdu: parent skb in the chained list
252  * @tail_msdu: Last skb in the chained list
253  * @func_name: caller function name
254  *
255  * Return: void
256  */
257 static inline void
258 dp_rx_mon_add_msdu_to_list_failure_handler(void *rx_tlv_hdr,
259 					   struct dp_pdev *pdev,
260 					   qdf_nbuf_t *last,
261 					   qdf_nbuf_t *head_msdu,
262 					   qdf_nbuf_t *tail_msdu,
263 					   const char *func_name)
264 {
265 	DP_STATS_INC(pdev, replenish.nbuf_alloc_fail, 1);
266 	qdf_frag_free(rx_tlv_hdr);
267 	if (head_msdu)
268 		qdf_nbuf_list_free(*head_msdu);
269 	dp_err("[%s] failed to allocate subsequent parent buffer to hold all frag\n",
270 	       func_name);
271 	if (head_msdu)
272 		*head_msdu = NULL;
273 	if (last)
274 		*last = NULL;
275 	if (tail_msdu)
276 		*tail_msdu = NULL;
277 }
278 
279 /**
280  * dp_rx_mon_get_paddr_from_desc() - Get paddr from desc
281  */
282 static inline
283 qdf_dma_addr_t dp_rx_mon_get_paddr_from_desc(struct dp_rx_desc *rx_desc)
284 {
285 	return rx_desc->paddr_buf_start;
286 }
287 
288 /**
289  * DP_RX_MON_IS_BUFFER_ADDR_NULL() - Is Buffer received from hw is NULL
290  */
291 #define DP_RX_MON_IS_BUFFER_ADDR_NULL(rx_desc) \
292 	(!(rx_desc->rx_buf_start))
293 
294 #define DP_RX_MON_IS_MSDU_NOT_NULL(msdu) \
295 	true
296 
297 /**
298  * dp_rx_mon_buffer_free() - Free nbuf or frag memory
299  * Free nbuf if feature is disabled, else free frag.
300  *
301  * @rx_desc: Rx desc
302  */
303 static inline void
304 dp_rx_mon_buffer_free(struct dp_rx_desc *rx_desc)
305 {
306 	qdf_frag_free(rx_desc->rx_buf_start);
307 }
308 
309 /**
310  * dp_rx_mon_buffer_unmap() - Unmap nbuf or frag memory
311  * Unmap nbuf if feature is disabled, else unmap frag.
312  *
313  * @soc: struct dp_soc *
314  * @rx_desc: struct dp_rx_desc *
315  * @size: Size to be unmapped
316  */
317 static inline void
318 dp_rx_mon_buffer_unmap(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
319 		       uint16_t size)
320 {
321 	qdf_mem_unmap_page(soc->osdev, rx_desc->paddr_buf_start,
322 			   size, QDF_DMA_FROM_DEVICE);
323 }
324 
325 /**
326  * dp_rx_mon_alloc_parent_buffer() - Allocate parent buffer to hold
327  * radiotap header and accommodate all frag memory in nr_frag.
328  *
329  * @head_msdu: Ptr to hold allocated Msdu
330  *
331  * Return: QDF_STATUS
332  */
333 static inline
334 QDF_STATUS dp_rx_mon_alloc_parent_buffer(qdf_nbuf_t *head_msdu)
335 {
336 	/*
337 	 * Headroom should accommodate radiotap header
338 	 * and protocol and flow tag for all frag
339 	 * Length reserved to accommodate Radiotap header
340 	 * is 128 bytes and length reserved for Protocol
341 	 * flow tag will vary based on QDF_NBUF_MAX_FRAGS.
342 	 */
343 	/*  -------------------------------------------------
344 	 * |       Protocol & Flow TAG      | Radiotap header|
345 	 * |                                |  Length(128 B) |
346 	 * |  ((4* QDF_NBUF_MAX_FRAGS) * 2) |                |
347 	 *  -------------------------------------------------
348 	 */
349 
350 	*head_msdu = qdf_nbuf_alloc_no_recycler(DP_RX_MON_MAX_MONITOR_HEADER,
351 						DP_RX_MON_MAX_MONITOR_HEADER, 4);
352 
353 	if (!(*head_msdu))
354 		return QDF_STATUS_E_FAILURE;
355 
356 	qdf_mem_zero(qdf_nbuf_head(*head_msdu), qdf_nbuf_headroom(*head_msdu));
357 
358 	/* Set *head_msdu->next as NULL as all msdus are
359 	 * mapped via nr frags
360 	 */
361 	qdf_nbuf_set_next(*head_msdu, NULL);
362 
363 	return QDF_STATUS_SUCCESS;
364 }
365 
366 /**
367  * dp_rx_mon_parse_desc_buffer() - Parse desc buffer based.
368  *
369  * Below code will parse desc buffer, handle continuation frame,
370  * adjust frag length and update l2_hdr_padding
371  *
372  * @soc                : struct dp_soc*
373  * @msdu_info          : struct hal_rx_msdu_desc_info*
374  * @is_frag_p          : is_frag *
375  * @total_frag_len_p   : Remaining frag len to be updated
376  * @frag_len_p         : frag len
377  * @l2_hdr_offset_p    : l2 hdr offset
378  * @rx_desc_tlv        : rx_desc_tlv
379  * @is_frag_non_raw_p  : Non raw frag
380  * @data               : NBUF Data
381  */
382 static inline void
383 dp_rx_mon_parse_desc_buffer(struct dp_soc *dp_soc,
384 			    struct hal_rx_msdu_desc_info *msdu_info,
385 			    bool *is_frag_p, uint32_t *total_frag_len_p,
386 			    uint32_t *frag_len_p, uint16_t *l2_hdr_offset_p,
387 			    qdf_frag_t rx_desc_tlv,
388 			    void **first_rx_desc_tlv,
389 			    bool *is_frag_non_raw_p, void *data)
390 {
391 	struct hal_rx_mon_dest_buf_info frame_info;
392 	uint16_t tot_payload_len =
393 			RX_MONITOR_BUFFER_SIZE - dp_soc->rx_pkt_tlv_size;
394 
395 	if (msdu_info->msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION) {
396 		/* First buffer of MSDU */
397 		if (!(*is_frag_p)) {
398 			/* Set total frag_len from msdu_len */
399 			*total_frag_len_p = msdu_info->msdu_len;
400 
401 			*is_frag_p = true;
402 			if (HAL_HW_RX_DECAP_FORMAT_RAW ==
403 			    hal_rx_tlv_decap_format_get(dp_soc->hal_soc,
404 							rx_desc_tlv)) {
405 				*l2_hdr_offset_p =
406 					DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
407 				frame_info.is_decap_raw = 1;
408 			} else {
409 				*l2_hdr_offset_p =
410 					DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE;
411 				frame_info.is_decap_raw = 0;
412 				*is_frag_non_raw_p = true;
413 			}
414 			dp_rx_mon_frag_adjust_frag_len(total_frag_len_p,
415 						       frag_len_p,
416 						       tot_payload_len -
417 						       *l2_hdr_offset_p);
418 
419 			frame_info.first_buffer = 1;
420 			frame_info.last_buffer = 0;
421 			hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc,
422 						    rx_desc_tlv,
423 						    (uint8_t *)&frame_info,
424 						    sizeof(frame_info));
425 		} else {
426 			/*
427 			 * Continuation Middle frame
428 			 * Here max limit will be same for Raw and Non raw case.
429 			 */
430 			*l2_hdr_offset_p = DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
431 			dp_rx_mon_frag_adjust_frag_len(total_frag_len_p,
432 						       frag_len_p,
433 						       tot_payload_len);
434 
435 			/* Update frame info if is non raw frame */
436 			if (*is_frag_non_raw_p)
437 				frame_info.is_decap_raw = 0;
438 			else
439 				frame_info.is_decap_raw = 1;
440 
441 			frame_info.first_buffer = 0;
442 			frame_info.last_buffer = 0;
443 			hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc,
444 						    rx_desc_tlv,
445 						    (uint8_t *)&frame_info,
446 						    sizeof(frame_info));
447 		}
448 	} else {
449 		/**
450 		 * Last buffer of MSDU spread among multiple buffer
451 		 * Here max limit will be same for Raw and Non raw case.
452 		 */
453 		if (*is_frag_p) {
454 			*l2_hdr_offset_p = DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
455 
456 			dp_rx_mon_frag_adjust_frag_len(total_frag_len_p,
457 						       frag_len_p,
458 						       tot_payload_len);
459 
460 			/* Update frame info if is non raw frame */
461 			if (*is_frag_non_raw_p)
462 				frame_info.is_decap_raw = 0;
463 			else
464 				frame_info.is_decap_raw = 1;
465 
466 			frame_info.first_buffer = 0;
467 			frame_info.last_buffer = 1;
468 			hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc,
469 						    rx_desc_tlv,
470 						    (uint8_t *)&frame_info,
471 						    sizeof(frame_info));
472 		} else {
473 			/* MSDU with single buffer */
474 			*frag_len_p = msdu_info->msdu_len;
475 			if (HAL_HW_RX_DECAP_FORMAT_RAW ==
476 			    hal_rx_tlv_decap_format_get(dp_soc->hal_soc,
477 							rx_desc_tlv)) {
478 				*l2_hdr_offset_p =
479 					DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
480 				frame_info.is_decap_raw = 1;
481 			} else {
482 				*l2_hdr_offset_p =
483 					DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE;
484 				frame_info.is_decap_raw = 0;
485 			}
486 
487 			frame_info.first_buffer = 1;
488 			frame_info.last_buffer = 1;
489 			hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc,
490 						    rx_desc_tlv,
491 						    (uint8_t *)&frame_info,
492 						    sizeof(frame_info));
493 		}
494 		/* Reset bool after complete processing of MSDU */
495 		*is_frag_p = false;
496 		*is_frag_non_raw_p = false;
497 	}
498 }
499 
500 /**
501  * dp_rx_mon_buffer_set_pktlen() - set pktlen for buffer
502  */
503 static inline void dp_rx_mon_buffer_set_pktlen(qdf_nbuf_t msdu, uint32_t size)
504 {
505 }
506 
507 /**
508  * dp_rx_mon_add_msdu_to_list()- Add msdu to list and update head_msdu
509  *      It will add reaped buffer frag to nr frag of parent msdu.
510  * @soc: DP soc handle
511  * @head_msdu: NULL if first time called else &msdu
512  * @msdu: Msdu where frag address needs to be added via nr_frag
513  * @last: Used to traverse in list if this feature is disabled.
514  * @rx_desc_tlv: Frag address
515  * @frag_len: Frag len
516  * @l2_hdr_offset: l2 hdr padding
517  */
518 static inline
519 QDF_STATUS dp_rx_mon_add_msdu_to_list(struct dp_soc *soc, qdf_nbuf_t *head_msdu,
520 				      qdf_nbuf_t msdu, qdf_nbuf_t *last,
521 				      qdf_frag_t rx_desc_tlv, uint32_t frag_len,
522 				      uint32_t l2_hdr_offset)
523 {
524 	uint32_t num_frags;
525 	qdf_nbuf_t msdu_curr;
526 
527 	/* Here head_msdu and *head_msdu must not be NULL */
528 	/* Dont add frag to skb if frag length is zero. Drop frame */
529 	if (qdf_unlikely(!frag_len || !head_msdu || !(*head_msdu))) {
530 		dp_err("[%s] frag_len[%d] || head_msdu[%pK] || *head_msdu is Null while adding frag to skb\n",
531 		       __func__, frag_len, head_msdu);
532 		return QDF_STATUS_E_FAILURE;
533 	}
534 
535 	/* In case of first desc of MPDU, assign curr msdu to *head_msdu */
536 	if (!qdf_nbuf_get_nr_frags(*head_msdu))
537 		msdu_curr = *head_msdu;
538 	else
539 		msdu_curr = *last;
540 
541 	/* Current msdu must not be NULL */
542 	if (qdf_unlikely(!msdu_curr)) {
543 		dp_err("[%s] Current msdu can't be Null while adding frag to skb\n",
544 		       __func__);
545 		return QDF_STATUS_E_FAILURE;
546 	}
547 
548 	num_frags = qdf_nbuf_get_nr_frags(msdu_curr);
549 	if (num_frags < QDF_NBUF_MAX_FRAGS) {
550 		qdf_nbuf_add_rx_frag(rx_desc_tlv, msdu_curr,
551 				     soc->rx_mon_pkt_tlv_size,
552 				     frag_len + l2_hdr_offset,
553 				     RX_MONITOR_BUFFER_SIZE,
554 				     false);
555 		if (*last != msdu_curr)
556 			*last = msdu_curr;
557 		return QDF_STATUS_SUCCESS;
558 	}
559 
560 	/* Execution will reach here only if num_frags == QDF_NBUF_MAX_FRAGS */
561 	msdu_curr = NULL;
562 	if ((dp_rx_mon_alloc_parent_buffer(&msdu_curr))
563 	    != QDF_STATUS_SUCCESS)
564 		return QDF_STATUS_E_FAILURE;
565 
566 	qdf_nbuf_add_rx_frag(rx_desc_tlv, msdu_curr, soc->rx_mon_pkt_tlv_size,
567 			     frag_len + l2_hdr_offset, RX_MONITOR_BUFFER_SIZE,
568 			     false);
569 
570 	/* Add allocated nbuf in the chain */
571 	qdf_nbuf_set_next(*last, msdu_curr);
572 
573 	/* Assign current msdu to last to avoid traversal */
574 	*last = msdu_curr;
575 
576 	return QDF_STATUS_SUCCESS;
577 }
578 
579 /**
580  * dp_rx_mon_init_tail_msdu() - Initialize tail msdu
581  *
582  * @head_msdu: Parent buffer to hold MPDU data
583  * @msdu: Msdu to be updated in tail_msdu
584  * @last: last msdu
585  * @tail_msdu: Last msdu
586  */
587 static inline
588 void dp_rx_mon_init_tail_msdu(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
589 			      qdf_nbuf_t last, qdf_nbuf_t *tail_msdu)
590 {
591 	if (!head_msdu || !(*head_msdu)) {
592 		*tail_msdu = NULL;
593 		return;
594 	}
595 
596 	if (last)
597 		qdf_nbuf_set_next(last, NULL);
598 	*tail_msdu = last;
599 }
600 
601 /**
602  * dp_rx_mon_remove_raw_frame_fcs_len() - Remove FCS length for Raw Frame
603  *
604  * If feature is disabled, then removal happens in restitch logic.
605  *
606  * @soc: Datapath soc handle
607  * @head_msdu: Head msdu
608  * @tail_msdu: Tail msdu
609  */
610 static inline
611 void dp_rx_mon_remove_raw_frame_fcs_len(struct dp_soc *soc,
612 					qdf_nbuf_t *head_msdu,
613 					qdf_nbuf_t *tail_msdu)
614 {
615 	qdf_frag_t addr;
616 
617 	if (qdf_unlikely(!head_msdu || !tail_msdu || !(*head_msdu)))
618 		return;
619 
620 	/* If *head_msdu is valid, then *tail_msdu must be valid */
621 	/* If head_msdu is valid, then it must have nr_frags */
622 	/* If tail_msdu is valid, then it must have nr_frags */
623 
624 	/* Strip FCS_LEN for Raw frame */
625 	addr = qdf_nbuf_get_frag_addr(*head_msdu, 0);
626 	addr -= soc->rx_mon_pkt_tlv_size;
627 	if (hal_rx_tlv_decap_format_get(soc->hal_soc, addr) ==
628 		HAL_HW_RX_DECAP_FORMAT_RAW) {
629 		qdf_nbuf_trim_add_frag_size(*tail_msdu,
630 			qdf_nbuf_get_nr_frags(*tail_msdu) - 1,
631 					-HAL_RX_FCS_LEN, 0);
632 	}
633 }
634 
635 /**
636  * dp_rx_mon_get_buffer_data()- Get data from desc buffer
637  * @rx_desc: desc
638  *
639  * Return address containing actual tlv content
640  */
641 static inline
642 uint8_t *dp_rx_mon_get_buffer_data(struct dp_rx_desc *rx_desc)
643 {
644 	return rx_desc->rx_buf_start;
645 }
646 
647 #else
648 
649 #define DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc) \
650 	(rx_desc->nbuf)
651 
652 static inline void
653 dp_rx_mon_add_msdu_to_list_failure_handler(void *rx_tlv_hdr,
654 					   struct dp_pdev *pdev,
655 					   qdf_nbuf_t *last,
656 					   qdf_nbuf_t *head_msdu,
657 					   qdf_nbuf_t *tail_msdu,
658 					   const char *func_name)
659 {
660 }
661 
662 static inline
663 qdf_dma_addr_t dp_rx_mon_get_paddr_from_desc(struct dp_rx_desc *rx_desc)
664 {
665 	qdf_dma_addr_t paddr = 0;
666 	qdf_nbuf_t msdu = NULL;
667 
668 	msdu = rx_desc->nbuf;
669 	if (msdu)
670 		paddr = qdf_nbuf_get_frag_paddr(msdu, 0);
671 
672 	return paddr;
673 }
674 
675 #define DP_RX_MON_IS_BUFFER_ADDR_NULL(rx_desc) \
676 	(!(rx_desc->nbuf))
677 
678 #define DP_RX_MON_IS_MSDU_NOT_NULL(msdu) \
679 	(msdu)
680 
681 static inline void
682 dp_rx_mon_buffer_free(struct dp_rx_desc *rx_desc)
683 {
684 	qdf_nbuf_free(rx_desc->nbuf);
685 }
686 
687 static inline void
688 dp_rx_mon_buffer_unmap(struct dp_soc *soc, struct dp_rx_desc *rx_desc,
689 		       uint16_t size)
690 {
691 	qdf_nbuf_unmap_nbytes_single(soc->osdev, rx_desc->nbuf,
692 				     QDF_DMA_FROM_DEVICE, size);
693 }
694 
695 static inline
696 QDF_STATUS dp_rx_mon_alloc_parent_buffer(qdf_nbuf_t *head_msdu)
697 {
698 	return QDF_STATUS_SUCCESS;
699 }
700 
701 #ifdef QCA_WIFI_MONITOR_MODE_NO_MSDU_START_TLV_SUPPORT
702 
703 #define RXDMA_DATA_DMA_BLOCK_SIZE 128
704 static inline void
705 dp_rx_mon_parse_desc_buffer(struct dp_soc *dp_soc,
706 			    struct hal_rx_msdu_desc_info *msdu_info,
707 			    bool *is_frag_p, uint32_t *total_frag_len_p,
708 			    uint32_t *frag_len_p,
709 			    uint16_t *l2_hdr_offset_p,
710 			    qdf_frag_t rx_desc_tlv,
711 			    void **first_rx_desc_tlv,
712 			    bool *is_frag_non_raw_p, void *data)
713 {
714 	struct hal_rx_mon_dest_buf_info frame_info;
715 	uint32_t rx_pkt_tlv_len = dp_soc->rx_mon_pkt_tlv_size;
716 
717 	/*
718 	 * HW structures call this L3 header padding
719 	 * -- even though this is actually the offset
720 	 * from the buffer beginning where the L2
721 	 * header begins.
722 	 */
723 	*l2_hdr_offset_p =
724 	hal_rx_msdu_end_l3_hdr_padding_get(dp_soc->hal_soc, data);
725 
726 	if (msdu_info->msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION) {
727 		/*
728 		 * Set l3_hdr_pad for first frag. This can be later
729 		 * changed based on decap format, detected in last frag
730 		 */
731 		*l2_hdr_offset_p = DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
732 		if (!(*is_frag_p)) {
733 			*l2_hdr_offset_p = DP_RX_MON_RAW_L2_HDR_PAD_BYTE;
734 			*first_rx_desc_tlv = rx_desc_tlv;
735 		}
736 
737 		*is_frag_p = true;
738 		*frag_len_p = (RX_MONITOR_BUFFER_SIZE - rx_pkt_tlv_len -
739 			       *l2_hdr_offset_p) &
740 			      (RXDMA_DATA_DMA_BLOCK_SIZE - 1);
741 		*total_frag_len_p += *frag_len_p;
742 	} else {
743 		if (hal_rx_tlv_decap_format_get(dp_soc->hal_soc, rx_desc_tlv) ==
744 		    HAL_HW_RX_DECAP_FORMAT_RAW)
745 			frame_info.is_decap_raw = 1;
746 
747 		if (hal_rx_tlv_mpdu_len_err_get(dp_soc->hal_soc, rx_desc_tlv))
748 			frame_info.mpdu_len_err = 1;
749 
750 		frame_info.l2_hdr_pad = hal_rx_msdu_end_l3_hdr_padding_get(
751 						dp_soc->hal_soc, rx_desc_tlv);
752 
753 		if (*is_frag_p) {
754 			/* Last fragment of msdu */
755 			*frag_len_p = msdu_info->msdu_len - *total_frag_len_p;
756 
757 			/* Set this in the first frag priv data */
758 			hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc,
759 						    *first_rx_desc_tlv,
760 						    (uint8_t *)&frame_info,
761 						    sizeof(frame_info));
762 		} else {
763 			*frag_len_p = msdu_info->msdu_len;
764 			hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc,
765 						    rx_desc_tlv,
766 						    (uint8_t *)&frame_info,
767 						    sizeof(frame_info));
768 		}
769 		*is_frag_p = false;
770 		*first_rx_desc_tlv = NULL;
771 	}
772 }
773 #else
774 
775 static inline void
776 dp_rx_mon_parse_desc_buffer(struct dp_soc *dp_soc,
777 			    struct hal_rx_msdu_desc_info *msdu_info,
778 			    bool *is_frag_p, uint32_t *total_frag_len_p,
779 			    uint32_t *frag_len_p,
780 			    uint16_t *l2_hdr_offset_p,
781 			    qdf_frag_t rx_desc_tlv,
782 			    qdf_frag_t first_rx_desc_tlv,
783 			    bool *is_frag_non_raw_p, void *data)
784 {
785 	/*
786 	 * HW structures call this L3 header padding
787 	 * -- even though this is actually the offset
788 	 * from the buffer beginning where the L2
789 	 * header begins.
790 	 */
791 	*l2_hdr_offset_p =
792 	hal_rx_msdu_end_l3_hdr_padding_get(dp_soc->hal_soc, data);
793 
794 	if (msdu_info->msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION) {
795 		if (!*(is_frag_p)) {
796 			*total_frag_len_p = msdu_info->msdu_len;
797 			*is_frag_p = true;
798 		}
799 		dp_mon_adjust_frag_len(dp_soc, total_frag_len_p, frag_len_p,
800 				       *l2_hdr_offset_p);
801 	} else {
802 		if (*is_frag_p) {
803 			dp_mon_adjust_frag_len(dp_soc, total_frag_len_p,
804 					       frag_len_p,
805 					       *l2_hdr_offset_p);
806 		} else {
807 			*frag_len_p = msdu_info->msdu_len;
808 		}
809 		*is_frag_p = false;
810 	}
811 }
812 #endif
813 
814 static inline void dp_rx_mon_buffer_set_pktlen(qdf_nbuf_t msdu, uint32_t size)
815 {
816 	qdf_nbuf_set_pktlen(msdu, size);
817 }
818 
819 static inline
820 QDF_STATUS dp_rx_mon_add_msdu_to_list(struct dp_soc *soc, qdf_nbuf_t *head_msdu,
821 				      qdf_nbuf_t msdu, qdf_nbuf_t *last,
822 				      qdf_frag_t rx_desc_tlv, uint32_t frag_len,
823 				      uint32_t l2_hdr_offset)
824 {
825 	if (head_msdu && !*head_msdu) {
826 		*head_msdu = msdu;
827 	} else {
828 		if (*last)
829 			qdf_nbuf_set_next(*last, msdu);
830 	}
831 	*last = msdu;
832 	return QDF_STATUS_SUCCESS;
833 }
834 
835 static inline
836 void dp_rx_mon_init_tail_msdu(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu,
837 			      qdf_nbuf_t last, qdf_nbuf_t *tail_msdu)
838 {
839 	if (last)
840 		qdf_nbuf_set_next(last, NULL);
841 
842 	*tail_msdu = msdu;
843 }
844 
845 static inline
846 void dp_rx_mon_remove_raw_frame_fcs_len(struct dp_soc *soc,
847 					qdf_nbuf_t *head_msdu,
848 					qdf_nbuf_t *tail_msdu)
849 {
850 }
851 
852 static inline
853 uint8_t *dp_rx_mon_get_buffer_data(struct dp_rx_desc *rx_desc)
854 {
855 	qdf_nbuf_t msdu = NULL;
856 	uint8_t *data = NULL;
857 
858 	msdu = rx_desc->nbuf;
859 	if (qdf_likely(msdu))
860 		data = qdf_nbuf_data(msdu);
861 	return data;
862 }
863 
864 #endif
865 
866 /**
867  * dp_rx_cookie_2_mon_link_desc() - Retrieve Link descriptor based on target
868  * @pdev: core physical device context
869  * @hal_buf_info: structure holding the buffer info
870  * mac_id: mac number
871  *
872  * Return: link descriptor address
873  */
874 static inline
875 void *dp_rx_cookie_2_mon_link_desc(struct dp_pdev *pdev,
876 				   struct hal_buf_info buf_info,
877 				   uint8_t mac_id)
878 {
879 	if (pdev->soc->wlan_cfg_ctx->rxdma1_enable)
880 		return dp_rx_cookie_2_mon_link_desc_va(pdev, &buf_info,
881 						       mac_id);
882 
883 	return dp_rx_cookie_2_link_desc_va(pdev->soc, &buf_info);
884 }
885 
886 /**
887  * dp_rx_monitor_link_desc_return() - Return Link descriptor based on target
888  * @pdev: core physical device context
889  * @p_last_buf_addr_info: MPDU Link descriptor
890  * mac_id: mac number
891  *
892  * Return: QDF_STATUS
893  */
894 static inline
895 QDF_STATUS dp_rx_monitor_link_desc_return(struct dp_pdev *pdev,
896 					  hal_buff_addrinfo_t
897 					  p_last_buf_addr_info,
898 					  uint8_t mac_id, uint8_t bm_action)
899 {
900 	if (pdev->soc->wlan_cfg_ctx->rxdma1_enable)
901 		return dp_rx_mon_link_desc_return(pdev, p_last_buf_addr_info,
902 						  mac_id);
903 
904 	return dp_rx_link_desc_return_by_addr(pdev->soc, p_last_buf_addr_info,
905 				      bm_action);
906 }
907 
908 static inline bool dp_is_rxdma_dst_ring_common(struct dp_pdev *pdev)
909 {
910 	struct dp_soc *soc = pdev->soc;
911 
912 	return (soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev == 1);
913 }
914 
915 /**
916  * dp_rxdma_get_mon_dst_ring() - Return the pointer to rxdma_err_dst_ring
917  *					or mon_dst_ring based on the target
918  * @pdev: core physical device context
919  * @mac_for_pdev: mac_id number
920  *
921  * Return: ring address
922  */
923 static inline
924 void *dp_rxdma_get_mon_dst_ring(struct dp_pdev *pdev,
925 				uint8_t mac_for_pdev)
926 {
927 	if (pdev->soc->wlan_cfg_ctx->rxdma1_enable)
928 		return pdev->soc->rxdma_mon_dst_ring[mac_for_pdev].hal_srng;
929 
930 	/* For targets with 1 RXDMA DST ring for both mac */
931 	if (dp_is_rxdma_dst_ring_common(pdev))
932 		return pdev->soc->rxdma_err_dst_ring[0].hal_srng;
933 
934 	return pdev->soc->rxdma_err_dst_ring[mac_for_pdev].hal_srng;
935 }
936 
937 /**
938  * dp_rxdma_get_mon_buf_ring() - Return monitor buf ring address
939  *				    based on target
940  * @pdev: core physical device context
941  * @mac_for_pdev: mac id number
942  *
943  * Return: ring address
944  */
945 static inline
946 struct dp_srng *dp_rxdma_get_mon_buf_ring(struct dp_pdev *pdev,
947 					  uint8_t mac_for_pdev)
948 {
949 	if (pdev->soc->wlan_cfg_ctx->rxdma1_enable)
950 		return &pdev->soc->rxdma_mon_buf_ring[mac_for_pdev];
951 
952 	/* For MCL there is only 1 rx refill ring */
953 	return &pdev->soc->rx_refill_buf_ring[0];
954 }
955 
956 /**
957  * dp_rx_get_mon_desc() - Return Rx descriptor based on target
958  * @soc: soc handle
959  * @cookie: cookie value
960  *
961  * Return: Rx descriptor
962  */
963 static inline
964 struct dp_rx_desc *dp_rx_get_mon_desc(struct dp_soc *soc,
965 				      uint32_t cookie)
966 {
967 	if (soc->wlan_cfg_ctx->rxdma1_enable)
968 		return dp_rx_cookie_2_va_mon_buf(soc, cookie);
969 
970 	return soc->arch_ops.dp_rx_desc_cookie_2_va(soc, cookie);
971 }
972 
973 #ifdef QCA_MONITOR_PKT_SUPPORT
974 /*
975  * dp_mon_htt_dest_srng_setup(): monitor dest srng setup
976  * @soc: DP SOC handle
977  * @pdev: DP PDEV handle
978  * @mac_id: MAC ID
979  * @mac_for_pdev: PDEV mac
980  *
981  * Return: status: QDF_STATUS_SUCCESS - Success, non-zero: Failure
982  */
983 QDF_STATUS dp_mon_htt_dest_srng_setup(struct dp_soc *soc,
984 				      struct dp_pdev *pdev,
985 				      int mac_id,
986 				      int mac_for_pdev);
987 
988 /*
989  * dp_mon_dest_rings_deinit(): deinit monitor dest rings
990  * @pdev: DP PDEV handle
991  * @lmac_id: MAC ID
992  *
993  * Return: status: None
994  */
995 void dp_mon_dest_rings_deinit(struct dp_pdev *pdev, int lmac_id);
996 
997 /*
998  * dp_mon_dest_rings_free(): free monitor dest rings
999  * @pdev: DP PDEV handle
1000  * @lmac_id: MAC ID
1001  *
1002  * Return: status: None
1003  */
1004 void dp_mon_dest_rings_free(struct dp_pdev *pdev, int lmac_id);
1005 
1006 /*
1007  * dp_mon_dest_rings_init(): init monitor dest rings
1008  * @pdev: DP PDEV handle
1009  * @lmac_id: MAC ID
1010  *
1011  * Return: status: QDF_STATUS_SUCCESS - Success, non-zero: Failure
1012  */
1013 QDF_STATUS dp_mon_dest_rings_init(struct dp_pdev *pdev, int lmac_id);
1014 
1015 /*
1016  * dp_mon_dest_rings_allocate(): allocate monitor dest rings
1017  * @pdev: DP PDEV handle
1018  * @lmac_id: MAC ID
1019  *
1020  * Return: status: QDF_STATUS_SUCCESS - Success, non-zero: Failure
1021  */
1022 QDF_STATUS dp_mon_dest_rings_alloc(struct dp_pdev *pdev, int lmac_id);
1023 
1024 #else
1025 QDF_STATUS dp_mon_htt_dest_srng_setup(struct dp_soc *soc,
1026 				      struct dp_pdev *pdev,
1027 				      int mac_id,
1028 				      int mac_for_pdev)
1029 {
1030 	return QDF_STATUS_SUCCESS;
1031 }
1032 
1033 static void dp_mon_dest_rings_deinit(struct dp_pdev *pdev, int lmac_id)
1034 {
1035 }
1036 
1037 static void dp_mon_dest_rings_free(struct dp_pdev *pdev, int lmac_id)
1038 {
1039 }
1040 
1041 static
1042 QDF_STATUS dp_mon_dest_rings_init(struct dp_pdev *pdev, int lmac_id)
1043 {
1044 	return QDF_STATUS_SUCCESS;
1045 }
1046 
1047 static
1048 QDF_STATUS dp_mon_dest_rings_alloc(struct dp_pdev *pdev, int lmac_id)
1049 {
1050 	return QDF_STATUS_SUCCESS;
1051 }
1052 #endif /* QCA_MONITOR_PKT_SUPPORT */
1053 
1054 #endif /* _DP_RX_MON_1_0_H_ */
1055