New upstream version 18.02
[deb_dpdk.git] / drivers / crypto / dpaa2_sec / hw / rta / load_cmd.h
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016 NXP
5  *
6  */
7
8 #ifndef __RTA_LOAD_CMD_H__
9 #define __RTA_LOAD_CMD_H__
10
11 extern enum rta_sec_era rta_sec_era;
12
13 /* Allowed length and offset masks for each SEC Era in case DST = DCTRL */
14 static const uint32_t load_len_mask_allowed[] = {
15         0x000000ee,
16         0x000000fe,
17         0x000000fe,
18         0x000000fe,
19         0x000000fe,
20         0x000000fe,
21         0x000000fe,
22         0x000000fe
23 };
24
25 static const uint32_t load_off_mask_allowed[] = {
26         0x0000000f,
27         0x000000ff,
28         0x000000ff,
29         0x000000ff,
30         0x000000ff,
31         0x000000ff,
32         0x000000ff,
33         0x000000ff
34 };
35
36 #define IMM_MUST 0
37 #define IMM_CAN  1
38 #define IMM_NO   2
39 #define IMM_DSNM 3 /* it doesn't matter the src type */
40
41 enum e_lenoff {
42         LENOF_03,
43         LENOF_4,
44         LENOF_48,
45         LENOF_448,
46         LENOF_18,
47         LENOF_32,
48         LENOF_24,
49         LENOF_16,
50         LENOF_8,
51         LENOF_128,
52         LENOF_256,
53         DSNM /* it doesn't matter the length/offset values */
54 };
55
56 struct load_map {
57         uint32_t dst;
58         uint32_t dst_opcode;
59         enum e_lenoff len_off;
60         uint8_t imm_src;
61
62 };
63
64 static const struct load_map load_dst[] = {
65 /*1*/   { KEY1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
66                    LENOF_4,   IMM_MUST },
67         { KEY2SZ,  LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
68                    LENOF_4,   IMM_MUST },
69         { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG,
70                    LENOF_448, IMM_MUST },
71         { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG,
72                    LENOF_448, IMM_MUST },
73         { ICV1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
74                    LENOF_4,   IMM_MUST },
75         { ICV2SZ,  LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
76                    LENOF_4,   IMM_MUST },
77         { CCTRL,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CHACTRL,
78                    LENOF_4,   IMM_MUST },
79         { DCTRL,   LDST_CLASS_DECO | LDST_IMM | LDST_SRCDST_WORD_DECOCTRL,
80                    DSNM,      IMM_DSNM },
81         { ICTRL,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_IRQCTRL,
82                    LENOF_4,   IMM_MUST },
83         { DPOVRD,  LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_PCLOVRD,
84                    LENOF_4,   IMM_MUST },
85         { CLRW,    LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CLRW,
86                    LENOF_4,   IMM_MUST },
87         { AAD1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ,
88                    LENOF_4,   IMM_MUST },
89         { IV1SZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ,
90                    LENOF_4,   IMM_MUST },
91         { ALTDS1,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ALTDS_CLASS1,
92                    LENOF_448, IMM_MUST },
93         { PKASZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ,
94                    LENOF_4,   IMM_MUST, },
95         { PKBSZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ,
96                    LENOF_4,   IMM_MUST },
97         { PKNSZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ,
98                    LENOF_4,   IMM_MUST },
99         { PKESZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ,
100                    LENOF_4,   IMM_MUST },
101         { NFIFO,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_INFO_FIFO,
102                    LENOF_48,  IMM_MUST },
103         { IFIFO,   LDST_SRCDST_BYTE_INFIFO,  LENOF_18, IMM_MUST },
104         { OFIFO,   LDST_SRCDST_BYTE_OUTFIFO, LENOF_18, IMM_MUST },
105         { MATH0,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0,
106                    LENOF_32,  IMM_CAN },
107         { MATH1,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1,
108                    LENOF_24,  IMM_CAN },
109         { MATH2,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2,
110                    LENOF_16,  IMM_CAN },
111         { MATH3,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3,
112                    LENOF_8,   IMM_CAN },
113         { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT,
114                    LENOF_128, IMM_CAN },
115         { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT,
116                    LENOF_128, IMM_CAN },
117         { KEY1,    LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_KEY,
118                    LENOF_32,  IMM_CAN },
119         { KEY2,    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY,
120                    LENOF_32,  IMM_CAN },
121         { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF,
122                    LENOF_256,  IMM_NO },
123         { DPID,    LDST_CLASS_DECO | LDST_SRCDST_WORD_PID,
124                    LENOF_448, IMM_MUST },
125 /*32*/  { IDFNS,   LDST_SRCDST_WORD_IFNSR, LENOF_18,  IMM_MUST },
126         { ODFNS,   LDST_SRCDST_WORD_OFNSR, LENOF_18,  IMM_MUST },
127         { ALTSOURCE, LDST_SRCDST_BYTE_ALTSOURCE, LENOF_18,  IMM_MUST },
128 /*35*/  { NFIFO_SZL, LDST_SRCDST_WORD_INFO_FIFO_SZL, LENOF_48, IMM_MUST },
129         { NFIFO_SZM, LDST_SRCDST_WORD_INFO_FIFO_SZM, LENOF_03, IMM_MUST },
130         { NFIFO_L, LDST_SRCDST_WORD_INFO_FIFO_L, LENOF_48, IMM_MUST },
131         { NFIFO_M, LDST_SRCDST_WORD_INFO_FIFO_M, LENOF_03, IMM_MUST },
132         { SZL,     LDST_SRCDST_WORD_SZL, LENOF_48, IMM_MUST },
133 /*40*/  { SZM,     LDST_SRCDST_WORD_SZM, LENOF_03, IMM_MUST }
134 };
135
136 /*
137  * Allowed LOAD destinations for each SEC Era.
138  * Values represent the number of entries from load_dst[] that are supported.
139  */
140 static const unsigned int load_dst_sz[] = { 31, 34, 34, 40, 40, 40, 40, 40 };
141
142 static inline int
143 load_check_len_offset(int pos, uint32_t length, uint32_t offset)
144 {
145         if ((load_dst[pos].dst == DCTRL) &&
146             ((length & ~load_len_mask_allowed[rta_sec_era]) ||
147              (offset & ~load_off_mask_allowed[rta_sec_era])))
148                 goto err;
149
150         switch (load_dst[pos].len_off) {
151         case (LENOF_03):
152                 if ((length > 3) || (offset))
153                         goto err;
154                 break;
155         case (LENOF_4):
156                 if ((length != 4) || (offset != 0))
157                         goto err;
158                 break;
159         case (LENOF_48):
160                 if (!(((length == 4) && (offset == 0)) ||
161                       ((length == 8) && (offset == 0))))
162                         goto err;
163                 break;
164         case (LENOF_448):
165                 if (!(((length == 4) && (offset == 0)) ||
166                       ((length == 4) && (offset == 4)) ||
167                       ((length == 8) && (offset == 0))))
168                         goto err;
169                 break;
170         case (LENOF_18):
171                 if ((length < 1) || (length > 8) || (offset != 0))
172                         goto err;
173                 break;
174         case (LENOF_32):
175                 if ((length > 32) || (offset > 32) || ((offset + length) > 32))
176                         goto err;
177                 break;
178         case (LENOF_24):
179                 if ((length > 24) || (offset > 24) || ((offset + length) > 24))
180                         goto err;
181                 break;
182         case (LENOF_16):
183                 if ((length > 16) || (offset > 16) || ((offset + length) > 16))
184                         goto err;
185                 break;
186         case (LENOF_8):
187                 if ((length > 8) || (offset > 8) || ((offset + length) > 8))
188                         goto err;
189                 break;
190         case (LENOF_128):
191                 if ((length > 128) || (offset > 128) ||
192                     ((offset + length) > 128))
193                         goto err;
194                 break;
195         case (LENOF_256):
196                 if ((length < 1) || (length > 256) || ((length + offset) > 256))
197                         goto err;
198                 break;
199         case (DSNM):
200                 break;
201         default:
202                 goto err;
203         }
204
205         return 0;
206 err:
207         return -EINVAL;
208 }
209
210 static inline int
211 rta_load(struct program *program, uint64_t src, uint64_t dst,
212          uint32_t offset, uint32_t length, uint32_t flags)
213 {
214         uint32_t opcode = 0;
215         int pos = -1, ret = -EINVAL;
216         unsigned int start_pc = program->current_pc, i;
217
218         if (flags & SEQ)
219                 opcode = CMD_SEQ_LOAD;
220         else
221                 opcode = CMD_LOAD;
222
223         if ((length & 0xffffff00) || (offset & 0xffffff00)) {
224                 pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
225                 goto err;
226         }
227
228         if (flags & SGF)
229                 opcode |= LDST_SGF;
230         if (flags & VLF)
231                 opcode |= LDST_VLF;
232
233         /* check load destination, length and offset and source type */
234         for (i = 0; i < load_dst_sz[rta_sec_era]; i++)
235                 if (dst == load_dst[i].dst) {
236                         pos = (int)i;
237                         break;
238                 }
239         if (-1 == pos) {
240                 pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
241                        program->current_pc);
242                 goto err;
243         }
244
245         if (flags & IMMED) {
246                 if (load_dst[pos].imm_src == IMM_NO) {
247                         pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
248                                program->current_pc);
249                         goto err;
250                 }
251                 opcode |= LDST_IMM;
252         } else if (load_dst[pos].imm_src == IMM_MUST) {
253                 pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
254                        program->current_pc);
255                 goto err;
256         }
257
258         ret = load_check_len_offset(pos, length, offset);
259         if (ret < 0) {
260                 pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
261                        program->current_pc);
262                 goto err;
263         }
264
265         opcode |= load_dst[pos].dst_opcode;
266
267         /* DESC BUFFER: length / offset values are specified in 4-byte words */
268         if (dst == DESCBUF) {
269                 opcode |= (length >> 2);
270                 opcode |= ((offset >> 2) << LDST_OFFSET_SHIFT);
271         } else {
272                 opcode |= length;
273                 opcode |= (offset << LDST_OFFSET_SHIFT);
274         }
275
276         __rta_out32(program, opcode);
277         program->current_instruction++;
278
279         /* DECO CONTROL: skip writing pointer of imm data */
280         if (dst == DCTRL)
281                 return (int)start_pc;
282
283         /*
284          * For data copy, 3 possible ways to specify how to copy data:
285          *  - IMMED & !COPY: copy data directly from src( max 8 bytes)
286          *  - IMMED & COPY: copy data imm from the location specified by user
287          *  - !IMMED and is not SEQ cmd: copy the address
288          */
289         if (flags & IMMED)
290                 __rta_inline_data(program, src, flags & __COPY_MASK, length);
291         else if (!(flags & SEQ))
292                 __rta_out64(program, program->ps, src);
293
294         return (int)start_pc;
295
296  err:
297         program->first_error_pc = start_pc;
298         program->current_instruction++;
299         return ret;
300 }
301
302 #endif /* __RTA_LOAD_CMD_H__*/