net/ice: fix flow redirector
[dpdk.git] / drivers / common / dpaax / caamflib / rta / fifo_load_store_cmd.h
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016,2019 NXP
5  */
6
7 #ifndef __RTA_FIFO_LOAD_STORE_CMD_H__
8 #define __RTA_FIFO_LOAD_STORE_CMD_H__
9
10 extern enum rta_sec_era rta_sec_era;
11
12 static const uint32_t fifo_load_table[][2] = {
13 /*1*/   { PKA0,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A0 },
14         { PKA1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A1 },
15         { PKA2,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A2 },
16         { PKA3,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A3 },
17         { PKB0,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B0 },
18         { PKB1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B1 },
19         { PKB2,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B2 },
20         { PKB3,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B3 },
21         { PKA,         FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A },
22         { PKB,         FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B },
23         { PKN,         FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_N },
24         { SKIP,        FIFOLD_CLASS_SKIP },
25         { MSG1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG },
26         { MSG2,        FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG },
27         { MSGOUTSNOOP, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG1OUT2 },
28         { MSGINSNOOP,  FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG },
29         { IV1,         FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_IV },
30         { IV2,         FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_IV },
31         { AAD1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_AAD },
32         { ICV1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_ICV },
33         { ICV2,        FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_ICV },
34         { BIT_DATA,    FIFOLD_TYPE_BITDATA },
35 /*23*/  { IFIFO,       FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_NOINFOFIFO }
36 };
37
38 /*
39  * Allowed FIFO_LOAD input data types for each SEC Era.
40  * Values represent the number of entries from fifo_load_table[] that are
41  * supported.
42  */
43 static const unsigned int fifo_load_table_sz[] = {22, 22, 23, 23,
44                                                   23, 23, 23, 23,
45                                                   23, 23};
46
47 static inline int
48 rta_fifo_load(struct program *program, uint32_t src,
49               uint64_t loc, uint32_t length, uint32_t flags)
50 {
51         uint32_t opcode = 0;
52         uint32_t ext_length = 0, val = 0;
53         int ret = -EINVAL;
54         bool is_seq_cmd = false;
55         unsigned int start_pc = program->current_pc;
56
57         /* write command type field */
58         if (flags & SEQ) {
59                 opcode = CMD_SEQ_FIFO_LOAD;
60                 is_seq_cmd = true;
61         } else {
62                 opcode = CMD_FIFO_LOAD;
63         }
64
65         /* Parameters checking */
66         if (is_seq_cmd) {
67                 if ((flags & IMMED) || (flags & SGF)) {
68                         pr_err("SEQ FIFO LOAD: Invalid command\n");
69                         goto err;
70                 }
71                 if ((rta_sec_era <= RTA_SEC_ERA_5) && (flags & AIDF)) {
72                         pr_err("SEQ FIFO LOAD: Flag(s) not supported by SEC Era %d\n",
73                                USER_SEC_ERA(rta_sec_era));
74                         goto err;
75                 }
76                 if ((flags & VLF) && ((flags & EXT) || (length >> 16))) {
77                         pr_err("SEQ FIFO LOAD: Invalid usage of VLF\n");
78                         goto err;
79                 }
80         } else {
81                 if (src == SKIP) {
82                         pr_err("FIFO LOAD: Invalid src\n");
83                         goto err;
84                 }
85                 if ((flags & AIDF) || (flags & VLF)) {
86                         pr_err("FIFO LOAD: Invalid command\n");
87                         goto err;
88                 }
89                 if ((flags & IMMED) && (flags & SGF)) {
90                         pr_err("FIFO LOAD: Invalid usage of SGF and IMM\n");
91                         goto err;
92                 }
93                 if ((flags & IMMED) && ((flags & EXT) || (length >> 16))) {
94                         pr_err("FIFO LOAD: Invalid usage of EXT and IMM\n");
95                         goto err;
96                 }
97         }
98
99         /* write input data type field */
100         ret = __rta_map_opcode(src, fifo_load_table,
101                                fifo_load_table_sz[rta_sec_era], &val);
102         if (ret < 0) {
103                 pr_err("FIFO LOAD: Source value is not supported. SEC Program Line: %d\n",
104                        program->current_pc);
105                 goto err;
106         }
107         opcode |= val;
108
109         if (flags & CLASS1)
110                 opcode |= FIFOLD_CLASS_CLASS1;
111         if (flags & CLASS2)
112                 opcode |= FIFOLD_CLASS_CLASS2;
113         if (flags & BOTH)
114                 opcode |= FIFOLD_CLASS_BOTH;
115
116         /* write fields: SGF|VLF, IMM, [LC1, LC2, F1] */
117         if (flags & FLUSH1)
118                 opcode |= FIFOLD_TYPE_FLUSH1;
119         if (flags & LAST1)
120                 opcode |= FIFOLD_TYPE_LAST1;
121         if (flags & LAST2)
122                 opcode |= FIFOLD_TYPE_LAST2;
123         if (!is_seq_cmd) {
124                 if (flags & SGF)
125                         opcode |= FIFOLDST_SGF;
126                 if (flags & IMMED)
127                         opcode |= FIFOLD_IMM;
128         } else {
129                 if (flags & VLF)
130                         opcode |= FIFOLDST_VLF;
131                 if (flags & AIDF)
132                         opcode |= FIFOLD_AIDF;
133         }
134
135         /*
136          * Verify if extended length is required. In case of BITDATA, calculate
137          * number of full bytes and additional valid bits.
138          */
139         if ((flags & EXT) || (length >> 16)) {
140                 opcode |= FIFOLDST_EXT;
141                 if (src == BIT_DATA) {
142                         ext_length = (length / 8);
143                         length = (length % 8);
144                 } else {
145                         ext_length = length;
146                         length = 0;
147                 }
148         }
149         opcode |= (uint16_t) length;
150
151         __rta_out32(program, opcode);
152         program->current_instruction++;
153
154         /* write pointer or immediate data field */
155         if (flags & IMMED)
156                 __rta_inline_data(program, loc, flags & __COPY_MASK, length);
157         else if (!is_seq_cmd)
158                 __rta_out64(program, program->ps, loc);
159
160         /* write extended length field */
161         if (opcode & FIFOLDST_EXT)
162                 __rta_out32(program, ext_length);
163
164         return (int)start_pc;
165
166  err:
167         program->first_error_pc = start_pc;
168         program->current_instruction++;
169         return ret;
170 }
171
172 static const uint32_t fifo_store_table[][2] = {
173 /*1*/   { PKA0,      FIFOST_TYPE_PKHA_A0 },
174         { PKA1,      FIFOST_TYPE_PKHA_A1 },
175         { PKA2,      FIFOST_TYPE_PKHA_A2 },
176         { PKA3,      FIFOST_TYPE_PKHA_A3 },
177         { PKB0,      FIFOST_TYPE_PKHA_B0 },
178         { PKB1,      FIFOST_TYPE_PKHA_B1 },
179         { PKB2,      FIFOST_TYPE_PKHA_B2 },
180         { PKB3,      FIFOST_TYPE_PKHA_B3 },
181         { PKA,       FIFOST_TYPE_PKHA_A },
182         { PKB,       FIFOST_TYPE_PKHA_B },
183         { PKN,       FIFOST_TYPE_PKHA_N },
184         { PKE,       FIFOST_TYPE_PKHA_E_JKEK },
185         { RNG,       FIFOST_TYPE_RNGSTORE },
186         { RNGOFIFO,  FIFOST_TYPE_RNGFIFO },
187         { AFHA_SBOX, FIFOST_TYPE_AF_SBOX_JKEK },
188         { MDHA_SPLIT_KEY, FIFOST_CLASS_CLASS2KEY | FIFOST_TYPE_SPLIT_KEK },
189         { MSG,       FIFOST_TYPE_MESSAGE_DATA },
190         { KEY1,      FIFOST_CLASS_CLASS1KEY | FIFOST_TYPE_KEY_KEK },
191         { KEY2,      FIFOST_CLASS_CLASS2KEY | FIFOST_TYPE_KEY_KEK },
192         { OFIFO,     FIFOST_TYPE_OUTFIFO_KEK},
193         { SKIP,      FIFOST_TYPE_SKIP },
194 /*22*/  { METADATA,  FIFOST_TYPE_METADATA},
195         { MSG_CKSUM,  FIFOST_TYPE_MESSAGE_DATA2 }
196 };
197
198 /*
199  * Allowed FIFO_STORE output data types for each SEC Era.
200  * Values represent the number of entries from fifo_store_table[] that are
201  * supported.
202  */
203 static const unsigned int fifo_store_table_sz[] = {21, 21, 21, 21,
204                                                    22, 22, 22, 23,
205                                                    23, 23};
206
207 static inline int
208 rta_fifo_store(struct program *program, uint32_t src,
209                uint32_t encrypt_flags, uint64_t dst,
210                uint32_t length, uint32_t flags)
211 {
212         uint32_t opcode = 0;
213         uint32_t val = 0;
214         int ret = -EINVAL;
215         bool is_seq_cmd = false;
216         unsigned int start_pc = program->current_pc;
217
218         /* write command type field */
219         if (flags & SEQ) {
220                 opcode = CMD_SEQ_FIFO_STORE;
221                 is_seq_cmd = true;
222         } else {
223                 opcode = CMD_FIFO_STORE;
224         }
225
226         /* Parameter checking */
227         if (is_seq_cmd) {
228                 if ((flags & VLF) && ((length >> 16) || (flags & EXT))) {
229                         pr_err("SEQ FIFO STORE: Invalid usage of VLF\n");
230                         goto err;
231                 }
232                 if (dst) {
233                         pr_err("SEQ FIFO STORE: Invalid command\n");
234                         goto err;
235                 }
236                 if ((src == METADATA) && (flags & (CONT | EXT))) {
237                         pr_err("SEQ FIFO STORE: Invalid flags\n");
238                         goto err;
239                 }
240         } else {
241                 if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) ||
242                     (src == METADATA)) {
243                         pr_err("FIFO STORE: Invalid destination\n");
244                         goto err;
245                 }
246         }
247         if ((rta_sec_era == RTA_SEC_ERA_7) && (src == AFHA_SBOX)) {
248                 pr_err("FIFO STORE: AFHA S-box not supported by SEC Era %d\n",
249                        USER_SEC_ERA(rta_sec_era));
250                 goto err;
251         }
252
253         /* write output data type field */
254         ret = __rta_map_opcode(src, fifo_store_table,
255                                fifo_store_table_sz[rta_sec_era], &val);
256         if (ret < 0) {
257                 pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n",
258                        program->current_pc);
259                 goto err;
260         }
261         opcode |= val;
262
263         if (encrypt_flags & TK)
264                 opcode |= (0x1 << FIFOST_TYPE_SHIFT);
265         if (encrypt_flags & EKT) {
266                 if (rta_sec_era == RTA_SEC_ERA_1) {
267                         pr_err("FIFO STORE: AES-CCM source types not supported\n");
268                         ret = -EINVAL;
269                         goto err;
270                 }
271                 opcode |= (0x10 << FIFOST_TYPE_SHIFT);
272                 opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT);
273         }
274
275         /* write flags fields */
276         if (flags & CONT)
277                 opcode |= FIFOST_CONT;
278         if ((flags & VLF) && (is_seq_cmd))
279                 opcode |= FIFOLDST_VLF;
280         if ((flags & SGF) && (!is_seq_cmd))
281                 opcode |= FIFOLDST_SGF;
282         if (flags & CLASS1)
283                 opcode |= FIFOST_CLASS_CLASS1KEY;
284         if (flags & CLASS2)
285                 opcode |= FIFOST_CLASS_CLASS2KEY;
286         if (flags & BOTH)
287                 opcode |= FIFOST_CLASS_BOTH;
288
289         /* Verify if extended length is required */
290         if ((length >> 16) || (flags & EXT))
291                 opcode |= FIFOLDST_EXT;
292         else
293                 opcode |= (uint16_t) length;
294
295         __rta_out32(program, opcode);
296         program->current_instruction++;
297
298         /* write pointer field */
299         if ((!is_seq_cmd) && (dst))
300                 __rta_out64(program, program->ps, dst);
301
302         /* write extended length field */
303         if (opcode & FIFOLDST_EXT)
304                 __rta_out32(program, length);
305
306         return (int)start_pc;
307
308  err:
309         program->first_error_pc = start_pc;
310         program->current_instruction++;
311         return ret;
312 }
313
314 #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */