root/drivers/crypto/caam/desc_constr.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. pad_sg_nents
  2. desc_len
  3. desc_bytes
  4. desc_end
  5. sh_desc_pdb
  6. init_desc
  7. init_sh_desc
  8. init_sh_desc_pdb
  9. init_job_desc
  10. init_job_desc_pdb
  11. append_ptr
  12. init_job_desc_shared
  13. append_data
  14. append_cmd
  15. append_u64
  16. write_cmd
  17. append_cmd_ptr
  18. append_cmd_ptr_extlen
  19. append_cmd_data
  20. APPEND_CMD_RET
  21. set_move_tgt_here
  22. APPEND_CMD_PTR
  23. desc_inline_query
  24. append_proto_dkp

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 /*
   3  * caam descriptor construction helper functions
   4  *
   5  * Copyright 2008-2012 Freescale Semiconductor, Inc.
   6  * Copyright 2019 NXP
   7  */
   8 
   9 #ifndef DESC_CONSTR_H
  10 #define DESC_CONSTR_H
  11 
  12 #include "desc.h"
  13 #include "regs.h"
  14 
  15 #define IMMEDIATE (1 << 23)
  16 #define CAAM_CMD_SZ sizeof(u32)
  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)
  20 #define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
  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)
  52 
  53 #ifdef DEBUG
  54 #define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\
  55                               &__func__[sizeof("append")]); } while (0)
  56 #else
  57 #define PRINT_POS
  58 #endif
  59 
  60 #define SET_OK_NO_PROP_ERRORS (IMMEDIATE | LDST_CLASS_DECO | \
  61                                LDST_SRCDST_WORD_DECOCTRL | \
  62                                (LDOFF_CHG_SHARE_OK_NO_PROP << \
  63                                 LDST_OFFSET_SHIFT))
  64 #define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
  65                                 LDST_SRCDST_WORD_DECOCTRL | \
  66                                 (LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
  67 #define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
  68                                LDST_SRCDST_WORD_DECOCTRL | \
  69                                (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
  70 
  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 }
  83 
  84 static inline int desc_len(u32 * const desc)
  85 {
  86         return caam32_to_cpu(*desc) & HDR_DESCLEN_MASK;
  87 }
  88 
  89 static inline int desc_bytes(void * const desc)
  90 {
  91         return desc_len(desc) * CAAM_CMD_SZ;
  92 }
  93 
  94 static inline u32 *desc_end(u32 * const desc)
  95 {
  96         return desc + desc_len(desc);
  97 }
  98 
  99 static inline void *sh_desc_pdb(u32 * const desc)
 100 {
 101         return desc + 1;
 102 }
 103 
 104 static inline void init_desc(u32 * const desc, u32 options)
 105 {
 106         *desc = cpu_to_caam32((options | HDR_ONE) + 1);
 107 }
 108 
 109 static inline void init_sh_desc(u32 * const desc, u32 options)
 110 {
 111         PRINT_POS;
 112         init_desc(desc, CMD_SHARED_DESC_HDR | options);
 113 }
 114 
 115 static inline void init_sh_desc_pdb(u32 * const desc, u32 options,
 116                                     size_t pdb_bytes)
 117 {
 118         u32 pdb_len = (pdb_bytes + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
 119 
 120         init_sh_desc(desc, (((pdb_len + 1) << HDR_START_IDX_SHIFT) + pdb_len) |
 121                      options);
 122 }
 123 
 124 static inline void init_job_desc(u32 * const desc, u32 options)
 125 {
 126         init_desc(desc, CMD_DESC_HDR | options);
 127 }
 128 
 129 static inline void init_job_desc_pdb(u32 * const desc, u32 options,
 130                                      size_t pdb_bytes)
 131 {
 132         u32 pdb_len = (pdb_bytes + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
 133 
 134         init_job_desc(desc, (((pdb_len + 1) << HDR_START_IDX_SHIFT)) | options);
 135 }
 136 
 137 static inline void append_ptr(u32 * const desc, dma_addr_t ptr)
 138 {
 139         if (caam_ptr_sz == sizeof(dma_addr_t)) {
 140                 dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
 141 
 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         }
 148 
 149         (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) +
 150                                 CAAM_PTR_SZ / CAAM_CMD_SZ);
 151 }
 152 
 153 static inline void init_job_desc_shared(u32 * const desc, dma_addr_t ptr,
 154                                         int len, u32 options)
 155 {
 156         PRINT_POS;
 157         init_job_desc(desc, HDR_SHARED | options |
 158                       (len << HDR_START_IDX_SHIFT));
 159         append_ptr(desc, ptr);
 160 }
 161 
 162 static inline void append_data(u32 * const desc, const void *data, int len)
 163 {
 164         u32 *offset = desc_end(desc);
 165 
 166         if (len) /* avoid sparse warning: memcpy with byte count of 0 */
 167                 memcpy(offset, data, len);
 168 
 169         (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) +
 170                                 (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ);
 171 }
 172 
 173 static inline void append_cmd(u32 * const desc, u32 command)
 174 {
 175         u32 *cmd = desc_end(desc);
 176 
 177         *cmd = cpu_to_caam32(command);
 178 
 179         (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + 1);
 180 }
 181 
 182 #define append_u32 append_cmd
 183 
 184 static inline void append_u64(u32 * const desc, u64 data)
 185 {
 186         u32 *offset = desc_end(desc);
 187 
 188         /* Only 32-bit alignment is guaranteed in descriptor buffer */
 189         if (caam_little_end) {
 190                 *offset = cpu_to_caam32(lower_32_bits(data));
 191                 *(++offset) = cpu_to_caam32(upper_32_bits(data));
 192         } else {
 193                 *offset = cpu_to_caam32(upper_32_bits(data));
 194                 *(++offset) = cpu_to_caam32(lower_32_bits(data));
 195         }
 196 
 197         (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + 2);
 198 }
 199 
 200 /* Write command without affecting header, and return pointer to next word */
 201 static inline u32 *write_cmd(u32 * const desc, u32 command)
 202 {
 203         *desc = cpu_to_caam32(command);
 204 
 205         return desc + 1;
 206 }
 207 
 208 static inline void append_cmd_ptr(u32 * const desc, dma_addr_t ptr, int len,
 209                                   u32 command)
 210 {
 211         append_cmd(desc, command | len);
 212         append_ptr(desc, ptr);
 213 }
 214 
 215 /* Write length after pointer, rather than inside command */
 216 static inline void append_cmd_ptr_extlen(u32 * const desc, dma_addr_t ptr,
 217                                          unsigned int len, u32 command)
 218 {
 219         append_cmd(desc, command);
 220         if (!(command & (SQIN_RTO | SQIN_PRE)))
 221                 append_ptr(desc, ptr);
 222         append_cmd(desc, len);
 223 }
 224 
 225 static inline void append_cmd_data(u32 * const desc, const void *data, int len,
 226                                    u32 command)
 227 {
 228         append_cmd(desc, command | IMMEDIATE | len);
 229         append_data(desc, data, len);
 230 }
 231 
 232 #define APPEND_CMD_RET(cmd, op) \
 233 static inline u32 *append_##cmd(u32 * const desc, u32 options) \
 234 { \
 235         u32 *cmd = desc_end(desc); \
 236         PRINT_POS; \
 237         append_cmd(desc, CMD_##op | options); \
 238         return cmd; \
 239 }
 240 APPEND_CMD_RET(jump, JUMP)
 241 APPEND_CMD_RET(move, MOVE)
 242 APPEND_CMD_RET(move_len, MOVE_LEN)
 243 
 244 static inline void set_jump_tgt_here(u32 * const desc, u32 *jump_cmd)
 245 {
 246         *jump_cmd = cpu_to_caam32(caam32_to_cpu(*jump_cmd) |
 247                                   (desc_len(desc) - (jump_cmd - desc)));
 248 }
 249 
 250 static inline void set_move_tgt_here(u32 * const desc, u32 *move_cmd)
 251 {
 252         u32 val = caam32_to_cpu(*move_cmd);
 253 
 254         val &= ~MOVE_OFFSET_MASK;
 255         val |= (desc_len(desc) << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
 256         *move_cmd = cpu_to_caam32(val);
 257 }
 258 
 259 #define APPEND_CMD(cmd, op) \
 260 static inline void append_##cmd(u32 * const desc, u32 options) \
 261 { \
 262         PRINT_POS; \
 263         append_cmd(desc, CMD_##op | options); \
 264 }
 265 APPEND_CMD(operation, OPERATION)
 266 
 267 #define APPEND_CMD_LEN(cmd, op) \
 268 static inline void append_##cmd(u32 * const desc, unsigned int len, \
 269                                 u32 options) \
 270 { \
 271         PRINT_POS; \
 272         append_cmd(desc, CMD_##op | len | options); \
 273 }
 274 
 275 APPEND_CMD_LEN(seq_load, SEQ_LOAD)
 276 APPEND_CMD_LEN(seq_store, SEQ_STORE)
 277 APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
 278 APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
 279 
 280 #define APPEND_CMD_PTR(cmd, op) \
 281 static inline void append_##cmd(u32 * const desc, dma_addr_t ptr, \
 282                                 unsigned int len, u32 options) \
 283 { \
 284         PRINT_POS; \
 285         append_cmd_ptr(desc, ptr, len, CMD_##op | options); \
 286 }
 287 APPEND_CMD_PTR(key, KEY)
 288 APPEND_CMD_PTR(load, LOAD)
 289 APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
 290 APPEND_CMD_PTR(fifo_store, FIFO_STORE)
 291 
 292 static inline void append_store(u32 * const desc, dma_addr_t ptr,
 293                                 unsigned int len, u32 options)
 294 {
 295         u32 cmd_src;
 296 
 297         cmd_src = options & LDST_SRCDST_MASK;
 298 
 299         append_cmd(desc, CMD_STORE | options | len);
 300 
 301         /* The following options do not require pointer */
 302         if (!(cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED ||
 303               cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB    ||
 304               cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB_WE ||
 305               cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED_WE))
 306                 append_ptr(desc, ptr);
 307 }
 308 
 309 #define APPEND_SEQ_PTR_INTLEN(cmd, op) \
 310 static inline void append_seq_##cmd##_ptr_intlen(u32 * const desc, \
 311                                                  dma_addr_t ptr, \
 312                                                  unsigned int len, \
 313                                                  u32 options) \
 314 { \
 315         PRINT_POS; \
 316         if (options & (SQIN_RTO | SQIN_PRE)) \
 317                 append_cmd(desc, CMD_SEQ_##op##_PTR | len | options); \
 318         else \
 319                 append_cmd_ptr(desc, ptr, len, CMD_SEQ_##op##_PTR | options); \
 320 }
 321 APPEND_SEQ_PTR_INTLEN(in, IN)
 322 APPEND_SEQ_PTR_INTLEN(out, OUT)
 323 
 324 #define APPEND_CMD_PTR_TO_IMM(cmd, op) \
 325 static inline void append_##cmd##_as_imm(u32 * const desc, const void *data, \
 326                                          unsigned int len, u32 options) \
 327 { \
 328         PRINT_POS; \
 329         append_cmd_data(desc, data, len, CMD_##op | options); \
 330 }
 331 APPEND_CMD_PTR_TO_IMM(load, LOAD);
 332 APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
 333 
 334 #define APPEND_CMD_PTR_EXTLEN(cmd, op) \
 335 static inline void append_##cmd##_extlen(u32 * const desc, dma_addr_t ptr, \
 336                                          unsigned int len, u32 options) \
 337 { \
 338         PRINT_POS; \
 339         append_cmd_ptr_extlen(desc, ptr, len, CMD_##op | SQIN_EXT | options); \
 340 }
 341 APPEND_CMD_PTR_EXTLEN(seq_in_ptr, SEQ_IN_PTR)
 342 APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR)
 343 
 344 /*
 345  * Determine whether to store length internally or externally depending on
 346  * the size of its type
 347  */
 348 #define APPEND_CMD_PTR_LEN(cmd, op, type) \
 349 static inline void append_##cmd(u32 * const desc, dma_addr_t ptr, \
 350                                 type len, u32 options) \
 351 { \
 352         PRINT_POS; \
 353         if (sizeof(type) > sizeof(u16)) \
 354                 append_##cmd##_extlen(desc, ptr, len, options); \
 355         else \
 356                 append_##cmd##_intlen(desc, ptr, len, options); \
 357 }
 358 APPEND_CMD_PTR_LEN(seq_in_ptr, SEQ_IN_PTR, u32)
 359 APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_PTR, u32)
 360 
 361 /*
 362  * 2nd variant for commands whose specified immediate length differs
 363  * from length of immediate data provided, e.g., split keys
 364  */
 365 #define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
 366 static inline void append_##cmd##_as_imm(u32 * const desc, const void *data, \
 367                                          unsigned int data_len, \
 368                                          unsigned int len, u32 options) \
 369 { \
 370         PRINT_POS; \
 371         append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \
 372         append_data(desc, data, data_len); \
 373 }
 374 APPEND_CMD_PTR_TO_IMM2(key, KEY);
 375 
 376 #define APPEND_CMD_RAW_IMM(cmd, op, type) \
 377 static inline void append_##cmd##_imm_##type(u32 * const desc, type immediate, \
 378                                              u32 options) \
 379 { \
 380         PRINT_POS; \
 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)); \
 386         append_cmd(desc, immediate); \
 387 }
 388 APPEND_CMD_RAW_IMM(load, LOAD, u32);
 389 
 390 /*
 391  * ee - endianness
 392  * size - size of immediate type in bytes
 393  */
 394 #define APPEND_CMD_RAW_IMM2(cmd, op, ee, size) \
 395 static inline void append_##cmd##_imm_##ee##size(u32 *desc, \
 396                                                    u##size immediate, \
 397                                                    u32 options) \
 398 { \
 399         __##ee##size data = cpu_to_##ee##size(immediate); \
 400         PRINT_POS; \
 401         append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(data)); \
 402         append_data(desc, &data, sizeof(data)); \
 403 }
 404 
 405 APPEND_CMD_RAW_IMM2(load, LOAD, be, 32);
 406 
 407 /*
 408  * Append math command. Only the last part of destination and source need to
 409  * be specified
 410  */
 411 #define APPEND_MATH(op, desc, dest, src_0, src_1, len) \
 412 append_cmd(desc, CMD_MATH | MATH_FUN_##op | MATH_DEST_##dest | \
 413         MATH_SRC0_##src_0 | MATH_SRC1_##src_1 | (u32)len);
 414 
 415 #define append_math_add(desc, dest, src0, src1, len) \
 416         APPEND_MATH(ADD, desc, dest, src0, src1, len)
 417 #define append_math_sub(desc, dest, src0, src1, len) \
 418         APPEND_MATH(SUB, desc, dest, src0, src1, len)
 419 #define append_math_add_c(desc, dest, src0, src1, len) \
 420         APPEND_MATH(ADDC, desc, dest, src0, src1, len)
 421 #define append_math_sub_b(desc, dest, src0, src1, len) \
 422         APPEND_MATH(SUBB, desc, dest, src0, src1, len)
 423 #define append_math_and(desc, dest, src0, src1, len) \
 424         APPEND_MATH(AND, desc, dest, src0, src1, len)
 425 #define append_math_or(desc, dest, src0, src1, len) \
 426         APPEND_MATH(OR, desc, dest, src0, src1, len)
 427 #define append_math_xor(desc, dest, src0, src1, len) \
 428         APPEND_MATH(XOR, desc, dest, src0, src1, len)
 429 #define append_math_lshift(desc, dest, src0, src1, len) \
 430         APPEND_MATH(LSHIFT, desc, dest, src0, src1, len)
 431 #define append_math_rshift(desc, dest, src0, src1, len) \
 432         APPEND_MATH(RSHIFT, desc, dest, src0, src1, len)
 433 #define append_math_ldshift(desc, dest, src0, src1, len) \
 434         APPEND_MATH(SHLD, desc, dest, src0, src1, len)
 435 
 436 /* Exactly one source is IMM. Data is passed in as u32 value */
 437 #define APPEND_MATH_IMM_u32(op, desc, dest, src_0, src_1, data) \
 438 do { \
 439         APPEND_MATH(op, desc, dest, src_0, src_1, CAAM_CMD_SZ); \
 440         append_cmd(desc, data); \
 441 } while (0)
 442 
 443 #define append_math_add_imm_u32(desc, dest, src0, src1, data) \
 444         APPEND_MATH_IMM_u32(ADD, desc, dest, src0, src1, data)
 445 #define append_math_sub_imm_u32(desc, dest, src0, src1, data) \
 446         APPEND_MATH_IMM_u32(SUB, desc, dest, src0, src1, data)
 447 #define append_math_add_c_imm_u32(desc, dest, src0, src1, data) \
 448         APPEND_MATH_IMM_u32(ADDC, desc, dest, src0, src1, data)
 449 #define append_math_sub_b_imm_u32(desc, dest, src0, src1, data) \
 450         APPEND_MATH_IMM_u32(SUBB, desc, dest, src0, src1, data)
 451 #define append_math_and_imm_u32(desc, dest, src0, src1, data) \
 452         APPEND_MATH_IMM_u32(AND, desc, dest, src0, src1, data)
 453 #define append_math_or_imm_u32(desc, dest, src0, src1, data) \
 454         APPEND_MATH_IMM_u32(OR, desc, dest, src0, src1, data)
 455 #define append_math_xor_imm_u32(desc, dest, src0, src1, data) \
 456         APPEND_MATH_IMM_u32(XOR, desc, dest, src0, src1, data)
 457 #define append_math_lshift_imm_u32(desc, dest, src0, src1, data) \
 458         APPEND_MATH_IMM_u32(LSHIFT, desc, dest, src0, src1, data)
 459 #define append_math_rshift_imm_u32(desc, dest, src0, src1, data) \
 460         APPEND_MATH_IMM_u32(RSHIFT, desc, dest, src0, src1, data)
 461 
 462 /* Exactly one source is IMM. Data is passed in as u64 value */
 463 #define APPEND_MATH_IMM_u64(op, desc, dest, src_0, src_1, data) \
 464 do { \
 465         u32 upper = (data >> 16) >> 16; \
 466         APPEND_MATH(op, desc, dest, src_0, src_1, CAAM_CMD_SZ * 2 | \
 467                     (upper ? 0 : MATH_IFB)); \
 468         if (upper) \
 469                 append_u64(desc, data); \
 470         else \
 471                 append_u32(desc, lower_32_bits(data)); \
 472 } while (0)
 473 
 474 #define append_math_add_imm_u64(desc, dest, src0, src1, data) \
 475         APPEND_MATH_IMM_u64(ADD, desc, dest, src0, src1, data)
 476 #define append_math_sub_imm_u64(desc, dest, src0, src1, data) \
 477         APPEND_MATH_IMM_u64(SUB, desc, dest, src0, src1, data)
 478 #define append_math_add_c_imm_u64(desc, dest, src0, src1, data) \
 479         APPEND_MATH_IMM_u64(ADDC, desc, dest, src0, src1, data)
 480 #define append_math_sub_b_imm_u64(desc, dest, src0, src1, data) \
 481         APPEND_MATH_IMM_u64(SUBB, desc, dest, src0, src1, data)
 482 #define append_math_and_imm_u64(desc, dest, src0, src1, data) \
 483         APPEND_MATH_IMM_u64(AND, desc, dest, src0, src1, data)
 484 #define append_math_or_imm_u64(desc, dest, src0, src1, data) \
 485         APPEND_MATH_IMM_u64(OR, desc, dest, src0, src1, data)
 486 #define append_math_xor_imm_u64(desc, dest, src0, src1, data) \
 487         APPEND_MATH_IMM_u64(XOR, desc, dest, src0, src1, data)
 488 #define append_math_lshift_imm_u64(desc, dest, src0, src1, data) \
 489         APPEND_MATH_IMM_u64(LSHIFT, desc, dest, src0, src1, data)
 490 #define append_math_rshift_imm_u64(desc, dest, src0, src1, data) \
 491         APPEND_MATH_IMM_u64(RSHIFT, desc, dest, src0, src1, data)
 492 
 493 /**
 494  * struct alginfo - Container for algorithm details
 495  * @algtype: algorithm selector; for valid values, see documentation of the
 496  *           functions where it is used.
 497  * @keylen: length of the provided algorithm key, in bytes
 498  * @keylen_pad: padded length of the provided algorithm key, in bytes
 499  * @key_dma: dma (bus) address where algorithm key resides
 500  * @key_virt: virtual address where algorithm key resides
 501  * @key_inline: true - key can be inlined in the descriptor; false - key is
 502  *              referenced by the descriptor
 503  */
 504 struct alginfo {
 505         u32 algtype;
 506         unsigned int keylen;
 507         unsigned int keylen_pad;
 508         dma_addr_t key_dma;
 509         const void *key_virt;
 510         bool key_inline;
 511 };
 512 
 513 /**
 514  * desc_inline_query() - Provide indications on which data items can be inlined
 515  *                       and which shall be referenced in a shared descriptor.
 516  * @sd_base_len: Shared descriptor base length - bytes consumed by the commands,
 517  *               excluding the data items to be inlined (or corresponding
 518  *               pointer if an item is not inlined). Each cnstr_* function that
 519  *               generates descriptors should have a define mentioning
 520  *               corresponding length.
 521  * @jd_len: Maximum length of the job descriptor(s) that will be used
 522  *          together with the shared descriptor.
 523  * @data_len: Array of lengths of the data items trying to be inlined
 524  * @inl_mask: 32bit mask with bit x = 1 if data item x can be inlined, 0
 525  *            otherwise.
 526  * @count: Number of data items (size of @data_len array); must be <= 32
 527  *
 528  * Return: 0 if data can be inlined / referenced, negative value if not. If 0,
 529  *         check @inl_mask for details.
 530  */
 531 static inline int desc_inline_query(unsigned int sd_base_len,
 532                                     unsigned int jd_len, unsigned int *data_len,
 533                                     u32 *inl_mask, unsigned int count)
 534 {
 535         int rem_bytes = (int)(CAAM_DESC_BYTES_MAX - sd_base_len - jd_len);
 536         unsigned int i;
 537 
 538         *inl_mask = 0;
 539         for (i = 0; (i < count) && (rem_bytes > 0); i++) {
 540                 if (rem_bytes - (int)(data_len[i] +
 541                         (count - i - 1) * CAAM_PTR_SZ) >= 0) {
 542                         rem_bytes -= data_len[i];
 543                         *inl_mask |= (1 << i);
 544                 } else {
 545                         rem_bytes -= CAAM_PTR_SZ;
 546                 }
 547         }
 548 
 549         return (rem_bytes >= 0) ? 0 : -1;
 550 }
 551 
 552 /**
 553  * append_proto_dkp - Derived Key Protocol (DKP): key -> split key
 554  * @desc: pointer to buffer used for descriptor construction
 555  * @adata: pointer to authentication transform definitions.
 556  *         keylen should be the length of initial key, while keylen_pad
 557  *         the length of the derived (split) key.
 558  *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
 559  *         SHA256, SHA384, SHA512}.
 560  */
 561 static inline void append_proto_dkp(u32 * const desc, struct alginfo *adata)
 562 {
 563         u32 protid;
 564 
 565         /*
 566          * Quick & dirty translation from OP_ALG_ALGSEL_{MD5, SHA*}
 567          * to OP_PCLID_DKP_{MD5, SHA*}
 568          */
 569         protid = (adata->algtype & OP_ALG_ALGSEL_SUBMASK) |
 570                  (0x20 << OP_ALG_ALGSEL_SHIFT);
 571 
 572         if (adata->key_inline) {
 573                 int words;
 574 
 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                 }
 593 
 594                 /* Reserve space in descriptor buffer for the derived key */
 595                 if (words)
 596                         (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + words);
 597         } else {
 598                 append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid |
 599                                  OP_PCL_DKP_SRC_PTR | OP_PCL_DKP_DST_PTR |
 600                                  adata->keylen);
 601                 append_ptr(desc, adata->key_dma);
 602         }
 603 }
 604 
 605 #endif /* DESC_CONSTR_H */

/* [<][>][^][v][top][bottom][index][help] */