Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * caam descriptor construction helper functions
0004  *
0005  * Copyright 2008-2012 Freescale Semiconductor, Inc.
0006  * Copyright 2019 NXP
0007  */
0008 
0009 #ifndef DESC_CONSTR_H
0010 #define DESC_CONSTR_H
0011 
0012 #include "desc.h"
0013 #include "regs.h"
0014 
0015 #define IMMEDIATE (1 << 23)
0016 #define CAAM_CMD_SZ sizeof(u32)
0017 #define CAAM_PTR_SZ caam_ptr_sz
0018 #define CAAM_PTR_SZ_MAX sizeof(dma_addr_t)
0019 #define CAAM_PTR_SZ_MIN sizeof(u32)
0020 #define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
0021 #define __DESC_JOB_IO_LEN(n) (CAAM_CMD_SZ * 5 + (n) * 3)
0022 #define DESC_JOB_IO_LEN __DESC_JOB_IO_LEN(CAAM_PTR_SZ)
0023 #define DESC_JOB_IO_LEN_MAX __DESC_JOB_IO_LEN(CAAM_PTR_SZ_MAX)
0024 #define DESC_JOB_IO_LEN_MIN __DESC_JOB_IO_LEN(CAAM_PTR_SZ_MIN)
0025 
0026 /*
0027  * The CAAM QI hardware constructs a job descriptor which points
0028  * to shared descriptor (as pointed by context_a of FQ to CAAM).
0029  * When the job descriptor is executed by deco, the whole job
0030  * descriptor together with shared descriptor gets loaded in
0031  * deco buffer which is 64 words long (each 32-bit).
0032  *
0033  * The job descriptor constructed by QI hardware has layout:
0034  *
0035  *  HEADER      (1 word)
0036  *  Shdesc ptr  (1 or 2 words)
0037  *  SEQ_OUT_PTR (1 word)
0038  *  Out ptr     (1 or 2 words)
0039  *  Out length  (1 word)
0040  *  SEQ_IN_PTR  (1 word)
0041  *  In ptr      (1 or 2 words)
0042  *  In length   (1 word)
0043  *
0044  * The shdesc ptr is used to fetch shared descriptor contents
0045  * into deco buffer.
0046  *
0047  * Apart from shdesc contents, the total number of words that
0048  * get loaded in deco buffer are '8' or '11'. The remaining words
0049  * in deco buffer can be used for storing shared descriptor.
0050  */
0051 #define MAX_SDLEN   ((CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN_MIN) / CAAM_CMD_SZ)
0052 
0053 #ifdef DEBUG
0054 #define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\
0055                   &__func__[sizeof("append")]); } while (0)
0056 #else
0057 #define PRINT_POS
0058 #endif
0059 
0060 #define SET_OK_NO_PROP_ERRORS (IMMEDIATE | LDST_CLASS_DECO | \
0061                    LDST_SRCDST_WORD_DECOCTRL | \
0062                    (LDOFF_CHG_SHARE_OK_NO_PROP << \
0063                 LDST_OFFSET_SHIFT))
0064 #define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
0065                 LDST_SRCDST_WORD_DECOCTRL | \
0066                 (LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
0067 #define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
0068                    LDST_SRCDST_WORD_DECOCTRL | \
0069                    (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
0070 
0071 extern bool caam_little_end;
0072 extern size_t caam_ptr_sz;
0073 
0074 /*
0075  * HW fetches 4 S/G table entries at a time, irrespective of how many entries
0076  * are in the table. It's SW's responsibility to make sure these accesses
0077  * do not have side effects.
0078  */
0079 static inline int pad_sg_nents(int sg_nents)
0080 {
0081     return ALIGN(sg_nents, 4);
0082 }
0083 
0084 static inline int desc_len(u32 * const desc)
0085 {
0086     return caam32_to_cpu(*desc) & HDR_DESCLEN_MASK;
0087 }
0088 
0089 static inline int desc_bytes(void * const desc)
0090 {
0091     return desc_len(desc) * CAAM_CMD_SZ;
0092 }
0093 
0094 static inline u32 *desc_end(u32 * const desc)
0095 {
0096     return desc + desc_len(desc);
0097 }
0098 
0099 static inline void *sh_desc_pdb(u32 * const desc)
0100 {
0101     return desc + 1;
0102 }
0103 
0104 static inline void init_desc(u32 * const desc, u32 options)
0105 {
0106     *desc = cpu_to_caam32((options | HDR_ONE) + 1);
0107 }
0108 
0109 static inline void init_sh_desc(u32 * const desc, u32 options)
0110 {
0111     PRINT_POS;
0112     init_desc(desc, CMD_SHARED_DESC_HDR | options);
0113 }
0114 
0115 static inline void init_sh_desc_pdb(u32 * const desc, u32 options,
0116                     size_t pdb_bytes)
0117 {
0118     u32 pdb_len = (pdb_bytes + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
0119 
0120     init_sh_desc(desc, (((pdb_len + 1) << HDR_START_IDX_SHIFT) + pdb_len) |
0121              options);
0122 }
0123 
0124 static inline void init_job_desc(u32 * const desc, u32 options)
0125 {
0126     init_desc(desc, CMD_DESC_HDR | options);
0127 }
0128 
0129 static inline void init_job_desc_pdb(u32 * const desc, u32 options,
0130                      size_t pdb_bytes)
0131 {
0132     u32 pdb_len = (pdb_bytes + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
0133 
0134     init_job_desc(desc, (((pdb_len + 1) << HDR_START_IDX_SHIFT)) | options);
0135 }
0136 
0137 static inline void append_ptr(u32 * const desc, dma_addr_t ptr)
0138 {
0139     if (caam_ptr_sz == sizeof(dma_addr_t)) {
0140         dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
0141 
0142         *offset = cpu_to_caam_dma(ptr);
0143     } else {
0144         u32 *offset = (u32 *)desc_end(desc);
0145 
0146         *offset = cpu_to_caam_dma(ptr);
0147     }
0148 
0149     (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) +
0150                 CAAM_PTR_SZ / CAAM_CMD_SZ);
0151 }
0152 
0153 static inline void init_job_desc_shared(u32 * const desc, dma_addr_t ptr,
0154                     int len, u32 options)
0155 {
0156     PRINT_POS;
0157     init_job_desc(desc, HDR_SHARED | options |
0158               (len << HDR_START_IDX_SHIFT));
0159     append_ptr(desc, ptr);
0160 }
0161 
0162 static inline void append_data(u32 * const desc, const void *data, int len)
0163 {
0164     u32 *offset = desc_end(desc);
0165 
0166     if (len) /* avoid sparse warning: memcpy with byte count of 0 */
0167         memcpy(offset, data, len);
0168 
0169     (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) +
0170                 (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ);
0171 }
0172 
0173 static inline void append_cmd(u32 * const desc, u32 command)
0174 {
0175     u32 *cmd = desc_end(desc);
0176 
0177     *cmd = cpu_to_caam32(command);
0178 
0179     (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + 1);
0180 }
0181 
0182 #define append_u32 append_cmd
0183 
0184 static inline void append_u64(u32 * const desc, u64 data)
0185 {
0186     u32 *offset = desc_end(desc);
0187 
0188     /* Only 32-bit alignment is guaranteed in descriptor buffer */
0189     if (caam_little_end) {
0190         *offset = cpu_to_caam32(lower_32_bits(data));
0191         *(++offset) = cpu_to_caam32(upper_32_bits(data));
0192     } else {
0193         *offset = cpu_to_caam32(upper_32_bits(data));
0194         *(++offset) = cpu_to_caam32(lower_32_bits(data));
0195     }
0196 
0197     (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + 2);
0198 }
0199 
0200 /* Write command without affecting header, and return pointer to next word */
0201 static inline u32 *write_cmd(u32 * const desc, u32 command)
0202 {
0203     *desc = cpu_to_caam32(command);
0204 
0205     return desc + 1;
0206 }
0207 
0208 static inline void append_cmd_ptr(u32 * const desc, dma_addr_t ptr, int len,
0209                   u32 command)
0210 {
0211     append_cmd(desc, command | len);
0212     append_ptr(desc, ptr);
0213 }
0214 
0215 /* Write length after pointer, rather than inside command */
0216 static inline void append_cmd_ptr_extlen(u32 * const desc, dma_addr_t ptr,
0217                      unsigned int len, u32 command)
0218 {
0219     append_cmd(desc, command);
0220     if (!(command & (SQIN_RTO | SQIN_PRE)))
0221         append_ptr(desc, ptr);
0222     append_cmd(desc, len);
0223 }
0224 
0225 static inline void append_cmd_data(u32 * const desc, const void *data, int len,
0226                    u32 command)
0227 {
0228     append_cmd(desc, command | IMMEDIATE | len);
0229     append_data(desc, data, len);
0230 }
0231 
0232 #define APPEND_CMD_RET(cmd, op) \
0233 static inline u32 *append_##cmd(u32 * const desc, u32 options) \
0234 { \
0235     u32 *cmd = desc_end(desc); \
0236     PRINT_POS; \
0237     append_cmd(desc, CMD_##op | options); \
0238     return cmd; \
0239 }
0240 APPEND_CMD_RET(jump, JUMP)
0241 APPEND_CMD_RET(move, MOVE)
0242 APPEND_CMD_RET(move_len, MOVE_LEN)
0243 
0244 static inline void set_jump_tgt_here(u32 * const desc, u32 *jump_cmd)
0245 {
0246     *jump_cmd = cpu_to_caam32(caam32_to_cpu(*jump_cmd) |
0247                   (desc_len(desc) - (jump_cmd - desc)));
0248 }
0249 
0250 static inline void set_move_tgt_here(u32 * const desc, u32 *move_cmd)
0251 {
0252     u32 val = caam32_to_cpu(*move_cmd);
0253 
0254     val &= ~MOVE_OFFSET_MASK;
0255     val |= (desc_len(desc) << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
0256     *move_cmd = cpu_to_caam32(val);
0257 }
0258 
0259 #define APPEND_CMD(cmd, op) \
0260 static inline void append_##cmd(u32 * const desc, u32 options) \
0261 { \
0262     PRINT_POS; \
0263     append_cmd(desc, CMD_##op | options); \
0264 }
0265 APPEND_CMD(operation, OPERATION)
0266 
0267 #define APPEND_CMD_LEN(cmd, op) \
0268 static inline void append_##cmd(u32 * const desc, unsigned int len, \
0269                 u32 options) \
0270 { \
0271     PRINT_POS; \
0272     append_cmd(desc, CMD_##op | len | options); \
0273 }
0274 
0275 APPEND_CMD_LEN(seq_load, SEQ_LOAD)
0276 APPEND_CMD_LEN(seq_store, SEQ_STORE)
0277 APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
0278 APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
0279 
0280 #define APPEND_CMD_PTR(cmd, op) \
0281 static inline void append_##cmd(u32 * const desc, dma_addr_t ptr, \
0282                 unsigned int len, u32 options) \
0283 { \
0284     PRINT_POS; \
0285     append_cmd_ptr(desc, ptr, len, CMD_##op | options); \
0286 }
0287 APPEND_CMD_PTR(key, KEY)
0288 APPEND_CMD_PTR(load, LOAD)
0289 APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
0290 APPEND_CMD_PTR(fifo_store, FIFO_STORE)
0291 
0292 static inline void append_store(u32 * const desc, dma_addr_t ptr,
0293                 unsigned int len, u32 options)
0294 {
0295     u32 cmd_src;
0296 
0297     cmd_src = options & LDST_SRCDST_MASK;
0298 
0299     append_cmd(desc, CMD_STORE | options | len);
0300 
0301     /* The following options do not require pointer */
0302     if (!(cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED ||
0303           cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB    ||
0304           cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB_WE ||
0305           cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED_WE))
0306         append_ptr(desc, ptr);
0307 }
0308 
0309 #define APPEND_SEQ_PTR_INTLEN(cmd, op) \
0310 static inline void append_seq_##cmd##_ptr_intlen(u32 * const desc, \
0311                          dma_addr_t ptr, \
0312                          unsigned int len, \
0313                          u32 options) \
0314 { \
0315     PRINT_POS; \
0316     if (options & (SQIN_RTO | SQIN_PRE)) \
0317         append_cmd(desc, CMD_SEQ_##op##_PTR | len | options); \
0318     else \
0319         append_cmd_ptr(desc, ptr, len, CMD_SEQ_##op##_PTR | options); \
0320 }
0321 APPEND_SEQ_PTR_INTLEN(in, IN)
0322 APPEND_SEQ_PTR_INTLEN(out, OUT)
0323 
0324 #define APPEND_CMD_PTR_TO_IMM(cmd, op) \
0325 static inline void append_##cmd##_as_imm(u32 * const desc, const void *data, \
0326                      unsigned int len, u32 options) \
0327 { \
0328     PRINT_POS; \
0329     append_cmd_data(desc, data, len, CMD_##op | options); \
0330 }
0331 APPEND_CMD_PTR_TO_IMM(load, LOAD);
0332 APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
0333 
0334 #define APPEND_CMD_PTR_EXTLEN(cmd, op) \
0335 static inline void append_##cmd##_extlen(u32 * const desc, dma_addr_t ptr, \
0336                      unsigned int len, u32 options) \
0337 { \
0338     PRINT_POS; \
0339     append_cmd_ptr_extlen(desc, ptr, len, CMD_##op | SQIN_EXT | options); \
0340 }
0341 APPEND_CMD_PTR_EXTLEN(seq_in_ptr, SEQ_IN_PTR)
0342 APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR)
0343 
0344 /*
0345  * Determine whether to store length internally or externally depending on
0346  * the size of its type
0347  */
0348 #define APPEND_CMD_PTR_LEN(cmd, op, type) \
0349 static inline void append_##cmd(u32 * const desc, dma_addr_t ptr, \
0350                 type len, u32 options) \
0351 { \
0352     PRINT_POS; \
0353     if (sizeof(type) > sizeof(u16)) \
0354         append_##cmd##_extlen(desc, ptr, len, options); \
0355     else \
0356         append_##cmd##_intlen(desc, ptr, len, options); \
0357 }
0358 APPEND_CMD_PTR_LEN(seq_in_ptr, SEQ_IN_PTR, u32)
0359 APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_PTR, u32)
0360 
0361 /*
0362  * 2nd variant for commands whose specified immediate length differs
0363  * from length of immediate data provided, e.g., split keys
0364  */
0365 #define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
0366 static inline void append_##cmd##_as_imm(u32 * const desc, const void *data, \
0367                      unsigned int data_len, \
0368                      unsigned int len, u32 options) \
0369 { \
0370     PRINT_POS; \
0371     append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \
0372     append_data(desc, data, data_len); \
0373 }
0374 APPEND_CMD_PTR_TO_IMM2(key, KEY);
0375 
0376 #define APPEND_CMD_RAW_IMM(cmd, op, type) \
0377 static inline void append_##cmd##_imm_##type(u32 * const desc, type immediate, \
0378                          u32 options) \
0379 { \
0380     PRINT_POS; \
0381     if (options & LDST_LEN_MASK) \
0382         append_cmd(desc, CMD_##op | IMMEDIATE | options); \
0383     else \
0384         append_cmd(desc, CMD_##op | IMMEDIATE | options | \
0385                sizeof(type)); \
0386     append_cmd(desc, immediate); \
0387 }
0388 APPEND_CMD_RAW_IMM(load, LOAD, u32);
0389 
0390 /*
0391  * ee - endianness
0392  * size - size of immediate type in bytes
0393  */
0394 #define APPEND_CMD_RAW_IMM2(cmd, op, ee, size) \
0395 static inline void append_##cmd##_imm_##ee##size(u32 *desc, \
0396                            u##size immediate, \
0397                            u32 options) \
0398 { \
0399     __##ee##size data = cpu_to_##ee##size(immediate); \
0400     PRINT_POS; \
0401     append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(data)); \
0402     append_data(desc, &data, sizeof(data)); \
0403 }
0404 
0405 APPEND_CMD_RAW_IMM2(load, LOAD, be, 32);
0406 
0407 /*
0408  * Append math command. Only the last part of destination and source need to
0409  * be specified
0410  */
0411 #define APPEND_MATH(op, desc, dest, src_0, src_1, len) \
0412 append_cmd(desc, CMD_MATH | MATH_FUN_##op | MATH_DEST_##dest | \
0413     MATH_SRC0_##src_0 | MATH_SRC1_##src_1 | (u32)len);
0414 
0415 #define append_math_add(desc, dest, src0, src1, len) \
0416     APPEND_MATH(ADD, desc, dest, src0, src1, len)
0417 #define append_math_sub(desc, dest, src0, src1, len) \
0418     APPEND_MATH(SUB, desc, dest, src0, src1, len)
0419 #define append_math_add_c(desc, dest, src0, src1, len) \
0420     APPEND_MATH(ADDC, desc, dest, src0, src1, len)
0421 #define append_math_sub_b(desc, dest, src0, src1, len) \
0422     APPEND_MATH(SUBB, desc, dest, src0, src1, len)
0423 #define append_math_and(desc, dest, src0, src1, len) \
0424     APPEND_MATH(AND, desc, dest, src0, src1, len)
0425 #define append_math_or(desc, dest, src0, src1, len) \
0426     APPEND_MATH(OR, desc, dest, src0, src1, len)
0427 #define append_math_xor(desc, dest, src0, src1, len) \
0428     APPEND_MATH(XOR, desc, dest, src0, src1, len)
0429 #define append_math_lshift(desc, dest, src0, src1, len) \
0430     APPEND_MATH(LSHIFT, desc, dest, src0, src1, len)
0431 #define append_math_rshift(desc, dest, src0, src1, len) \
0432     APPEND_MATH(RSHIFT, desc, dest, src0, src1, len)
0433 #define append_math_ldshift(desc, dest, src0, src1, len) \
0434     APPEND_MATH(SHLD, desc, dest, src0, src1, len)
0435 
0436 /* Exactly one source is IMM. Data is passed in as u32 value */
0437 #define APPEND_MATH_IMM_u32(op, desc, dest, src_0, src_1, data) \
0438 do { \
0439     APPEND_MATH(op, desc, dest, src_0, src_1, CAAM_CMD_SZ); \
0440     append_cmd(desc, data); \
0441 } while (0)
0442 
0443 #define append_math_add_imm_u32(desc, dest, src0, src1, data) \
0444     APPEND_MATH_IMM_u32(ADD, desc, dest, src0, src1, data)
0445 #define append_math_sub_imm_u32(desc, dest, src0, src1, data) \
0446     APPEND_MATH_IMM_u32(SUB, desc, dest, src0, src1, data)
0447 #define append_math_add_c_imm_u32(desc, dest, src0, src1, data) \
0448     APPEND_MATH_IMM_u32(ADDC, desc, dest, src0, src1, data)
0449 #define append_math_sub_b_imm_u32(desc, dest, src0, src1, data) \
0450     APPEND_MATH_IMM_u32(SUBB, desc, dest, src0, src1, data)
0451 #define append_math_and_imm_u32(desc, dest, src0, src1, data) \
0452     APPEND_MATH_IMM_u32(AND, desc, dest, src0, src1, data)
0453 #define append_math_or_imm_u32(desc, dest, src0, src1, data) \
0454     APPEND_MATH_IMM_u32(OR, desc, dest, src0, src1, data)
0455 #define append_math_xor_imm_u32(desc, dest, src0, src1, data) \
0456     APPEND_MATH_IMM_u32(XOR, desc, dest, src0, src1, data)
0457 #define append_math_lshift_imm_u32(desc, dest, src0, src1, data) \
0458     APPEND_MATH_IMM_u32(LSHIFT, desc, dest, src0, src1, data)
0459 #define append_math_rshift_imm_u32(desc, dest, src0, src1, data) \
0460     APPEND_MATH_IMM_u32(RSHIFT, desc, dest, src0, src1, data)
0461 
0462 /* Exactly one source is IMM. Data is passed in as u64 value */
0463 #define APPEND_MATH_IMM_u64(op, desc, dest, src_0, src_1, data) \
0464 do { \
0465     u32 upper = (data >> 16) >> 16; \
0466     APPEND_MATH(op, desc, dest, src_0, src_1, CAAM_CMD_SZ * 2 | \
0467             (upper ? 0 : MATH_IFB)); \
0468     if (upper) \
0469         append_u64(desc, data); \
0470     else \
0471         append_u32(desc, lower_32_bits(data)); \
0472 } while (0)
0473 
0474 #define append_math_add_imm_u64(desc, dest, src0, src1, data) \
0475     APPEND_MATH_IMM_u64(ADD, desc, dest, src0, src1, data)
0476 #define append_math_sub_imm_u64(desc, dest, src0, src1, data) \
0477     APPEND_MATH_IMM_u64(SUB, desc, dest, src0, src1, data)
0478 #define append_math_add_c_imm_u64(desc, dest, src0, src1, data) \
0479     APPEND_MATH_IMM_u64(ADDC, desc, dest, src0, src1, data)
0480 #define append_math_sub_b_imm_u64(desc, dest, src0, src1, data) \
0481     APPEND_MATH_IMM_u64(SUBB, desc, dest, src0, src1, data)
0482 #define append_math_and_imm_u64(desc, dest, src0, src1, data) \
0483     APPEND_MATH_IMM_u64(AND, desc, dest, src0, src1, data)
0484 #define append_math_or_imm_u64(desc, dest, src0, src1, data) \
0485     APPEND_MATH_IMM_u64(OR, desc, dest, src0, src1, data)
0486 #define append_math_xor_imm_u64(desc, dest, src0, src1, data) \
0487     APPEND_MATH_IMM_u64(XOR, desc, dest, src0, src1, data)
0488 #define append_math_lshift_imm_u64(desc, dest, src0, src1, data) \
0489     APPEND_MATH_IMM_u64(LSHIFT, desc, dest, src0, src1, data)
0490 #define append_math_rshift_imm_u64(desc, dest, src0, src1, data) \
0491     APPEND_MATH_IMM_u64(RSHIFT, desc, dest, src0, src1, data)
0492 
0493 /**
0494  * struct alginfo - Container for algorithm details
0495  * @algtype: algorithm selector; for valid values, see documentation of the
0496  *           functions where it is used.
0497  * @keylen: length of the provided algorithm key, in bytes
0498  * @keylen_pad: padded length of the provided algorithm key, in bytes
0499  * @key_dma: dma (bus) address where algorithm key resides
0500  * @key_virt: virtual address where algorithm key resides
0501  * @key_inline: true - key can be inlined in the descriptor; false - key is
0502  *              referenced by the descriptor
0503  */
0504 struct alginfo {
0505     u32 algtype;
0506     unsigned int keylen;
0507     unsigned int keylen_pad;
0508     dma_addr_t key_dma;
0509     const void *key_virt;
0510     bool key_inline;
0511 };
0512 
0513 /**
0514  * desc_inline_query() - Provide indications on which data items can be inlined
0515  *                       and which shall be referenced in a shared descriptor.
0516  * @sd_base_len: Shared descriptor base length - bytes consumed by the commands,
0517  *               excluding the data items to be inlined (or corresponding
0518  *               pointer if an item is not inlined). Each cnstr_* function that
0519  *               generates descriptors should have a define mentioning
0520  *               corresponding length.
0521  * @jd_len: Maximum length of the job descriptor(s) that will be used
0522  *          together with the shared descriptor.
0523  * @data_len: Array of lengths of the data items trying to be inlined
0524  * @inl_mask: 32bit mask with bit x = 1 if data item x can be inlined, 0
0525  *            otherwise.
0526  * @count: Number of data items (size of @data_len array); must be <= 32
0527  *
0528  * Return: 0 if data can be inlined / referenced, negative value if not. If 0,
0529  *         check @inl_mask for details.
0530  */
0531 static inline int desc_inline_query(unsigned int sd_base_len,
0532                     unsigned int jd_len, unsigned int *data_len,
0533                     u32 *inl_mask, unsigned int count)
0534 {
0535     int rem_bytes = (int)(CAAM_DESC_BYTES_MAX - sd_base_len - jd_len);
0536     unsigned int i;
0537 
0538     *inl_mask = 0;
0539     for (i = 0; (i < count) && (rem_bytes > 0); i++) {
0540         if (rem_bytes - (int)(data_len[i] +
0541             (count - i - 1) * CAAM_PTR_SZ) >= 0) {
0542             rem_bytes -= data_len[i];
0543             *inl_mask |= (1 << i);
0544         } else {
0545             rem_bytes -= CAAM_PTR_SZ;
0546         }
0547     }
0548 
0549     return (rem_bytes >= 0) ? 0 : -1;
0550 }
0551 
0552 /**
0553  * append_proto_dkp - Derived Key Protocol (DKP): key -> split key
0554  * @desc: pointer to buffer used for descriptor construction
0555  * @adata: pointer to authentication transform definitions.
0556  *         keylen should be the length of initial key, while keylen_pad
0557  *         the length of the derived (split) key.
0558  *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
0559  *         SHA256, SHA384, SHA512}.
0560  */
0561 static inline void append_proto_dkp(u32 * const desc, struct alginfo *adata)
0562 {
0563     u32 protid;
0564 
0565     /*
0566      * Quick & dirty translation from OP_ALG_ALGSEL_{MD5, SHA*}
0567      * to OP_PCLID_DKP_{MD5, SHA*}
0568      */
0569     protid = (adata->algtype & OP_ALG_ALGSEL_SUBMASK) |
0570          (0x20 << OP_ALG_ALGSEL_SHIFT);
0571 
0572     if (adata->key_inline) {
0573         int words;
0574 
0575         if (adata->keylen > adata->keylen_pad) {
0576             append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid |
0577                      OP_PCL_DKP_SRC_PTR |
0578                      OP_PCL_DKP_DST_IMM | adata->keylen);
0579             append_ptr(desc, adata->key_dma);
0580 
0581             words = (ALIGN(adata->keylen_pad, CAAM_CMD_SZ) -
0582                  CAAM_PTR_SZ) / CAAM_CMD_SZ;
0583         } else {
0584             append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid |
0585                      OP_PCL_DKP_SRC_IMM |
0586                      OP_PCL_DKP_DST_IMM | adata->keylen);
0587             append_data(desc, adata->key_virt, adata->keylen);
0588 
0589             words = (ALIGN(adata->keylen_pad, CAAM_CMD_SZ) -
0590                  ALIGN(adata->keylen, CAAM_CMD_SZ)) /
0591                 CAAM_CMD_SZ;
0592         }
0593 
0594         /* Reserve space in descriptor buffer for the derived key */
0595         if (words)
0596             (*desc) = cpu_to_caam32(caam32_to_cpu(*desc) + words);
0597     } else {
0598         append_operation(desc, OP_TYPE_UNI_PROTOCOL | protid |
0599                  OP_PCL_DKP_SRC_PTR | OP_PCL_DKP_DST_PTR |
0600                  adata->keylen);
0601         append_ptr(desc, adata->key_dma);
0602     }
0603 }
0604 
0605 #endif /* DESC_CONSTR_H */