1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
8 #ifndef __RTA_FIFO_LOAD_STORE_CMD_H__
9 #define __RTA_FIFO_LOAD_STORE_CMD_H__
11 extern enum rta_sec_era rta_sec_era;
13 static const uint32_t fifo_load_table[][2] = {
14 /*1*/ { PKA0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A0 },
15 { PKA1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A1 },
16 { PKA2, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A2 },
17 { PKA3, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A3 },
18 { PKB0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B0 },
19 { PKB1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B1 },
20 { PKB2, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B2 },
21 { PKB3, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B3 },
22 { PKA, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_A },
23 { PKB, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_B },
24 { PKN, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_PK_N },
25 { SKIP, FIFOLD_CLASS_SKIP },
26 { MSG1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG },
27 { MSG2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG },
28 { MSGOUTSNOOP, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG1OUT2 },
29 { MSGINSNOOP, FIFOLD_CLASS_BOTH | FIFOLD_TYPE_MSG },
30 { IV1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_IV },
31 { IV2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_IV },
32 { AAD1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_AAD },
33 { ICV1, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_ICV },
34 { ICV2, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_ICV },
35 { BIT_DATA, FIFOLD_TYPE_BITDATA },
36 /*23*/ { IFIFO, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_NOINFOFIFO }
40 * Allowed FIFO_LOAD input data types for each SEC Era.
41 * Values represent the number of entries from fifo_load_table[] that are
44 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,
207 rta_fifo_store(struct program *program, uint32_t src,
208 uint32_t encrypt_flags, uint64_t dst,
209 uint32_t length, uint32_t flags)
214 bool is_seq_cmd = false;
215 unsigned int start_pc = program->current_pc;
217 /* write command type field */
219 opcode = CMD_SEQ_FIFO_STORE;
222 opcode = CMD_FIFO_STORE;
225 /* Parameter checking */
227 if ((flags & VLF) && ((length >> 16) || (flags & EXT))) {
228 pr_err("SEQ FIFO STORE: Invalid usage of VLF\n");
232 pr_err("SEQ FIFO STORE: Invalid command\n");
235 if ((src == METADATA) && (flags & (CONT | EXT))) {
236 pr_err("SEQ FIFO STORE: Invalid flags\n");
240 if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) ||
242 pr_err("FIFO STORE: Invalid destination\n");
246 if ((rta_sec_era == RTA_SEC_ERA_7) && (src == AFHA_SBOX)) {
247 pr_err("FIFO STORE: AFHA S-box not supported by SEC Era %d\n",
248 USER_SEC_ERA(rta_sec_era));
252 /* write output data type field */
253 ret = __rta_map_opcode(src, fifo_store_table,
254 fifo_store_table_sz[rta_sec_era], &val);
256 pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n",
257 program->current_pc);
262 if (encrypt_flags & TK)
263 opcode |= (0x1 << FIFOST_TYPE_SHIFT);
264 if (encrypt_flags & EKT) {
265 if (rta_sec_era == RTA_SEC_ERA_1) {
266 pr_err("FIFO STORE: AES-CCM source types not supported\n");
270 opcode |= (0x10 << FIFOST_TYPE_SHIFT);
271 opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT);
274 /* write flags fields */
276 opcode |= FIFOST_CONT;
277 if ((flags & VLF) && (is_seq_cmd))
278 opcode |= FIFOLDST_VLF;
279 if ((flags & SGF) && (!is_seq_cmd))
280 opcode |= FIFOLDST_SGF;
282 opcode |= FIFOST_CLASS_CLASS1KEY;
284 opcode |= FIFOST_CLASS_CLASS2KEY;
286 opcode |= FIFOST_CLASS_BOTH;
288 /* Verify if extended length is required */
289 if ((length >> 16) || (flags & EXT))
290 opcode |= FIFOLDST_EXT;
292 opcode |= (uint16_t) length;
294 __rta_out32(program, opcode);
295 program->current_instruction++;
297 /* write pointer field */
298 if ((!is_seq_cmd) && (dst))
299 __rta_out64(program, program->ps, dst);
301 /* write extended length field */
302 if (opcode & FIFOLDST_EXT)
303 __rta_out32(program, length);
305 return (int)start_pc;
308 program->first_error_pc = start_pc;
309 program->current_instruction++;
313 #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */