New upstream version 18.11-rc1
[deb_dpdk.git] / drivers / common / cpt / cpt_hw_types.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Cavium, Inc
3  */
4
5 #ifndef _CPT_HW_TYPES_H_
6 #define _CPT_HW_TYPES_H_
7
8 #include <rte_byteorder.h>
9
10 /*
11  * This file defines HRM specific structs.
12  *
13  */
14
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)
22
23 #define CPT_INST_SIZE           (64)
24 #define CPT_NEXT_CHUNK_PTR_SIZE (8)
25
26 /*
27  * CPT_INST_S software command definitions
28  * Words EI (0-3)
29  */
30 typedef union {
31         uint64_t u64;
32         struct {
33                 uint16_t opcode;
34                 uint16_t param1;
35                 uint16_t param2;
36                 uint16_t dlen;
37         } s;
38 } vq_cmd_word0_t;
39
40 typedef union {
41         uint64_t u64;
42         struct {
43 #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
44                 uint64_t grp    : 3;
45                 uint64_t cptr   : 61;
46 #else
47                 uint64_t cptr   : 61;
48                 uint64_t grp    : 3;
49 #endif
50         } s;
51 } vq_cmd_word3_t;
52
53 typedef struct cpt_vq_command {
54         vq_cmd_word0_t cmd;
55         uint64_t dptr;
56         uint64_t rptr;
57         vq_cmd_word3_t cptr;
58 } cpt_vq_cmd_t;
59
60 /**
61  * Structure cpt_inst_s
62  *
63  * CPT Instruction Structure
64  * This structure specifies the instruction layout.
65  * Instructions are stored in memory as little-endian unless
66  * CPT()_PF_Q()_CTL[INST_BE] is set.
67  */
68 typedef union cpt_inst_s {
69         uint64_t u[8];
70         struct cpt_inst_s_8s {
71 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
72                 uint64_t reserved_17_63        : 47;
73                 /* [ 16: 16] Done interrupt.
74                  * 0 = No interrupts related to this instruction.
75                  * 1 = When the instruction completes,CPT()_VQ()_DONE[DONE]
76                  * will be incremented, and based on the rules described
77                  * there an interrupt may occur.
78                  */
79                 uint64_t doneint               : 1;
80                 uint64_t reserved_0_15         : 16;
81 #else /* Word 0 - Little Endian */
82                 uint64_t reserved_0_15         : 16;
83                 uint64_t doneint               : 1;
84                 uint64_t reserved_17_63        : 47;
85 #endif /* Word 0 - End */
86 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 1 - Big Endian */
87                 /* [127: 64] Result IOVA.
88                  * If nonzero, specifies where to write CPT_RES_S.
89                  * If zero, no result structure will be written.
90                  * Address must be 16-byte aligned.
91                  *
92                  * Bits <63:49> are ignored by hardware; software should
93                  * use a sign-extended bit <48> for forward compatibility.
94                  */
95                 uint64_t res_addr              : 64;
96 #else /* Word 1 - Little Endian */
97                 uint64_t res_addr              : 64;
98 #endif /* Word 1 - End */
99 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 2 - Big Endian */
100                 uint64_t reserved_172_191      : 20;
101                 /* [171:162] If [WQ_PTR] is nonzero, the SSO guest-group to
102                  * use when CPT submits work to SSO.
103                  * For the SSO to not discard the add-work request, FPA_PF_MAP()
104                  * must map [GRP] and CPT()_PF_Q()_GMCTL[GMID] as valid.
105                  */
106                 uint64_t grp                   : 10;
107                 /* [161:160] If [WQ_PTR] is nonzero, the SSO tag type to use
108                  * when CPT submits work to SSO.
109                  */
110                 uint64_t tt                    : 2;
111                 /* [159:128] If [WQ_PTR] is nonzero, the SSO tag to use when
112                  * CPT submits work to SSO.
113                  */
114                 uint64_t tag                   : 32;
115 #else /* Word 2 - Little Endian */
116                 uint64_t tag                   : 32;
117                 uint64_t tt                    : 2;
118                 uint64_t grp                   : 10;
119                 uint64_t reserved_172_191      : 20;
120 #endif /* Word 2 - End */
121 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 3 - Big Endian */
122                 /** [255:192] If [WQ_PTR] is nonzero, it is a pointer to a
123                  * work-queue entry that CPT submits work to SSO after all
124                  * context, output data, and result write operations are
125                  * visible to other CNXXXX units and the cores.
126                  * Bits <2:0> must be zero.
127                  * Bits <63:49> are ignored by hardware; software should use a
128                  * sign-extended bit <48> for forward compatibility.
129                  * Internal:Bits <63:49>, <2:0> are ignored by hardware,
130                  * treated as always 0x0.
131                  **/
132                 uint64_t wq_ptr                : 64;
133 #else /* Word 3 - Little Endian */
134                 uint64_t wq_ptr                : 64;
135 #endif /* Word 3 - End */
136 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 4 - Big Endian */
137                 union {
138                         /** [319:256] Engine instruction word 0. Passed to the
139                          * AE/SE.
140                          **/
141                         uint64_t ei0                   : 64;
142                         vq_cmd_word0_t vq_cmd_w0;
143                 };
144 #else /* Word 4 - Little Endian */
145                 union {
146                         uint64_t ei0                   : 64;
147                         vq_cmd_word0_t vq_cmd_w0;
148                 };
149 #endif /* Word 4 - End */
150 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 5 - Big Endian */
151                 union {
152                         /** [383:320] Engine instruction word 1. Passed to the
153                          * AE/SE.
154                          **/
155                         uint64_t ei1                   : 64;
156                         uint64_t dptr;
157                 };
158 #else /* Word 5 - Little Endian */
159                 union {
160                         uint64_t ei1                   : 64;
161                         uint64_t dptr;
162                 };
163 #endif /* Word 5 - End */
164 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 6 - Big Endian */
165                 union {
166                         /** [447:384] Engine instruction word 2. Passed to the
167                          * AE/SE.
168                          **/
169                         uint64_t ei2                   : 64;
170                         uint64_t rptr;
171                 };
172 #else /* Word 6 - Little Endian */
173                 union {
174                         uint64_t ei2                   : 64;
175                         uint64_t rptr;
176                 };
177 #endif /* Word 6 - End */
178 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 7 - Big Endian */
179                 union {
180                         /** [511:448] Engine instruction word 3. Passed to the
181                          * AE/SE.
182                          **/
183                         uint64_t ei3                   : 64;
184                         vq_cmd_word3_t vq_cmd_w3;
185                 };
186 #else /* Word 7 - Little Endian */
187                 union {
188                         uint64_t ei3                   : 64;
189                         vq_cmd_word3_t vq_cmd_w3;
190                 };
191 #endif /* Word 7 - End */
192         } s8x;
193 } cpt_inst_s_t;
194
195 /**
196  * Structure cpt_res_s
197  *
198  * CPT Result Structure
199  * The CPT coprocessor writes the result structure after it completes a
200  * CPT_INST_S instruction. The result structure is exactly 16 bytes, and each
201  * instruction completion produces exactly one result structure.
202  *
203  * This structure is stored in memory as little-endian unless
204  * CPT()_PF_Q()_CTL[INST_BE] is set.
205  */
206 typedef union cpt_res_s {
207         uint64_t u[2];
208         struct cpt_res_s_8s {
209 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
210                 uint64_t reserved_17_63        : 47;
211                 /** [ 16: 16] Done interrupt. This bit is copied from the
212                  * corresponding instruction's CPT_INST_S[DONEINT].
213                  **/
214                 uint64_t doneint               : 1;
215                 uint64_t reserved_8_15         : 8;
216                 /** [  7:  0] Indicates completion/error status of the CPT
217                  * coprocessor for the associated instruction, as enumerated by
218                  * CPT_COMP_E. Core software may write the memory location
219                  * containing [COMPCODE] to 0x0 before ringing the doorbell, and
220                  * then poll for completion by checking for a nonzero value.
221                  *
222                  * Once the core observes a nonzero [COMPCODE] value in this
223                  * case, the CPT coprocessor will have also completed L2/DRAM
224                  * write operations.
225                  **/
226                 uint64_t compcode              : 8;
227 #else /* Word 0 - Little Endian */
228                 uint64_t compcode              : 8;
229                 uint64_t reserved_8_15         : 8;
230                 uint64_t doneint               : 1;
231                 uint64_t reserved_17_63        : 47;
232 #endif /* Word 0 - End */
233 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 1 - Big Endian */
234                 uint64_t reserved_64_127       : 64;
235 #else /* Word 1 - Little Endian */
236                 uint64_t reserved_64_127       : 64;
237 #endif /* Word 1 - End */
238         } s8x;
239 } cpt_res_s_t;
240
241 /**
242  * Register (NCB) cpt#_vq#_ctl
243  *
244  * CPT VF Queue Control Registers
245  * This register configures queues. This register should be changed (other than
246  * clearing [ENA]) only when quiescent (see CPT()_VQ()_INPROG[INFLIGHT]).
247  */
248 typedef union {
249         uint64_t u;
250         struct cptx_vqx_ctl_s {
251 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
252                 uint64_t reserved_1_63         : 63;
253                 /** [  0:  0](R/W/H) Enables the logical instruction queue.
254                  * See also CPT()_PF_Q()_CTL[CONT_ERR] and
255                  * CPT()_VQ()_INPROG[INFLIGHT].
256                  * 1 = Queue is enabled.
257                  * 0 = Queue is disabled.
258                  **/
259                 uint64_t ena                   : 1;
260 #else /* Word 0 - Little Endian */
261                 uint64_t ena                   : 1;
262                 uint64_t reserved_1_63         : 63;
263 #endif /* Word 0 - End */
264         } s;
265 } cptx_vqx_ctl_t;
266
267 /**
268  * Register (NCB) cpt#_vq#_done
269  *
270  * CPT Queue Done Count Registers
271  * These registers contain the per-queue instruction done count.
272  */
273 typedef union {
274         uint64_t u;
275         struct cptx_vqx_done_s {
276 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
277                 uint64_t reserved_20_63        : 44;
278                 /** [ 19:  0](R/W/H) Done count. When CPT_INST_S[DONEINT] set
279                  * and that instruction completes,CPT()_VQ()_DONE[DONE] is
280                  * incremented when the instruction finishes. Write to this
281                  * field are for diagnostic use only; instead software writes
282                  * CPT()_VQ()_DONE_ACK with the number of decrements for this
283                  * field.
284                  *
285                  * Interrupts are sent as follows:
286                  *
287                  * When CPT()_VQ()_DONE[DONE] = 0, then no results are pending,
288                  * the interrupt coalescing timer is held to zero, and an
289                  * interrupt is not sent.
290                  *
291                  * When CPT()_VQ()_DONE[DONE] != 0, then the interrupt
292                  * coalescing timer counts. If the counter is >= CPT()_VQ()_DONE
293                  * _WAIT[TIME_WAIT]*1024, or CPT()_VQ()_DONE[DONE] >= CPT()_VQ()
294                  * _DONE_WAIT[NUM_WAIT], i.e. enough time has passed or enough
295                  * results have arrived, then the interrupt is sent.  Otherwise,
296                  * it is not sent due to coalescing.
297                  *
298                  * When CPT()_VQ()_DONE_ACK is written (or CPT()_VQ()_DONE is
299                  * written but this is not typical), the interrupt coalescing
300                  * timer restarts.  Note after decrementing this interrupt
301                  * equation is recomputed, for example if CPT()_VQ()_DONE[DONE]
302                  * >= CPT()_VQ()_DONE_WAIT[NUM_WAIT] and because the timer is
303                  * zero, the interrupt will be resent immediately.  (This covers
304                  * the race case between software acknowledging an interrupt and
305                  * a result returning.)
306                  *
307                  * When CPT()_VQ()_DONE_ENA_W1S[DONE] = 0, interrupts are not
308                  * sent, but the counting described above still occurs.
309                  *
310                  * Since CPT instructions complete out-of-order, if software is
311                  * using completion interrupts the suggested scheme is to
312                  * request a DONEINT on each request, and when an interrupt
313                  * arrives perform a "greedy" scan for completions; even if a
314                  * later command is acknowledged first this will not result in
315                  * missing a completion.
316                  *
317                  * Software is responsible for making sure [DONE] does not
318                  * overflow; for example by insuring there are not more than
319                  * 2^20-1 instructions in flight that may request interrupts.
320                  **/
321                 uint64_t done                  : 20;
322 #else /* Word 0 - Little Endian */
323                 uint64_t done                  : 20;
324                 uint64_t reserved_20_63        : 44;
325 #endif /* Word 0 - End */
326         } s;
327 } cptx_vqx_done_t;
328
329 /**
330  * Register (NCB) cpt#_vq#_done_ack
331  *
332  * CPT Queue Done Count Ack Registers
333  * This register is written by software to acknowledge interrupts.
334  */
335 typedef union {
336         uint64_t u;
337         struct cptx_vqx_done_ack_s {
338 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
339                 uint64_t reserved_20_63        : 44;
340                 /** [ 19:  0](R/W/H) Number of decrements to CPT()_VQ()_DONE
341                  * [DONE]. Reads CPT()_VQ()_DONE[DONE].
342                  *
343                  * Written by software to acknowledge interrupts. If CPT()_VQ()_
344                  * DONE[DONE] is still nonzero the interrupt will be re-sent if
345                  * the conditions described in CPT()_VQ()_DONE[DONE] are
346                  * satisfied.
347                  **/
348                 uint64_t done_ack              : 20;
349 #else /* Word 0 - Little Endian */
350                 uint64_t done_ack              : 20;
351                 uint64_t reserved_20_63        : 44;
352 #endif /* Word 0 - End */
353         } s;
354 } cptx_vqx_done_ack_t;
355
356 /**
357  * Register (NCB) cpt#_vq#_done_wait
358  *
359  * CPT Queue Done Interrupt Coalescing Wait Registers
360  * Specifies the per queue interrupt coalescing settings.
361  */
362 typedef union {
363         uint64_t u;
364         struct cptx_vqx_done_wait_s {
365 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
366                 uint64_t reserved_48_63        : 16;
367                 /** [ 47: 32](R/W) Time hold-off. When CPT()_VQ()_DONE[DONE] =
368                  * 0, or CPT()_VQ()_DONE_ACK is written a timer is cleared. When
369                  * the timer reaches [TIME_WAIT]*1024 then interrupt coalescing
370                  * ends; see CPT()_VQ()_DONE[DONE]. If 0x0, time coalescing is
371                  * disabled.
372                  **/
373                 uint64_t time_wait             : 16;
374                 uint64_t reserved_20_31        : 12;
375                 /** [ 19:  0](R/W) Number of messages hold-off. When
376                  * CPT()_VQ()_DONE[DONE] >= [NUM_WAIT] then interrupt coalescing
377                  * ends; see CPT()_VQ()_DONE[DONE]. If 0x0, same behavior as
378                  * 0x1.
379                  **/
380                 uint64_t num_wait              : 20;
381 #else /* Word 0 - Little Endian */
382                 uint64_t num_wait              : 20;
383                 uint64_t reserved_20_31        : 12;
384                 uint64_t time_wait             : 16;
385                 uint64_t reserved_48_63        : 16;
386 #endif /* Word 0 - End */
387         } s;
388 } cptx_vqx_done_wait_t;
389
390 /**
391  * Register (NCB) cpt#_vq#_doorbell
392  *
393  * CPT Queue Doorbell Registers
394  * Doorbells for the CPT instruction queues.
395  */
396 typedef union {
397         uint64_t u;
398         struct cptx_vqx_doorbell_s {
399 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
400                 uint64_t reserved_20_63        : 44;
401                 uint64_t dbell_cnt             : 20;
402                 /** [ 19:  0](R/W/H) Number of instruction queue 64-bit words
403                  * to add to the CPT instruction doorbell count. Readback value
404                  * is the the current number of pending doorbell requests.
405                  *
406                  * If counter overflows CPT()_VQ()_MISC_INT[DBELL_DOVF] is set.
407                  *
408                  * To reset the count back to zero, write one to clear
409                  * CPT()_VQ()_MISC_INT_ENA_W1C[DBELL_DOVF], then write a value
410                  * of 2^20 minus the read [DBELL_CNT], then write one to
411                  * CPT()_VQ()_MISC_INT_W1C[DBELL_DOVF] and
412                  * CPT()_VQ()_MISC_INT_ENA_W1S[DBELL_DOVF].
413                  *
414                  * Must be a multiple of 8.  All CPT instructions are 8 words
415                  * and require a doorbell count of multiple of 8.
416                  **/
417 #else /* Word 0 - Little Endian */
418                 uint64_t dbell_cnt             : 20;
419                 uint64_t reserved_20_63        : 44;
420 #endif /* Word 0 - End */
421         } s;
422 } cptx_vqx_doorbell_t;
423
424 /**
425  * Register (NCB) cpt#_vq#_inprog
426  *
427  * CPT Queue In Progress Count Registers
428  * These registers contain the per-queue instruction in flight registers.
429  */
430 typedef union {
431         uint64_t u;
432         struct cptx_vqx_inprog_s {
433 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
434                 uint64_t reserved_8_63         : 56;
435                 /** [  7:  0](RO/H) Inflight count. Counts the number of
436                  * instructions for the VF for which CPT is fetching, executing
437                  * or responding to instructions. However this does not include
438                  * any interrupts that are awaiting software handling
439                  * (CPT()_VQ()_DONE[DONE] != 0x0).
440                  *
441                  * A queue may not be reconfigured until:
442                  *  1. CPT()_VQ()_CTL[ENA] is cleared by software.
443                  *  2. [INFLIGHT] is polled until equals to zero.
444                  **/
445                 uint64_t inflight              : 8;
446 #else /* Word 0 - Little Endian */
447                 uint64_t inflight              : 8;
448                 uint64_t reserved_8_63         : 56;
449 #endif /* Word 0 - End */
450         } s;
451 } cptx_vqx_inprog_t;
452
453 /**
454  * Register (NCB) cpt#_vq#_misc_int
455  *
456  * CPT Queue Misc Interrupt Register
457  * These registers contain the per-queue miscellaneous interrupts.
458  */
459 typedef union {
460         uint64_t u;
461         struct cptx_vqx_misc_int_s {
462 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
463                 uint64_t reserved_7_63         : 57;
464                 /** [  6:  6](R/W1C/H) Translation fault detected. */
465                 uint64_t fault                 : 1;
466                 /** [  5:  5](R/W1C/H) Hardware error from engines. */
467                 uint64_t hwerr                 : 1;
468                 /** [  4:  4](R/W1C/H) Software error from engines. */
469                 uint64_t swerr                 : 1;
470                 /** [  3:  3](R/W1C/H) NCB result write response error. */
471                 uint64_t nwrp                  : 1;
472                 /** [  2:  2](R/W1C/H) Instruction NCB read response error. */
473                 uint64_t irde                  : 1;
474                 /** [  1:  1](R/W1C/H) Doorbell overflow. */
475                 uint64_t dovf                  : 1;
476                 /** [  0:  0](R/W1C/H) PF to VF mailbox interrupt. Set when
477                  * CPT()_VF()_PF_MBOX(0) is written.
478                  **/
479                 uint64_t mbox                  : 1;
480 #else /* Word 0 - Little Endian */
481                 uint64_t mbox                  : 1;
482                 uint64_t dovf                  : 1;
483                 uint64_t irde                  : 1;
484                 uint64_t nwrp                  : 1;
485                 uint64_t swerr                 : 1;
486                 uint64_t hwerr                 : 1;
487                 uint64_t fault                 : 1;
488                 uint64_t reserved_5_63         : 59;
489 #endif /* Word 0 - End */
490         } s;
491 } cptx_vqx_misc_int_t;
492
493 /**
494  * Register (NCB) cpt#_vq#_saddr
495  *
496  * CPT Queue Starting Buffer Address Registers
497  * These registers set the instruction buffer starting address.
498  */
499 typedef union {
500         uint64_t u;
501         struct cptx_vqx_saddr_s {
502 #if (RTE_BYTE_ORDER == RTE_BIG_ENDIAN) /* Word 0 - Big Endian */
503                 uint64_t reserved_49_63        : 15;
504                 /** [ 48:  6](R/W/H) Instruction buffer IOVA <48:6>
505                  * (64-byte aligned). When written, it is the initial buffer
506                  * starting address; when read, it is the next read pointer to
507                  * be requested from L2C. The PTR field is overwritten with the
508                  * next pointer each time that the command buffer segment is
509                  * exhausted. New commands will then be read from the newly
510                  * specified command buffer pointer.
511                  **/
512                 uint64_t ptr                   : 43;
513                 uint64_t reserved_0_5          : 6;
514 #else /* Word 0 - Little Endian */
515                 uint64_t reserved_0_5          : 6;
516                 uint64_t ptr                   : 43;
517                 uint64_t reserved_49_63        : 15;
518 #endif /* Word 0 - End */
519         } s;
520 } cptx_vqx_saddr_t;
521
522 #endif /*_CPT_HW_TYPES_H_ */