2 * Copyright 2008-2016 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: BSD-3-Clause or GPL-2.0+
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,
47 rta_fifo_load(struct program *program, uint32_t src,
48 uint64_t loc, uint32_t length, uint32_t flags)
51 uint32_t ext_length = 0, val = 0;
53 bool is_seq_cmd = false;
54 unsigned int start_pc = program->current_pc;
56 /* write command type field */
58 opcode = CMD_SEQ_FIFO_LOAD;
61 opcode = CMD_FIFO_LOAD;
64 /* Parameters checking */
66 if ((flags & IMMED) || (flags & SGF)) {
67 pr_err("SEQ FIFO LOAD: Invalid command\n");
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));
75 if ((flags & VLF) && ((flags & EXT) || (length >> 16))) {
76 pr_err("SEQ FIFO LOAD: Invalid usage of VLF\n");
81 pr_err("FIFO LOAD: Invalid src\n");
84 if ((flags & AIDF) || (flags & VLF)) {
85 pr_err("FIFO LOAD: Invalid command\n");
88 if ((flags & IMMED) && (flags & SGF)) {
89 pr_err("FIFO LOAD: Invalid usage of SGF and IMM\n");
92 if ((flags & IMMED) && ((flags & EXT) || (length >> 16))) {
93 pr_err("FIFO LOAD: Invalid usage of EXT and IMM\n");
98 /* write input data type field */
99 ret = __rta_map_opcode(src, fifo_load_table,
100 fifo_load_table_sz[rta_sec_era], &val);
102 pr_err("FIFO LOAD: Source value is not supported. SEC Program Line: %d\n",
103 program->current_pc);
109 opcode |= FIFOLD_CLASS_CLASS1;
111 opcode |= FIFOLD_CLASS_CLASS2;
113 opcode |= FIFOLD_CLASS_BOTH;
115 /* write fields: SGF|VLF, IMM, [LC1, LC2, F1] */
117 opcode |= FIFOLD_TYPE_FLUSH1;
119 opcode |= FIFOLD_TYPE_LAST1;
121 opcode |= FIFOLD_TYPE_LAST2;
124 opcode |= FIFOLDST_SGF;
126 opcode |= FIFOLD_IMM;
129 opcode |= FIFOLDST_VLF;
131 opcode |= FIFOLD_AIDF;
135 * Verify if extended length is required. In case of BITDATA, calculate
136 * number of full bytes and additional valid bits.
138 if ((flags & EXT) || (length >> 16)) {
139 opcode |= FIFOLDST_EXT;
140 if (src == BIT_DATA) {
141 ext_length = (length / 8);
142 length = (length % 8);
148 opcode |= (uint16_t) length;
150 __rta_out32(program, opcode);
151 program->current_instruction++;
153 /* write pointer or immediate data field */
155 __rta_inline_data(program, loc, flags & __COPY_MASK, length);
156 else if (!is_seq_cmd)
157 __rta_out64(program, program->ps, loc);
159 /* write extended length field */
160 if (opcode & FIFOLDST_EXT)
161 __rta_out32(program, ext_length);
163 return (int)start_pc;
166 program->first_error_pc = start_pc;
167 program->current_instruction++;
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 }
198 * Allowed FIFO_STORE output data types for each SEC Era.
199 * Values represent the number of entries from fifo_store_table[] that are
202 static const unsigned int fifo_store_table_sz[] = {21, 21, 21, 21,
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)
213 bool is_seq_cmd = false;
214 unsigned int start_pc = program->current_pc;
216 /* write command type field */
218 opcode = CMD_SEQ_FIFO_STORE;
221 opcode = CMD_FIFO_STORE;
224 /* Parameter checking */
226 if ((flags & VLF) && ((length >> 16) || (flags & EXT))) {
227 pr_err("SEQ FIFO STORE: Invalid usage of VLF\n");
231 pr_err("SEQ FIFO STORE: Invalid command\n");
234 if ((src == METADATA) && (flags & (CONT | EXT))) {
235 pr_err("SEQ FIFO STORE: Invalid flags\n");
239 if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) ||
241 pr_err("FIFO STORE: Invalid destination\n");
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));
251 /* write output data type field */
252 ret = __rta_map_opcode(src, fifo_store_table,
253 fifo_store_table_sz[rta_sec_era], &val);
255 pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n",
256 program->current_pc);
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");
269 opcode |= (0x10 << FIFOST_TYPE_SHIFT);
270 opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT);
273 /* write flags fields */
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;
281 opcode |= FIFOST_CLASS_CLASS1KEY;
283 opcode |= FIFOST_CLASS_CLASS2KEY;
285 opcode |= FIFOST_CLASS_BOTH;
287 /* Verify if extended length is required */
288 if ((length >> 16) || (flags & EXT))
289 opcode |= FIFOLDST_EXT;
291 opcode |= (uint16_t) length;
293 __rta_out32(program, opcode);
294 program->current_instruction++;
296 /* write pointer field */
297 if ((!is_seq_cmd) && (dst))
298 __rta_out64(program, program->ps, dst);
300 /* write extended length field */
301 if (opcode & FIFOLDST_EXT)
302 __rta_out32(program, length);
304 return (int)start_pc;
307 program->first_error_pc = start_pc;
308 program->current_instruction++;
312 #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */