xref: /dpdk/drivers/common/dpaax/caamflib/rta/fifo_load_store_cmd.h (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016,2019 NXP
5  */
6 
7 #ifndef __RTA_FIFO_LOAD_STORE_CMD_H__
8 #define __RTA_FIFO_LOAD_STORE_CMD_H__
9 
10 extern enum rta_sec_era rta_sec_era;
11 
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 }
36 };
37 
38 /*
39  * Allowed FIFO_LOAD input data types for each SEC Era.
40  * Values represent the number of entries from fifo_load_table[] that are
41  * supported.
42  */
43 static const unsigned int fifo_load_table_sz[] = {22, 22, 23, 23,
44 						  23, 23, 23, 23,
45 						  23, 23};
46 
47 static inline int
48 rta_fifo_load(struct program *program, uint32_t src,
49 	      uint64_t loc, uint32_t length, uint32_t flags)
50 {
51 	uint32_t opcode = 0;
52 	uint32_t ext_length = 0, val = 0;
53 	int ret = -EINVAL;
54 	bool is_seq_cmd = false;
55 	unsigned int start_pc = program->current_pc;
56 
57 	/* write command type field */
58 	if (flags & SEQ) {
59 		opcode = CMD_SEQ_FIFO_LOAD;
60 		is_seq_cmd = true;
61 	} else {
62 		opcode = CMD_FIFO_LOAD;
63 	}
64 
65 	/* Parameters checking */
66 	if (is_seq_cmd) {
67 		if ((flags & IMMED) || (flags & SGF)) {
68 			pr_err("SEQ FIFO LOAD: Invalid command\n");
69 			goto err;
70 		}
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));
74 			goto err;
75 		}
76 		if ((flags & VLF) && ((flags & EXT) || (length >> 16))) {
77 			pr_err("SEQ FIFO LOAD: Invalid usage of VLF\n");
78 			goto err;
79 		}
80 	} else {
81 		if (src == SKIP) {
82 			pr_err("FIFO LOAD: Invalid src\n");
83 			goto err;
84 		}
85 		if ((flags & AIDF) || (flags & VLF)) {
86 			pr_err("FIFO LOAD: Invalid command\n");
87 			goto err;
88 		}
89 		if ((flags & IMMED) && (flags & SGF)) {
90 			pr_err("FIFO LOAD: Invalid usage of SGF and IMM\n");
91 			goto err;
92 		}
93 		if ((flags & IMMED) && ((flags & EXT) || (length >> 16))) {
94 			pr_err("FIFO LOAD: Invalid usage of EXT and IMM\n");
95 			goto err;
96 		}
97 	}
98 
99 	/* write input data type field */
100 	ret = __rta_map_opcode(src, fifo_load_table,
101 			       fifo_load_table_sz[rta_sec_era], &val);
102 	if (ret < 0) {
103 		pr_err("FIFO LOAD: Source value is not supported. SEC Program Line: %d\n",
104 		       program->current_pc);
105 		goto err;
106 	}
107 	opcode |= val;
108 
109 	if (flags & CLASS1)
110 		opcode |= FIFOLD_CLASS_CLASS1;
111 	if (flags & CLASS2)
112 		opcode |= FIFOLD_CLASS_CLASS2;
113 	if (flags & BOTH)
114 		opcode |= FIFOLD_CLASS_BOTH;
115 
116 	/* write fields: SGF|VLF, IMM, [LC1, LC2, F1] */
117 	if (flags & FLUSH1)
118 		opcode |= FIFOLD_TYPE_FLUSH1;
119 	if (flags & LAST1)
120 		opcode |= FIFOLD_TYPE_LAST1;
121 	if (flags & LAST2)
122 		opcode |= FIFOLD_TYPE_LAST2;
123 	if (!is_seq_cmd) {
124 		if (flags & SGF)
125 			opcode |= FIFOLDST_SGF;
126 		if (flags & IMMED)
127 			opcode |= FIFOLD_IMM;
128 	} else {
129 		if (flags & VLF)
130 			opcode |= FIFOLDST_VLF;
131 		if (flags & AIDF)
132 			opcode |= FIFOLD_AIDF;
133 	}
134 
135 	/*
136 	 * Verify if extended length is required. In case of BITDATA, calculate
137 	 * number of full bytes and additional valid bits.
138 	 */
139 	if ((flags & EXT) || (length >> 16)) {
140 		opcode |= FIFOLDST_EXT;
141 		if (src == BIT_DATA) {
142 			ext_length = (length / 8);
143 			length = (length % 8);
144 		} else {
145 			ext_length = length;
146 			length = 0;
147 		}
148 	}
149 	opcode |= (uint16_t) length;
150 
151 	__rta_out32(program, opcode);
152 	program->current_instruction++;
153 
154 	/* write pointer or immediate data field */
155 	if (flags & IMMED)
156 		__rta_inline_data(program, loc, flags & __COPY_MASK, length);
157 	else if (!is_seq_cmd)
158 		__rta_out64(program, program->ps, loc);
159 
160 	/* write extended length field */
161 	if (opcode & FIFOLDST_EXT)
162 		__rta_out32(program, ext_length);
163 
164 	return (int)start_pc;
165 
166  err:
167 	program->first_error_pc = start_pc;
168 	program->current_instruction++;
169 	return ret;
170 }
171 
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 }
196 };
197 
198 /*
199  * Allowed FIFO_STORE output data types for each SEC Era.
200  * Values represent the number of entries from fifo_store_table[] that are
201  * supported.
202  */
203 static const unsigned int fifo_store_table_sz[] = {21, 21, 21, 21,
204 						   22, 22, 22, 23,
205 						   23, 23};
206 
207 static inline int
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)
211 {
212 	uint32_t opcode = 0;
213 	uint32_t val = 0;
214 	int ret = -EINVAL;
215 	bool is_seq_cmd = false;
216 	unsigned int start_pc = program->current_pc;
217 
218 	/* write command type field */
219 	if (flags & SEQ) {
220 		opcode = CMD_SEQ_FIFO_STORE;
221 		is_seq_cmd = true;
222 	} else {
223 		opcode = CMD_FIFO_STORE;
224 	}
225 
226 	/* Parameter checking */
227 	if (is_seq_cmd) {
228 		if ((flags & VLF) && ((length >> 16) || (flags & EXT))) {
229 			pr_err("SEQ FIFO STORE: Invalid usage of VLF\n");
230 			goto err;
231 		}
232 		if (dst) {
233 			pr_err("SEQ FIFO STORE: Invalid command\n");
234 			goto err;
235 		}
236 		if ((src == METADATA) && (flags & (CONT | EXT))) {
237 			pr_err("SEQ FIFO STORE: Invalid flags\n");
238 			goto err;
239 		}
240 	} else {
241 		if (((src == RNGOFIFO) && ((dst) || (flags & EXT))) ||
242 		    (src == METADATA)) {
243 			pr_err("FIFO STORE: Invalid destination\n");
244 			goto err;
245 		}
246 	}
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));
250 		goto err;
251 	}
252 
253 	/* write output data type field */
254 	ret = __rta_map_opcode(src, fifo_store_table,
255 			       fifo_store_table_sz[rta_sec_era], &val);
256 	if (ret < 0) {
257 		pr_err("FIFO STORE: Source type not supported. SEC Program Line: %d\n",
258 		       program->current_pc);
259 		goto err;
260 	}
261 	opcode |= val;
262 
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");
268 			ret = -EINVAL;
269 			goto err;
270 		}
271 		opcode |= (0x10 << FIFOST_TYPE_SHIFT);
272 		opcode &= (uint32_t)~(0x20 << FIFOST_TYPE_SHIFT);
273 	}
274 
275 	/* write flags fields */
276 	if (flags & CONT)
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;
282 	if (flags & CLASS1)
283 		opcode |= FIFOST_CLASS_CLASS1KEY;
284 	if (flags & CLASS2)
285 		opcode |= FIFOST_CLASS_CLASS2KEY;
286 	if (flags & BOTH)
287 		opcode |= FIFOST_CLASS_BOTH;
288 
289 	/* Verify if extended length is required */
290 	if ((length >> 16) || (flags & EXT))
291 		opcode |= FIFOLDST_EXT;
292 	else
293 		opcode |= (uint16_t) length;
294 
295 	__rta_out32(program, opcode);
296 	program->current_instruction++;
297 
298 	/* write pointer field */
299 	if ((!is_seq_cmd) && (dst))
300 		__rta_out64(program, program->ps, dst);
301 
302 	/* write extended length field */
303 	if (opcode & FIFOLDST_EXT)
304 		__rta_out32(program, length);
305 
306 	return (int)start_pc;
307 
308  err:
309 	program->first_error_pc = start_pc;
310 	program->current_instruction++;
311 	return ret;
312 }
313 
314 #endif /* __RTA_FIFO_LOAD_STORE_CMD_H__ */
315