1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
4 * Copyright 2016,2019 NXP
7 #ifndef __RTA_FIFO_LOAD_STORE_CMD_H__
8 #define __RTA_FIFO_LOAD_STORE_CMD_H__
10 extern enum rta_sec_era rta_sec_era;
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 }
39 * Allowed FIFO_LOAD input data types for each SEC Era.
40 * Values represent the number of entries from fifo_load_table[] that are
43 static const unsigned int fifo_load_table_sz[] = {22, 22, 23, 23,
48 rta_fifo_load(struct program *program, uint32_t src,
49 uint64_t loc, uint32_t length, uint32_t flags)
52 uint32_t ext_length = 0, val = 0;
54 bool is_seq_cmd = false;
55 unsigned int start_pc = program->current_pc;
57 /* write command type field */
59 opcode = CMD_SEQ_FIFO_LOAD;
62 opcode = CMD_FIFO_LOAD;
65 /* Parameters checking */
67 if ((flags & IMMED) || (flags & SGF)) {
68 pr_err("SEQ FIFO LOAD: Invalid command\n");
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));
76 if ((flags & VLF) && ((flags & EXT) || (length >> 16))) {
77 pr_err("SEQ FIFO LOAD: Invalid usage of VLF\n");
82 pr_err("FIFO LOAD: Invalid src\n");
85 if ((flags & AIDF) || (flags & VLF)) {
86 pr_err("FIFO LOAD: Invalid command\n");
89 if ((flags & IMMED) && (flags & SGF)) {
90 pr_err("FIFO LOAD: Invalid usage of SGF and IMM\n");
93 if ((flags & IMMED) && ((flags & EXT) || (length >> 16))) {
94 pr_err("FIFO LOAD: Invalid usage of EXT and IMM\n");
99 /* write input data type field */
100 ret = __rta_map_opcode(src, fifo_load_table,
101 fifo_load_table_sz[rta_sec_era], &val);
103 pr_err("FIFO LOAD: Source value is not supported. SEC Program Line: %d\n",
104 program->current_pc);
110 opcode |= FIFOLD_CLASS_CLASS1;
112 opcode |= FIFOLD_CLASS_CLASS2;
114 opcode |= FIFOLD_CLASS_BOTH;
116 /* write fields: SGF|VLF, IMM, [LC1, LC2, F1] */
118 opcode |= FIFOLD_TYPE_FLUSH1;
120 opcode |= FIFOLD_TYPE_LAST1;
122 opcode |= FIFOLD_TYPE_LAST2;
125 opcode |= FIFOLDST_SGF;
127 opcode |= FIFOLD_IMM;
130 opcode |= FIFOLDST_VLF;
132 opcode |= FIFOLD_AIDF;
136 * Verify if extended length is required. In case of BITDATA, calculate
137 * number of full bytes and additional valid bits.
139 if ((flags & EXT) || (length >> 16)) {
140 opcode |= FIFOLDST_EXT;
141 if (src == BIT_DATA) {
142 ext_length = (length / 8);
143 length = (length % 8);
149 opcode |= (uint16_t) length;
151 __rta_out32(program, opcode);
152 program->current_instruction++;
154 /* write pointer or immediate data field */
156 __rta_inline_data(program, loc, flags & __COPY_MASK, length);
157 else if (!is_seq_cmd)
158 __rta_out64(program, program->ps, loc);
160 /* write extended length field */
161 if (opcode & FIFOLDST_EXT)
162 __rta_out32(program, ext_length);
164 return (int)start_pc;
167 program->first_error_pc = start_pc;
168 program->current_instruction++;
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 }
199 * Allowed FIFO_STORE output data types for each SEC Era.
200 * Values represent the number of entries from fifo_store_table[] that are
203 static const unsigned int fifo_store_table_sz[] = {21, 21, 21, 21,
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)
215 bool is_seq_cmd = false;
216 unsigned int start_pc = program->current_pc;
218 /* write command type field */
220 opcode = CMD_SEQ_FIFO_STORE;
223 opcode = CMD_FIFO_STORE;
226 /* Parameter checking */
228 if ((flags & VLF) && ((length >> 16) || (flags & EXT))) {
229 pr_err("SEQ FIFO STORE: Invalid usage of VLF\n");
233 pr_err("SEQ FIFO STORE: Invalid command\n");
236 if ((src == METADATA) && (flags & (CONT | EXT))) {
237 pr_err("SEQ FIFO STORE: Invalid flags\n");
241 if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) ||
243 pr_err("FIFO STORE: Invalid destination\n");
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));
253 /* write output data type field */
254 ret = __rta_map_opcode(src, fifo_store_table,
255 fifo_store_table_sz[rta_sec_era], &val);
257 pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n",
258 program->current_pc);
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");
271 opcode |= (0x10 << FIFOST_TYPE_SHIFT);
272 opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT);
275 /* write flags fields */
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;
283 opcode |= FIFOST_CLASS_CLASS1KEY;
285 opcode |= FIFOST_CLASS_CLASS2KEY;
287 opcode |= FIFOST_CLASS_BOTH;
289 /* Verify if extended length is required */
290 if ((length >> 16) || (flags & EXT))
291 opcode |= FIFOLDST_EXT;
293 opcode |= (uint16_t) length;
295 __rta_out32(program, opcode);
296 program->current_instruction++;
298 /* write pointer field */
299 if ((!is_seq_cmd) && (dst))
300 __rta_out64(program, program->ps, dst);
302 /* write extended length field */
303 if (opcode & FIFOLDST_EXT)
304 __rta_out32(program, length);
306 return (int)start_pc;
309 program->first_error_pc = start_pc;
310 program->current_instruction++;
314 #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */