common/dpaax/caamflib: update ZUC-ZUC descriptor sharing
[dpdk.git] / drivers / common / dpaax / caamflib / rta / operation_cmd.h
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_OPERATION_CMD_H__
8 #define __RTA_OPERATION_CMD_H__
9
10 #if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 70000)
11 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
12 #endif
13
14 extern enum rta_sec_era rta_sec_era;
15
16 static inline int
17 __rta_alg_aai_aes(uint16_t aai)
18 {
19         uint16_t aes_mode = aai & OP_ALG_AESA_MODE_MASK;
20
21         if (aai & OP_ALG_AAI_C2K) {
22                 if (rta_sec_era < RTA_SEC_ERA_5)
23                         return -1;
24                 if ((aes_mode != OP_ALG_AAI_CCM) &&
25                     (aes_mode != OP_ALG_AAI_GCM))
26                         return -EINVAL;
27         }
28
29         switch (aes_mode) {
30         case OP_ALG_AAI_CBC_CMAC:
31         case OP_ALG_AAI_CTR_CMAC_LTE:
32         case OP_ALG_AAI_CTR_CMAC:
33                 if (rta_sec_era < RTA_SEC_ERA_2)
34                         return -EINVAL;
35                 /* no break */
36         case OP_ALG_AAI_CTR:
37         case OP_ALG_AAI_CBC:
38         case OP_ALG_AAI_ECB:
39         case OP_ALG_AAI_OFB:
40         case OP_ALG_AAI_CFB:
41         case OP_ALG_AAI_XTS:
42         case OP_ALG_AAI_CMAC:
43         case OP_ALG_AAI_XCBC_MAC:
44         case OP_ALG_AAI_CCM:
45         case OP_ALG_AAI_GCM:
46         case OP_ALG_AAI_CBC_XCBCMAC:
47         case OP_ALG_AAI_CTR_XCBCMAC:
48                 return 0;
49         }
50
51         return -EINVAL;
52 }
53
54 static inline int
55 __rta_alg_aai_des(uint16_t aai)
56 {
57         uint16_t aai_code = (uint16_t)(aai & ~OP_ALG_AAI_CHECKODD);
58
59         switch (aai_code) {
60         case OP_ALG_AAI_CBC:
61         case OP_ALG_AAI_ECB:
62         case OP_ALG_AAI_CFB:
63         case OP_ALG_AAI_OFB:
64                 return 0;
65         }
66
67         return -EINVAL;
68 }
69
70 static inline int
71 __rta_alg_aai_md5(uint16_t aai)
72 {
73         switch (aai) {
74         case OP_ALG_AAI_HMAC:
75                 if (rta_sec_era < RTA_SEC_ERA_2)
76                         return -EINVAL;
77                 /* no break */
78         case OP_ALG_AAI_SMAC:
79         case OP_ALG_AAI_HASH:
80         case OP_ALG_AAI_HMAC_PRECOMP:
81                 return 0;
82         }
83
84         return -EINVAL;
85 }
86
87 static inline int
88 __rta_alg_aai_sha(uint16_t aai)
89 {
90         switch (aai) {
91         case OP_ALG_AAI_HMAC:
92                 if (rta_sec_era < RTA_SEC_ERA_2)
93                         return -EINVAL;
94                 /* no break */
95         case OP_ALG_AAI_HASH:
96         case OP_ALG_AAI_HMAC_PRECOMP:
97                 return 0;
98         }
99
100         return -EINVAL;
101 }
102
103 static inline int
104 __rta_alg_aai_rng(uint16_t aai)
105 {
106         uint16_t rng_mode = aai & OP_ALG_RNG_MODE_MASK;
107         uint16_t rng_sh = aai & OP_ALG_AAI_RNG4_SH_MASK;
108
109         switch (rng_mode) {
110         case OP_ALG_AAI_RNG:
111         case OP_ALG_AAI_RNG_NZB:
112         case OP_ALG_AAI_RNG_OBP:
113                 break;
114         default:
115                 return -EINVAL;
116         }
117
118         /* State Handle bits are valid only for SEC Era >= 5 */
119         if ((rta_sec_era < RTA_SEC_ERA_5) && rng_sh)
120                 return -EINVAL;
121
122         /* PS, AI, SK bits are also valid only for SEC Era >= 5 */
123         if ((rta_sec_era < RTA_SEC_ERA_5) && (aai &
124              (OP_ALG_AAI_RNG4_PS | OP_ALG_AAI_RNG4_AI | OP_ALG_AAI_RNG4_SK)))
125                 return -EINVAL;
126
127         switch (rng_sh) {
128         case OP_ALG_AAI_RNG4_SH_0:
129         case OP_ALG_AAI_RNG4_SH_1:
130                 return 0;
131         }
132
133         return -EINVAL;
134 }
135
136 static inline int
137 __rta_alg_aai_crc(uint16_t aai)
138 {
139         uint16_t aai_code = aai & OP_ALG_CRC_POLY_MASK;
140
141         switch (aai_code) {
142         case OP_ALG_AAI_802:
143         case OP_ALG_AAI_3385:
144         case OP_ALG_AAI_CUST_POLY:
145                 return 0;
146         }
147
148         return -EINVAL;
149 }
150
151 static inline int
152 __rta_alg_aai_kasumi(uint16_t aai)
153 {
154         switch (aai) {
155         case OP_ALG_AAI_GSM:
156         case OP_ALG_AAI_EDGE:
157         case OP_ALG_AAI_F8:
158         case OP_ALG_AAI_F9:
159                 return 0;
160         }
161
162         return -EINVAL;
163 }
164
165 static inline int
166 __rta_alg_aai_snow_f9(uint16_t aai)
167 {
168         if (aai == OP_ALG_AAI_F9)
169                 return 0;
170
171         return -EINVAL;
172 }
173
174 static inline int
175 __rta_alg_aai_snow_f8(uint16_t aai)
176 {
177         if (aai == OP_ALG_AAI_F8)
178                 return 0;
179
180         return -EINVAL;
181 }
182
183 static inline int
184 __rta_alg_aai_zuce(uint16_t aai)
185 {
186         if (aai == OP_ALG_AAI_F8)
187                 return 0;
188
189         return -EINVAL;
190 }
191
192 static inline int
193 __rta_alg_aai_zuca(uint16_t aai)
194 {
195         if (aai == OP_ALG_AAI_F9)
196                 return 0;
197
198         return -EINVAL;
199 }
200
201 struct alg_aai_map {
202         uint32_t chipher_algo;
203         int (*aai_func)(uint16_t);
204         uint32_t class;
205 };
206
207 static const struct alg_aai_map alg_table[] = {
208 /*1*/   { OP_ALG_ALGSEL_AES,      __rta_alg_aai_aes,    OP_TYPE_CLASS1_ALG },
209         { OP_ALG_ALGSEL_DES,      __rta_alg_aai_des,    OP_TYPE_CLASS1_ALG },
210         { OP_ALG_ALGSEL_3DES,     __rta_alg_aai_des,    OP_TYPE_CLASS1_ALG },
211         { OP_ALG_ALGSEL_MD5,      __rta_alg_aai_md5,    OP_TYPE_CLASS2_ALG },
212         { OP_ALG_ALGSEL_SHA1,     __rta_alg_aai_md5,    OP_TYPE_CLASS2_ALG },
213         { OP_ALG_ALGSEL_SHA224,   __rta_alg_aai_sha,    OP_TYPE_CLASS2_ALG },
214         { OP_ALG_ALGSEL_SHA256,   __rta_alg_aai_sha,    OP_TYPE_CLASS2_ALG },
215         { OP_ALG_ALGSEL_SHA384,   __rta_alg_aai_sha,    OP_TYPE_CLASS2_ALG },
216         { OP_ALG_ALGSEL_SHA512,   __rta_alg_aai_sha,    OP_TYPE_CLASS2_ALG },
217         { OP_ALG_ALGSEL_RNG,      __rta_alg_aai_rng,    OP_TYPE_CLASS1_ALG },
218 /*11*/  { OP_ALG_ALGSEL_CRC,      __rta_alg_aai_crc,    OP_TYPE_CLASS2_ALG },
219         { OP_ALG_ALGSEL_ARC4,     NULL,                 OP_TYPE_CLASS1_ALG },
220         { OP_ALG_ALGSEL_SNOW_F8,  __rta_alg_aai_snow_f8, OP_TYPE_CLASS1_ALG },
221 /*14*/  { OP_ALG_ALGSEL_KASUMI,   __rta_alg_aai_kasumi, OP_TYPE_CLASS1_ALG },
222         { OP_ALG_ALGSEL_SNOW_F9,  __rta_alg_aai_snow_f9, OP_TYPE_CLASS2_ALG },
223         { OP_ALG_ALGSEL_ZUCE,     __rta_alg_aai_zuce,   OP_TYPE_CLASS1_ALG },
224 /*17*/  { OP_ALG_ALGSEL_ZUCA,     __rta_alg_aai_zuca,   OP_TYPE_CLASS2_ALG }
225 };
226
227 /*
228  * Allowed OPERATION algorithms for each SEC Era.
229  * Values represent the number of entries from alg_table[] that are supported.
230  */
231 static const unsigned int alg_table_sz[] = {14, 15, 15, 15, 17, 17,
232                                                 11, 17, 17, 17};
233
234 static inline int
235 rta_operation(struct program *program, uint32_t cipher_algo,
236               uint16_t aai, uint8_t algo_state,
237               int icv_checking, int enc)
238 {
239         uint32_t opcode = CMD_OPERATION;
240         unsigned int i, found = 0;
241         unsigned int start_pc = program->current_pc;
242         int ret;
243
244         for (i = 0; i < alg_table_sz[rta_sec_era]; i++) {
245                 if (alg_table[i].chipher_algo == cipher_algo) {
246                         if ((aai ==  OP_ALG_AAI_XCBC_MAC) ||
247                                         (aai == OP_ALG_AAI_CBC_XCBCMAC))
248                                 opcode |= cipher_algo | OP_TYPE_CLASS2_ALG;
249                         else
250                                 opcode |= cipher_algo | alg_table[i].class;
251                         /* nothing else to verify */
252                         if (alg_table[i].aai_func == NULL) {
253                                 found = 1;
254                                 break;
255                         }
256
257                         aai &= OP_ALG_AAI_MASK;
258
259                         ret = (*alg_table[i].aai_func)(aai);
260                         if (ret < 0) {
261                                 pr_err("OPERATION: Bad AAI Type. SEC Program Line: %d\n",
262                                        program->current_pc);
263                                 goto err;
264                         }
265                         opcode |= aai;
266                         found = 1;
267                         break;
268                 }
269         }
270         if (!found) {
271                 pr_err("OPERATION: Invalid Command. SEC Program Line: %d\n",
272                        program->current_pc);
273                 ret = -EINVAL;
274                 goto err;
275         }
276
277         switch (algo_state) {
278         case OP_ALG_AS_UPDATE:
279         case OP_ALG_AS_INIT:
280         case OP_ALG_AS_FINALIZE:
281         case OP_ALG_AS_INITFINAL:
282                 opcode |= algo_state;
283                 break;
284         default:
285                 pr_err("Invalid Operation Command\n");
286                 ret = -EINVAL;
287                 goto err;
288         }
289
290         switch (icv_checking) {
291         case ICV_CHECK_DISABLE:
292                 /*
293                  * opcode |= OP_ALG_ICV_OFF;
294                  * OP_ALG_ICV_OFF is 0
295                  */
296                 break;
297         case ICV_CHECK_ENABLE:
298                 opcode |= OP_ALG_ICV_ON;
299                 break;
300         default:
301                 pr_err("Invalid Operation Command\n");
302                 ret = -EINVAL;
303                 goto err;
304         }
305
306         switch (enc) {
307         case DIR_DEC:
308                 /*
309                  * opcode |= OP_ALG_DECRYPT;
310                  * OP_ALG_DECRYPT is 0
311                  */
312                 break;
313         case DIR_ENC:
314                 opcode |= OP_ALG_ENCRYPT;
315                 break;
316         default:
317                 pr_err("Invalid Operation Command\n");
318                 ret = -EINVAL;
319                 goto err;
320         }
321
322         __rta_out32(program, opcode);
323         program->current_instruction++;
324         return (int)start_pc;
325
326  err:
327         program->first_error_pc = start_pc;
328         return ret;
329 }
330
331 /*
332  * OPERATION PKHA routines
333  */
334 static inline int
335 __rta_pkha_clearmem(uint32_t pkha_op)
336 {
337         switch (pkha_op) {
338         case (OP_ALG_PKMODE_CLEARMEM_ALL):
339         case (OP_ALG_PKMODE_CLEARMEM_ABE):
340         case (OP_ALG_PKMODE_CLEARMEM_ABN):
341         case (OP_ALG_PKMODE_CLEARMEM_AB):
342         case (OP_ALG_PKMODE_CLEARMEM_AEN):
343         case (OP_ALG_PKMODE_CLEARMEM_AE):
344         case (OP_ALG_PKMODE_CLEARMEM_AN):
345         case (OP_ALG_PKMODE_CLEARMEM_A):
346         case (OP_ALG_PKMODE_CLEARMEM_BEN):
347         case (OP_ALG_PKMODE_CLEARMEM_BE):
348         case (OP_ALG_PKMODE_CLEARMEM_BN):
349         case (OP_ALG_PKMODE_CLEARMEM_B):
350         case (OP_ALG_PKMODE_CLEARMEM_EN):
351         case (OP_ALG_PKMODE_CLEARMEM_N):
352         case (OP_ALG_PKMODE_CLEARMEM_E):
353                 return 0;
354         }
355
356         return -EINVAL;
357 }
358
359 static inline int
360 __rta_pkha_mod_arithmetic(uint32_t pkha_op)
361 {
362         pkha_op &= (uint32_t)~OP_ALG_PKMODE_OUT_A;
363
364         switch (pkha_op) {
365         case (OP_ALG_PKMODE_MOD_ADD):
366         case (OP_ALG_PKMODE_MOD_SUB_AB):
367         case (OP_ALG_PKMODE_MOD_SUB_BA):
368         case (OP_ALG_PKMODE_MOD_MULT):
369         case (OP_ALG_PKMODE_MOD_MULT_IM):
370         case (OP_ALG_PKMODE_MOD_MULT_IM_OM):
371         case (OP_ALG_PKMODE_MOD_EXPO):
372         case (OP_ALG_PKMODE_MOD_EXPO_TEQ):
373         case (OP_ALG_PKMODE_MOD_EXPO_IM):
374         case (OP_ALG_PKMODE_MOD_EXPO_IM_TEQ):
375         case (OP_ALG_PKMODE_MOD_REDUCT):
376         case (OP_ALG_PKMODE_MOD_INV):
377         case (OP_ALG_PKMODE_MOD_MONT_CNST):
378         case (OP_ALG_PKMODE_MOD_CRT_CNST):
379         case (OP_ALG_PKMODE_MOD_GCD):
380         case (OP_ALG_PKMODE_MOD_PRIMALITY):
381         case (OP_ALG_PKMODE_MOD_SML_EXP):
382         case (OP_ALG_PKMODE_F2M_ADD):
383         case (OP_ALG_PKMODE_F2M_MUL):
384         case (OP_ALG_PKMODE_F2M_MUL_IM):
385         case (OP_ALG_PKMODE_F2M_MUL_IM_OM):
386         case (OP_ALG_PKMODE_F2M_EXP):
387         case (OP_ALG_PKMODE_F2M_EXP_TEQ):
388         case (OP_ALG_PKMODE_F2M_AMODN):
389         case (OP_ALG_PKMODE_F2M_INV):
390         case (OP_ALG_PKMODE_F2M_R2):
391         case (OP_ALG_PKMODE_F2M_GCD):
392         case (OP_ALG_PKMODE_F2M_SML_EXP):
393         case (OP_ALG_PKMODE_ECC_F2M_ADD):
394         case (OP_ALG_PKMODE_ECC_F2M_ADD_IM_OM_PROJ):
395         case (OP_ALG_PKMODE_ECC_F2M_DBL):
396         case (OP_ALG_PKMODE_ECC_F2M_DBL_IM_OM_PROJ):
397         case (OP_ALG_PKMODE_ECC_F2M_MUL):
398         case (OP_ALG_PKMODE_ECC_F2M_MUL_TEQ):
399         case (OP_ALG_PKMODE_ECC_F2M_MUL_R2):
400         case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_TEQ):
401         case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_PROJ):
402         case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_PROJ_TEQ):
403         case (OP_ALG_PKMODE_ECC_MOD_ADD):
404         case (OP_ALG_PKMODE_ECC_MOD_ADD_IM_OM_PROJ):
405         case (OP_ALG_PKMODE_ECC_MOD_DBL):
406         case (OP_ALG_PKMODE_ECC_MOD_DBL_IM_OM_PROJ):
407         case (OP_ALG_PKMODE_ECC_MOD_MUL):
408         case (OP_ALG_PKMODE_ECC_MOD_MUL_TEQ):
409         case (OP_ALG_PKMODE_ECC_MOD_MUL_R2):
410         case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_TEQ):
411         case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_PROJ):
412         case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_PROJ_TEQ):
413                 return 0;
414         }
415
416         return -EINVAL;
417 }
418
419 static inline int
420 __rta_pkha_copymem(uint32_t pkha_op)
421 {
422         switch (pkha_op) {
423         case (OP_ALG_PKMODE_COPY_NSZ_A0_B0):
424         case (OP_ALG_PKMODE_COPY_NSZ_A0_B1):
425         case (OP_ALG_PKMODE_COPY_NSZ_A0_B2):
426         case (OP_ALG_PKMODE_COPY_NSZ_A0_B3):
427         case (OP_ALG_PKMODE_COPY_NSZ_A1_B0):
428         case (OP_ALG_PKMODE_COPY_NSZ_A1_B1):
429         case (OP_ALG_PKMODE_COPY_NSZ_A1_B2):
430         case (OP_ALG_PKMODE_COPY_NSZ_A1_B3):
431         case (OP_ALG_PKMODE_COPY_NSZ_A2_B0):
432         case (OP_ALG_PKMODE_COPY_NSZ_A2_B1):
433         case (OP_ALG_PKMODE_COPY_NSZ_A2_B2):
434         case (OP_ALG_PKMODE_COPY_NSZ_A2_B3):
435         case (OP_ALG_PKMODE_COPY_NSZ_A3_B0):
436         case (OP_ALG_PKMODE_COPY_NSZ_A3_B1):
437         case (OP_ALG_PKMODE_COPY_NSZ_A3_B2):
438         case (OP_ALG_PKMODE_COPY_NSZ_A3_B3):
439         case (OP_ALG_PKMODE_COPY_NSZ_B0_A0):
440         case (OP_ALG_PKMODE_COPY_NSZ_B0_A1):
441         case (OP_ALG_PKMODE_COPY_NSZ_B0_A2):
442         case (OP_ALG_PKMODE_COPY_NSZ_B0_A3):
443         case (OP_ALG_PKMODE_COPY_NSZ_B1_A0):
444         case (OP_ALG_PKMODE_COPY_NSZ_B1_A1):
445         case (OP_ALG_PKMODE_COPY_NSZ_B1_A2):
446         case (OP_ALG_PKMODE_COPY_NSZ_B1_A3):
447         case (OP_ALG_PKMODE_COPY_NSZ_B2_A0):
448         case (OP_ALG_PKMODE_COPY_NSZ_B2_A1):
449         case (OP_ALG_PKMODE_COPY_NSZ_B2_A2):
450         case (OP_ALG_PKMODE_COPY_NSZ_B2_A3):
451         case (OP_ALG_PKMODE_COPY_NSZ_B3_A0):
452         case (OP_ALG_PKMODE_COPY_NSZ_B3_A1):
453         case (OP_ALG_PKMODE_COPY_NSZ_B3_A2):
454         case (OP_ALG_PKMODE_COPY_NSZ_B3_A3):
455         case (OP_ALG_PKMODE_COPY_NSZ_A_E):
456         case (OP_ALG_PKMODE_COPY_NSZ_A_N):
457         case (OP_ALG_PKMODE_COPY_NSZ_B_E):
458         case (OP_ALG_PKMODE_COPY_NSZ_B_N):
459         case (OP_ALG_PKMODE_COPY_NSZ_N_A):
460         case (OP_ALG_PKMODE_COPY_NSZ_N_B):
461         case (OP_ALG_PKMODE_COPY_NSZ_N_E):
462         case (OP_ALG_PKMODE_COPY_SSZ_A0_B0):
463         case (OP_ALG_PKMODE_COPY_SSZ_A0_B1):
464         case (OP_ALG_PKMODE_COPY_SSZ_A0_B2):
465         case (OP_ALG_PKMODE_COPY_SSZ_A0_B3):
466         case (OP_ALG_PKMODE_COPY_SSZ_A1_B0):
467         case (OP_ALG_PKMODE_COPY_SSZ_A1_B1):
468         case (OP_ALG_PKMODE_COPY_SSZ_A1_B2):
469         case (OP_ALG_PKMODE_COPY_SSZ_A1_B3):
470         case (OP_ALG_PKMODE_COPY_SSZ_A2_B0):
471         case (OP_ALG_PKMODE_COPY_SSZ_A2_B1):
472         case (OP_ALG_PKMODE_COPY_SSZ_A2_B2):
473         case (OP_ALG_PKMODE_COPY_SSZ_A2_B3):
474         case (OP_ALG_PKMODE_COPY_SSZ_A3_B0):
475         case (OP_ALG_PKMODE_COPY_SSZ_A3_B1):
476         case (OP_ALG_PKMODE_COPY_SSZ_A3_B2):
477         case (OP_ALG_PKMODE_COPY_SSZ_A3_B3):
478         case (OP_ALG_PKMODE_COPY_SSZ_B0_A0):
479         case (OP_ALG_PKMODE_COPY_SSZ_B0_A1):
480         case (OP_ALG_PKMODE_COPY_SSZ_B0_A2):
481         case (OP_ALG_PKMODE_COPY_SSZ_B0_A3):
482         case (OP_ALG_PKMODE_COPY_SSZ_B1_A0):
483         case (OP_ALG_PKMODE_COPY_SSZ_B1_A1):
484         case (OP_ALG_PKMODE_COPY_SSZ_B1_A2):
485         case (OP_ALG_PKMODE_COPY_SSZ_B1_A3):
486         case (OP_ALG_PKMODE_COPY_SSZ_B2_A0):
487         case (OP_ALG_PKMODE_COPY_SSZ_B2_A1):
488         case (OP_ALG_PKMODE_COPY_SSZ_B2_A2):
489         case (OP_ALG_PKMODE_COPY_SSZ_B2_A3):
490         case (OP_ALG_PKMODE_COPY_SSZ_B3_A0):
491         case (OP_ALG_PKMODE_COPY_SSZ_B3_A1):
492         case (OP_ALG_PKMODE_COPY_SSZ_B3_A2):
493         case (OP_ALG_PKMODE_COPY_SSZ_B3_A3):
494         case (OP_ALG_PKMODE_COPY_SSZ_A_E):
495         case (OP_ALG_PKMODE_COPY_SSZ_A_N):
496         case (OP_ALG_PKMODE_COPY_SSZ_B_E):
497         case (OP_ALG_PKMODE_COPY_SSZ_B_N):
498         case (OP_ALG_PKMODE_COPY_SSZ_N_A):
499         case (OP_ALG_PKMODE_COPY_SSZ_N_B):
500         case (OP_ALG_PKMODE_COPY_SSZ_N_E):
501                 return 0;
502         }
503
504         return -EINVAL;
505 }
506
507 static inline int
508 rta_pkha_operation(struct program *program, uint32_t op_pkha)
509 {
510         uint32_t opcode = CMD_OPERATION | OP_TYPE_PK | OP_ALG_PK;
511         uint32_t pkha_func;
512         unsigned int start_pc = program->current_pc;
513         int ret = -EINVAL;
514
515         pkha_func = op_pkha & OP_ALG_PK_FUN_MASK;
516
517         switch (pkha_func) {
518         case (OP_ALG_PKMODE_CLEARMEM):
519                 ret = __rta_pkha_clearmem(op_pkha);
520                 if (ret < 0) {
521                         pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
522                                program->current_pc);
523                         goto err;
524                 }
525                 break;
526         case (OP_ALG_PKMODE_MOD_ADD):
527         case (OP_ALG_PKMODE_MOD_SUB_AB):
528         case (OP_ALG_PKMODE_MOD_SUB_BA):
529         case (OP_ALG_PKMODE_MOD_MULT):
530         case (OP_ALG_PKMODE_MOD_EXPO):
531         case (OP_ALG_PKMODE_MOD_REDUCT):
532         case (OP_ALG_PKMODE_MOD_INV):
533         case (OP_ALG_PKMODE_MOD_MONT_CNST):
534         case (OP_ALG_PKMODE_MOD_CRT_CNST):
535         case (OP_ALG_PKMODE_MOD_GCD):
536         case (OP_ALG_PKMODE_MOD_PRIMALITY):
537         case (OP_ALG_PKMODE_MOD_SML_EXP):
538         case (OP_ALG_PKMODE_ECC_MOD_ADD):
539         case (OP_ALG_PKMODE_ECC_MOD_DBL):
540         case (OP_ALG_PKMODE_ECC_MOD_MUL):
541                 ret = __rta_pkha_mod_arithmetic(op_pkha);
542                 if (ret < 0) {
543                         pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
544                                program->current_pc);
545                         goto err;
546                 }
547                 break;
548         case (OP_ALG_PKMODE_COPY_NSZ):
549         case (OP_ALG_PKMODE_COPY_SSZ):
550                 ret = __rta_pkha_copymem(op_pkha);
551                 if (ret < 0) {
552                         pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
553                                program->current_pc);
554                         goto err;
555                 }
556                 break;
557         default:
558                 pr_err("Invalid Operation Command\n");
559                 goto err;
560         }
561
562         opcode |= op_pkha;
563
564         __rta_out32(program, opcode);
565         program->current_instruction++;
566         return (int)start_pc;
567
568  err:
569         program->first_error_pc = start_pc;
570         program->current_instruction++;
571         return ret;
572 }
573
574 #endif /* __RTA_OPERATION_CMD_H__ */