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