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