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.
7 * Copyright 2008-2016 Freescale Semiconductor Inc.
8 * Copyright (c) 2016 NXP.
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.
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
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.
41 #ifndef __RTA_FIFO_LOAD_STORE_CMD_H__
42 #define __RTA_FIFO_LOAD_STORE_CMD_H__
44 extern enum rta_sec_era rta_sec_era;
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 }
73 * Allowed FIFO_LOAD input data types for each SEC Era.
74 * Values represent the number of entries from fifo_load_table[] that are
77 static const unsigned int fifo_load_table_sz[] = {22, 22, 23, 23,
81 rta_fifo_load(struct program *program, uint32_t src,
82 uint64_t loc, uint32_t length, uint32_t flags)
85 uint32_t ext_length = 0, val = 0;
87 bool is_seq_cmd = false;
88 unsigned int start_pc = program->current_pc;
90 /* write command type field */
92 opcode = CMD_SEQ_FIFO_LOAD;
95 opcode = CMD_FIFO_LOAD;
98 /* Parameters checking */
100 if ((flags & IMMED) || (flags & SGF)) {
101 pr_err("SEQ FIFO LOAD: Invalid command\n");
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));
109 if ((flags & VLF) && ((flags & EXT) || (length >> 16))) {
110 pr_err("SEQ FIFO LOAD: Invalid usage of VLF\n");
115 pr_err("FIFO LOAD: Invalid src\n");
118 if ((flags & AIDF) || (flags & VLF)) {
119 pr_err("FIFO LOAD: Invalid command\n");
122 if ((flags & IMMED) && (flags & SGF)) {
123 pr_err("FIFO LOAD: Invalid usage of SGF and IMM\n");
126 if ((flags & IMMED) && ((flags & EXT) || (length >> 16))) {
127 pr_err("FIFO LOAD: Invalid usage of EXT and IMM\n");
132 /* write input data type field */
133 ret = __rta_map_opcode(src, fifo_load_table,
134 fifo_load_table_sz[rta_sec_era], &val);
136 pr_err("FIFO LOAD: Source value is not supported. SEC Program Line: %d\n",
137 program->current_pc);
143 opcode |= FIFOLD_CLASS_CLASS1;
145 opcode |= FIFOLD_CLASS_CLASS2;
147 opcode |= FIFOLD_CLASS_BOTH;
149 /* write fields: SGF|VLF, IMM, [LC1, LC2, F1] */
151 opcode |= FIFOLD_TYPE_FLUSH1;
153 opcode |= FIFOLD_TYPE_LAST1;
155 opcode |= FIFOLD_TYPE_LAST2;
158 opcode |= FIFOLDST_SGF;
160 opcode |= FIFOLD_IMM;
163 opcode |= FIFOLDST_VLF;
165 opcode |= FIFOLD_AIDF;
169 * Verify if extended length is required. In case of BITDATA, calculate
170 * number of full bytes and additional valid bits.
172 if ((flags & EXT) || (length >> 16)) {
173 opcode |= FIFOLDST_EXT;
174 if (src == BIT_DATA) {
175 ext_length = (length / 8);
176 length = (length % 8);
182 opcode |= (uint16_t) length;
184 __rta_out32(program, opcode);
185 program->current_instruction++;
187 /* write pointer or immediate data field */
189 __rta_inline_data(program, loc, flags & __COPY_MASK, length);
190 else if (!is_seq_cmd)
191 __rta_out64(program, program->ps, loc);
193 /* write extended length field */
194 if (opcode & FIFOLDST_EXT)
195 __rta_out32(program, ext_length);
197 return (int)start_pc;
200 program->first_error_pc = start_pc;
201 program->current_instruction++;
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 }
232 * Allowed FIFO_STORE output data types for each SEC Era.
233 * Values represent the number of entries from fifo_store_table[] that are
236 static const unsigned int fifo_store_table_sz[] = {21, 21, 21, 21,
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)
247 bool is_seq_cmd = false;
248 unsigned int start_pc = program->current_pc;
250 /* write command type field */
252 opcode = CMD_SEQ_FIFO_STORE;
255 opcode = CMD_FIFO_STORE;
258 /* Parameter checking */
260 if ((flags & VLF) && ((length >> 16) || (flags & EXT))) {
261 pr_err("SEQ FIFO STORE: Invalid usage of VLF\n");
265 pr_err("SEQ FIFO STORE: Invalid command\n");
268 if ((src == METADATA) && (flags & (CONT | EXT))) {
269 pr_err("SEQ FIFO STORE: Invalid flags\n");
273 if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) ||
275 pr_err("FIFO STORE: Invalid destination\n");
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));
285 /* write output data type field */
286 ret = __rta_map_opcode(src, fifo_store_table,
287 fifo_store_table_sz[rta_sec_era], &val);
289 pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n",
290 program->current_pc);
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");
303 opcode |= (0x10 << FIFOST_TYPE_SHIFT);
304 opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT);
307 /* write flags fields */
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;
315 opcode |= FIFOST_CLASS_CLASS1KEY;
317 opcode |= FIFOST_CLASS_CLASS2KEY;
319 opcode |= FIFOST_CLASS_BOTH;
321 /* Verify if extended length is required */
322 if ((length >> 16) || (flags & EXT))
323 opcode |= FIFOLDST_EXT;
325 opcode |= (uint16_t) length;
327 __rta_out32(program, opcode);
328 program->current_instruction++;
330 /* write pointer field */
331 if ((!is_seq_cmd) && (dst))
332 __rta_out64(program, program->ps, dst);
334 /* write extended length field */
335 if (opcode & FIFOLDST_EXT)
336 __rta_out32(program, length);
338 return (int)start_pc;
341 program->first_error_pc = start_pc;
342 program->current_instruction++;
346 #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */