1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Cavium, Inc
5 #ifndef _CPT_HW_TYPES_H_
6 #define _CPT_HW_TYPES_H_
8 #include <rte_byteorder.h>
11 * This file defines HRM specific structs.
15 #define CPT_VF_INTR_MBOX_MASK (1<<0)
16 #define CPT_VF_INTR_DOVF_MASK (1<<1)
17 #define CPT_VF_INTR_IRDE_MASK (1<<2)
18 #define CPT_VF_INTR_NWRP_MASK (1<<3)
19 #define CPT_VF_INTR_SWERR_MASK (1<<4)
20 #define CPT_VF_INTR_HWERR_MASK (1<<5)
21 #define CPT_VF_INTR_FAULT_MASK (1<<6)
23 #define CPT_INST_SIZE (64)
24 #define CPT_NEXT_CHUNK_PTR_SIZE (8)
27 * CPT_INST_S software command definitions
33 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
56 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
66 typedef struct cpt_vq_command {
74 * Structure cpt_inst_s
76 * CPT Instruction Structure
77 * This structure specifies the instruction layout.
78 * Instructions are stored in memory as little-endian unless
79 * CPT()_PF_Q()_CTL[INST_BE] is set.
81 typedef union cpt_inst_s {
83 struct cpt_inst_s_8s {
84 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
85 uint64_t reserved_17_63 : 47;
86 /* [ 16: 16] Done interrupt.
87 * 0 = No interrupts related to this instruction.
88 * 1 = When the instruction completes,CPT()_VQ()_DONE[DONE]
89 * will be incremented, and based on the rules described
90 * there an interrupt may occur.
93 uint64_t reserved_0_15 : 16;
94 #else /* Word 0 - Little Endian */
95 uint64_t reserved_0_15 : 16;
97 uint64_t reserved_17_63 : 47;
98 #endif /* Word 0 - End */
99 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 1 - Big Endian */
100 /* [127: 64] Result IOVA.
101 * If nonzero, specifies where to write CPT_RES_S.
102 * If zero, no result structure will be written.
103 * Address must be 16-byte aligned.
105 * Bits <63:49> are ignored by hardware; software should
106 * use a sign-extended bit <48> for forward compatibility.
108 uint64_t res_addr : 64;
109 #else /* Word 1 - Little Endian */
110 uint64_t res_addr : 64;
111 #endif /* Word 1 - End */
112 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 2 - Big Endian */
113 uint64_t reserved_172_191 : 20;
114 /* [171:162] If [WQ_PTR] is nonzero, the SSO guest-group to
115 * use when CPT submits work to SSO.
116 * For the SSO to not discard the add-work request, FPA_PF_MAP()
117 * must map [GRP] and CPT()_PF_Q()_GMCTL[GMID] as valid.
120 /* [161:160] If [WQ_PTR] is nonzero, the SSO tag type to use
121 * when CPT submits work to SSO.
124 /* [159:128] If [WQ_PTR] is nonzero, the SSO tag to use when
125 * CPT submits work to SSO.
128 #else /* Word 2 - Little Endian */
132 uint64_t reserved_172_191 : 20;
133 #endif /* Word 2 - End */
134 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 3 - Big Endian */
135 /** [255:192] If [WQ_PTR] is nonzero, it is a pointer to a
136 * work-queue entry that CPT submits work to SSO after all
137 * context, output data, and result write operations are
138 * visible to other CNXXXX units and the cores.
139 * Bits <2:0> must be zero.
140 * Bits <63:49> are ignored by hardware; software should use a
141 * sign-extended bit <48> for forward compatibility.
142 * Internal:Bits <63:49>, <2:0> are ignored by hardware,
143 * treated as always 0x0.
145 uint64_t wq_ptr : 64;
146 #else /* Word 3 - Little Endian */
147 uint64_t wq_ptr : 64;
148 #endif /* Word 3 - End */
149 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 4 - Big Endian */
151 /** [319:256] Engine instruction word 0. Passed to the
155 vq_cmd_word0_t vq_cmd_w0;
157 #else /* Word 4 - Little Endian */
160 vq_cmd_word0_t vq_cmd_w0;
162 #endif /* Word 4 - End */
163 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 5 - Big Endian */
165 /** [383:320] Engine instruction word 1. Passed to the
171 #else /* Word 5 - Little Endian */
176 #endif /* Word 5 - End */
177 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 6 - Big Endian */
179 /** [447:384] Engine instruction word 2. Passed to the
185 #else /* Word 6 - Little Endian */
190 #endif /* Word 6 - End */
191 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 7 - Big Endian */
193 /** [511:448] Engine instruction word 3. Passed to the
197 vq_cmd_word3_t vq_cmd_w3;
199 #else /* Word 7 - Little Endian */
202 vq_cmd_word3_t vq_cmd_w3;
204 #endif /* Word 7 - End */
206 struct cpt_inst_s_9s {
207 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
208 uint64_t nixtx_addr : 60;
209 uint64_t doneint : 1;
211 #else /* Word 0 - Little Endian */
213 uint64_t doneint : 1;
214 uint64_t nixtx_addr : 60;
215 #endif /* Word 0 - End */
217 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 2 - Big Endian */
218 uint64_t rvu_pf_func : 16;
219 uint64_t reserved_172_175 : 4;
223 #else /* Word 2 - Little Endian */
227 uint64_t reserved_172_175 : 4;
228 uint64_t rvu_pf_func : 16;
229 #endif /* Word 2 - End */
230 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 3 - Big Endian */
231 uint64_t wq_ptr : 61;
232 uint64_t reserved_194_193 : 2;
234 #else /* Word 3 - Little Endian */
236 uint64_t reserved_194_193 : 2;
237 uint64_t wq_ptr : 61;
238 #endif /* Word 3 - End */
247 * Structure cpt_res_s
249 * CPT Result Structure
250 * The CPT coprocessor writes the result structure after it completes a
251 * CPT_INST_S instruction. The result structure is exactly 16 bytes, and each
252 * instruction completion produces exactly one result structure.
254 * This structure is stored in memory as little-endian unless
255 * CPT()_PF_Q()_CTL[INST_BE] is set.
257 typedef union cpt_res_s {
259 struct cpt_res_s_8s {
260 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
261 uint64_t reserved_17_63 : 47;
262 /** [ 16: 16] Done interrupt. This bit is copied from the
263 * corresponding instruction's CPT_INST_S[DONEINT].
265 uint64_t doneint : 1;
266 uint64_t reserved_8_15 : 8;
267 /** [ 7: 0] Indicates completion/error status of the CPT
268 * coprocessor for the associated instruction, as enumerated by
269 * CPT_COMP_E. Core software may write the memory location
270 * containing [COMPCODE] to 0x0 before ringing the doorbell, and
271 * then poll for completion by checking for a nonzero value.
273 * Once the core observes a nonzero [COMPCODE] value in this
274 * case, the CPT coprocessor will have also completed L2/DRAM
277 uint64_t compcode : 8;
278 #else /* Word 0 - Little Endian */
279 uint64_t compcode : 8;
280 uint64_t reserved_8_15 : 8;
281 uint64_t doneint : 1;
282 uint64_t reserved_17_63 : 47;
283 #endif /* Word 0 - End */
284 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 1 - Big Endian */
285 uint64_t reserved_64_127 : 64;
286 #else /* Word 1 - Little Endian */
287 uint64_t reserved_64_127 : 64;
288 #endif /* Word 1 - End */
290 struct cpt_res_s_9s {
291 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
292 uint64_t reserved_17_63:47;
294 uint64_t uc_compcode:8;
296 #else /* Word 0 - Little Endian */
298 uint64_t uc_compcode:8;
300 uint64_t reserved_17_63:47;
301 #endif /* Word 0 - End */
302 uint64_t reserved_64_127;
307 * Register (NCB) cpt#_vq#_ctl
309 * CPT VF Queue Control Registers
310 * This register configures queues. This register should be changed (other than
311 * clearing [ENA]) only when quiescent (see CPT()_VQ()_INPROG[INFLIGHT]).
315 struct cptx_vqx_ctl_s {
316 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
317 uint64_t reserved_1_63 : 63;
318 /** [ 0: 0](R/W/H) Enables the logical instruction queue.
319 * See also CPT()_PF_Q()_CTL[CONT_ERR] and
320 * CPT()_VQ()_INPROG[INFLIGHT].
321 * 1 = Queue is enabled.
322 * 0 = Queue is disabled.
325 #else /* Word 0 - Little Endian */
327 uint64_t reserved_1_63 : 63;
328 #endif /* Word 0 - End */
333 * Register (NCB) cpt#_vq#_done
335 * CPT Queue Done Count Registers
336 * These registers contain the per-queue instruction done count.
340 struct cptx_vqx_done_s {
341 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
342 uint64_t reserved_20_63 : 44;
343 /** [ 19: 0](R/W/H) Done count. When CPT_INST_S[DONEINT] set
344 * and that instruction completes,CPT()_VQ()_DONE[DONE] is
345 * incremented when the instruction finishes. Write to this
346 * field are for diagnostic use only; instead software writes
347 * CPT()_VQ()_DONE_ACK with the number of decrements for this
350 * Interrupts are sent as follows:
352 * When CPT()_VQ()_DONE[DONE] = 0, then no results are pending,
353 * the interrupt coalescing timer is held to zero, and an
354 * interrupt is not sent.
356 * When CPT()_VQ()_DONE[DONE] != 0, then the interrupt
357 * coalescing timer counts. If the counter is >= CPT()_VQ()_DONE
358 * _WAIT[TIME_WAIT]*1024, or CPT()_VQ()_DONE[DONE] >= CPT()_VQ()
359 * _DONE_WAIT[NUM_WAIT], i.e. enough time has passed or enough
360 * results have arrived, then the interrupt is sent. Otherwise,
361 * it is not sent due to coalescing.
363 * When CPT()_VQ()_DONE_ACK is written (or CPT()_VQ()_DONE is
364 * written but this is not typical), the interrupt coalescing
365 * timer restarts. Note after decrementing this interrupt
366 * equation is recomputed, for example if CPT()_VQ()_DONE[DONE]
367 * >= CPT()_VQ()_DONE_WAIT[NUM_WAIT] and because the timer is
368 * zero, the interrupt will be resent immediately. (This covers
369 * the race case between software acknowledging an interrupt and
370 * a result returning.)
372 * When CPT()_VQ()_DONE_ENA_W1S[DONE] = 0, interrupts are not
373 * sent, but the counting described above still occurs.
375 * Since CPT instructions complete out-of-order, if software is
376 * using completion interrupts the suggested scheme is to
377 * request a DONEINT on each request, and when an interrupt
378 * arrives perform a "greedy" scan for completions; even if a
379 * later command is acknowledged first this will not result in
380 * missing a completion.
382 * Software is responsible for making sure [DONE] does not
383 * overflow; for example by insuring there are not more than
384 * 2^20-1 instructions in flight that may request interrupts.
387 #else /* Word 0 - Little Endian */
389 uint64_t reserved_20_63 : 44;
390 #endif /* Word 0 - End */
395 * Register (NCB) cpt#_vq#_done_ack
397 * CPT Queue Done Count Ack Registers
398 * This register is written by software to acknowledge interrupts.
402 struct cptx_vqx_done_ack_s {
403 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
404 uint64_t reserved_20_63 : 44;
405 /** [ 19: 0](R/W/H) Number of decrements to CPT()_VQ()_DONE
406 * [DONE]. Reads CPT()_VQ()_DONE[DONE].
408 * Written by software to acknowledge interrupts. If CPT()_VQ()_
409 * DONE[DONE] is still nonzero the interrupt will be re-sent if
410 * the conditions described in CPT()_VQ()_DONE[DONE] are
413 uint64_t done_ack : 20;
414 #else /* Word 0 - Little Endian */
415 uint64_t done_ack : 20;
416 uint64_t reserved_20_63 : 44;
417 #endif /* Word 0 - End */
419 } cptx_vqx_done_ack_t;
422 * Register (NCB) cpt#_vq#_done_wait
424 * CPT Queue Done Interrupt Coalescing Wait Registers
425 * Specifies the per queue interrupt coalescing settings.
429 struct cptx_vqx_done_wait_s {
430 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
431 uint64_t reserved_48_63 : 16;
432 /** [ 47: 32](R/W) Time hold-off. When CPT()_VQ()_DONE[DONE] =
433 * 0, or CPT()_VQ()_DONE_ACK is written a timer is cleared. When
434 * the timer reaches [TIME_WAIT]*1024 then interrupt coalescing
435 * ends; see CPT()_VQ()_DONE[DONE]. If 0x0, time coalescing is
438 uint64_t time_wait : 16;
439 uint64_t reserved_20_31 : 12;
440 /** [ 19: 0](R/W) Number of messages hold-off. When
441 * CPT()_VQ()_DONE[DONE] >= [NUM_WAIT] then interrupt coalescing
442 * ends; see CPT()_VQ()_DONE[DONE]. If 0x0, same behavior as
445 uint64_t num_wait : 20;
446 #else /* Word 0 - Little Endian */
447 uint64_t num_wait : 20;
448 uint64_t reserved_20_31 : 12;
449 uint64_t time_wait : 16;
450 uint64_t reserved_48_63 : 16;
451 #endif /* Word 0 - End */
453 } cptx_vqx_done_wait_t;
456 * Register (NCB) cpt#_vq#_doorbell
458 * CPT Queue Doorbell Registers
459 * Doorbells for the CPT instruction queues.
463 struct cptx_vqx_doorbell_s {
464 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
465 uint64_t reserved_20_63 : 44;
466 uint64_t dbell_cnt : 20;
467 /** [ 19: 0](R/W/H) Number of instruction queue 64-bit words
468 * to add to the CPT instruction doorbell count. Readback value
469 * is the the current number of pending doorbell requests.
471 * If counter overflows CPT()_VQ()_MISC_INT[DBELL_DOVF] is set.
473 * To reset the count back to zero, write one to clear
474 * CPT()_VQ()_MISC_INT_ENA_W1C[DBELL_DOVF], then write a value
475 * of 2^20 minus the read [DBELL_CNT], then write one to
476 * CPT()_VQ()_MISC_INT_W1C[DBELL_DOVF] and
477 * CPT()_VQ()_MISC_INT_ENA_W1S[DBELL_DOVF].
479 * Must be a multiple of 8. All CPT instructions are 8 words
480 * and require a doorbell count of multiple of 8.
482 #else /* Word 0 - Little Endian */
483 uint64_t dbell_cnt : 20;
484 uint64_t reserved_20_63 : 44;
485 #endif /* Word 0 - End */
487 } cptx_vqx_doorbell_t;
490 * Register (NCB) cpt#_vq#_inprog
492 * CPT Queue In Progress Count Registers
493 * These registers contain the per-queue instruction in flight registers.
497 struct cptx_vqx_inprog_s {
498 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
499 uint64_t reserved_8_63 : 56;
500 /** [ 7: 0](RO/H) Inflight count. Counts the number of
501 * instructions for the VF for which CPT is fetching, executing
502 * or responding to instructions. However this does not include
503 * any interrupts that are awaiting software handling
504 * (CPT()_VQ()_DONE[DONE] != 0x0).
506 * A queue may not be reconfigured until:
507 * 1. CPT()_VQ()_CTL[ENA] is cleared by software.
508 * 2. [INFLIGHT] is polled until equals to zero.
510 uint64_t inflight : 8;
511 #else /* Word 0 - Little Endian */
512 uint64_t inflight : 8;
513 uint64_t reserved_8_63 : 56;
514 #endif /* Word 0 - End */
519 * Register (NCB) cpt#_vq#_misc_int
521 * CPT Queue Misc Interrupt Register
522 * These registers contain the per-queue miscellaneous interrupts.
526 struct cptx_vqx_misc_int_s {
527 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
528 uint64_t reserved_7_63 : 57;
529 /** [ 6: 6](R/W1C/H) Translation fault detected. */
531 /** [ 5: 5](R/W1C/H) Hardware error from engines. */
533 /** [ 4: 4](R/W1C/H) Software error from engines. */
535 /** [ 3: 3](R/W1C/H) NCB result write response error. */
537 /** [ 2: 2](R/W1C/H) Instruction NCB read response error. */
539 /** [ 1: 1](R/W1C/H) Doorbell overflow. */
541 /** [ 0: 0](R/W1C/H) PF to VF mailbox interrupt. Set when
542 * CPT()_VF()_PF_MBOX(0) is written.
545 #else /* Word 0 - Little Endian */
553 uint64_t reserved_5_63 : 59;
554 #endif /* Word 0 - End */
556 } cptx_vqx_misc_int_t;
559 * Register (NCB) cpt#_vq#_saddr
561 * CPT Queue Starting Buffer Address Registers
562 * These registers set the instruction buffer starting address.
566 struct cptx_vqx_saddr_s {
567 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
568 uint64_t reserved_49_63 : 15;
569 /** [ 48: 6](R/W/H) Instruction buffer IOVA <48:6>
570 * (64-byte aligned). When written, it is the initial buffer
571 * starting address; when read, it is the next read pointer to
572 * be requested from L2C. The PTR field is overwritten with the
573 * next pointer each time that the command buffer segment is
574 * exhausted. New commands will then be read from the newly
575 * specified command buffer pointer.
578 uint64_t reserved_0_5 : 6;
579 #else /* Word 0 - Little Endian */
580 uint64_t reserved_0_5 : 6;
582 uint64_t reserved_49_63 : 15;
583 #endif /* Word 0 - End */
587 #endif /*_CPT_HW_TYPES_H_ */