xref: /wlan-dirver/qca-wifi-host-cmn/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h (revision 8cfe6b10058a04cafb17eed051f2ddf11bee8931)
1 /*
2  * Copyright (c) 2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #ifndef _DP_MON_2_0_H_
19 #define _DP_MON_2_0_H_
20 
21 #if !defined(DISABLE_MON_CONFIG)
22 #include <qdf_lock.h>
23 #include <dp_types.h>
24 #include <dp_mon.h>
25 #include <dp_mon_filter.h>
26 #include <dp_htt.h>
27 #include <dp_mon.h>
28 #include <dp_tx_mon_2.0.h>
29 
30 #define DP_MON_RING_FILL_LEVEL_DEFAULT 2048
31 #define DP_MON_DATA_BUFFER_SIZE     2048
32 #define DP_MON_DESC_MAGIC 0xdeadabcd
33 #define DP_MON_MAX_STATUS_BUF 1200
34 #define DP_MON_QUEUE_DEPTH_MAX 16
35 #define DP_MON_MSDU_LOGGING 0
36 #define DP_MON_MPDU_LOGGING 1
37 
38 #define DP_MON_DECAP_FORMAT_INVALID 0xff
39 #define DP_MON_MIN_FRAGS_FOR_RESTITCH 2
40 
41 /* monitor frame filter modes */
42 enum dp_mon_frm_filter_mode {
43 	/* mode filter pass */
44 	DP_MON_FRM_FILTER_MODE_FP = 0,
45 	/* mode monitor direct */
46 	DP_MON_FRM_FILTER_MODE_MD = 1,
47 	/* mode monitor other */
48 	DP_MON_FRM_FILTER_MODE_MO = 2,
49 	/* mode filter pass monitor other */
50 	DP_MON_FRM_FILTER_MODE_FP_MO = 3,
51 };
52 
53 /* mpdu filter categories */
54 enum dp_mpdu_filter_category {
55 	/* category filter pass */
56 	DP_MPDU_FILTER_CATEGORY_FP = 0,
57 	/* category monitor direct */
58 	DP_MPDU_FILTER_CATEGORY_MD = 1,
59 	/* category monitor other */
60 	DP_MPDU_FILTER_CATEGORY_MO = 2,
61 	/* category filter pass monitor override */
62 	DP_MPDU_FILTER_CATEGORY_FP_MO = 3,
63 };
64 
65 /**
66  * struct dp_mon_filter_be - Monitor TLV filter
67  * @rx_tlv_filter: Rx MON TLV filter
68  * @tx_tlv_filter: Tx MON TLV filter
69  * @tx_valid: enable/disable Tx Mon TLV filter
70  */
71 struct dp_mon_filter_be {
72 	struct dp_mon_filter rx_tlv_filter;
73 #ifdef QCA_MONITOR_2_0_SUPPORT
74 	struct htt_tx_ring_tlv_filter tx_tlv_filter;
75 #endif
76 	bool tx_valid;
77 };
78 
79 /**
80  * struct dp_mon_desc
81  *
82  * @buf_addr: virtual address
83  * @paddr: physical address
84  * @in_use: desc is in use
85  * @unmapped: used to mark desc an unmapped if the corresponding
86  * nbuf is already unmapped
87  * @end_offset: offset in status buffer where DMA ended
88  * @cookie: unique desc identifier
89  * @magic: magic number to validate desc data
90  */
91 struct dp_mon_desc {
92 	uint8_t *buf_addr;
93 	qdf_dma_addr_t paddr;
94 	uint8_t in_use:1,
95 		unmapped:1;
96 	uint16_t end_offset;
97 	uint32_t cookie;
98 	uint32_t magic;
99 };
100 
101 /**
102  * struct dp_mon_desc_list_elem_t
103  * @next: Next pointer to form free list
104  * @mon_desc: DP mon descriptor
105  */
106 union dp_mon_desc_list_elem_t {
107 	union dp_mon_desc_list_elem_t *next;
108 	struct dp_mon_desc mon_desc;
109 };
110 
111 /**
112  * struct dp_mon_desc_pool - monitor desc pool
113  * @pool_size: number of descriptor in the pool
114  * @array: pointer to array of descriptor
115  * @freelist: pointer to free descriptor list
116  * @lock: Protection for the descriptor pool
117  * @owner: owner for nbuf
118  * @buf_size: Buffer size
119  * @buf_alignment: Buffer alignment
120  * @pf_cache: page frag cache
121  */
122 struct dp_mon_desc_pool {
123 	uint32_t pool_size;
124 	union dp_mon_desc_list_elem_t *array;
125 	union dp_mon_desc_list_elem_t *freelist;
126 	qdf_spinlock_t lock;
127 	uint8_t owner;
128 	uint16_t buf_size;
129 	uint8_t buf_alignment;
130 	qdf_frag_cache_t pf_cache;
131 };
132 
133 /*
134  * NB: intentionally not using kernel-doc comment because the kernel-doc
135  *     script does not handle the TAILQ_HEAD macro
136  * struct dp_mon_pdev_be - BE specific monitor pdev object
137  * @mon_pdev: monitor pdev structure
138  * @filter_be: filters sent to fw
139  * @tx_mon_mode: tx monitor mode
140  * @tx_mon_filter_length: tx monitor filter length
141  * @tx_monitor_be: pointer to tx monitor be structure
142  * @tx_stats: tx monitor drop stats
143  * @rx_mon_wq_lock: Rx mon workqueue lock
144  * @rx_mon_workqueue: Rx mon workqueue
145  * @rx_mon_work: Rx mon work
146  * @rx_mon_queue: RxMON queue
147  * @rx_mon_free_queue: RxMON ppdu info free element queue
148  * @ppdu_info_lock: RxPPDU ppdu info queue lock
149  * @rx_mon_queue_depth: RxMON queue depth
150  * @desc_count: reaped status desc count
151  * @status: reaped status buffer per ppdu
152  * @lite_mon_rx_config: rx litemon config
153  * @lite_mon_tx_config: tx litemon config
154  * @prev_rxmon_desc: prev destination desc
155  * @prev_rxmon_cookie: prev rxmon cookie
156  * @ppdu_info_cache: PPDU info cache
157  * @total_free_elem: total free element in queue
158  */
159 struct dp_mon_pdev_be {
160 	struct dp_mon_pdev mon_pdev;
161 	struct dp_mon_filter_be **filter_be;
162 	uint8_t tx_mon_mode;
163 	uint8_t tx_mon_filter_length;
164 	struct dp_pdev_tx_monitor_be tx_monitor_be;
165 	struct dp_tx_monitor_drop_stats tx_stats;
166 	qdf_spinlock_t rx_mon_wq_lock;
167 	qdf_workqueue_t *rx_mon_workqueue;
168 	qdf_work_t rx_mon_work;
169 
170 	TAILQ_HEAD(, hal_rx_ppdu_info) rx_mon_queue;
171 	TAILQ_HEAD(, hal_rx_ppdu_info) rx_mon_free_queue;
172 	qdf_spinlock_t ppdu_info_lock;
173 	uint16_t rx_mon_queue_depth;
174 	uint16_t desc_count;
175 	struct dp_mon_desc *status[DP_MON_MAX_STATUS_BUF];
176 #ifdef QCA_SUPPORT_LITE_MONITOR
177 	struct dp_lite_mon_rx_config *lite_mon_rx_config;
178 	struct dp_lite_mon_tx_config *lite_mon_tx_config;
179 #endif
180 	void *prev_rxmon_desc;
181 	uint32_t prev_rxmon_cookie;
182 	qdf_kmem_cache_t ppdu_info_cache;
183 	uint32_t total_free_elem;
184 };
185 
186 /**
187  * struct dp_mon_soc_be - BE specific monitor soc
188  * @mon_soc: Monitor soc structure
189  * @tx_mon_buf_ring: TxMon replenish ring
190  * @tx_mon_dst_ring: TxMon Destination ring
191  * @tx_desc_mon: descriptor pool for tx mon src ring
192  * @rx_desc_mon: descriptor pool for rx mon src ring
193  * @rx_mon_ring_fill_level: rx mon ring refill level
194  * @tx_mon_ring_fill_level: tx mon ring refill level
195  * @tx_low_thresh_intrs: number of tx mon low threshold interrupts received
196  * @rx_low_thresh_intrs: number of rx mon low threshold interrupts received
197  * @is_dp_mon_soc_initialized: flag to indicate soc is initialized
198  */
199 struct dp_mon_soc_be {
200 	struct dp_mon_soc mon_soc;
201 	/* Source ring for Tx monitor */
202 	struct dp_srng tx_mon_buf_ring;
203 	struct dp_srng tx_mon_dst_ring[MAX_NUM_LMAC_HW];
204 
205 	/* Sw descriptor pool for tx mon source ring */
206 	struct dp_mon_desc_pool tx_desc_mon;
207 	/* Sw descriptor pool for rx mon source ring */
208 	struct dp_mon_desc_pool rx_desc_mon;
209 
210 	uint16_t rx_mon_ring_fill_level;
211 	uint16_t tx_mon_ring_fill_level;
212 	uint32_t tx_low_thresh_intrs;
213 	uint32_t rx_low_thresh_intrs;
214 
215 	bool is_dp_mon_soc_initialized;
216 };
217 #endif
218 
219 /**
220  * dp_mon_desc_pool_init() - Monitor descriptor pool init
221  * @mon_desc_pool: mon desc pool
222  * @pool_size: Pool size
223  *
224  * Return: non-zero for failure, zero for success
225  */
226 QDF_STATUS
227 dp_mon_desc_pool_init(struct dp_mon_desc_pool *mon_desc_pool,
228 		      uint32_t pool_size);
229 
230 /**
231  * dp_mon_desc_pool_deinit()- monitor descriptor pool deinit
232  * @mon_desc_pool: mon desc pool
233  *
234  * Return: None
235  *
236  */
237 void dp_mon_desc_pool_deinit(struct dp_mon_desc_pool *mon_desc_pool);
238 
239 /**
240  * dp_mon_desc_pool_free()- monitor descriptor pool free
241  * @mon_desc_pool: mon desc pool
242  *
243  * Return: None
244  *
245  */
246 void dp_mon_desc_pool_free(struct dp_mon_desc_pool *mon_desc_pool);
247 
248 /**
249  * dp_mon_desc_pool_alloc() - Monitor descriptor pool alloc
250  * @pool_size: Pool size
251  * @mon_desc_pool: mon desc pool
252  *
253  * Return: non-zero for failure, zero for success
254  */
255 QDF_STATUS dp_mon_desc_pool_alloc(uint32_t pool_size,
256 				  struct dp_mon_desc_pool *mon_desc_pool);
257 
258 /**
259  * dp_mon_pool_frag_unmap_and_free() - free the mon desc frag called during
260  *			    de-initialization of wifi module.
261  *
262  * @dp_soc: DP soc handle
263  * @mon_desc_pool: monitor descriptor pool pointer
264  *
265  * Return: None
266  */
267 void dp_mon_pool_frag_unmap_and_free(struct dp_soc *dp_soc,
268 				     struct dp_mon_desc_pool *mon_desc_pool);
269 
270 /**
271  * dp_mon_buffers_replenish() - replenish monitor ring with nbufs
272  *
273  * @dp_soc: core txrx main context
274  * @dp_mon_srng: dp monitor circular ring
275  * @mon_desc_pool: Pointer to free mon descriptor pool
276  * @num_req_buffers: number of buffer to be replenished
277  * @desc_list: list of descs if called from dp_rx_process
278  *	       or NULL during dp rx initialization or out of buffer
279  *	       interrupt.
280  * @tail: tail of descs list
281  * @replenish_cnt_ref: pointer to update replenish_cnt
282  *
283  * Return: return success or failure
284  */
285 QDF_STATUS dp_mon_buffers_replenish(struct dp_soc *dp_soc,
286 				struct dp_srng *dp_mon_srng,
287 				struct dp_mon_desc_pool *mon_desc_pool,
288 				uint32_t num_req_buffers,
289 				union dp_mon_desc_list_elem_t **desc_list,
290 				union dp_mon_desc_list_elem_t **tail,
291 				uint32_t *replenish_cnt_ref);
292 
293 /**
294  * dp_mon_filter_show_tx_filter_be() - Show the set filters
295  * @mode: The filter modes
296  * @filter: tlv filter
297  */
298 void dp_mon_filter_show_tx_filter_be(enum dp_mon_filter_mode mode,
299 				     struct dp_mon_filter_be *filter);
300 
301 /**
302  * dp_mon_filter_show_rx_filter_be() - Show the set filters
303  * @mode: The filter modes
304  * @filter: tlv filter
305  */
306 void dp_mon_filter_show_rx_filter_be(enum dp_mon_filter_mode mode,
307 				     struct dp_mon_filter_be *filter);
308 
309 /**
310  * dp_vdev_set_monitor_mode_buf_rings_tx_2_0() - Add buffers to tx ring
311  * @pdev: Pointer to dp_pdev object
312  * @num_of_buffers: Number of buffers to allocate
313  *
314  * Return: QDF_STATUS
315  */
316 QDF_STATUS dp_vdev_set_monitor_mode_buf_rings_tx_2_0(struct dp_pdev *pdev,
317 						     uint16_t num_of_buffers);
318 
319 /**
320  * dp_vdev_set_monitor_mode_buf_rings_rx_2_0() - Add buffers to rx ring
321  * @pdev: Pointer to dp_pdev object
322  *
323  * Return: QDF_STATUS
324  */
325 QDF_STATUS dp_vdev_set_monitor_mode_buf_rings_rx_2_0(struct dp_pdev *pdev);
326 
327 #ifdef QCA_ENHANCED_STATS_SUPPORT
328 /**
329  * dp_mon_get_puncture_type() - Get puncture type
330  * @puncture_pattern: puncture bitmap
331  * @bw: Bandwidth
332  */
333 enum cdp_punctured_modes
334 dp_mon_get_puncture_type(uint16_t puncture_pattern, uint8_t bw);
335 #endif
336 
337 /**
338  * dp_mon_desc_get() - get monitor sw descriptor
339  *
340  * @cookie: cookie
341  *
342  * Return: dp_mon_desc
343  */
344 static inline
345 struct dp_mon_desc *dp_mon_desc_get(uint64_t *cookie)
346 {
347 	return (struct dp_mon_desc *)cookie;
348 }
349 
350 /**
351  * __dp_mon_add_to_free_desc_list() - Adds to a local free descriptor list
352  *
353  * @head: pointer to the head of local free list
354  * @tail: pointer to the tail of local free list
355  * @new: new descriptor that is added to the free list
356  * @func_name: caller func name
357  *
358  * Return: void
359  */
360 static inline
361 void __dp_mon_add_to_free_desc_list(union dp_mon_desc_list_elem_t **head,
362 				    union dp_mon_desc_list_elem_t **tail,
363 				    struct dp_mon_desc *new,
364 				    const char *func_name)
365 {
366 	qdf_assert(head && new);
367 
368 	new->buf_addr = NULL;
369 	new->in_use = 0;
370 
371 	((union dp_mon_desc_list_elem_t *)new)->next = *head;
372 	*head = (union dp_mon_desc_list_elem_t *)new;
373 	 /* reset tail if head->next is NULL */
374 	if (!*tail || !(*head)->next)
375 		*tail = *head;
376 }
377 
378 #define dp_mon_add_to_free_desc_list(head, tail, new) \
379 	__dp_mon_add_to_free_desc_list(head, tail, new, __func__)
380 
381 /**
382  * dp_mon_add_desc_list_to_free_list() - append unused desc_list back to
383  * freelist.
384  *
385  * @soc: core txrx main context
386  * @local_desc_list: local desc list provided by the caller
387  * @tail: attach the point to last desc of local desc list
388  * @mon_desc_pool: monitor descriptor pool pointer
389  */
390 
391 void
392 dp_mon_add_desc_list_to_free_list(struct dp_soc *soc,
393 				  union dp_mon_desc_list_elem_t **local_desc_list,
394 				  union dp_mon_desc_list_elem_t **tail,
395 				  struct dp_mon_desc_pool *mon_desc_pool);
396 
397 /**
398  * dp_rx_mon_add_frag_to_skb() - Add page frag to skb
399  *
400  * @ppdu_info: PPDU status info
401  * @nbuf: SKB to which frag need to be added
402  * @status_frag: Frag to add
403  *
404  * Return: void
405  */
406 static inline void
407 dp_rx_mon_add_frag_to_skb(struct hal_rx_ppdu_info *ppdu_info,
408 			  qdf_nbuf_t nbuf,
409 			  qdf_frag_t status_frag)
410 {
411 	uint16_t num_frags;
412 
413 	num_frags = qdf_nbuf_get_nr_frags(nbuf);
414 	if (num_frags < QDF_NBUF_MAX_FRAGS) {
415 		qdf_nbuf_add_rx_frag(status_frag, nbuf,
416 				     ppdu_info->data - (unsigned char *)status_frag,
417 				     ppdu_info->hdr_len,
418 				     RX_MONITOR_BUFFER_SIZE,
419 				     false);
420 	} else {
421 		dp_mon_err("num_frags exceeding MAX frags");
422 		qdf_assert_always(0);
423 	}
424 }
425 
426 #if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) ||\
427 	defined(WLAN_SUPPORT_RX_FLOW_TAG)
428 /**
429  * dp_mon_rx_update_rx_protocol_tag_stats() - Update mon protocols's
430  *					      statistics from given protocol
431  *					      type
432  * @pdev: pdev handle
433  * @protocol_index: Protocol index for which the stats should be incremented
434  *
435  * Return: void
436  */
437 void dp_mon_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev,
438 					    uint16_t protocol_index);
439 #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */
440 
441 #if !defined(DISABLE_MON_CONFIG) && defined(QCA_MONITOR_2_0_SUPPORT)
442 /**
443  * dp_mon_get_context_size_be() - get BE specific size for mon pdev/soc
444  * @context_type: context type for which the size is needed
445  *
446  * Return: size in bytes for the context_type
447  */
448 static inline
449 qdf_size_t dp_mon_get_context_size_be(enum dp_context_type context_type)
450 {
451 	switch (context_type) {
452 	case DP_CONTEXT_TYPE_MON_SOC:
453 		return sizeof(struct dp_mon_soc_be);
454 	case DP_CONTEXT_TYPE_MON_PDEV:
455 		return sizeof(struct dp_mon_pdev_be);
456 	default:
457 		return 0;
458 	}
459 }
460 #endif
461 
462 #ifdef QCA_MONITOR_2_0_SUPPORT
463 /**
464  * dp_get_be_mon_soc_from_dp_mon_soc() - get dp_mon_soc_be from dp_mon_soc
465  * @soc: dp_mon_soc pointer
466  *
467  * Return: dp_mon_soc_be pointer
468  */
469 static inline
470 struct dp_mon_soc_be *dp_get_be_mon_soc_from_dp_mon_soc(struct dp_mon_soc *soc)
471 {
472 	return (struct dp_mon_soc_be *)soc;
473 }
474 
475 /**
476  * dp_get_be_mon_pdev_from_dp_mon_pdev() - get dp_mon_pdev_be from dp_mon_pdev
477  * @mon_pdev: dp_mon_pdev pointer
478  *
479  * Return: dp_mon_pdev_be pointer
480  */
481 static inline
482 struct dp_mon_pdev_be *dp_get_be_mon_pdev_from_dp_mon_pdev(struct dp_mon_pdev *mon_pdev)
483 {
484 	return (struct dp_mon_pdev_be *)mon_pdev;
485 }
486 #endif
487 #endif /* _DP_MON_2_0_H_ */
488