| .. | .. |
|---|
| 3 | 3 | * caam descriptor construction helper functions |
|---|
| 4 | 4 | * |
|---|
| 5 | 5 | * Copyright 2008-2012 Freescale Semiconductor, Inc. |
|---|
| 6 | + * Copyright 2019 NXP |
|---|
| 6 | 7 | */ |
|---|
| 7 | 8 | |
|---|
| 8 | 9 | #ifndef DESC_CONSTR_H |
|---|
| .. | .. |
|---|
| 13 | 14 | |
|---|
| 14 | 15 | #define IMMEDIATE (1 << 23) |
|---|
| 15 | 16 | #define CAAM_CMD_SZ sizeof(u32) |
|---|
| 16 | | -#define CAAM_PTR_SZ sizeof(dma_addr_t) |
|---|
| 17 | +#define CAAM_PTR_SZ caam_ptr_sz |
|---|
| 18 | +#define CAAM_PTR_SZ_MAX sizeof(dma_addr_t) |
|---|
| 19 | +#define CAAM_PTR_SZ_MIN sizeof(u32) |
|---|
| 17 | 20 | #define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE) |
|---|
| 18 | | -#define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3) |
|---|
| 21 | +#define __DESC_JOB_IO_LEN(n) (CAAM_CMD_SZ * 5 + (n) * 3) |
|---|
| 22 | +#define DESC_JOB_IO_LEN __DESC_JOB_IO_LEN(CAAM_PTR_SZ) |
|---|
| 23 | +#define DESC_JOB_IO_LEN_MAX __DESC_JOB_IO_LEN(CAAM_PTR_SZ_MAX) |
|---|
| 24 | +#define DESC_JOB_IO_LEN_MIN __DESC_JOB_IO_LEN(CAAM_PTR_SZ_MIN) |
|---|
| 25 | + |
|---|
| 26 | +/* |
|---|
| 27 | + * The CAAM QI hardware constructs a job descriptor which points |
|---|
| 28 | + * to shared descriptor (as pointed by context_a of FQ to CAAM). |
|---|
| 29 | + * When the job descriptor is executed by deco, the whole job |
|---|
| 30 | + * descriptor together with shared descriptor gets loaded in |
|---|
| 31 | + * deco buffer which is 64 words long (each 32-bit). |
|---|
| 32 | + * |
|---|
| 33 | + * The job descriptor constructed by QI hardware has layout: |
|---|
| 34 | + * |
|---|
| 35 | + * HEADER (1 word) |
|---|
| 36 | + * Shdesc ptr (1 or 2 words) |
|---|
| 37 | + * SEQ_OUT_PTR (1 word) |
|---|
| 38 | + * Out ptr (1 or 2 words) |
|---|
| 39 | + * Out length (1 word) |
|---|
| 40 | + * SEQ_IN_PTR (1 word) |
|---|
| 41 | + * In ptr (1 or 2 words) |
|---|
| 42 | + * In length (1 word) |
|---|
| 43 | + * |
|---|
| 44 | + * The shdesc ptr is used to fetch shared descriptor contents |
|---|
| 45 | + * into deco buffer. |
|---|
| 46 | + * |
|---|
| 47 | + * Apart from shdesc contents, the total number of words that |
|---|
| 48 | + * get loaded in deco buffer are '8' or '11'. The remaining words |
|---|
| 49 | + * in deco buffer can be used for storing shared descriptor. |
|---|
| 50 | + */ |
|---|
| 51 | +#define MAX_SDLEN ((CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN_MIN) / CAAM_CMD_SZ) |
|---|
| 19 | 52 | |
|---|
| 20 | 53 | #ifdef DEBUG |
|---|
| 21 | 54 | #define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\ |
|---|
| .. | .. |
|---|
| 36 | 69 | (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT)) |
|---|
| 37 | 70 | |
|---|
| 38 | 71 | extern bool caam_little_end; |
|---|
| 72 | +extern size_t caam_ptr_sz; |
|---|
| 73 | + |
|---|
| 74 | +/* |
|---|
| 75 | + * HW fetches 4 S/G table entries at a time, irrespective of how many entries |
|---|
| 76 | + * are in the table. It's SW's responsibility to make sure these accesses |
|---|
| 77 | + * do not have side effects. |
|---|
| 78 | + */ |
|---|
| 79 | +static inline int pad_sg_nents(int sg_nents) |
|---|
| 80 | +{ |
|---|
| 81 | + return ALIGN(sg_nents, 4); |
|---|
| 82 | +} |
|---|
| 39 | 83 | |
|---|
| 40 | 84 | static inline int desc_len(u32 * const desc) |
|---|
| 41 | 85 | { |
|---|
| .. | .. |
|---|
| 92 | 136 | |
|---|
| 93 | 137 | static inline void append_ptr(u32 * const desc, dma_addr_t ptr) |
|---|
| 94 | 138 | { |
|---|
| 95 | | - dma_addr_t *offset = (dma_addr_t *)desc_end(desc); |
|---|
| 139 | + if (caam_ptr_sz == sizeof(dma_addr_t)) { |
|---|
| 140 | + dma_addr_t *offset = (dma_addr_t *)desc_end(desc); |
|---|
| 96 | 141 | |
|---|
| 97 | | - *offset = cpu_to_caam_dma(ptr); |
|---|
| 142 | + *offset = cpu_to_caam_dma(ptr); |
|---|
| 143 | + } else { |
|---|
| 144 | + u32 *offset = (u32 *)desc_end(desc); |
|---|
| 145 | + |
|---|
| 146 | + *offset = cpu_to_caam_dma(ptr); |
|---|
| 147 | + } |
|---|
| 98 | 148 | |
|---|
| 99 | 149 | (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + |
|---|
| 100 | 150 | CAAM_PTR_SZ / CAAM_CMD_SZ); |
|---|
| .. | .. |
|---|
| 189 | 239 | } |
|---|
| 190 | 240 | APPEND_CMD_RET(jump, JUMP) |
|---|
| 191 | 241 | APPEND_CMD_RET(move, MOVE) |
|---|
| 242 | +APPEND_CMD_RET(move_len, MOVE_LEN) |
|---|
| 192 | 243 | |
|---|
| 193 | 244 | static inline void set_jump_tgt_here(u32 * const desc, u32 *jump_cmd) |
|---|
| 194 | 245 | { |
|---|
| .. | .. |
|---|
| 327 | 378 | u32 options) \ |
|---|
| 328 | 379 | { \ |
|---|
| 329 | 380 | PRINT_POS; \ |
|---|
| 330 | | - append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \ |
|---|
| 381 | + if (options & LDST_LEN_MASK) \ |
|---|
| 382 | + append_cmd(desc, CMD_##op | IMMEDIATE | options); \ |
|---|
| 383 | + else \ |
|---|
| 384 | + append_cmd(desc, CMD_##op | IMMEDIATE | options | \ |
|---|
| 385 | + sizeof(type)); \ |
|---|
| 331 | 386 | append_cmd(desc, immediate); \ |
|---|
| 332 | 387 | } |
|---|
| 333 | 388 | APPEND_CMD_RAW_IMM(load, LOAD, u32); |
|---|
| .. | .. |
|---|
| 441 | 496 | * functions where it is used. |
|---|
| 442 | 497 | * @keylen: length of the provided algorithm key, in bytes |
|---|
| 443 | 498 | * @keylen_pad: padded length of the provided algorithm key, in bytes |
|---|
| 444 | | - * @key: address where algorithm key resides; virtual address if key_inline |
|---|
| 445 | | - * is true, dma (bus) address if key_inline is false. |
|---|
| 499 | + * @key_dma: dma (bus) address where algorithm key resides |
|---|
| 500 | + * @key_virt: virtual address where algorithm key resides |
|---|
| 446 | 501 | * @key_inline: true - key can be inlined in the descriptor; false - key is |
|---|
| 447 | 502 | * referenced by the descriptor |
|---|
| 448 | 503 | */ |
|---|
| .. | .. |
|---|
| 450 | 505 | u32 algtype; |
|---|
| 451 | 506 | unsigned int keylen; |
|---|
| 452 | 507 | unsigned int keylen_pad; |
|---|
| 453 | | - union { |
|---|
| 454 | | - dma_addr_t key_dma; |
|---|
| 455 | | - const void *key_virt; |
|---|
| 456 | | - }; |
|---|
| 508 | + dma_addr_t key_dma; |
|---|
| 509 | + const void *key_virt; |
|---|
| 457 | 510 | bool key_inline; |
|---|
| 458 | 511 | }; |
|---|
| 459 | 512 | |
|---|
| .. | .. |
|---|
| 519 | 572 | if (adata->key_inline) { |
|---|
| 520 | 573 | int words; |
|---|
| 521 | 574 | |
|---|
| 522 | | - append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid | |
|---|
| 523 | | - OP_PCL_DKP_SRC_IMM | OP_PCL_DKP_DST_IMM | |
|---|
| 524 | | - adata->keylen); |
|---|
| 525 | | - append_data(desc, adata->key_virt, adata->keylen); |
|---|
| 575 | + if (adata->keylen > adata->keylen_pad) { |
|---|
| 576 | + append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid | |
|---|
| 577 | + OP_PCL_DKP_SRC_PTR | |
|---|
| 578 | + OP_PCL_DKP_DST_IMM | adata->keylen); |
|---|
| 579 | + append_ptr(desc, adata->key_dma); |
|---|
| 580 | + |
|---|
| 581 | + words = (ALIGN(adata->keylen_pad, CAAM_CMD_SZ) - |
|---|
| 582 | + CAAM_PTR_SZ) / CAAM_CMD_SZ; |
|---|
| 583 | + } else { |
|---|
| 584 | + append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid | |
|---|
| 585 | + OP_PCL_DKP_SRC_IMM | |
|---|
| 586 | + OP_PCL_DKP_DST_IMM | adata->keylen); |
|---|
| 587 | + append_data(desc, adata->key_virt, adata->keylen); |
|---|
| 588 | + |
|---|
| 589 | + words = (ALIGN(adata->keylen_pad, CAAM_CMD_SZ) - |
|---|
| 590 | + ALIGN(adata->keylen, CAAM_CMD_SZ)) / |
|---|
| 591 | + CAAM_CMD_SZ; |
|---|
| 592 | + } |
|---|
| 526 | 593 | |
|---|
| 527 | 594 | /* Reserve space in descriptor buffer for the derived key */ |
|---|
| 528 | | - words = (ALIGN(adata->keylen_pad, CAAM_CMD_SZ) - |
|---|
| 529 | | - ALIGN(adata->keylen, CAAM_CMD_SZ)) / CAAM_CMD_SZ; |
|---|
| 530 | 595 | if (words) |
|---|
| 531 | 596 | (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + words); |
|---|
| 532 | 597 | } else { |
|---|