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
ce_h2t_tx_ce_cleanup(struct CE_handle * ce_hdl)685 static inline void ce_h2t_tx_ce_cleanup(struct CE_handle *ce_hdl)
686 {
687 }
688
ce_t2h_msg_ce_cleanup(struct CE_handle * ce_hdl)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
hif_record_ce_srng_desc_event(struct hif_softc * scn,int ce_id,enum hif_ce_event_type type,union ce_srng_desc * descriptor,void * memory,int index,int len,void * hal_ring)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
hif_clear_ce_desc_debug_data(struct hif_ce_desc_event * event)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
alloc_mem_ce_debug_hist_data(struct hif_softc * scn,uint32_t ce_id)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
free_mem_ce_debug_hist_data(struct hif_softc * scn,uint32_t ce_id)861 void free_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id) { }
862
863 static inline
hif_ce_desc_data_record(struct hif_ce_desc_event * event,int len)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 */
ce_validate_nbytes(uint32_t nbytes,struct CE_state * ce_state)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
ce_validate_nbytes(uint32_t nbytes,struct CE_state * ce_state)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
hif_ce_desc_record_rx_paddr(struct hif_softc * scn,struct hif_ce_desc_event * event,qdf_nbuf_t nbuf)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
ce_ring_aquire_lock(struct CE_handle * handle)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
ce_ring_release_lock(struct CE_handle * handle)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 */
ce_ring_clear_event(struct CE_ring_state * ring,int event)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 */
ce_ring_set_event(struct CE_ring_state * ring,int event)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 */
ce_ring_get_clear_event(struct CE_ring_state * ring,int event)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
ce_ring_inc_flush_cnt(struct CE_ring_state * ring)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