doc: fix list of unsupported features in IPsec guide
[dpdk.git] / drivers / crypto / dpaa2_sec / hw / rta / math_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_MATH_CMD_H__
8 #define __RTA_MATH_CMD_H__
9
10 extern enum rta_sec_era rta_sec_era;
11
12 static const uint32_t math_op1[][2] = {
13 /*1*/   { MATH0,     MATH_SRC0_REG0 },
14         { MATH1,     MATH_SRC0_REG1 },
15         { MATH2,     MATH_SRC0_REG2 },
16         { MATH3,     MATH_SRC0_REG3 },
17         { SEQINSZ,   MATH_SRC0_SEQINLEN },
18         { SEQOUTSZ,  MATH_SRC0_SEQOUTLEN },
19         { VSEQINSZ,  MATH_SRC0_VARSEQINLEN },
20         { VSEQOUTSZ, MATH_SRC0_VARSEQOUTLEN },
21         { ZERO,      MATH_SRC0_ZERO },
22 /*10*/  { NONE,      0 }, /* dummy value */
23         { DPOVRD,    MATH_SRC0_DPOVRD },
24         { ONE,       MATH_SRC0_ONE }
25 };
26
27 /*
28  * Allowed MATH op1 sources for each SEC Era.
29  * Values represent the number of entries from math_op1[] that are supported.
30  */
31 static const unsigned int math_op1_sz[] = {10, 10, 12, 12, 12, 12,
32                                            12, 12, 12, 12};
33
34 static const uint32_t math_op2[][2] = {
35 /*1*/   { MATH0,     MATH_SRC1_REG0 },
36         { MATH1,     MATH_SRC1_REG1 },
37         { MATH2,     MATH_SRC1_REG2 },
38         { MATH3,     MATH_SRC1_REG3 },
39         { ABD,       MATH_SRC1_INFIFO },
40         { OFIFO,     MATH_SRC1_OUTFIFO },
41         { ONE,       MATH_SRC1_ONE },
42 /*8*/   { NONE,      0 }, /* dummy value */
43         { JOBSRC,    MATH_SRC1_JOBSOURCE },
44         { DPOVRD,    MATH_SRC1_DPOVRD },
45         { VSEQINSZ,  MATH_SRC1_VARSEQINLEN },
46         { VSEQOUTSZ, MATH_SRC1_VARSEQOUTLEN },
47 /*13*/  { ZERO,      MATH_SRC1_ZERO }
48 };
49
50 /*
51  * Allowed MATH op2 sources for each SEC Era.
52  * Values represent the number of entries from math_op2[] that are supported.
53  */
54 static const unsigned int math_op2_sz[] = {8, 9, 13, 13, 13, 13, 13, 13,
55                                            13, 13};
56
57 static const uint32_t math_result[][2] = {
58 /*1*/   { MATH0,     MATH_DEST_REG0 },
59         { MATH1,     MATH_DEST_REG1 },
60         { MATH2,     MATH_DEST_REG2 },
61         { MATH3,     MATH_DEST_REG3 },
62         { SEQINSZ,   MATH_DEST_SEQINLEN },
63         { SEQOUTSZ,  MATH_DEST_SEQOUTLEN },
64         { VSEQINSZ,  MATH_DEST_VARSEQINLEN },
65         { VSEQOUTSZ, MATH_DEST_VARSEQOUTLEN },
66 /*9*/   { NONE,      MATH_DEST_NONE },
67         { DPOVRD,    MATH_DEST_DPOVRD }
68 };
69
70 /*
71  * Allowed MATH result destinations for each SEC Era.
72  * Values represent the number of entries from math_result[] that are
73  * supported.
74  */
75 static const unsigned int math_result_sz[] = {9, 9, 10, 10, 10, 10, 10, 10,
76                                               10, 10};
77
78 static inline int
79 rta_math(struct program *program, uint64_t operand1,
80          uint32_t op, uint64_t operand2, uint32_t result,
81          int length, uint32_t options)
82 {
83         uint32_t opcode = CMD_MATH;
84         uint32_t val = 0;
85         int ret = -EINVAL;
86         unsigned int start_pc = program->current_pc;
87
88         if (((op == MATH_FUN_BSWAP) && (rta_sec_era < RTA_SEC_ERA_4)) ||
89             ((op == MATH_FUN_ZBYT) && (rta_sec_era < RTA_SEC_ERA_2))) {
90                 pr_err("MATH: operation not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
91                        USER_SEC_ERA(rta_sec_era), program->current_pc,
92                        program->current_instruction);
93                 goto err;
94         }
95
96         if (options & SWP) {
97                 if (rta_sec_era < RTA_SEC_ERA_7) {
98                         pr_err("MATH: operation not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
99                                USER_SEC_ERA(rta_sec_era), program->current_pc,
100                                program->current_instruction);
101                         goto err;
102                 }
103
104                 if ((options & IFB) ||
105                     (!(options & IMMED) && !(options & IMMED2)) ||
106                     ((options & IMMED) && (options & IMMED2))) {
107                         pr_err("MATH: SWP - invalid configuration. SEC PC: %d; Instr: %d\n",
108                                program->current_pc,
109                                program->current_instruction);
110                         goto err;
111                 }
112         }
113
114         /*
115          * SHLD operation is different from others and we
116          * assume that we can have _NONE as first operand
117          * or _SEQINSZ as second operand
118          */
119         if ((op != MATH_FUN_SHLD) && ((operand1 == NONE) ||
120                                       (operand2 == SEQINSZ))) {
121                 pr_err("MATH: Invalid operand. SEC PC: %d; Instr: %d\n",
122                        program->current_pc, program->current_instruction);
123                 goto err;
124         }
125
126         /*
127          * We first check if it is unary operation. In that
128          * case second operand must be _NONE
129          */
130         if (((op == MATH_FUN_ZBYT) || (op == MATH_FUN_BSWAP)) &&
131             (operand2 != NONE)) {
132                 pr_err("MATH: Invalid operand2. SEC PC: %d; Instr: %d\n",
133                        program->current_pc, program->current_instruction);
134                 goto err;
135         }
136
137         /* Write first operand field */
138         if (options & IMMED) {
139                 opcode |= MATH_SRC0_IMM;
140         } else {
141                 ret = __rta_map_opcode((uint32_t)operand1, math_op1,
142                                        math_op1_sz[rta_sec_era], &val);
143                 if (ret < 0) {
144                         pr_err("MATH: operand1 not supported. SEC PC: %d; Instr: %d\n",
145                                program->current_pc,
146                                program->current_instruction);
147                         goto err;
148                 }
149                 opcode |= val;
150         }
151
152         /* Write second operand field */
153         if (options & IMMED2) {
154                 opcode |= MATH_SRC1_IMM;
155         } else {
156                 ret = __rta_map_opcode((uint32_t)operand2, math_op2,
157                                        math_op2_sz[rta_sec_era], &val);
158                 if (ret < 0) {
159                         pr_err("MATH: operand2 not supported. SEC PC: %d; Instr: %d\n",
160                                program->current_pc,
161                                program->current_instruction);
162                         goto err;
163                 }
164                 opcode |= val;
165         }
166
167         /* Write result field */
168         ret = __rta_map_opcode(result, math_result, math_result_sz[rta_sec_era],
169                                &val);
170         if (ret < 0) {
171                 pr_err("MATH: result not supported. SEC PC: %d; Instr: %d\n",
172                        program->current_pc, program->current_instruction);
173                 goto err;
174         }
175         opcode |= val;
176
177         /*
178          * as we encode operations with their "real" values, we do not
179          * to translate but we do need to validate the value
180          */
181         switch (op) {
182         /*Binary operators */
183         case (MATH_FUN_ADD):
184         case (MATH_FUN_ADDC):
185         case (MATH_FUN_SUB):
186         case (MATH_FUN_SUBB):
187         case (MATH_FUN_OR):
188         case (MATH_FUN_AND):
189         case (MATH_FUN_XOR):
190         case (MATH_FUN_LSHIFT):
191         case (MATH_FUN_RSHIFT):
192         case (MATH_FUN_SHLD):
193         /* Unary operators */
194         case (MATH_FUN_ZBYT):
195         case (MATH_FUN_BSWAP):
196                 opcode |= op;
197                 break;
198         default:
199                 pr_err("MATH: operator is not supported. SEC PC: %d; Instr: %d\n",
200                        program->current_pc, program->current_instruction);
201                 ret = -EINVAL;
202                 goto err;
203         }
204
205         opcode |= (options & ~(IMMED | IMMED2));
206
207         /* Verify length */
208         switch (length) {
209         case (1):
210                 opcode |= MATH_LEN_1BYTE;
211                 break;
212         case (2):
213                 opcode |= MATH_LEN_2BYTE;
214                 break;
215         case (4):
216                 opcode |= MATH_LEN_4BYTE;
217                 break;
218         case (8):
219                 opcode |= MATH_LEN_8BYTE;
220                 break;
221         default:
222                 pr_err("MATH: length is not supported. SEC PC: %d; Instr: %d\n",
223                        program->current_pc, program->current_instruction);
224                 ret = -EINVAL;
225                 goto err;
226         }
227
228         __rta_out32(program, opcode);
229         program->current_instruction++;
230
231         /* Write immediate value */
232         if ((options & IMMED) && !(options & IMMED2)) {
233                 __rta_out64(program, (length > 4) && !(options & IFB),
234                             operand1);
235         } else if ((options & IMMED2) && !(options & IMMED)) {
236                 __rta_out64(program, (length > 4) && !(options & IFB),
237                             operand2);
238         } else if ((options & IMMED) && (options & IMMED2)) {
239                 __rta_out32(program, lower_32_bits(operand1));
240                 __rta_out32(program, lower_32_bits(operand2));
241         }
242
243         return (int)start_pc;
244
245  err:
246         program->first_error_pc = start_pc;
247         program->current_instruction++;
248         return ret;
249 }
250
251 static inline int
252 rta_mathi(struct program *program, uint64_t operand,
253           uint32_t op, uint8_t imm, uint32_t result,
254           int length, uint32_t options)
255 {
256         uint32_t opcode = CMD_MATHI;
257         uint32_t val = 0;
258         int ret = -EINVAL;
259         unsigned int start_pc = program->current_pc;
260
261         if (rta_sec_era < RTA_SEC_ERA_6) {
262                 pr_err("MATHI: Command not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
263                        USER_SEC_ERA(rta_sec_era), program->current_pc,
264                        program->current_instruction);
265                 goto err;
266         }
267
268         if (((op == MATH_FUN_FBYT) && (options & SSEL))) {
269                 pr_err("MATHI: Illegal combination - FBYT and SSEL. SEC PC: %d; Instr: %d\n",
270                        program->current_pc, program->current_instruction);
271                 goto err;
272         }
273
274         if ((options & SWP) && (rta_sec_era < RTA_SEC_ERA_7)) {
275                 pr_err("MATHI: SWP not supported by SEC Era %d. SEC PC: %d; Instr: %d\n",
276                        USER_SEC_ERA(rta_sec_era), program->current_pc,
277                        program->current_instruction);
278                 goto err;
279         }
280
281         /* Write first operand field */
282         if (!(options & SSEL))
283                 ret = __rta_map_opcode((uint32_t)operand, math_op1,
284                                        math_op1_sz[rta_sec_era], &val);
285         else
286                 ret = __rta_map_opcode((uint32_t)operand, math_op2,
287                                        math_op2_sz[rta_sec_era], &val);
288         if (ret < 0) {
289                 pr_err("MATHI: operand not supported. SEC PC: %d; Instr: %d\n",
290                        program->current_pc, program->current_instruction);
291                 goto err;
292         }
293
294         if (!(options & SSEL))
295                 opcode |= val;
296         else
297                 opcode |= (val << (MATHI_SRC1_SHIFT - MATH_SRC1_SHIFT));
298
299         /* Write second operand field */
300         opcode |= (imm << MATHI_IMM_SHIFT);
301
302         /* Write result field */
303         ret = __rta_map_opcode(result, math_result, math_result_sz[rta_sec_era],
304                                &val);
305         if (ret < 0) {
306                 pr_err("MATHI: result not supported. SEC PC: %d; Instr: %d\n",
307                        program->current_pc, program->current_instruction);
308                 goto err;
309         }
310         opcode |= (val << (MATHI_DEST_SHIFT - MATH_DEST_SHIFT));
311
312         /*
313          * as we encode operations with their "real" values, we do not have to
314          * translate but we do need to validate the value
315          */
316         switch (op) {
317         case (MATH_FUN_ADD):
318         case (MATH_FUN_ADDC):
319         case (MATH_FUN_SUB):
320         case (MATH_FUN_SUBB):
321         case (MATH_FUN_OR):
322         case (MATH_FUN_AND):
323         case (MATH_FUN_XOR):
324         case (MATH_FUN_LSHIFT):
325         case (MATH_FUN_RSHIFT):
326         case (MATH_FUN_FBYT):
327                 opcode |= op;
328                 break;
329         default:
330                 pr_err("MATHI: operator not supported. SEC PC: %d; Instr: %d\n",
331                        program->current_pc, program->current_instruction);
332                 ret = -EINVAL;
333                 goto err;
334         }
335
336         opcode |= options;
337
338         /* Verify length */
339         switch (length) {
340         case (1):
341                 opcode |= MATH_LEN_1BYTE;
342                 break;
343         case (2):
344                 opcode |= MATH_LEN_2BYTE;
345                 break;
346         case (4):
347                 opcode |= MATH_LEN_4BYTE;
348                 break;
349         case (8):
350                 opcode |= MATH_LEN_8BYTE;
351                 break;
352         default:
353                 pr_err("MATHI: length %d not supported. SEC PC: %d; Instr: %d\n",
354                        length, program->current_pc,
355                        program->current_instruction);
356                 ret = -EINVAL;
357                 goto err;
358         }
359
360         __rta_out32(program, opcode);
361         program->current_instruction++;
362
363         return (int)start_pc;
364
365  err:
366         program->first_error_pc = start_pc;
367         program->current_instruction++;
368         return ret;
369 }
370
371 #endif /* __RTA_MATH_CMD_H__ */