dc0a3342ab66cf07a94ce0985ac1c56b0824df9c
[deb_dpdk.git] / drivers / crypto / dpaa2_sec / hw / rta / fifo_load_store_cmd.h
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license. When using or
3  * redistributing this file, you may do so under either license.
4  *
5  *   BSD LICENSE
6  *
7  * Copyright 2008-2016 Freescale Semiconductor Inc.
8  * Copyright 2016 NXP.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * * Neither the name of the above-listed copyright holders nor the
18  * names of any contributors may be used to endorse or promote products
19  * derived from this software without specific prior written permission.
20  *
21  *   GPL LICENSE SUMMARY
22  *
23  * ALTERNATIVELY, this software may be distributed under the terms of the
24  * GNU General Public License ("GPL") as published by the Free Software
25  * Foundation, either version 2 of that License or (at your option) any
26  * later version.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40
41 #ifndef __RTA_FIFO_LOAD_STORE_CMD_H__
42 #define __RTA_FIFO_LOAD_STORE_CMD_H__
43
44 extern enum rta_sec_era rta_sec_era;
45
46 static const uint32_t fifo_load_table[][2] = {
47 /*1*/   { PKA0,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A0 },
48         { PKA1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A1 },
49         { PKA2,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A2 },
50         { PKA3,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A3 },
51         { PKB0,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B0 },
52         { PKB1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B1 },
53         { PKB2,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B2 },
54         { PKB3,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B3 },
55         { PKA,         FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A },
56         { PKB,         FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B },
57         { PKN,         FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_N },
58         { SKIP,        FIFOLD_CLASS_SKIP },
59         { MSG1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG },
60         { MSG2,        FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG },
61         { MSGOUTSNOOP, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG1OUT2 },
62         { MSGINSNOOP,  FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG },
63         { IV1,         FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_IV },
64         { IV2,         FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_IV },
65         { AAD1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_AAD },
66         { ICV1,        FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_ICV },
67         { ICV2,        FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_ICV },
68         { BIT_DATA,    FIFOLD_TYPE_BITDATA },
69 /*23*/  { IFIFO,       FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_NOINFOFIFO }
70 };
71
72 /*
73  * Allowed FIFO_LOAD input data types for each SEC Era.
74  * Values represent the number of entries from fifo_load_table[] that are
75  * supported.
76  */
77 static const unsigned int fifo_load_table_sz[] = {22, 22, 23, 23,
78                                                   23, 23, 23, 23};
79
80 static inline int
81 rta_fifo_load(struct program *program, uint32_t src,
82               uint64_t loc, uint32_t length, uint32_t flags)
83 {
84         uint32_t opcode = 0;
85         uint32_t ext_length = 0, val = 0;
86         int ret = -EINVAL;
87         bool is_seq_cmd = false;
88         unsigned int start_pc = program->current_pc;
89
90         /* write command type field */
91         if (flags & SEQ) {
92                 opcode = CMD_SEQ_FIFO_LOAD;
93                 is_seq_cmd = true;
94         } else {
95                 opcode = CMD_FIFO_LOAD;
96         }
97
98         /* Parameters checking */
99         if (is_seq_cmd) {
100                 if ((flags & IMMED) || (flags & SGF)) {
101                         pr_err("SEQ FIFO LOAD: Invalid command\n");
102                         goto err;
103                 }
104                 if ((rta_sec_era <= RTA_SEC_ERA_5) && (flags & AIDF)) {
105                         pr_err("SEQ FIFO LOAD: Flag(s) not supported by SEC Era %d\n",
106                                USER_SEC_ERA(rta_sec_era));
107                         goto err;
108                 }
109                 if ((flags & VLF) && ((flags & EXT) || (length >> 16))) {
110                         pr_err("SEQ FIFO LOAD: Invalid usage of VLF\n");
111                         goto err;
112                 }
113         } else {
114                 if (src == SKIP) {
115                         pr_err("FIFO LOAD: Invalid src\n");
116                         goto err;
117                 }
118                 if ((flags & AIDF) || (flags & VLF)) {
119                         pr_err("FIFO LOAD: Invalid command\n");
120                         goto err;
121                 }
122                 if ((flags & IMMED) && (flags & SGF)) {
123                         pr_err("FIFO LOAD: Invalid usage of SGF and IMM\n");
124                         goto err;
125                 }
126                 if ((flags & IMMED) && ((flags & EXT) || (length >> 16))) {
127                         pr_err("FIFO LOAD: Invalid usage of EXT and IMM\n");
128                         goto err;
129                 }
130         }
131
132         /* write input data type field */
133         ret = __rta_map_opcode(src, fifo_load_table,
134                                fifo_load_table_sz[rta_sec_era], &val);
135         if (ret < 0) {
136                 pr_err("FIFO LOAD: Source value is not supported. SEC Program Line: %d\n",
137                        program->current_pc);
138                 goto err;
139         }
140         opcode |= val;
141
142         if (flags & CLASS1)
143                 opcode |= FIFOLD_CLASS_CLASS1;
144         if (flags & CLASS2)
145                 opcode |= FIFOLD_CLASS_CLASS2;
146         if (flags & BOTH)
147                 opcode |= FIFOLD_CLASS_BOTH;
148
149         /* write fields: SGF|VLF, IMM, [LC1, LC2, F1] */
150         if (flags & FLUSH1)
151                 opcode |= FIFOLD_TYPE_FLUSH1;
152         if (flags & LAST1)
153                 opcode |= FIFOLD_TYPE_LAST1;
154         if (flags & LAST2)
155                 opcode |= FIFOLD_TYPE_LAST2;
156         if (!is_seq_cmd) {
157                 if (flags & SGF)
158                         opcode |= FIFOLDST_SGF;
159                 if (flags & IMMED)
160                         opcode |= FIFOLD_IMM;
161         } else {
162                 if (flags & VLF)
163                         opcode |= FIFOLDST_VLF;
164                 if (flags & AIDF)
165                         opcode |= FIFOLD_AIDF;
166         }
167
168         /*
169          * Verify if extended length is required. In case of BITDATA, calculate
170          * number of full bytes and additional valid bits.
171          */
172         if ((flags & EXT) || (length >> 16)) {
173                 opcode |= FIFOLDST_EXT;
174                 if (src == BIT_DATA) {
175                         ext_length = (length / 8);
176                         length = (length % 8);
177                 } else {
178                         ext_length = length;
179                         length = 0;
180                 }
181         }
182         opcode |= (uint16_t) length;
183
184         __rta_out32(program, opcode);
185         program->current_instruction++;
186
187         /* write pointer or immediate data field */
188         if (flags & IMMED)
189                 __rta_inline_data(program, loc, flags & __COPY_MASK, length);
190         else if (!is_seq_cmd)
191                 __rta_out64(program, program->ps, loc);
192
193         /* write extended length field */
194         if (opcode & FIFOLDST_EXT)
195                 __rta_out32(program, ext_length);
196
197         return (int)start_pc;
198
199  err:
200         program->first_error_pc = start_pc;
201         program->current_instruction++;
202         return ret;
203 }
204
205 static const uint32_t fifo_store_table[][2] = {
206 /*1*/   { PKA0,      FIFOST_TYPE_PKHA_A0 },
207         { PKA1,      FIFOST_TYPE_PKHA_A1 },
208         { PKA2,      FIFOST_TYPE_PKHA_A2 },
209         { PKA3,      FIFOST_TYPE_PKHA_A3 },
210         { PKB0,      FIFOST_TYPE_PKHA_B0 },
211         { PKB1,      FIFOST_TYPE_PKHA_B1 },
212         { PKB2,      FIFOST_TYPE_PKHA_B2 },
213         { PKB3,      FIFOST_TYPE_PKHA_B3 },
214         { PKA,       FIFOST_TYPE_PKHA_A },
215         { PKB,       FIFOST_TYPE_PKHA_B },
216         { PKN,       FIFOST_TYPE_PKHA_N },
217         { PKE,       FIFOST_TYPE_PKHA_E_JKEK },
218         { RNG,       FIFOST_TYPE_RNGSTORE },
219         { RNGOFIFO,  FIFOST_TYPE_RNGFIFO },
220         { AFHA_SBOX, FIFOST_TYPE_AF_SBOX_JKEK },
221         { MDHA_SPLIT_KEY, FIFOST_CLASS_CLASS2KEY | FIFOST_TYPE_SPLIT_KEK },
222         { MSG,       FIFOST_TYPE_MESSAGE_DATA },
223         { KEY1,      FIFOST_CLASS_CLASS1KEY | FIFOST_TYPE_KEY_KEK },
224         { KEY2,      FIFOST_CLASS_CLASS2KEY | FIFOST_TYPE_KEY_KEK },
225         { OFIFO,     FIFOST_TYPE_OUTFIFO_KEK},
226         { SKIP,      FIFOST_TYPE_SKIP },
227 /*22*/  { METADATA,  FIFOST_TYPE_METADATA},
228         { MSG_CKSUM,  FIFOST_TYPE_MESSAGE_DATA2 }
229 };
230
231 /*
232  * Allowed FIFO_STORE output data types for each SEC Era.
233  * Values represent the number of entries from fifo_store_table[] that are
234  * supported.
235  */
236 static const unsigned int fifo_store_table_sz[] = {21, 21, 21, 21,
237                                                    22, 22, 22, 23};
238
239 static inline int
240 rta_fifo_store(struct program *program, uint32_t src,
241                uint32_t encrypt_flags, uint64_t dst,
242                uint32_t length, uint32_t flags)
243 {
244         uint32_t opcode = 0;
245         uint32_t val = 0;
246         int ret = -EINVAL;
247         bool is_seq_cmd = false;
248         unsigned int start_pc = program->current_pc;
249
250         /* write command type field */
251         if (flags & SEQ) {
252                 opcode = CMD_SEQ_FIFO_STORE;
253                 is_seq_cmd = true;
254         } else {
255                 opcode = CMD_FIFO_STORE;
256         }
257
258         /* Parameter checking */
259         if (is_seq_cmd) {
260                 if ((flags & VLF) && ((length >> 16) || (flags & EXT))) {
261                         pr_err("SEQ FIFO STORE: Invalid usage of VLF\n");
262                         goto err;
263                 }
264                 if (dst) {
265                         pr_err("SEQ FIFO STORE: Invalid command\n");
266                         goto err;
267                 }
268                 if ((src == METADATA) && (flags & (CONT | EXT))) {
269                         pr_err("SEQ FIFO STORE: Invalid flags\n");
270                         goto err;
271                 }
272         } else {
273                 if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) ||
274                     (src == METADATA)) {
275                         pr_err("FIFO STORE: Invalid destination\n");
276                         goto err;
277                 }
278         }
279         if ((rta_sec_era == RTA_SEC_ERA_7) && (src == AFHA_SBOX)) {
280                 pr_err("FIFO STORE: AFHA S-box not supported by SEC Era %d\n",
281                        USER_SEC_ERA(rta_sec_era));
282                 goto err;
283         }
284
285         /* write output data type field */
286         ret = __rta_map_opcode(src, fifo_store_table,
287                                fifo_store_table_sz[rta_sec_era], &val);
288         if (ret < 0) {
289                 pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n",
290                        program->current_pc);
291                 goto err;
292         }
293         opcode |= val;
294
295         if (encrypt_flags & TK)
296                 opcode |= (0x1 << FIFOST_TYPE_SHIFT);
297         if (encrypt_flags & EKT) {
298                 if (rta_sec_era == RTA_SEC_ERA_1) {
299                         pr_err("FIFO STORE: AES-CCM source types not supported\n");
300                         ret = -EINVAL;
301                         goto err;
302                 }
303                 opcode |= (0x10 << FIFOST_TYPE_SHIFT);
304                 opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT);
305         }
306
307         /* write flags fields */
308         if (flags & CONT)
309                 opcode |= FIFOST_CONT;
310         if ((flags & VLF) && (is_seq_cmd))
311                 opcode |= FIFOLDST_VLF;
312         if ((flags & SGF) && (!is_seq_cmd))
313                 opcode |= FIFOLDST_SGF;
314         if (flags & CLASS1)
315                 opcode |= FIFOST_CLASS_CLASS1KEY;
316         if (flags & CLASS2)
317                 opcode |= FIFOST_CLASS_CLASS2KEY;
318         if (flags & BOTH)
319                 opcode |= FIFOST_CLASS_BOTH;
320
321         /* Verify if extended length is required */
322         if ((length >> 16) || (flags & EXT))
323                 opcode |= FIFOLDST_EXT;
324         else
325                 opcode |= (uint16_t) length;
326
327         __rta_out32(program, opcode);
328         program->current_instruction++;
329
330         /* write pointer field */
331         if ((!is_seq_cmd) && (dst))
332                 __rta_out64(program, program->ps, dst);
333
334         /* write extended length field */
335         if (opcode & FIFOLDST_EXT)
336                 __rta_out32(program, length);
337
338         return (int)start_pc;
339
340  err:
341         program->first_error_pc = start_pc;
342         program->current_instruction++;
343         return ret;
344 }
345
346 #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */