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