xref: /wlan-dirver/qca-wifi-host-cmn/hif/src/ce/ce_internal.h (revision 6b801c30d6a98fe9c4a8d7f8032538a9de770395)
1 /*
2  * Copyright (c) 2013-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
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef __COPY_ENGINE_INTERNAL_H__
21 #define __COPY_ENGINE_INTERNAL_H__
22 
23 #include <hif.h>                /* A_TARGET_WRITE */
24 
25 #ifndef QCA_WIFI_WCN6450
26 /* Mask for packet offset in the CE descriptor */
27 #define CE_DESC_PKT_OFFSET_BIT_M 0x0FFF0000
28 
29 /* Packet offset start bit position in CE descriptor */
30 #define CE_DESC_PKT_OFFSET_BIT_S 16
31 
32 /* Packet type start bit position in CE descriptor */
33 #define CE_DESC_PKT_TYPE_BIT_S 6
34 
35 /* Tx classify start bit position in CE descriptor */
36 #define CE_DESC_TX_CLASSIFY_BIT_S 5
37 #else
38 /* Mask for packet offset in the CE descriptor */
39 #define CE_DESC_PKT_OFFSET_BIT_M 0x7FF80000
40 
41 /* Packet offset start bit position in CE descriptor */
42 #define CE_DESC_PKT_OFFSET_BIT_S  19
43 
44 /* Packet type start bit position in CE descriptor */
45 #define CE_DESC_PKT_TYPE_BIT_S   9
46 
47 /* Tx classify start bit position in CE descriptor */
48 #define CE_DESC_TX_CLASSIFY_BIT_S   8
49 #endif
50 
51 /* Copy Engine operational state */
52 enum CE_op_state {
53 	CE_UNUSED,
54 	CE_PAUSED,
55 	CE_RUNNING,
56 	CE_PENDING,
57 };
58 
59 enum ol_ath_hif_ce_ecodes {
60 	CE_RING_DELTA_FAIL = 0
61 };
62 
63 struct CE_src_desc;
64 
65 /* CE ring BIT mask
66  * CE_RING_FLUSH_EVENT: flush ce ring index in case of link down
67  */
68 #define CE_RING_FLUSH_EVENT BIT(0)
69 
70 /* Copy Engine Ring internal state */
71 struct CE_ring_state {
72 
73 	/* Number of entries in this ring; must be power of 2 */
74 	unsigned int nentries;
75 	unsigned int nentries_mask;
76 
77 	/*
78 	 * For dest ring, this is the next index to be processed
79 	 * by software after it was/is received into.
80 	 *
81 	 * For src ring, this is the last descriptor that was sent
82 	 * and completion processed by software.
83 	 *
84 	 * Regardless of src or dest ring, this is an invariant
85 	 * (modulo ring size):
86 	 *     write index >= read index >= sw_index
87 	 */
88 	unsigned int sw_index;
89 	unsigned int write_index;       /* cached copy */
90 	/*
91 	 * For src ring, this is the next index not yet processed by HW.
92 	 * This is a cached copy of the real HW index (read index), used
93 	 * for avoiding reading the HW index register more often than
94 	 * necessary.
95 	 * This extends the invariant:
96 	 *     write index >= read index >= hw_index >= sw_index
97 	 *
98 	 * For dest ring, this is currently unused.
99 	 */
100 	unsigned int hw_index;  /* cached copy */
101 
102 	/* Start of DMA-coherent area reserved for descriptors */
103 	void *base_addr_owner_space_unaligned;  /* Host address space */
104 	qdf_dma_addr_t base_addr_CE_space_unaligned; /* CE address space */
105 
106 	/*
107 	 * Actual start of descriptors.
108 	 * Aligned to descriptor-size boundary.
109 	 * Points into reserved DMA-coherent area, above.
110 	 */
111 	void *base_addr_owner_space;    /* Host address space */
112 	qdf_dma_addr_t base_addr_CE_space;   /* CE address space */
113 	/*
114 	 * Start of shadow copy of descriptors, within regular memory.
115 	 * Aligned to descriptor-size boundary.
116 	 */
117 	char *shadow_base_unaligned;
118 	struct CE_src_desc *shadow_base;
119 
120 	unsigned int low_water_mark_nentries;
121 	unsigned int high_water_mark_nentries;
122 	void *srng_ctx;
123 	void **per_transfer_context;
124 
125 	/* HAL CE ring type */
126 	uint32_t hal_ring_type;
127 	/* ring memory prealloc */
128 	uint8_t is_ring_prealloc;
129 
130 	OS_DMA_MEM_CONTEXT(ce_dmacontext); /* OS Specific DMA context */
131 
132 	uint32_t flush_count;
133 	/*ce ring event */
134 	unsigned long event;
135 	/* last flushed time stamp */
136 	uint64_t last_flush_ts;
137 };
138 
139 #ifdef FEATURE_HIF_DELAYED_REG_WRITE
140 /**
141  * struct ce_reg_write_stats - stats to keep track of register writes
142  * @enqueues: writes enqueued to delayed work
143  * @dequeues: writes dequeued from delayed work (not written yet)
144  * @coalesces: writes not enqueued since srng is already queued up
145  * @direct: writes not enqueued and written to register directly
146  * @dequeue_delay: dequeue operation be delayed
147  */
148 struct ce_reg_write_stats {
149 	uint32_t enqueues;
150 	uint32_t dequeues;
151 	uint32_t coalesces;
152 	uint32_t direct;
153 	uint32_t dequeue_delay;
154 };
155 #endif
156 
157 /* Copy Engine internal state */
158 struct CE_state {
159 	struct hif_softc *scn;
160 	unsigned int id;
161 	unsigned int attr_flags;  /* CE_ATTR_* */
162 	uint32_t ctrl_addr;       /* relative to BAR */
163 	enum CE_op_state state;
164 
165 #ifdef WLAN_FEATURE_FASTPATH
166 	fastpath_msg_handler fastpath_handler;
167 	void *context;
168 #endif /* WLAN_FEATURE_FASTPATH */
169 	qdf_work_t oom_allocation_work;
170 
171 	ce_send_cb send_cb;
172 	void *send_context;
173 
174 	CE_recv_cb recv_cb;
175 	void *recv_context;
176 
177 	/* misc_cbs - are any callbacks besides send and recv enabled? */
178 	uint8_t misc_cbs;
179 
180 	CE_watermark_cb watermark_cb;
181 	void *wm_context;
182 
183 #ifdef CUSTOM_CB_SCHEDULER_SUPPORT
184 	qdf_atomic_t custom_cb_pending;
185 	void (*custom_cb)(void *arg);
186 	void *custom_cb_context;
187 #endif /* CUSTOM_CB_SCHEDULER_SUPPORT */
188 	/*Record the state of the copy compl interrupt */
189 	int disable_copy_compl_intr;
190 
191 	unsigned int src_sz_max;
192 	struct CE_ring_state *src_ring;
193 	struct CE_ring_state *dest_ring;
194 	struct CE_ring_state *status_ring;
195 	atomic_t rx_pending;
196 
197 	qdf_spinlock_t ce_index_lock;
198 #ifdef CE_TASKLET_SCHEDULE_ON_FULL
199 	qdf_spinlock_t ce_interrupt_lock;
200 #endif
201 	/* Flag to indicate whether to break out the DPC context */
202 	bool force_break;
203 
204 	/* time in nanoseconds to yield control of napi poll */
205 	unsigned long long ce_service_yield_time;
206 	/* CE service start time in nanoseconds */
207 	unsigned long long ce_service_start_time;
208 	/* Num Of Receive Buffers handled for one interrupt DPC routine */
209 	unsigned int receive_count;
210 	/* epping */
211 	bool timer_inited;
212 	qdf_timer_t poll_timer;
213 
214 	/* datapath - for faster access, use bools instead of a bitmap */
215 	bool htt_tx_data;
216 	bool htt_rx_data;
217 	qdf_lro_ctx_t lro_data;
218 
219 	void (*service)(struct hif_softc *scn, int CE_id);
220 #ifdef WLAN_TRACEPOINTS
221 	/* CE tasklet sched time in nanoseconds */
222 	unsigned long long ce_tasklet_sched_time;
223 #endif
224 	bool msi_supported;
225 	bool batch_intr_supported;
226 #ifdef FEATURE_HIF_DELAYED_REG_WRITE
227 	struct ce_reg_write_stats wstats;
228 	uint8_t reg_write_in_progress;
229 	qdf_time_t last_dequeue_time;
230 #endif
231 	uint32_t ce_wrt_idx_offset;
232 };
233 
234 /* Descriptor rings must be aligned to this boundary */
235 #define CE_DESC_RING_ALIGN 8
236 #define CLOCK_OVERRIDE 0x2
237 
238 #ifdef QCA_WIFI_3_0
239 #define HIF_CE_DESC_ADDR_TO_DMA(desc) \
240 	(qdf_dma_addr_t)(((uint64_t)(desc)->buffer_addr + \
241 	((uint64_t)((desc)->buffer_addr_hi & CE_RING_BASE_ADDR_HIGH_MASK) << \
242 	 32)))
243 #else
244 #define HIF_CE_DESC_ADDR_TO_DMA(desc) \
245 	(qdf_dma_addr_t)((desc)->buffer_addr)
246 #endif
247 
248 #if defined(QCA_WIFI_WCN6450)
249 struct CE_src_desc {
250 	uint32_t buffer_addr:32;
251 #if _BYTE_ORDER == _BIG_ENDIAN
252 	uint32_t gather:1,
253 		 packet_result_offset:12,
254 		 toeplitz_hash_enable:1, /* reserved */
255 		 addr_x_search_disable:1, /* reserved */
256 		 addr_y_search_disable:1, /* reserved */
257 		 misc_int_disable:1,
258 		 target_int_disable:1,
259 		 host_int_disable:1,
260 		 dest_byte_swap:1,
261 		 byte_swap:1,
262 		 type:2, /* reserved */
263 		 tx_classify:1,
264 		 buffer_addr_hi:8;
265 	uint32_t meta_data:16,
266 		 nbytes:16;
267 #else
268 	uint32_t buffer_addr_hi:8,
269 		 tx_classify:1,
270 		 type:2, /* reserved */
271 		 byte_swap:1, /* src_byte_swap */
272 		 dest_byte_swap:1,
273 		 host_int_disable:1,
274 		 target_int_disable:1,
275 		 misc_int_disable:1,
276 		 addr_y_search_disable:1, /* reserved */
277 		 addr_x_search_disable:1, /* reserved */
278 		 toeplitz_hash_enable:1, /* reserved */
279 		 packet_result_offset:12,
280 		 gather:1;
281 	uint32_t nbytes:16,
282 		 meta_data:16;
283 #endif
284 	uint32_t toeplitz_hash_result:32;
285 };
286 
287 struct CE_dest_desc {
288 	uint32_t buffer_addr:32;
289 #if _BYTE_ORDER == _BIG_ENDIAN
290 	uint32_t gather:1,
291 		 packet_result_offset:12,
292 		 toeplitz_hash_enable:1, /* reserved */
293 		 addr_x_search_disable:1, /* reserved */
294 		 addr_y_search_disable:1, /* reserved */
295 		 misc_int_disable:1,
296 		 target_int_disable:1,
297 		 host_int_disable:1,
298 		 byte_swap:1, /* dest_byte_swap */
299 		 src_byte_swap:1,
300 		 type:2, /* reserved */
301 		 tx_classify:1,
302 		 buffer_addr_hi:8;
303 	uint32_t meta_data:16,
304 		 nbytes:16;
305 #else
306 	uint32_t buffer_addr_hi:8,
307 		 tx_classify:1,
308 		 type:2, /* reserved */
309 		 src_byte_swap:1,
310 		 byte_swap:1, /* dest_byte_swap */
311 		 host_int_disable:1,
312 		 target_int_disable:1,
313 		 misc_int_disable:1,
314 		 addr_y_search_disable:1, /* reserved */
315 		 addr_x_search_disable:1, /* reserved */
316 		 toeplitz_hash_enable:1, /* reserved */
317 		 packet_result_offset:12,
318 		 gather:1;
319 	uint32_t nbytes:16,
320 		 meta_data:16;
321 #endif
322 	uint32_t toeplitz_hash_result:32;
323 };
324 #elif defined(QCA_WIFI_3_0)
325 struct CE_src_desc {
326 	uint32_t buffer_addr:32;
327 #if _BYTE_ORDER == _BIG_ENDIAN
328 	uint32_t gather:1,
329 		enable_11h:1,
330 		meta_data_low:2, /* fw_metadata_low */
331 		packet_result_offset:12,
332 		toeplitz_hash_enable:1,
333 		addr_y_search_disable:1,
334 		addr_x_search_disable:1,
335 		misc_int_disable:1,
336 		target_int_disable:1,
337 		host_int_disable:1,
338 		dest_byte_swap:1,
339 		byte_swap:1,
340 		type:2,
341 		tx_classify:1,
342 		buffer_addr_hi:5;
343 		uint32_t meta_data:16, /* fw_metadata_high */
344 		nbytes:16;       /* length in register map */
345 #else
346 	uint32_t buffer_addr_hi:5,
347 		tx_classify:1,
348 		type:2,
349 		byte_swap:1,          /* src_byte_swap */
350 		dest_byte_swap:1,
351 		host_int_disable:1,
352 		target_int_disable:1,
353 		misc_int_disable:1,
354 		addr_x_search_disable:1,
355 		addr_y_search_disable:1,
356 		toeplitz_hash_enable:1,
357 		packet_result_offset:12,
358 		meta_data_low:2, /* fw_metadata_low */
359 		enable_11h:1,
360 		gather:1;
361 		uint32_t nbytes:16, /* length in register map */
362 		meta_data:16; /* fw_metadata_high */
363 #endif
364 	uint32_t toeplitz_hash_result:32;
365 };
366 
367 struct CE_dest_desc {
368 	uint32_t buffer_addr:32;
369 #if _BYTE_ORDER == _BIG_ENDIAN
370 	uint32_t gather:1,
371 		enable_11h:1,
372 		meta_data_low:2, /* fw_metadata_low */
373 		packet_result_offset:12,
374 		toeplitz_hash_enable:1,
375 		addr_y_search_disable:1,
376 		addr_x_search_disable:1,
377 		misc_int_disable:1,
378 		target_int_disable:1,
379 		host_int_disable:1,
380 		byte_swap:1,
381 		src_byte_swap:1,
382 		type:2,
383 		tx_classify:1,
384 		buffer_addr_hi:5;
385 		uint32_t meta_data:16, /* fw_metadata_high */
386 		nbytes:16;          /* length in register map */
387 #else
388 	uint32_t buffer_addr_hi:5,
389 		tx_classify:1,
390 		type:2,
391 		src_byte_swap:1,
392 		byte_swap:1,         /* dest_byte_swap */
393 		host_int_disable:1,
394 		target_int_disable:1,
395 		misc_int_disable:1,
396 		addr_x_search_disable:1,
397 		addr_y_search_disable:1,
398 		toeplitz_hash_enable:1,
399 		packet_result_offset:12,
400 		meta_data_low:2, /* fw_metadata_low */
401 		enable_11h:1,
402 		gather:1;
403 		uint32_t nbytes:16, /* length in register map */
404 		meta_data:16;    /* fw_metadata_high */
405 #endif
406 	uint32_t toeplitz_hash_result:32;
407 };
408 #else
409 struct CE_src_desc {
410 	uint32_t buffer_addr;
411 #if _BYTE_ORDER == _BIG_ENDIAN
412 	uint32_t  meta_data:12,
413 		  target_int_disable:1,
414 		  host_int_disable:1,
415 		  byte_swap:1,
416 		  gather:1,
417 		  nbytes:16;
418 #else
419 
420 	uint32_t nbytes:16,
421 		 gather:1,
422 		 byte_swap:1,
423 		 host_int_disable:1,
424 		 target_int_disable:1,
425 		 meta_data:12;
426 #endif
427 };
428 
429 struct CE_dest_desc {
430 	uint32_t buffer_addr;
431 #if _BYTE_ORDER == _BIG_ENDIAN
432 	uint32_t  meta_data:12,
433 		  target_int_disable:1,
434 		  host_int_disable:1,
435 		  byte_swap:1,
436 		  gather:1,
437 		  nbytes:16;
438 #else
439 	uint32_t nbytes:16,
440 		 gather:1,
441 		 byte_swap:1,
442 		 host_int_disable:1,
443 		 target_int_disable:1,
444 		 meta_data:12;
445 #endif
446 };
447 #endif /* QCA_WIFI_WCN6450 */
448 
449 struct ce_srng_src_desc {
450 	uint32_t buffer_addr_lo;
451 #if _BYTE_ORDER == _BIG_ENDIAN
452 	uint32_t nbytes:16,
453 		 rsvd:4,
454 		 gather:1,
455 		 dest_swap:1,
456 		 byte_swap:1,
457 		 toeplitz_hash_enable:1,
458 		 buffer_addr_hi:8;
459 	uint32_t rsvd1:16,
460 		 meta_data:16;
461 	uint32_t loop_count:4,
462 		 ring_id:8,
463 		 rsvd3:20;
464 #else
465 	uint32_t buffer_addr_hi:8,
466 		 toeplitz_hash_enable:1,
467 		 byte_swap:1,
468 		 dest_swap:1,
469 		 gather:1,
470 		 rsvd:4,
471 		 nbytes:16;
472 	uint32_t meta_data:16,
473 		 rsvd1:16;
474 	uint32_t rsvd3:20,
475 		 ring_id:8,
476 		 loop_count:4;
477 #endif
478 };
479 struct ce_srng_dest_desc {
480 	uint32_t buffer_addr_lo;
481 #if _BYTE_ORDER == _BIG_ENDIAN
482 	uint32_t loop_count:4,
483 		 ring_id:8,
484 		 rsvd1:12,
485 		 buffer_addr_hi:8;
486 #else
487 	uint32_t buffer_addr_hi:8,
488 		 rsvd1:12,
489 		 ring_id:8,
490 		 loop_count:4;
491 #endif
492 };
493 struct ce_srng_dest_status_desc {
494 #if _BYTE_ORDER == _BIG_ENDIAN
495 	uint32_t nbytes:16,
496 		 rsvd:4,
497 		 gather:1,
498 		 dest_swap:1,
499 		 byte_swap:1,
500 		 toeplitz_hash_enable:1,
501 		 rsvd0:8;
502 	uint32_t rsvd1:16,
503 		 meta_data:16;
504 #else
505 	uint32_t rsvd0:8,
506 		 toeplitz_hash_enable:1,
507 		 byte_swap:1,
508 		 dest_swap:1,
509 		 gather:1,
510 		 rsvd:4,
511 		 nbytes:16;
512 	uint32_t meta_data:16,
513 		 rsvd1:16;
514 #endif
515 	uint32_t toeplitz_hash;
516 #if _BYTE_ORDER == _BIG_ENDIAN
517 	uint32_t loop_count:4,
518 		 ring_id:8,
519 		 rsvd3:20;
520 #else
521 	uint32_t rsvd3:20,
522 		 ring_id:8,
523 		 loop_count:4;
524 #endif
525 };
526 
527 #define CE_SENDLIST_ITEMS_MAX 12
528 
529 /**
530  * union ce_desc - unified data type for ce descriptors
531  * @src_desc: source descriptor
532  * @dest_desc: destination descriptor
533  *
534  * Both src and destination descriptors follow the same format.
535  * They use different data structures for different access semantics.
536  * Here we provide a unifying data type.
537  */
538 union ce_desc {
539 	struct CE_src_desc src_desc;
540 	struct CE_dest_desc dest_desc;
541 };
542 
543 /**
544  * union ce_srng_desc - unified data type for ce srng descriptors
545  * @src_desc: ce srng Source ring descriptor
546  * @dest_desc: ce srng destination ring descriptor
547  * @dest_status_desc: ce srng status ring descriptor
548  */
549 union ce_srng_desc {
550 	struct ce_srng_src_desc src_desc;
551 	struct ce_srng_dest_desc dest_desc;
552 	struct ce_srng_dest_status_desc dest_status_desc;
553 };
554 
555 /**
556  * enum hif_ce_event_type - HIF copy engine event type
557  * @HIF_RX_DESC_POST: event recorded before updating write index of RX ring.
558  * @HIF_RX_DESC_COMPLETION: event recorded before updating sw index of RX ring.
559  * @HIF_TX_GATHER_DESC_POST: post gather desc. (no write index update)
560  * @HIF_TX_DESC_POST: event recorded before updating write index of TX ring.
561  * @HIF_TX_DESC_SOFTWARE_POST: event recorded when dropping a write to the write
562  *	index in a normal tx
563  * @HIF_TX_DESC_COMPLETION: event recorded before updating sw index of TX ring.
564  * @FAST_RX_WRITE_INDEX_UPDATE: event recorded before updating the write index
565  *	of the RX ring in fastpath
566  * @FAST_RX_SOFTWARE_INDEX_UPDATE: event recorded before updating the software
567  *	index of the RX ring in fastpath
568  * @FAST_TX_WRITE_INDEX_UPDATE: event recorded before updating the write index
569  *	of the TX ring in fastpath
570  * @FAST_TX_WRITE_INDEX_SOFTWARE_UPDATE: recorded when dropping a write to
571  *	the write index in fastpath
572  * @FAST_TX_SOFTWARE_INDEX_UPDATE: event recorded before updating the software
573  *	index of the RX ring in fastpath
574  * @RESUME_WRITE_INDEX_UPDATE:
575  * @HIF_IRQ_EVENT: event recorded in the irq before scheduling the bh
576  * @HIF_CE_TASKLET_ENTRY: records the start of the ce_tasklet
577  * @HIF_CE_TASKLET_RESCHEDULE: records the rescheduling of the wlan_tasklet
578  * @HIF_CE_TASKLET_REAP_REPOLL: records the repoll of the wlan_tasklet
579  * @HIF_CE_TASKLET_EXIT: records the exit of the wlan tasklet without reschedule
580  * @HIF_CE_REAP_ENTRY: records when we process completion outside of a bh
581  * @HIF_CE_REAP_EXIT:  records when we process completion outside of a bh
582  * @NAPI_SCHEDULE: records when napi is scheduled from the irq context
583  * @NAPI_POLL_ENTER: records the start of the napi poll function
584  * @NAPI_COMPLETE: records when interrupts are re-enabled
585  * @NAPI_POLL_EXIT: records when the napi poll function returns
586  * @HIF_RX_NBUF_ALLOC_FAILURE: record the packet when nbuf fails to allocate
587  * @HIF_RX_NBUF_MAP_FAILURE: record the packet when dma map fails
588  * @HIF_RX_NBUF_ENQUEUE_FAILURE: record the packet when enqueue to ce fails
589  * @HIF_CE_SRC_RING_BUFFER_POST: record the packet when buffer is posted to ce src ring
590  * @HIF_CE_DEST_RING_BUFFER_POST: record the packet when buffer is posted to ce dst ring
591  * @HIF_CE_DEST_RING_BUFFER_REAP: record the packet when buffer is reaped from ce dst ring
592  * @HIF_CE_DEST_STATUS_RING_REAP: record the packet when status ring is reaped
593  * @HIF_RX_DESC_PRE_NBUF_ALLOC: record the packet before nbuf allocation
594  * @HIF_RX_DESC_PRE_NBUF_MAP: record the packet before nbuf map
595  * @HIF_RX_DESC_POST_NBUF_MAP: record the packet after nbuf map
596  * @HIF_EVENT_TYPE_MAX: max event
597  */
598 enum hif_ce_event_type {
599 	HIF_RX_DESC_POST,
600 	HIF_RX_DESC_COMPLETION,
601 	HIF_TX_GATHER_DESC_POST,
602 	HIF_TX_DESC_POST,
603 	HIF_TX_DESC_SOFTWARE_POST,
604 	HIF_TX_DESC_COMPLETION,
605 	FAST_RX_WRITE_INDEX_UPDATE,
606 	FAST_RX_SOFTWARE_INDEX_UPDATE,
607 	FAST_TX_WRITE_INDEX_UPDATE,
608 	FAST_TX_WRITE_INDEX_SOFTWARE_UPDATE,
609 	FAST_TX_SOFTWARE_INDEX_UPDATE,
610 	RESUME_WRITE_INDEX_UPDATE,
611 
612 	HIF_IRQ_EVENT = 0x10,
613 	HIF_CE_TASKLET_ENTRY,
614 	HIF_CE_TASKLET_RESCHEDULE,
615 	HIF_CE_TASKLET_REAP_REPOLL,
616 	HIF_CE_TASKLET_EXIT,
617 	HIF_CE_REAP_ENTRY,
618 	HIF_CE_REAP_EXIT,
619 	NAPI_SCHEDULE,
620 	NAPI_POLL_ENTER,
621 	NAPI_COMPLETE,
622 	NAPI_POLL_EXIT,
623 
624 	HIF_RX_NBUF_ALLOC_FAILURE = 0x20,
625 	HIF_RX_NBUF_MAP_FAILURE,
626 	HIF_RX_NBUF_ENQUEUE_FAILURE,
627 
628 	HIF_CE_SRC_RING_BUFFER_POST,
629 	HIF_CE_DEST_RING_BUFFER_POST,
630 	HIF_CE_DEST_RING_BUFFER_REAP,
631 	HIF_CE_DEST_STATUS_RING_REAP,
632 
633 	HIF_RX_DESC_PRE_NBUF_ALLOC,
634 	HIF_RX_DESC_PRE_NBUF_MAP,
635 	HIF_RX_DESC_POST_NBUF_MAP,
636 
637 	HIF_EVENT_TYPE_MAX,
638 };
639 
640 void ce_init_ce_desc_event_log(struct hif_softc *scn, int ce_id, int size);
641 void ce_deinit_ce_desc_event_log(struct hif_softc *scn, int ce_id);
642 void hif_record_ce_desc_event(struct hif_softc *scn, int ce_id,
643 			      enum hif_ce_event_type type,
644 			      union ce_desc *descriptor, void *memory,
645 			      int index, int len);
646 
647 enum ce_sendlist_type_e {
648 	CE_SIMPLE_BUFFER_TYPE,
649 	/* TBDXXX: CE_RX_DESC_LIST, */
650 };
651 
652 /*
653  * There's a public "ce_sendlist" and a private "ce_sendlist_s".
654  * The former is an opaque structure with sufficient space
655  * to hold the latter.  The latter is the actual structure
656  * definition and it is only used internally.  The opaque version
657  * of the structure allows callers to allocate an instance on the
658  * run-time stack without knowing any of the details of the
659  * structure layout.
660  */
661 struct ce_sendlist_s {
662 	unsigned int num_items;
663 	struct ce_sendlist_item {
664 		enum ce_sendlist_type_e send_type;
665 		dma_addr_t data;        /* e.g. buffer or desc list */
666 		union {
667 			unsigned int nbytes;    /* simple buffer */
668 			unsigned int ndesc;     /* Rx descriptor list */
669 		} u;
670 		/* flags: externally-specified flags;
671 		 * OR-ed with internal flags
672 		 */
673 		uint32_t flags;
674 		uint32_t user_flags;
675 	} item[CE_SENDLIST_ITEMS_MAX];
676 };
677 
678 bool hif_ce_service_should_yield(struct hif_softc *scn, struct CE_state
679 				 *ce_state);
680 
681 #ifdef WLAN_FEATURE_FASTPATH
682 void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl);
683 void ce_t2h_msg_ce_cleanup(struct CE_handle *ce_hdl);
684 #else
685 static inline void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl)
686 {
687 }
688 
689 static inline void ce_t2h_msg_ce_cleanup(struct CE_handle *ce_hdl)
690 {
691 }
692 #endif
693 
694 /* which ring of a CE? */
695 #define CE_RING_SRC  0
696 #define CE_RING_DEST 1
697 #define CE_RING_STATUS 2
698 
699 #define CDC_WAR_MAGIC_STR   0xceef0000
700 #define CDC_WAR_DATA_CE     4
701 
702 /* Additional internal-only ce_send flags */
703 #define CE_SEND_FLAG_GATHER             0x00010000      /* Use Gather */
704 
705 /**
706  * hif_get_wake_ce_id() - gets the copy engine id used for waking up
707  * @scn: The hif context to use
708  * @ce_id: a pointer where the copy engine Id should be populated
709  *
710  * Return: errno
711  */
712 int hif_get_wake_ce_id(struct hif_softc *scn, uint8_t *ce_id);
713 
714 /**
715  * hif_get_fw_diag_ce_id() - gets the copy engine id used for FW diag
716  * @scn: The hif context to use
717  * @ce_id: a pointer where the copy engine Id should be populated
718  *
719  * Return: errno
720  */
721 int hif_get_fw_diag_ce_id(struct hif_softc *scn, uint8_t *ce_id);
722 
723 #if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)
724 
725 #ifndef HIF_CE_HISTORY_MAX
726 #if defined(CONFIG_SLUB_DEBUG_ON)
727 #define HIF_CE_HISTORY_MAX 1024
728 #else
729 #define HIF_CE_HISTORY_MAX 768
730 #endif /* CONFIG_SLUB_DEBUG_ON */
731 #endif /* !HIF_CE_HISTORY_MAX */
732 
733 #define CE_DEBUG_MAX_DATA_BUF_SIZE 64
734 
735 /**
736  * struct hif_ce_desc_event - structure for detailing a ce event
737  * @index: location of the descriptor in the ce ring;
738  * @type: what the event was
739  * @time: when it happened
740  * @cpu_id:
741  * @current_hp: holds the current ring hp value
742  * @current_tp: holds the current ring tp value
743  * @descriptor: descriptor enqueued or dequeued
744  * @memory: virtual address that was used
745  * @dma_addr: physical/iova address based on smmu status
746  * @dma_to_phy: physical address from iova address
747  * @virt_to_phy: physical address from virtual address
748  * @actual_data_len: length of the data
749  * @data: data pointed by descriptor
750  */
751 struct hif_ce_desc_event {
752 	int index;
753 	enum hif_ce_event_type type;
754 	uint64_t time;
755 	int cpu_id;
756 #ifdef HELIUMPLUS
757 	union ce_desc descriptor;
758 #else
759 	uint32_t current_hp;
760 	uint32_t current_tp;
761 	union ce_srng_desc descriptor;
762 #endif
763 	void *memory;
764 
765 #ifdef HIF_RECORD_PADDR
766 	/* iova/pa based on smmu status */
767 	qdf_dma_addr_t dma_addr;
768 	/* store pa from iova address */
769 	qdf_dma_addr_t dma_to_phy;
770 	/* store pa */
771 	qdf_dma_addr_t virt_to_phy;
772 #endif /* HIF_RECORD_ADDR */
773 
774 #ifdef HIF_CE_DEBUG_DATA_BUF
775 	size_t actual_data_len;
776 	uint8_t *data;
777 #endif /* HIF_CE_DEBUG_DATA_BUF */
778 };
779 #else
780 struct hif_ce_desc_event;
781 #endif /*#if defined(HIF_CONFIG_SLUB_DEBUG_ON)||defined(HIF_CE_DEBUG_DATA_BUF)*/
782 
783 /**
784  * get_next_record_index() - get the next record index
785  * @table_index: atomic index variable to increment
786  * @array_size: array size of the circular buffer
787  *
788  * Increment the atomic index and reserve the value.
789  * Takes care of buffer wrap.
790  * Guaranteed to be thread safe as long as fewer than array_size contexts
791  * try to access the array.  If there are more than array_size contexts
792  * trying to access the array, full locking of the recording process would
793  * be needed to have sane logging.
794  */
795 int get_next_record_index(qdf_atomic_t *table_index, int array_size);
796 
797 #if defined(HIF_CONFIG_SLUB_DEBUG_ON) || defined(HIF_CE_DEBUG_DATA_BUF)
798 /**
799  * hif_record_ce_srng_desc_event() - Record data pointed by the CE descriptor
800  * @scn: structure detailing a ce event
801  * @ce_id: length of the data
802  * @type: event_type
803  * @descriptor: ce src/dest/status ring descriptor
804  * @memory: nbuf
805  * @index: current sw/write index
806  * @len: len of the buffer
807  * @hal_ring: ce hw ring
808  *
809  * Return: None
810  */
811 void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id,
812 				   enum hif_ce_event_type type,
813 				   union ce_srng_desc *descriptor,
814 				   void *memory, int index,
815 				   int len, void *hal_ring);
816 
817 /**
818  * hif_clear_ce_desc_debug_data() - Clear the contents of hif_ce_desc_event
819  * upto data field before reusing it.
820  *
821  * @event: record every CE event
822  *
823  * Return: None
824  */
825 void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event);
826 #else
827 static inline
828 void hif_record_ce_srng_desc_event(struct hif_softc *scn, int ce_id,
829 				   enum hif_ce_event_type type,
830 				   union ce_srng_desc *descriptor,
831 				   void *memory, int index,
832 				   int len, void *hal_ring)
833 {
834 }
835 
836 static inline
837 void hif_clear_ce_desc_debug_data(struct hif_ce_desc_event *event)
838 {
839 }
840 #endif /* HIF_CONFIG_SLUB_DEBUG_ON || HIF_CE_DEBUG_DATA_BUF */
841 
842 #ifdef HIF_CE_DEBUG_DATA_BUF
843 /**
844  * hif_ce_desc_data_record() - Record data pointed by the CE descriptor
845  * @event: structure detailing a ce event
846  * @len: length of the data
847  * Return:
848  */
849 void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len);
850 
851 QDF_STATUS alloc_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id);
852 void free_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id);
853 #else
854 static inline
855 QDF_STATUS alloc_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id)
856 {
857 	return QDF_STATUS_SUCCESS;
858 }
859 
860 static inline
861 void free_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id) { }
862 
863 static inline
864 void hif_ce_desc_data_record(struct hif_ce_desc_event *event, int len)
865 {
866 }
867 #endif /*HIF_CE_DEBUG_DATA_BUF*/
868 
869 #ifdef HIF_CONFIG_SLUB_DEBUG_ON
870 /**
871  * ce_validate_nbytes() - validate nbytes for slub builds on tx descriptors
872  * @nbytes: nbytes value being written into a send descriptor
873  * @ce_state: context of the copy engine
874  *
875  * nbytes should be non-zero and less than max configured for the copy engine
876  *
877  * Return: none
878  */
879 static inline void ce_validate_nbytes(uint32_t nbytes,
880 				      struct CE_state *ce_state)
881 {
882 	if (nbytes <= 0 || nbytes > ce_state->src_sz_max)
883 		QDF_BUG(0);
884 }
885 #else
886 static inline void ce_validate_nbytes(uint32_t nbytes,
887 				      struct CE_state *ce_state)
888 {
889 }
890 #endif /* HIF_CONFIG_SLUB_DEBUG_ON */
891 
892 #if defined(HIF_RECORD_PADDR)
893 /**
894  * hif_ce_desc_record_rx_paddr() - record physical address for IOMMU
895  * IOVA addr and MMU virtual addr for Rx
896  * @scn: hif_softc
897  * @event: event details
898  * @nbuf: buffer posted to fw
899  *
900  * record physical address for ce_event_type HIF_RX_DESC_POST and
901  * HIF_RX_DESC_COMPLETION
902  *
903  * Return: none
904  */
905 void hif_ce_desc_record_rx_paddr(struct hif_softc *scn,
906 				 struct hif_ce_desc_event *event,
907 				 qdf_nbuf_t nbuf);
908 #else
909 static inline
910 void hif_ce_desc_record_rx_paddr(struct hif_softc *scn,
911 				 struct hif_ce_desc_event *event,
912 				 qdf_nbuf_t nbuf)
913 {
914 }
915 #endif /* HIF_RECORD_PADDR */
916 
917 static inline void ce_ring_aquire_lock(struct CE_handle *handle)
918 {
919 	struct CE_state *ce_state = (struct CE_state *)handle;
920 
921 	qdf_spin_lock_bh(&ce_state->ce_index_lock);
922 }
923 
924 static inline void ce_ring_release_lock(struct CE_handle *handle)
925 {
926 	struct CE_state *ce_state = (struct CE_state *)handle;
927 
928 	qdf_spin_unlock_bh(&ce_state->ce_index_lock);
929 }
930 
931 /*
932  * ce_ring_clear_event() - Clear ring event
933  * @ring: Ring pointer
934  * @event: ring event type
935  *
936  */
937 static inline void ce_ring_clear_event(struct CE_ring_state *ring, int event)
938 {
939 	qdf_atomic_clear_bit(event, &ring->event);
940 }
941 
942 /*
943  * ce_ring_set_event() - Set ring event
944  * @ring: Ring pointer
945  * @event: Ring event type
946  *
947  */
948 static inline void ce_ring_set_event(struct CE_ring_state *ring, int event)
949 {
950 	qdf_atomic_set_bit(event, &ring->event);
951 }
952 
953 /*
954  * ce_ring_get_clear_event() - Clear ring event and return old value
955  * @ring: Ring pointer
956  * @event: Ring event type
957  *
958  */
959 static inline int ce_ring_get_clear_event(struct CE_ring_state *ring, int event)
960 {
961 	return qdf_atomic_test_and_clear_bit(event, &ring->event);
962 }
963 
964 static inline void ce_ring_inc_flush_cnt(struct CE_ring_state *ring)
965 {
966 	ring->flush_count++;
967 }
968 #endif /* __COPY_ENGINE_INTERNAL_H__ */
969