1db55b3360721c4fcd76aa1ae45c53737a49925f
[deb_dpdk.git] / drivers / crypto / dpaa2_sec / hw / rta / load_cmd.h
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license. When using or
3  * redistributing this file, you may do so under either license.
4  *
5  *   BSD LICENSE
6  *
7  * Copyright 2008-2016 Freescale Semiconductor Inc.
8  * Copyright (c) 2016 NXP.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * * Neither the name of the above-listed copyright holders nor the
18  * names of any contributors may be used to endorse or promote products
19  * derived from this software without specific prior written permission.
20  *
21  *   GPL LICENSE SUMMARY
22  *
23  * ALTERNATIVELY, this software may be distributed under the terms of the
24  * GNU General Public License ("GPL") as published by the Free Software
25  * Foundation, either version 2 of that License or (at your option) any
26  * later version.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40
41 #ifndef __RTA_LOAD_CMD_H__
42 #define __RTA_LOAD_CMD_H__
43
44 extern enum rta_sec_era rta_sec_era;
45
46 /* Allowed length and offset masks for each SEC Era in case DST = DCTRL */
47 static const uint32_t load_len_mask_allowed[] = {
48         0x000000ee,
49         0x000000fe,
50         0x000000fe,
51         0x000000fe,
52         0x000000fe,
53         0x000000fe,
54         0x000000fe,
55         0x000000fe
56 };
57
58 static const uint32_t load_off_mask_allowed[] = {
59         0x0000000f,
60         0x000000ff,
61         0x000000ff,
62         0x000000ff,
63         0x000000ff,
64         0x000000ff,
65         0x000000ff,
66         0x000000ff
67 };
68
69 #define IMM_MUST 0
70 #define IMM_CAN  1
71 #define IMM_NO   2
72 #define IMM_DSNM 3 /* it doesn't matter the src type */
73
74 enum e_lenoff {
75         LENOF_03,
76         LENOF_4,
77         LENOF_48,
78         LENOF_448,
79         LENOF_18,
80         LENOF_32,
81         LENOF_24,
82         LENOF_16,
83         LENOF_8,
84         LENOF_128,
85         LENOF_256,
86         DSNM /* it doesn't matter the length/offset values */
87 };
88
89 struct load_map {
90         uint32_t dst;
91         uint32_t dst_opcode;
92         enum e_lenoff len_off;
93         uint8_t imm_src;
94
95 };
96
97 static const struct load_map load_dst[] = {
98 /*1*/   { KEY1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
99                    LENOF_4,   IMM_MUST },
100         { KEY2SZ,  LDST_CLASS_2_CCB | LDST_SRCDST_WORD_KEYSZ_REG,
101                    LENOF_4,   IMM_MUST },
102         { DATA1SZ, LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DATASZ_REG,
103                    LENOF_448, IMM_MUST },
104         { DATA2SZ, LDST_CLASS_2_CCB | LDST_SRCDST_WORD_DATASZ_REG,
105                    LENOF_448, IMM_MUST },
106         { ICV1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
107                    LENOF_4,   IMM_MUST },
108         { ICV2SZ,  LDST_CLASS_2_CCB | LDST_SRCDST_WORD_ICVSZ_REG,
109                    LENOF_4,   IMM_MUST },
110         { CCTRL,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CHACTRL,
111                    LENOF_4,   IMM_MUST },
112         { DCTRL,   LDST_CLASS_DECO | LDST_IMM | LDST_SRCDST_WORD_DECOCTRL,
113                    DSNM,      IMM_DSNM },
114         { ICTRL,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_IRQCTRL,
115                    LENOF_4,   IMM_MUST },
116         { DPOVRD,  LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_PCLOVRD,
117                    LENOF_4,   IMM_MUST },
118         { CLRW,    LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_CLRW,
119                    LENOF_4,   IMM_MUST },
120         { AAD1SZ,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_DECO_AAD_SZ,
121                    LENOF_4,   IMM_MUST },
122         { IV1SZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_CLASS1_IV_SZ,
123                    LENOF_4,   IMM_MUST },
124         { ALTDS1,  LDST_CLASS_1_CCB | LDST_SRCDST_WORD_ALTDS_CLASS1,
125                    LENOF_448, IMM_MUST },
126         { PKASZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_A_SZ,
127                    LENOF_4,   IMM_MUST, },
128         { PKBSZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_B_SZ,
129                    LENOF_4,   IMM_MUST },
130         { PKNSZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_N_SZ,
131                    LENOF_4,   IMM_MUST },
132         { PKESZ,   LDST_CLASS_1_CCB | LDST_SRCDST_WORD_PKHA_E_SZ,
133                    LENOF_4,   IMM_MUST },
134         { NFIFO,   LDST_CLASS_IND_CCB | LDST_SRCDST_WORD_INFO_FIFO,
135                    LENOF_48,  IMM_MUST },
136         { IFIFO,   LDST_SRCDST_BYTE_INFIFO,  LENOF_18, IMM_MUST },
137         { OFIFO,   LDST_SRCDST_BYTE_OUTFIFO, LENOF_18, IMM_MUST },
138         { MATH0,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH0,
139                    LENOF_32,  IMM_CAN },
140         { MATH1,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH1,
141                    LENOF_24,  IMM_CAN },
142         { MATH2,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH2,
143                    LENOF_16,  IMM_CAN },
144         { MATH3,   LDST_CLASS_DECO | LDST_SRCDST_WORD_DECO_MATH3,
145                    LENOF_8,   IMM_CAN },
146         { CONTEXT1, LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT,
147                    LENOF_128, IMM_CAN },
148         { CONTEXT2, LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT,
149                    LENOF_128, IMM_CAN },
150         { KEY1,    LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_KEY,
151                    LENOF_32,  IMM_CAN },
152         { KEY2,    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY,
153                    LENOF_32,  IMM_CAN },
154         { DESCBUF, LDST_CLASS_DECO | LDST_SRCDST_WORD_DESCBUF,
155                    LENOF_256,  IMM_NO },
156         { DPID,    LDST_CLASS_DECO | LDST_SRCDST_WORD_PID,
157                    LENOF_448, IMM_MUST },
158 /*32*/  { IDFNS,   LDST_SRCDST_WORD_IFNSR, LENOF_18,  IMM_MUST },
159         { ODFNS,   LDST_SRCDST_WORD_OFNSR, LENOF_18,  IMM_MUST },
160         { ALTSOURCE, LDST_SRCDST_BYTE_ALTSOURCE, LENOF_18,  IMM_MUST },
161 /*35*/  { NFIFO_SZL, LDST_SRCDST_WORD_INFO_FIFO_SZL, LENOF_48, IMM_MUST },
162         { NFIFO_SZM, LDST_SRCDST_WORD_INFO_FIFO_SZM, LENOF_03, IMM_MUST },
163         { NFIFO_L, LDST_SRCDST_WORD_INFO_FIFO_L, LENOF_48, IMM_MUST },
164         { NFIFO_M, LDST_SRCDST_WORD_INFO_FIFO_M, LENOF_03, IMM_MUST },
165         { SZL,     LDST_SRCDST_WORD_SZL, LENOF_48, IMM_MUST },
166 /*40*/  { SZM,     LDST_SRCDST_WORD_SZM, LENOF_03, IMM_MUST }
167 };
168
169 /*
170  * Allowed LOAD destinations for each SEC Era.
171  * Values represent the number of entries from load_dst[] that are supported.
172  */
173 static const unsigned int load_dst_sz[] = { 31, 34, 34, 40, 40, 40, 40, 40 };
174
175 static inline int
176 load_check_len_offset(int pos, uint32_t length, uint32_t offset)
177 {
178         if ((load_dst[pos].dst == DCTRL) &&
179             ((length & ~load_len_mask_allowed[rta_sec_era]) ||
180              (offset & ~load_off_mask_allowed[rta_sec_era])))
181                 goto err;
182
183         switch (load_dst[pos].len_off) {
184         case (LENOF_03):
185                 if ((length > 3) || (offset))
186                         goto err;
187                 break;
188         case (LENOF_4):
189                 if ((length != 4) || (offset != 0))
190                         goto err;
191                 break;
192         case (LENOF_48):
193                 if (!(((length == 4) && (offset == 0)) ||
194                       ((length == 8) && (offset == 0))))
195                         goto err;
196                 break;
197         case (LENOF_448):
198                 if (!(((length == 4) && (offset == 0)) ||
199                       ((length == 4) && (offset == 4)) ||
200                       ((length == 8) && (offset == 0))))
201                         goto err;
202                 break;
203         case (LENOF_18):
204                 if ((length < 1) || (length > 8) || (offset != 0))
205                         goto err;
206                 break;
207         case (LENOF_32):
208                 if ((length > 32) || (offset > 32) || ((offset + length) > 32))
209                         goto err;
210                 break;
211         case (LENOF_24):
212                 if ((length > 24) || (offset > 24) || ((offset + length) > 24))
213                         goto err;
214                 break;
215         case (LENOF_16):
216                 if ((length > 16) || (offset > 16) || ((offset + length) > 16))
217                         goto err;
218                 break;
219         case (LENOF_8):
220                 if ((length > 8) || (offset > 8) || ((offset + length) > 8))
221                         goto err;
222                 break;
223         case (LENOF_128):
224                 if ((length > 128) || (offset > 128) ||
225                     ((offset + length) > 128))
226                         goto err;
227                 break;
228         case (LENOF_256):
229                 if ((length < 1) || (length > 256) || ((length + offset) > 256))
230                         goto err;
231                 break;
232         case (DSNM):
233                 break;
234         default:
235                 goto err;
236         }
237
238         return 0;
239 err:
240         return -EINVAL;
241 }
242
243 static inline int
244 rta_load(struct program *program, uint64_t src, uint64_t dst,
245          uint32_t offset, uint32_t length, uint32_t flags)
246 {
247         uint32_t opcode = 0;
248         int pos = -1, ret = -EINVAL;
249         unsigned int start_pc = program->current_pc, i;
250
251         if (flags & SEQ)
252                 opcode = CMD_SEQ_LOAD;
253         else
254                 opcode = CMD_LOAD;
255
256         if ((length & 0xffffff00) || (offset & 0xffffff00)) {
257                 pr_err("LOAD: Bad length/offset passed. Should be 8 bits\n");
258                 goto err;
259         }
260
261         if (flags & SGF)
262                 opcode |= LDST_SGF;
263         if (flags & VLF)
264                 opcode |= LDST_VLF;
265
266         /* check load destination, length and offset and source type */
267         for (i = 0; i < load_dst_sz[rta_sec_era]; i++)
268                 if (dst == load_dst[i].dst) {
269                         pos = (int)i;
270                         break;
271                 }
272         if (-1 == pos) {
273                 pr_err("LOAD: Invalid dst. SEC Program Line: %d\n",
274                        program->current_pc);
275                 goto err;
276         }
277
278         if (flags & IMMED) {
279                 if (load_dst[pos].imm_src == IMM_NO) {
280                         pr_err("LOAD: Invalid source type. SEC Program Line: %d\n",
281                                program->current_pc);
282                         goto err;
283                 }
284                 opcode |= LDST_IMM;
285         } else if (load_dst[pos].imm_src == IMM_MUST) {
286                 pr_err("LOAD IMM: Invalid source type. SEC Program Line: %d\n",
287                        program->current_pc);
288                 goto err;
289         }
290
291         ret = load_check_len_offset(pos, length, offset);
292         if (ret < 0) {
293                 pr_err("LOAD: Invalid length/offset. SEC Program Line: %d\n",
294                        program->current_pc);
295                 goto err;
296         }
297
298         opcode |= load_dst[pos].dst_opcode;
299
300         /* DESC BUFFER: length / offset values are specified in 4-byte words */
301         if (dst == DESCBUF) {
302                 opcode |= (length >> 2);
303                 opcode |= ((offset >> 2) << LDST_OFFSET_SHIFT);
304         } else {
305                 opcode |= length;
306                 opcode |= (offset << LDST_OFFSET_SHIFT);
307         }
308
309         __rta_out32(program, opcode);
310         program->current_instruction++;
311
312         /* DECO CONTROL: skip writing pointer of imm data */
313         if (dst == DCTRL)
314                 return (int)start_pc;
315
316         /*
317          * For data copy, 3 possible ways to specify how to copy data:
318          *  - IMMED & !COPY: copy data directly from src( max 8 bytes)
319          *  - IMMED & COPY: copy data imm from the location specified by user
320          *  - !IMMED and is not SEQ cmd: copy the address
321          */
322         if (flags & IMMED)
323                 __rta_inline_data(program, src, flags & __COPY_MASK, length);
324         else if (!(flags & SEQ))
325                 __rta_out64(program, program->ps, src);
326
327         return (int)start_pc;
328
329  err:
330         program->first_error_pc = start_pc;
331         program->current_instruction++;
332         return ret;
333 }
334
335 #endif /* __RTA_LOAD_CMD_H__*/