xref: /wlan-dirver/qca-wifi-host-cmn/dp/wifi3.0/monitor/2.0/dp_mon_2.0.h (revision 2888b71da71bce103343119fa1b31f4a0cee07c8)
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 
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  * struct dp_mon_pdev_be - BE specific monitor pdev object
135  * @mon_pdev: monitor pdev structure
136  * @filter_be: filters sent to fw
137  * @tx_mon_mode: tx monitor mode
138  * @tx_mon_filter_length: tx monitor filter length
139  * @tx_monitor_be: pointer to tx monitor be structure
140  * @tx_stats: tx monitor drop stats
141  * @rx_mon_wq_lock: Rx mon workqueue lock
142  * @rx_mon_workqueue: Rx mon workqueue
143  * @rx_mon_work: Rx mon work
144  * @rx_mon_queue: RxMON queue
145  * @rx_mon_free_queue: RxMON ppdu info free element queue
146  * @ppdu_info_lock: RxPPDU ppdu info queue lock
147  * @rx_mon_queue_depth: RxMON queue depth
148  * @desc_count: reaped status desc count
149  * @status: reaped status buffer per ppdu
150  * @lite_mon_rx_config: rx litemon config
151  * @lite_mon_tx_config: tx litemon config
152  * @prev_rxmon_desc: prev destination desc
153  * @prev_rxmon_cookie: prev rxmon cookie
154  * @ppdu_info_cache: PPDU info cache
155  * @total_free_elem: total free element in queue
156  */
157 struct dp_mon_pdev_be {
158 	struct dp_mon_pdev mon_pdev;
159 	struct dp_mon_filter_be **filter_be;
160 	uint8_t tx_mon_mode;
161 	uint8_t tx_mon_filter_length;
162 	struct dp_pdev_tx_monitor_be tx_monitor_be;
163 	struct dp_tx_monitor_drop_stats tx_stats;
164 	qdf_spinlock_t rx_mon_wq_lock;
165 	qdf_workqueue_t *rx_mon_workqueue;
166 	qdf_work_t rx_mon_work;
167 
168 	TAILQ_HEAD(, hal_rx_ppdu_info) rx_mon_queue;
169 	TAILQ_HEAD(, hal_rx_ppdu_info) rx_mon_free_queue;
170 	qdf_spinlock_t ppdu_info_lock;
171 	uint16_t rx_mon_queue_depth;
172 	uint16_t desc_count;
173 	struct dp_mon_desc *status[DP_MON_MAX_STATUS_BUF];
174 #ifdef QCA_SUPPORT_LITE_MONITOR
175 	struct dp_lite_mon_rx_config *lite_mon_rx_config;
176 	struct dp_lite_mon_tx_config *lite_mon_tx_config;
177 #endif
178 	void *prev_rxmon_desc;
179 	uint32_t prev_rxmon_cookie;
180 	qdf_kmem_cache_t ppdu_info_cache;
181 	uint32_t total_free_elem;
182 };
183 
184 /**
185  * struct dp_mon_soc_be - BE specific monitor soc
186  * @mon_soc: Monitor soc structure
187  * @tx_mon_buf_ring: TxMon replenish ring
188  * @tx_mon_dst_ring: TxMon Destination ring
189  * @tx_desc_mon: descriptor pool for tx mon src ring
190  * @rx_desc_mon: descriptor pool for rx mon src ring
191  * @rx_mon_ring_fill_level: rx mon ring refill level
192  * @tx_mon_ring_fill_level: tx mon ring refill level
193  * @tx_low_thresh_intrs: number of tx mon low threshold interrupts received
194  * @rx_low_thresh_intrs: number of rx mon low threshold interrupts received
195  * @is_dp_mon_soc_initialized: flag to indicate soc is initialized
196  */
197 struct dp_mon_soc_be {
198 	struct dp_mon_soc mon_soc;
199 	/* Source ring for Tx monitor */
200 	struct dp_srng tx_mon_buf_ring;
201 	struct dp_srng tx_mon_dst_ring[MAX_NUM_LMAC_HW];
202 
203 	/* Sw descriptor pool for tx mon source ring */
204 	struct dp_mon_desc_pool tx_desc_mon;
205 	/* Sw descriptor pool for rx mon source ring */
206 	struct dp_mon_desc_pool rx_desc_mon;
207 
208 	uint16_t rx_mon_ring_fill_level;
209 	uint16_t tx_mon_ring_fill_level;
210 	uint32_t tx_low_thresh_intrs;
211 	uint32_t rx_low_thresh_intrs;
212 
213 	bool is_dp_mon_soc_initialized;
214 };
215 #endif
216 
217 /**
218  * dp_mon_desc_pool_init() - Monitor descriptor pool init
219  * @mon_desc_pool: mon desc pool
220  * @pool_size
221  *
222  * Return: non-zero for failure, zero for success
223  */
224 QDF_STATUS
225 dp_mon_desc_pool_init(struct dp_mon_desc_pool *mon_desc_pool,
226 		      uint32_t pool_size);
227 
228 /*
229  * dp_mon_desc_pool_deinit()- monitor descriptor pool deinit
230  * @mon_desc_pool: mon desc pool
231  *
232  * Return: None
233  *
234  */
235 void dp_mon_desc_pool_deinit(struct dp_mon_desc_pool *mon_desc_pool);
236 
237 /*
238  * dp_mon_desc_pool_free()- monitor descriptor pool free
239  * @mon_desc_pool: mon desc pool
240  *
241  * Return: None
242  *
243  */
244 void dp_mon_desc_pool_free(struct dp_mon_desc_pool *mon_desc_pool);
245 
246 /**
247  * dp_mon_desc_pool_alloc() - Monitor descriptor pool alloc
248  * @mon_desc_pool: mon desc pool
249  * @pool_size: Pool size
250  *
251  * Return: non-zero for failure, zero for success
252  */
253 QDF_STATUS dp_mon_desc_pool_alloc(uint32_t pool_size,
254 				  struct dp_mon_desc_pool *mon_desc_pool);
255 
256 /*
257  * dp_mon_pool_frag_unmap_and_free() - free the mon desc frag called during
258  *			    de-initialization of wifi module.
259  *
260  * @soc: DP soc handle
261  * @mon_desc_pool: monitor descriptor pool pointer
262  *
263  * Return: None
264  */
265 void dp_mon_pool_frag_unmap_and_free(struct dp_soc *dp_soc,
266 				     struct dp_mon_desc_pool *mon_desc_pool);
267 
268 /*
269  * dp_mon_buffers_replenish() - replenish monitor ring with nbufs
270  *
271  * @soc: core txrx main context
272  * @dp_mon_srng: dp monitor circular ring
273  * @mon_desc_pool: Pointer to free mon descriptor pool
274  * @num_req_buffers: number of buffer to be replenished
275  * @desc_list: list of descs if called from dp_rx_process
276  *	       or NULL during dp rx initialization or out of buffer
277  *	       interrupt.
278  * @tail: tail of descs list
279  * @relenish_cnt_ref: pointer to update replenish_cnt
280  *
281  * Return: return success or failure
282  */
283 QDF_STATUS dp_mon_buffers_replenish(struct dp_soc *dp_soc,
284 				struct dp_srng *dp_mon_srng,
285 				struct dp_mon_desc_pool *mon_desc_pool,
286 				uint32_t num_req_buffers,
287 				union dp_mon_desc_list_elem_t **desc_list,
288 				union dp_mon_desc_list_elem_t **tail,
289 				uint32_t *replenish_cnt_ref);
290 
291 /**
292  * dp_mon_filter_show_tx_filter_be() - Show the set filters
293  * @mode: The filter modes
294  * @tlv_filter: tlv filter
295  */
296 void dp_mon_filter_show_tx_filter_be(enum dp_mon_filter_mode mode,
297 				     struct dp_mon_filter_be *filter);
298 
299 /**
300  * dp_mon_filter_show_rx_filter_be() - Show the set filters
301  * @mode: The filter modes
302  * @tlv_filter: tlv filter
303  */
304 void dp_mon_filter_show_rx_filter_be(enum dp_mon_filter_mode mode,
305 				     struct dp_mon_filter_be *filter);
306 
307 /**
308  * dp_vdev_set_monitor_mode_buf_rings_tx_2_0() - Add buffers to tx ring
309  * @pdev: Pointer to dp_pdev object
310  *
311  * Return: QDF_STATUS
312  */
313 QDF_STATUS dp_vdev_set_monitor_mode_buf_rings_tx_2_0(struct dp_pdev *pdev);
314 
315 /**
316  * dp_vdev_set_monitor_mode_buf_rings_rx_2_0() - Add buffers to rx ring
317  * @pdev: Pointer to dp_pdev object
318  *
319  * Return: QDF_STATUS
320  */
321 QDF_STATUS dp_vdev_set_monitor_mode_buf_rings_rx_2_0(struct dp_pdev *pdev);
322 
323 #ifdef QCA_ENHANCED_STATS_SUPPORT
324 /**
325  * dp_mon_get_puncture_type() - Get puncture type
326  * @puncture_pattern: puncture bitmap
327  * @bw: Bandwidth
328  */
329 enum cdp_punctured_modes
330 dp_mon_get_puncture_type(uint16_t puncture_pattern, uint8_t bw);
331 #endif
332 
333 /*
334  * dp_mon_desc_get() - get monitor sw descriptor
335  *
336  * @cookie: cookie
337  *
338  * Return: dp_mon_desc
339  */
340 static inline
341 struct dp_mon_desc *dp_mon_desc_get(uint64_t *cookie)
342 {
343 	return (struct dp_mon_desc *)cookie;
344 }
345 
346 /**
347  * dp_rx_add_to_free_desc_list() - Adds to a local free descriptor list
348  *
349  * @head: pointer to the head of local free list
350  * @tail: pointer to the tail of local free list
351  * @new: new descriptor that is added to the free list
352  * @func_name: caller func name
353  *
354  * Return: void
355  */
356 static inline
357 void __dp_mon_add_to_free_desc_list(union dp_mon_desc_list_elem_t **head,
358 				    union dp_mon_desc_list_elem_t **tail,
359 				    struct dp_mon_desc *new,
360 				    const char *func_name)
361 {
362 	qdf_assert(head && new);
363 
364 	new->buf_addr = NULL;
365 	new->in_use = 0;
366 
367 	((union dp_mon_desc_list_elem_t *)new)->next = *head;
368 	*head = (union dp_mon_desc_list_elem_t *)new;
369 	 /* reset tail if head->next is NULL */
370 	if (!*tail || !(*head)->next)
371 		*tail = *head;
372 }
373 
374 #define dp_mon_add_to_free_desc_list(head, tail, new) \
375 	__dp_mon_add_to_free_desc_list(head, tail, new, __func__)
376 
377 /*
378  * dp_mon_add_desc_list_to_free_list() - append unused desc_list back to
379  * freelist.
380  *
381  * @soc: core txrx main context
382  * @local_desc_list: local desc list provided by the caller
383  * @tail: attach the point to last desc of local desc list
384  * @mon_desc_pool: monitor descriptor pool pointer
385  */
386 
387 void
388 dp_mon_add_desc_list_to_free_list(struct dp_soc *soc,
389 				  union dp_mon_desc_list_elem_t **local_desc_list,
390 				  union dp_mon_desc_list_elem_t **tail,
391 				  struct dp_mon_desc_pool *mon_desc_pool);
392 
393 /**
394  * dp_rx_mon_add_frag_to_skb () - Add page frag to skb
395  *
396  * @ppdu_info: PPDU status info
397  * @nbuf: SKB to which frag need to be added
398  * @status_frag: Frag to add
399  *
400  * Return: void
401  */
402 static inline void
403 dp_rx_mon_add_frag_to_skb(struct hal_rx_ppdu_info *ppdu_info,
404 			  qdf_nbuf_t nbuf,
405 			  qdf_frag_t status_frag)
406 {
407 	uint16_t num_frags;
408 
409 	num_frags = qdf_nbuf_get_nr_frags(nbuf);
410 	if (num_frags < QDF_NBUF_MAX_FRAGS) {
411 		qdf_nbuf_add_rx_frag(status_frag, nbuf,
412 				     ppdu_info->data - (unsigned char *)status_frag,
413 				     ppdu_info->hdr_len,
414 				     RX_MONITOR_BUFFER_SIZE,
415 				     false);
416 	} else {
417 		dp_mon_err("num_frags exceeding MAX frags");
418 		qdf_assert_always(0);
419 	}
420 }
421 
422 #if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) ||\
423 	defined(WLAN_SUPPORT_RX_FLOW_TAG)
424 /** dp_mon_rx_update_rx_err_protocol_tag_stats() - Update mon protocols's
425  *					      statistics from given protocol
426  *					      type
427  * @pdev: pdev handle
428  * @protocol_index: Protocol index for which the stats should be incremented
429  *
430  * Return: void
431  */
432 void dp_mon_rx_update_rx_protocol_tag_stats(struct dp_pdev *pdev,
433 					    uint16_t protocol_index);
434 #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */
435 
436 #if !defined(DISABLE_MON_CONFIG) && defined(QCA_MONITOR_2_0_SUPPORT)
437 /**
438  * dp_mon_get_context_size_be() - get BE specific size for mon pdev/soc
439  * @arch_ops: arch ops pointer
440  *
441  * Return: size in bytes for the context_type
442  */
443 static inline
444 qdf_size_t dp_mon_get_context_size_be(enum dp_context_type context_type)
445 {
446 	switch (context_type) {
447 	case DP_CONTEXT_TYPE_MON_SOC:
448 		return sizeof(struct dp_mon_soc_be);
449 	case DP_CONTEXT_TYPE_MON_PDEV:
450 		return sizeof(struct dp_mon_pdev_be);
451 	default:
452 		return 0;
453 	}
454 }
455 #endif
456 
457 #ifdef QCA_MONITOR_2_0_SUPPORT
458 /**
459  * dp_get_be_mon_soc_from_dp_mon_soc() - get dp_mon_soc_be from dp_mon_soc
460  * @soc: dp_mon_soc pointer
461  *
462  * Return: dp_mon_soc_be pointer
463  */
464 static inline
465 struct dp_mon_soc_be *dp_get_be_mon_soc_from_dp_mon_soc(struct dp_mon_soc *soc)
466 {
467 	return (struct dp_mon_soc_be *)soc;
468 }
469 
470 /**
471  * dp_get_be_mon_pdev_from_dp_mon_pdev() - get dp_mon_pdev_be from dp_mon_pdev
472  * @pdev: dp_mon_pdev pointer
473  *
474  * Return: dp_mon_pdev_be pointer
475  */
476 static inline
477 struct dp_mon_pdev_be *dp_get_be_mon_pdev_from_dp_mon_pdev(struct dp_mon_pdev *mon_pdev)
478 {
479 	return (struct dp_mon_pdev_be *)mon_pdev;
480 }
481 #endif
482 #endif /* _DP_MON_2_0_H_ */
483