blob: 910fcd697006a521eebc0395556e6ea996cf8018 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001/*****************************************************************************
2* Copyright Statement:
3* --------------------
4* This software is protected by Copyright and the information contained
5* herein is confidential. The software may not be copied and the information
6* contained herein may not be used or disclosed except with the written
7* permission of MediaTek Inc. (C) 2013
8*
9* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
10* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
11* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
12* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
13* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
14* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
15* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
16* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
17* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
18* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
19* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
20* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
21*
22* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
23* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
24* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
25* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
26* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
27*
28* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
29* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
30* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
31* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
32* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
33*
34*****************************************************************************/
35/*****************************************************************************
36 *
37 * Filename:
38 * ---------
39 * drv_soe.c
40 *
41 * Description:
42 * ------------
43 * SOE Driver
44 *
45 * Author:
46 * -------
47 * -------
48 *
49 *============================================================================
50 * HISTORY
51 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
52 *------------------------------------------------------------------------------
53 * removed!
54 * removed!
55 * removed!
56 *
57 * removed!
58 * removed!
59 *
60 * removed!
61 * removed!
62 *
63 * removed!
64 * removed!
65 *
66 * removed!
67 * removed!
68 *
69 * removed!
70 * removed!
71 * removed!
72 *
73 * removed!
74 * removed!
75 * removed!
76 *
77 * removed!
78 * removed!
79 *
80 * removed!
81 * removed!
82 *
83 * removed!
84 * removed!
85 *
86 * removed!
87 * removed!
88 *
89 *
90 *------------------------------------------------------------------------------
91 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
92 *============================================================================
93 *****************************************************************************/
94
95
96/*******************************************************************************
97 * Include header files
98 *******************************************************************************/
99#include "kal_general_types.h"
100#include "sleepdrv_interface.h"
101#include "drvpdn.h"
102#include "ex_public.h"
103
104#include "drv_soe_reg.h"
105#include "drv_soe_key.h"
106#include "drv_soe_bm.h"
107#include "drv_soe_engine.h"
108
109#ifdef SOE_CHB_MODE
110 #define SOE_GPD_CHK SOE_CHK_32
111#else
112 #define SOE_GPD_CHK SOE_CHK_28
113#endif
114#define SOE_BD_CHK SOE_CHK_16
115
116#if 0 //defined(ATEST_ENABLE)
117/* under construction !*/
118/* under construction !*/
119/* under construction !*/
120/* under construction !*/
121/* under construction !*/
122#else
123#define DRV_MSG(level, fmt...)
124#endif
125
126#if defined(ATEST_ENABLE)
127kal_uint32 drv_soe_dbg_frc[5];
128kal_uint32 drv_soe_frc_start[5], drv_soe_frc_end[5];
129extern kal_uint32 drv_sm_getCurFRC(void);
130
131#define DRV_DBG_FRC_INIT(t) drv_soe_dbg_frc[t]=0
132#define DRV_DBG_FRC_START(t) do{ drv_soe_frc_start[t] = drv_sm_getCurFRC(); \
133 }while(0)
134
135#define DRV_DBG_FRC_END(t) do{ drv_soe_frc_end[t] = drv_sm_getCurFRC(); \
136 drv_soe_dbg_frc[t] += (drv_soe_frc_end[t] - drv_soe_frc_start[t]); \
137 }while(0)
138#else
139#define DRV_DBG_FRC_INIT(t)
140#define DRV_DBG_FRC_START(t)
141#define DRV_DBG_FRC_END(t)
142#endif
143
144//#define DRV_DISABLE_IRQ
145
146/*******************************************************************************
147 * global variable definitions
148 *******************************************************************************/
149static kal_bool drv_inited = KAL_FALSE;
150static kal_enhmutexid drv_soe_locker;
151static kal_eventgrpid drv_soe_egid;
152#ifdef ATEST_ENABLE
153static void (*drv_soe_lisr_handler_cb)(kal_uint32 vector) = NULL;
154#endif
155
156kal_bool drv_soe_irq_en = KAL_TRUE;
157
158/*******************************************************************************
159 * SOE register dump
160 *******************************************************************************/
161EX_BBREG_DUMP soe_reg_dump;
162const kal_uint32 soe_reg_dump_regions[] = {
163 SOE_BASE, 0xC0, 4,
164 SOE_BASE+0x200, 0xB0, 4,
165 SOE_BASE+0x8000, 0x10, 4,
166};
167
168static void drv_soe_register_bbreg_dump(void)
169{
170 soe_reg_dump.regions = (kal_uint32*)soe_reg_dump_regions;
171 soe_reg_dump.num = sizeof(soe_reg_dump_regions) / (sizeof(kal_uint32) * 3);
172 soe_reg_dump.bbreg_dump_callback = NULL;
173 EX_REGISTER_BBREG_DUMP(&soe_reg_dump);
174}
175
176/*******************************************************************************
177 * Function definitions
178 *******************************************************************************/
179static kal_uint8 drv_soe_calc_chksum(kal_uint8 *data, kal_uint16 len)
180{
181 kal_uint8 *uDataPtr, ckSum;
182 kal_uint16 i;
183
184 *(data + 1) = 0x0;
185 uDataPtr = data;
186 ckSum = 0;
187 for (i = 0; i < len; i++)
188 ckSum += *(uDataPtr + i);
189 return 0xFF - ckSum;
190}
191
192static void drv_soe_set_reg(kal_uint32 reg, kal_uint32 mask, kal_uint32 val, kal_uint32 offset)
193{
194 kal_uint32 tmp;
195 tmp = SOE_REG(reg);
196 tmp &= (~mask);
197 tmp |= (val << offset);
198 SOE_REG(SOE_CR) = tmp;
199}
200
201void drv_soe_lisr(kal_uint32 irq_id)
202{
203 kal_uint32 intr_status;
204
205#ifdef ATEST_ENABLE
206 if(drv_soe_lisr_handler_cb != NULL) {
207 drv_soe_lisr_handler_cb(irq_id);
208 return;
209 }
210#endif
211 intr_status = SOE_REG(SOE_L2ISAR);
212 SOE_REG(SOE_L2ISAR) = intr_status;
213#if defined(MT6297)
214 intr_status |= (SOE_REG(SOE_ASYM_STATUS_REG7) << 8);
215#endif
216 Data_Sync_Barrier();
217 IRQClearInt(SOE_IRQ);
218 Data_Sync_Barrier();
219
220 kal_set_eg_events(drv_soe_egid, intr_status, KAL_OR);
221}
222
223#ifdef ATEST_ENABLE
224void drv_soe_reg_interrupt(void (*handler)(kal_uint32 vector))
225{
226 drv_soe_lisr_handler_cb = handler;
227}
228#endif
229
230void drv_soe_init(void)
231{
232 if(drv_inited) {
233 return;
234 }
235
236 drv_soe_locker = kal_create_enh_mutex("SOEMtx");
237 if(!drv_soe_locker) ASSERT(0);
238
239 drv_soe_egid = kal_create_event_group("SOEEvt");
240 if(!drv_soe_egid) ASSERT(0);
241
242 //move to interface/service/config/kal_config/xxx_isr_config.h
243 //IRQ_Register_LISR(SOE_IRQ, drv_soe_lisr, "SOE handler");
244 //IRQSensitivity(SOE_IRQ, KAL_TRUE);
245 IRQClearInt(SOE_IRQ);
246 IRQUnmask(SOE_IRQ);
247
248 drv_inited = KAL_TRUE;
249 DRV_DBG_FRC_INIT(0);
250 DRV_DBG_FRC_INIT(1);
251 drv_soe_register_bbreg_dump();
252}
253
254static kal_uint32 drv_soe_gen_key_attr(drv_soe_key_attr_t *key_attr, sec_key_t *key_table)
255{
256#ifdef SOE_CHB_MODE
257 kal_uint32 kindex2;
258#endif
259 kal_uint32 i, kindex = 0;
260 kal_bool extKey = KAL_TRUE;
261
262 //Get valid key index
263 for(i=0; i < SOE_DRV_KEY_ENTRY_MAX; i++) {
264 if(!SECK_GET_VALID(key_table[i])) {
265 kindex = i;
266#ifdef SOE_CHB_MODE
267 kindex2 = (i + 1);
268#endif
269 break;
270 }
271 }
272 if(i == (SOE_KEY_ENTRY_MAX + 1)) {
273 return 1;
274 }
275
276 if (key_attr->mode == SECK_CHB) {
277 key_attr->en = SECK_DEC;
278 }
279
280 if((kal_uint32)key_attr->key >= (kal_uint32)key_table &&
281 (kal_uint32)key_attr->key < ((kal_uint32)key_table + sizeof(sec_key_t))) {
282 extKey = KAL_FALSE;
283 }
284 else {
285 memset(&key_table[kindex], 0, sizeof(sec_key_t));
286 }
287 SECK_SET_VALID(key_table[kindex]);
288 key_attr->idx = (kindex + 1);
289
290 if (key_attr->en == SECK_ENC) {
291 SECK_SET_ENC(key_table[kindex]);
292 }
293 else {
294 SECK_SET_DEC(key_table[kindex]);
295 }
296
297 if (key_attr->mode == SECK_CHB) {
298 SECK_SET_MODE(key_table[kindex], SECK_AES);
299 }
300 else {
301 SECK_SET_MODE(key_table[kindex], key_attr->mode);
302 }
303 SECK_SET_OPT(key_table[kindex], key_attr->opt);
304 SECK_SET_ALG(key_table[kindex], key_attr->alg);
305
306 if (key_attr->mode == SECK_DES && key_attr->opt == SECK_OPT_3DES) {
307 SECK_SET_3DES(key_table[kindex], key_attr->desmode);
308 }
309#if defined(SOE_MD97_HW)
310 if (key_attr->mode == SECK_RC5) {
311 rc5_para_t rc5_para;
312 rc5_para.pack.keylen = key_attr->var_key.rc5_len;
313 rc5_para.pack.block = key_attr->ops_para.rc5_attr.word_size / SECK_RC5_WORD_SIZE_BIT_INC;
314 rc5_para.pack.round = key_attr->ops_para.rc5_attr.rounds / SECK_RC5_ROUND_INC ;
315 SECK_SET_RC5_ATTR(key_table[kindex], rc5_para.p);
316 }
317
318 if (key_attr->mode == SECK_IDEA && key_attr->opt == SECK_OPT_3IDEA) {
319 SECK_SET_3IDEA(key_table[kindex], key_attr->ideamode);
320 }
321
322 if (key_attr->mode == SECK_CAST5 || key_attr->mode == SECK_CAST6 || key_attr->mode == SECK_BLOWFISH) {
323 SECK_SET_VAR_KEYLEN(key_table[kindex], key_attr->keylen);
324 }
325 if ((key_attr->mode == SECK_HASH || key_attr->mode == SECK_HMAC) && (key_attr->alg == SECK_ALG_TIGER))
326 {
327 tiger_para_t tiger_para;
328 tiger_para.pack.bits = key_attr->ops_para.tiger_attr.bits;
329 tiger_para.pack.rounds = key_attr->ops_para.tiger_attr.rounds;
330 SECK_SET_TIGER_ATTR(key_table[kindex], tiger_para.p);
331 }
332#endif
333 /*MSG(MSG_INFO, "%s mod = %d\r\n", __FUNCTION__, attr->mode);*/
334
335 if (key_attr->key && extKey) {
336 SECK_SET_KEY(key_table[kindex], key_attr->key, key_attr->keylen);
337 }
338 SOE_CACHE_STORE(&key_table[kindex], sizeof(sec_key_t));
339#ifdef SOE_CHB_MODE
340 if (key_attr->mode == SECK_CHB) {
341 if(extKey) {
342 memset(&key_table[kindex2], 0, sizeof(sec_key_t));
343 }
344 SECK_SET_VALID(key_table[kindex2]);
345 key_attr->idx2 = (kindex2 + 1);
346
347 if (key_attr->en == SECK_ENC) {
348 SECK_SET_ENC(key_table[kindex2]);
349 }
350 else {
351 SECK_SET_DEC(key_table[kindex2]);
352 }
353
354 SECK_SET_MODE(key_table[kindex2], SECK_HMAC);
355 SECK_SET_OPT(key_table[kindex2], key_attr->opt2);
356 SECK_SET_ALG(key_table[kindex2], key_attr->alg2);
357
358 if (key_attr->key2 && extKey) {
359 SECK_SET_KEY(key_table[kindex2], key_attr->key2, key_attr->keylen2);
360 }
361 SOE_CACHE_STORE(&key_table[kindex2], sizeof(sec_key_t));
362 }
363#endif
364 return 0;
365}
366
367static kal_uint32 drv_soe_list_init(drv_soe_list_attr_t *attr)
368{
369 kal_uint16 i, type;
370 gpd_t *gpd_now = NULL, *gpd_new;
371 bd_t *bd_now = NULL, *bd_new;
372 drv_soe_gpd_attr_t *gpd_attr;
373 drv_soe_key_attr_t *key_attr;
374 kal_uint32 len;
375 kal_uint8 *buf;
376
377 for (i = 0; i < attr->gpdnum; i++) {
378 /* reset variable */
379 gpd_attr = &attr->gpd[i];
380 key_attr = &attr->key[i];
381 bd_now = NULL;
382 gpd_new = gpd_attr->gpd;
383 if (gpd_now != NULL) {
384 SOE_SET_NEXT(gpd_now, virt_to_phys(gpd_new));
385 SOE_SET_CHKSUM(gpd_now, SOE_GPD_CHK);
386 }
387 memset(gpd_new, 0, GPD_SIZE);
388 SOE_SET_FLAGS_HWO(gpd_new);
389 if (gpd_attr->bd == NULL) {
390 SOE_CLR_FLAGS_BDP(gpd_new);
391 } else {
392 SOE_SET_FLAGS_BDP(gpd_new);
393 }
394 SOE_CLR_FORMAT_VR(gpd_new);
395
396 if(!SOE_IS_DYNA_DRAM((kal_uint32)gpd_attr->outbuf, gpd_attr->outlen)) {
397 return DRV_SOE_ERR_INVALID_PTR;
398 }
399 if(query_is_cached_ram((kal_uint32)gpd_attr->outbuf, gpd_attr->outlen)) {
400 SOE_CACHE_STORE(gpd_attr->outbuf, gpd_attr->outlen);
401 SOE_CACHE_INVALIDATE(gpd_attr->outbuf, gpd_attr->outlen);
402 gpd_attr->outbuf = (kal_uint8*)virt_to_phys(gpd_attr->outbuf);
403 }
404 SOE_SET_BUF_LEN(gpd_new, gpd_attr->buflen);
405 SOE_SET_OUTPTR(gpd_new, gpd_attr->outbuf);
406
407 if(gpd_attr->icblen) {
408 if(!SOE_IS_DYNA_DRAM((kal_uint32)gpd_attr->icb, gpd_attr->icblen)) {
409 return DRV_SOE_ERR_INVALID_PTR;
410 }
411 if(query_is_cached_ram((kal_uint32)gpd_attr->icb, gpd_attr->icblen)) {
412 SOE_CACHE_STORE(gpd_attr->icb, gpd_attr->icblen);
413 gpd_attr->icb = (kal_uint8*)virt_to_phys(gpd_attr->icb);
414 }
415 SOE_SET_ICBPTR(gpd_new, gpd_attr->icb);
416 if(key_attr->alg == SECK_ALG_CBC) {
417#if defined(SOE_MD97_HW) && !defined(MT6297)
418 SOE_SET_FORMAT_UI(gpd_new);
419#else
420 /* Apollo is not ready for using UI with new algorithms */
421 do {
422 if(key_attr->mode == SECK_DES || key_attr->mode == SECK_AES)
423 SOE_SET_FORMAT_UI(gpd_new);
424 }while(0);
425#endif
426 }
427 }
428 else {
429 SOE_SET_ICBPTR(gpd_new, gpd_attr->outbuf); //dummy ptr
430 }
431
432 if(gpd_attr->icvlen) {
433 if(!SOE_IS_DYNA_DRAM((kal_uint32)gpd_attr->icv, gpd_attr->icvlen)) {
434 return DRV_SOE_ERR_INVALID_PTR;
435 }
436 if(query_is_cached_ram((kal_uint32)gpd_attr->icv, gpd_attr->icvlen)) {
437 SOE_CACHE_STORE(gpd_attr->icv, gpd_attr->icvlen);
438 SOE_CACHE_INVALIDATE(gpd_attr->icv, gpd_attr->icvlen);
439 gpd_attr->icv = (kal_uint8*)virt_to_phys(gpd_attr->icv);
440 }
441 SOE_SET_ICVPTR(gpd_new, gpd_attr->icv);
442 }
443 else {
444 SOE_SET_ICVPTR(gpd_new, gpd_attr->outbuf); //dummy ptr
445 }
446 SOE_SET_KEY_IDX(gpd_new, gpd_attr->keyidx);
447#ifdef SOE_CHB_MODE
448 SOE_SET_KEY_IDX2(gpd_new, gpd_attr->keyidx2);
449 SOE_SET_CIPHER_OFFSET(gpd_new, gpd_attr->cipher_offset);
450 if (key_attr->mode == SECK_CHB) {
451 SOE_SET_FORMAT_CHB(gpd_new);
452 }
453 else {
454 SOE_CLR_FORMAT_CHB(gpd_new);
455 }
456#endif
457
458 if (gpd_attr->bd == NULL) {
459 /* No BD, set data ptr */
460 if(!SOE_IS_DYNA_DRAM((kal_uint32)gpd_attr->inbuf, gpd_attr->inlen)) {
461 return DRV_SOE_ERR_INVALID_PTR;
462 }
463 if(query_is_cached_ram((kal_uint32)gpd_attr->inbuf, gpd_attr->inlen)) {
464 SOE_CACHE_STORE(gpd_attr->inbuf, gpd_attr->inlen);
465 gpd_attr->inbuf = (kal_uint8*)virt_to_phys(gpd_attr->inbuf);
466 }
467 SOE_SET_DATA(gpd_new, gpd_attr->inbuf);
468 } else {
469 /* Generate BDs */
470 for (type = 0; type < 2; type++) {
471 if(key_attr->alg == SECK_ALG_XCBC) {
472 // XCBC
473 buf = type ? gpd_attr->inbuf : gpd_attr->icb;
474 len = type ? gpd_attr->inlen : gpd_attr->icblen;
475 }
476 else {
477 // CCM/GCM
478 buf = type ? gpd_attr->inbuf : gpd_attr->abuf;
479 len = type ? gpd_attr->inlen : gpd_attr->alen;
480 }
481
482 if(!SOE_IS_DYNA_DRAM((kal_uint32)buf, len)) {
483 return DRV_SOE_ERR_INVALID_PTR;
484 }
485 if(query_is_cached_ram((kal_uint32)buf, len)) {
486 SOE_CACHE_STORE(buf, len);
487 buf = (kal_uint8*)virt_to_phys(buf);
488 }
489 bd_new = &gpd_attr->bd[type];
490
491 /* set data ptr */
492 memset(bd_new, 0, BD_SIZE);
493 BD_SET_DATA(bd_new, buf);
494 BD_SET_BUF_LEN(bd_new, len);
495 /* set list */
496 if (bd_now == NULL) {
497 SOE_SET_BD(gpd_new, virt_to_phys(bd_new));
498 } else {
499 if(!len)
500 BD_SET_FLAGS_EOL(bd_now);
501 BD_SET_NEXT(bd_now, virt_to_phys(bd_new));
502 BD_SET_CHKSUM(bd_now, SOE_BD_CHK);
503 SOE_CACHE_STORE(bd_now, BD_SIZE);
504 }
505 if (type == 1) { /* last BD */
506 BD_SET_FLAGS_EOL(bd_new);
507 }
508 bd_now = bd_new;
509 }
510 BD_SET_CHKSUM(bd_now, SOE_BD_CHK);
511 SOE_CACHE_STORE(bd_now, BD_SIZE);
512 }
513 SOE_SET_CHKSUM(gpd_new, SOE_GPD_CHK);
514 SOE_CACHE_STORE(gpd_new, GPD_SIZE);
515 gpd_now = gpd_new;
516 }
517 /* link last GPD */
518 gpd_new = (gpd_t *)&gpd_now[1];
519 SOE_SET_NEXT(gpd_now, virt_to_phys(gpd_new));
520 SOE_SET_FLAGS_INT(gpd_now);
521 SOE_SET_CHKSUM(gpd_now, SOE_GPD_CHK);
522 SOE_CACHE_STORE(gpd_now, GPD_SIZE);
523 memset(gpd_new, 0, GPD_SIZE);
524 SOE_CACHE_STORE(gpd_new, GPD_SIZE);
525 return 0;
526}
527
528static kal_uint32 drv_soe_gen_gpd_attr(drv_soe_gpd_attr_t *attr, drv_soe_key_attr_t *key)
529{
530 kal_uint32 err = 0;
531
532 // check keylen and datalen
533 switch(key->mode) {
534 case SECK_NULL:
535 err = 0;
536 break;
537 case SECK_HMAC:
538 switch(key->alg) {
539 case SECK_ALG_MD5:
540 case SECK_ALG_SHA1:
541 case SECK_ALG_SHA256:
542#if defined(SOE_MD97_HW)
543 case SECK_ALG_TIGER:
544#endif
545 if(key->keylen != 64) err = DRV_SOE_ERR_KEYLEN;
546 break;
547 case SECK_ALG_SHA384:
548 case SECK_ALG_SHA512:
549 if(key->keylen != 128) err = DRV_SOE_ERR_KEYLEN;
550 break;
551 default:
552 err = DRV_SOE_ERR_ALG;
553 break;
554 }
555 //following check as HASH
556 case SECK_HASH:
557 if(attr->inlen > 65535) err = DRV_SOE_ERR_INLEN;
558#if defined(SOE_MD97_HW)
559 if(key->alg > SECK_ALG_TIGER) err = DRV_SOE_ERR_ALG;
560#else
561 if(key->alg > SECK_ALG_SHA512) err = DRV_SOE_ERR_ALG;
562#endif
563 switch(key->alg) {
564 case SECK_ALG_MD5:
565 if(attr->outlen != 16) err = DRV_SOE_ERR_OUTLEN;
566 break;
567 case SECK_ALG_SHA1:
568 if(attr->outlen != 20) err = DRV_SOE_ERR_OUTLEN;
569 break;
570 case SECK_ALG_SHA256:
571 if(attr->outlen != 32) err = DRV_SOE_ERR_OUTLEN;
572 break;
573 case SECK_ALG_SHA384:
574 if(attr->outlen != 48) err = DRV_SOE_ERR_OUTLEN;
575 break;
576 case SECK_ALG_SHA512:
577 if(attr->outlen != 64) err = DRV_SOE_ERR_OUTLEN;
578 break;
579#if defined(SOE_MD97_HW)
580 case SECK_ALG_TIGER:
581 if(attr->outlen != 16 && attr->outlen != 24 && attr->outlen != 32) err = DRV_SOE_ERR_OUTLEN;
582 break;
583#endif
584 default:
585 err = DRV_SOE_ERR_ALG;
586 break;
587 }
588 break;
589 case SECK_DES:
590 if(key->opt > SECK_OPT_3DES) err = DRV_SOE_ERR_OPT;
591 if(key->alg > SECK_ALG_CBC) err = DRV_SOE_ERR_ALG;
592 if(!(attr->inlen == 8 || (attr->inlen >= 16 && attr->inlen <= 65528))) err = DRV_SOE_ERR_INLEN;
593 if(attr->inlen != attr->outlen) err = DRV_SOE_ERR_OUTLEN;
594 if(key->opt == SECK_OPT_DES && key->keylen != 8) err = DRV_SOE_ERR_KEYLEN;
595 if(key->opt == SECK_OPT_3DES && key->keylen != 24) err = DRV_SOE_ERR_KEYLEN;
596 if(key->alg == SECK_ALG_CBC && attr->icblen != 8) err = DRV_SOE_ERR_ICBLEN;
597 break;
598 case SECK_AES:
599 if(key->alg != SECK_ALG_XCBC && key->alg != SECK_ALG_CMAC) {
600 if(key->opt > SECK_AES_256) err = DRV_SOE_ERR_OPT;
601 if(attr->inlen != attr->outlen) err = DRV_SOE_ERR_OUTLEN;
602 }
603 else {
604 if(key->opt > SECK_AES_128) err = DRV_SOE_ERR_OPT;
605 if(attr->inlen > 65535) err = DRV_SOE_ERR_INLEN;
606 if(key->en == SECK_DEC && attr->icvlen != 16) err = DRV_SOE_ERR_ICVLEN;
607 }
608 switch(key->alg) {
609 case SECK_ALG_CBC:
610 if(attr->icblen != 16) err = DRV_SOE_ERR_ICBLEN;
611 //following check as ECB
612 case SECK_ALG_ECB:
613 if(!(attr->inlen == 16 || (attr->inlen >= 32 && attr->inlen <= 65520))) err = DRV_SOE_ERR_INLEN;
614 break;
615 case SECK_ALG_CTR:
616 if(attr->inlen == 0 || attr->inlen > 65535) {
617 err = DRV_SOE_ERR_INLEN;
618 }
619 if(attr->icblen != 16) err = DRV_SOE_ERR_ICBLEN;
620 break;
621 case SECK_ALG_CCM:
622 case SECK_ALG_GCM:
623 //check in next stage
624 default:
625 break;
626 }
627 break;
628#if defined(SOE_MD97_HW)
629 case SECK_RC5:
630 if(key->opt != 0) err = DRV_SOE_ERR_OPT;
631 if(key->alg > SECK_ALG_CBC) err = DRV_SOE_ERR_ALG;
632 if(!(attr->inlen == 8 || (attr->inlen >= 16 && attr->inlen <= 65528))) err = DRV_SOE_ERR_INLEN;
633 if(attr->inlen != attr->outlen) err = DRV_SOE_ERR_OUTLEN;
634 if(key->alg == SECK_ALG_CBC && (attr->icblen != 4 && attr->icblen != 8 && attr->icblen != 16)) err = DRV_SOE_ERR_ICBLEN;
635 if(key->keylen == 0 /*|| key->keylen > 255 */) err = DRV_SOE_ERR_KEYLEN;
636 break;
637 case SECK_IDEA:
638 if(key->opt > SECK_OPT_3IDEA) err = DRV_SOE_ERR_OPT;
639 if(key->alg > SECK_ALG_CBC) err = DRV_SOE_ERR_ALG;
640 if(!(attr->inlen == 8 || (attr->inlen >= 16 && attr->inlen <= 65528))) err = DRV_SOE_ERR_INLEN;
641 if(attr->inlen != attr->outlen) err = DRV_SOE_ERR_OUTLEN;
642 if(key->opt == SECK_OPT_IDEA && key->keylen != 16) err = DRV_SOE_ERR_KEYLEN;
643 if(key->opt == SECK_OPT_3IDEA && key->keylen != 48) err = DRV_SOE_ERR_KEYLEN;
644 if(key->alg == SECK_ALG_CBC && attr->icblen != 8) err = DRV_SOE_ERR_ICBLEN;
645 break;
646 case SECK_CAST5:
647 if(key->opt != 0) err = DRV_SOE_ERR_OPT;
648 if(key->alg > SECK_ALG_CBC) err = DRV_SOE_ERR_ALG;
649 if(!(attr->inlen == 8 || (attr->inlen >= 16 && attr->inlen <= 65528))) err = DRV_SOE_ERR_INLEN;
650 if(attr->inlen != attr->outlen) err = DRV_SOE_ERR_OUTLEN;
651 if(key->alg == SECK_ALG_CBC && attr->icblen != 8) err = DRV_SOE_ERR_ICBLEN;
652 if(key->keylen < 5 || key->keylen > 16) err = DRV_SOE_ERR_KEYLEN;
653 break;
654 case SECK_CAST6:
655 if(key->opt != 0) err = DRV_SOE_ERR_OPT;
656 if(key->alg > SECK_ALG_CBC) err = DRV_SOE_ERR_ALG;
657 if(!(attr->inlen == 16 || (attr->inlen >= 32 && attr->inlen <= 65520))) err = DRV_SOE_ERR_INLEN;
658 if(attr->inlen != attr->outlen) err = DRV_SOE_ERR_OUTLEN;
659 if(key->alg == SECK_ALG_CBC && attr->icblen != 16) err = DRV_SOE_ERR_ICBLEN;
660 if(key->keylen < 16 || key->keylen > 32 || (key->keylen & 3) != 0) err = DRV_SOE_ERR_KEYLEN;
661 break;
662 case SECK_BLOWFISH:
663 if(key->opt != 0) err = DRV_SOE_ERR_OPT;
664 if(key->alg > SECK_ALG_CBC) err = DRV_SOE_ERR_ALG;
665 if(!(attr->inlen == 8 || (attr->inlen >= 16 && attr->inlen <= 65528))) err = DRV_SOE_ERR_INLEN;
666 if(attr->inlen != attr->outlen) err = DRV_SOE_ERR_OUTLEN;
667 if(key->alg == SECK_ALG_CBC && attr->icblen != 8) err = DRV_SOE_ERR_ICBLEN;
668 if(key->keylen < 4 || key->keylen > 56) err = DRV_SOE_ERR_KEYLEN;
669 break;
670 case SECK_CHB:
671 if (key->opt != SECK_AES_128) err = DRV_SOE_ERR_OPT;
672 if (key->alg != SECK_ALG_CBC) err = DRV_SOE_ERR_ALG;
673 if (key->alg2 > SECK_ALG_SHA256) err = 3;
674 break;
675 case SECK_RSADH:
676 if (key->opt != 0) err = DRV_SOE_ERR_OPT;
677 if (key->alg > SECK_ALG_MODEXP) err = DRV_SOE_ERR_ALG;
678 break;
679 case SECK_ECC:
680 if (key->opt != 0) err = DRV_SOE_ERR_OPT;
681 if (key->alg > SECK_ALG_PADD) err = DRV_SOE_ERR_ALG;
682 break;
683#endif
684 default:
685 err = DRV_SOE_ERR_MODE;
686 }
687
688 //check CHB mode
689 if (key->mode != SECK_CHB) {
690 if ((key->mode == SECK_AES) && (key->alg == SECK_ALG_CCM || key->alg == SECK_ALG_GCM)) {
691 attr->buflen = attr->inlen;
692 if((attr->inlen + attr->alen) > 65535) {
693 err = DRV_SOE_ERR_CHBLEN;
694 }
695 }
696 else {
697 attr->alen = 0;
698 }
699 }
700 else {
701 attr->alen = 0;
702 }
703 if(err) {
704 DRV_MSG(MSG_INFO, "%s err: %x\r\n", __FUNCTION__, err);
705 return err;
706 }
707
708 //assign keyidx
709 attr->keyidx = key->idx;
710 if (key->mode == SECK_CHB) {
711 attr->keyidx2 = key->idx2;
712 }
713 DRV_MSG(MSG_INFO, "%s keyidx:%d keyidx2:%d\r\n", __FUNCTION__, attr->keyidx, attr->keyidx2);
714
715 return 0;
716}
717
718kal_uint32 drv_soe_gen_attr(drv_soe_ctrl_struct_t *ctrl)
719{
720 drv_soe_list_attr_t *attr = &ctrl->list_attr;
721 kal_uint32 i, idx, ret;
722
723 DRV_DBG_FRC_START(0);
724
725 // check ptr
726 if(ctrl->gpd == NULL || ctrl->key == NULL) {
727 return DRV_SOE_ERR_INVALID_PTR;
728 }
729 if(!SOE_IS_DYNA_DRAM((kal_uint32)ctrl->gpd, sizeof(gpd_t))) {
730 return DRV_SOE_ERR_INVALID_PTR;
731 }
732 if(!SOE_IS_DYNA_DRAM((kal_uint32)ctrl->key, sizeof(sec_key_t))) {
733 return DRV_SOE_ERR_INVALID_PTR;
734 }
735
736 // set key table
737 for(i = 0, idx = 0; i < attr->gpdnum; i++) {
738 if(idx == (SOE_DRV_GPD_MAX + 1)) {
739 return DRV_SOE_ERR_GPD_OVERFLOW;
740 }
741
742 ret = drv_soe_gen_key_attr(&attr->key[i], ctrl->key);
743 if(ret) {
744 DRV_MSG(MSG_INFO, "%s gen_key err: %x\r\n", __FUNCTION__, ret);
745 return ret;
746 }
747
748 if(attr->gpd[i].alen > 0) {
749 ret = attr->key[i].idx - 1;
750 SECK_SET_ADATA(ctrl->key[ret], attr->gpd[i].alen);
751 SOE_CACHE_STORE(&ctrl->key[ret], sizeof(sec_key_t));
752 }
753
754 memset(&ctrl->gpd[idx], 0, sizeof(gpd_t));
755 attr->gpd[i].gpd = &ctrl->gpd[idx++];
756 ret = drv_soe_gen_gpd_attr(&attr->gpd[i], &attr->key[i]);
757 if(ret) {
758 DRV_MSG(MSG_INFO, "%s gen_gpd err: %x\r\n", __FUNCTION__, ret);
759 return ret;
760 }
761 if(attr->gpd[i].alen || (attr->key[i].mode == SECK_AES && attr->key[i].alg == SECK_ALG_XCBC && attr->gpd[i].icblen) ) {
762 memset(&ctrl->gpd[idx], 0, sizeof(gpd_t));
763 attr->gpd[i].bd = (bd_t*)&ctrl->gpd[attr->gpdnum + idx];
764 }
765 }
766 ret = drv_soe_list_init(attr);
767
768#ifdef ATEST_ENABLE
769 if(!ret)
770 ctrl->r_gpd_cnt += attr->gpdnum;
771#endif
772 DRV_DBG_FRC_END(0);
773 return ret;
774}
775
776kal_uint32 drv_soe_update_attr(drv_soe_ctrl_struct_t *ctrl)
777{
778 drv_soe_list_attr_t *attr = &ctrl->list_attr;
779 kal_uint32 ret;
780
781 DRV_DBG_FRC_START(0);
782
783 // check ctrl
784 if(!SOE_GET_NEXT(ctrl->gpd)) {
785 return DRV_SOE_ERR_INVALID_GPD;
786 }
787
788 // update GPD
789 ret = drv_soe_list_init(attr);
790
791#ifdef ATEST_ENABLE
792 if(!ret)
793 ctrl->r_gpd_cnt += attr->gpdnum;
794#endif
795 DRV_DBG_FRC_END(0);
796 return ret;
797}
798
799kal_uint32 drv_soe_trigger(gpd_t *pGpd, sec_key_t *pKey)
800{
801 kal_uint32 err = 0;
802 kal_uint32 event_group = 0;
803 kal_uint32 soe_timeout_ticks;
804 gpd_t *last_gpd = pGpd;
805
806 //check GPD/KEY
807 if(last_gpd == NULL || pKey == NULL) return DRV_SOE_ERR_INVALID_PTR;
808 if((kal_uint32)last_gpd & 0x3) return DRV_SOE_ERR_INVALID_PTR;
809 if((kal_uint32)pKey & 0x3) return DRV_SOE_ERR_INVALID_PTR;
810 if(!SOE_IS_DYNA_DRAM((kal_uint32)pGpd, sizeof(gpd_t))) return DRV_SOE_ERR_INVALID_PTR;
811
812 pKey = (sec_key_t*)((kal_uint32)pKey - sizeof(sec_key_t));
813 if(!SOE_IS_DYNA_DRAM((kal_uint32)pKey, sizeof(sec_key_t))) return DRV_SOE_ERR_INVALID_PTR;
814 while(SOE_IS_FLAGS_HWO(last_gpd)) {
815 if(!SECK_GET_VALID(pKey[last_gpd->keyidx])) return DRV_SOE_ERR_INVALID_KEY;
816 if(last_gpd->pnext == NULL) return DRV_SOE_ERR_INVALID_PNEXT;
817 if(last_gpd->icbptr == NULL) return DRV_SOE_ERR_INVALID_ICB;
818 if(last_gpd->icvptr == NULL) return DRV_SOE_ERR_INVALID_ICV;
819 last_gpd = last_gpd->pnext;
820 }
821 if(last_gpd == pGpd) return DRV_SOE_ERR_INVALID_GPD;
822
823 DRV_DBG_FRC_START(0);
824
825 //check drv init
826 if(!drv_inited) {
827 drv_soe_init();
828 }
829
830 //mutex lock
831 kal_take_enh_mutex(drv_soe_locker);
832 SleepDrv_LockSleep(SLEEP_CTL_SOE, SMP);
833 PDN_CLR(PDN_SOE);
834
835 //check SOE status
836 Data_Mem_Barrier();
837 if(SOE_REG(SOE_QCSR) & SOQ_STAT) {
838 err = DRV_SOE_ERR_STAT_BUSY;
839 goto EngineError;
840 }
841
842 //unmask irq
843#ifndef DRV_DISABLE_IRQ
844 if(drv_soe_irq_en) {
845 SOE_REG(SOE_L2ISAR) = 0xFFFFFFFF;
846 SOE_REG(SOE_L2IMCR) = 0xFFFFFFFF;
847 IRQClearInt(SOE_IRQ);
848 IRQUnmask(SOE_IRQ);
849 }
850#endif
851
852 //config SOE
853#if defined(MT6297)
854 SOE_REG(SOE_ASYM_STATUS_REG7) = 0xFFFFFFFF;
855#endif
856 SOE_REG(SOE_CR) = (SOE_CS_EN | SOE_CSALL_EN);
857 drv_soe_set_reg(SOE_CR, SOE_DMA_MODE, SOE_DMA_MODE, SOE_DMA_MODE_BITS);
858 if(query_is_cached_ram((kal_uint32)pKey, sizeof(sec_key_t))) {
859 SOE_REG(SOE_KTSAR) = virt_to_phys(pKey);
860 }
861 else {
862 SOE_REG(SOE_KTSAR) = (kal_uint32)pKey;
863 }
864 if(query_is_cached_ram((kal_uint32)pGpd, sizeof(gpd_t))) {
865 SOE_REG(SOE_QSAR) = virt_to_phys(pGpd);
866 }
867 else {
868 SOE_REG(SOE_QSAR) = (kal_uint32)pGpd;
869 }
870
871 //start queue
872 Data_Mem_Barrier();
873 DRV_DBG_FRC_START(1);
874 SOE_REG(SOE_QCSR) = SOQ_START;
875 Data_Sync_Barrier();
876
877 //wait done
878#ifndef DRV_DISABLE_IRQ
879 if(drv_soe_irq_en) {
880 kal_retrieve_eg_events(drv_soe_egid, (SO_ERROR_MASK | SO_DONE), KAL_OR_CONSUME, &event_group, KAL_SUSPEND);
881 }
882 else
883#endif
884 {
885 soe_timeout_ticks = drv_get_current_time();
886 while(SOE_REG(SOE_QCSR) & SOQ_STAT) {
887 if(drv_get_duration_ms(soe_timeout_ticks) > 8000) {
888 DRV_DBG_FRC_END(1);
889 err = DRV_SOE_ERR_STAT_BUSY;
890 goto EngineError;
891 }
892 }
893 event_group = SOE_REG(SOE_L2ISAR);
894 #if defined(MT6297)
895 event_group |= (SOE_REG(SOE_ASYM_STATUS_REG7) << 8);
896 #endif
897 }
898 DRV_DBG_FRC_END(1);
899 if(event_group & SO_GPD_CSERR) err = DRV_SOE_ERR_GPD_CSERR;
900 if(event_group & SO_BD_CSERR) err = DRV_SOE_ERR_BD_CSERR;
901 if(event_group & SO_LENERR) err = DRV_SOE_ERR_LENERR;
902 if(event_group & SO_KTERR) err = DRV_SOE_ERR_KTERR;
903 if(SOE_IS_FORMAT_VR(pGpd)) err = DRV_SOE_ERR_VRERR;
904 if(event_group & SO_ASYM_ERROR_MASK) err = DRV_SOE_ERR_ASYMERR;
905 if(err) goto EngineError;
906
907 SOE_REG(SOE_L2IMSR) = 0xFFFFFFFF;
908 Data_Sync_Barrier();
909EngineError:
910 PDN_SET(PDN_SOE);
911 SleepDrv_UnlockSleep(SLEEP_CTL_SOE, SMP);
912 kal_give_enh_mutex(drv_soe_locker);
913 DRV_DBG_FRC_END(0);
914 return err;
915}
916
917void drv_soe_cache_ctrl(kal_bool clean, kal_bool invalidate, kal_uint32 addr, kal_uint32 ln)
918{
919 if(clean)
920 SOE_CACHE_STORE(addr, ln);
921 if(invalidate)
922 SOE_CACHE_INVALIDATE(addr, ln);
923}
924
925void* drv_soe_memcpy(kal_uint8 *dst, kal_uint8 *src, kal_uint32 ln)
926{
927 return memcpy((kal_uint8*)virt_to_phys(dst), \
928 (kal_uint8*)virt_to_phys(src), \
929 ln);
930}
931
932//Call from devdrv_common.c Drv_Init_Phase2()
933void SOE_Drv_Init(void)
934{
935 drv_soe_init();
936 PDN_SET(PDN_SOE);
937}