uboot/drivers/crypto/fsl/desc_constr.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * caam descriptor construction helper functions
   4 *
   5 * Copyright 2008-2014 Freescale Semiconductor, Inc.
   6 *
   7 * Based on desc_constr.h file in linux drivers/crypto/caam
   8 */
   9
  10#include <linux/compat.h>
  11#include "desc.h"
  12
  13#define IMMEDIATE (1 << 23)
  14#define CAAM_CMD_SZ sizeof(u32)
  15#define CAAM_PTR_SZ sizeof(dma_addr_t)
  16#define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
  17#define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3)
  18
  19#ifdef DEBUG
  20#define PRINT_POS do { printf("%02d: %s\n", desc_len(desc),\
  21                              &__func__[sizeof("append")]); \
  22                     } while (0)
  23#else
  24#define PRINT_POS
  25#endif
  26
  27#define SET_OK_NO_PROP_ERRORS (IMMEDIATE | LDST_CLASS_DECO | \
  28                               LDST_SRCDST_WORD_DECOCTRL | \
  29                               (LDOFF_CHG_SHARE_OK_NO_PROP << \
  30                                LDST_OFFSET_SHIFT))
  31#define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
  32                                LDST_SRCDST_WORD_DECOCTRL | \
  33                                (LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
  34#define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
  35                               LDST_SRCDST_WORD_DECOCTRL | \
  36                               (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
  37
  38#ifdef CONFIG_PHYS_64BIT
  39union ptr_addr_t {
  40        u64 m_whole;
  41        struct {
  42#ifdef CONFIG_SYS_FSL_SEC_LE
  43                u32 low;
  44                u32 high;
  45#elif defined(CONFIG_SYS_FSL_SEC_BE)
  46                u32 high;
  47                u32 low;
  48#else
  49#error Neither CONFIG_SYS_FSL_SEC_LE nor CONFIG_SYS_FSL_SEC_BE is defined
  50#endif
  51        } m_halfs;
  52};
  53#endif
  54
  55static inline void pdb_add_ptr(dma_addr_t *offset, dma_addr_t ptr)
  56{
  57#ifdef CONFIG_PHYS_64BIT
  58        /* The Position of low and high part of 64 bit address
  59         * will depend on the endianness of CAAM Block */
  60        union ptr_addr_t *ptr_addr = (union ptr_addr_t *)offset;
  61        ptr_addr->m_halfs.high = (u32)(ptr >> 32);
  62        ptr_addr->m_halfs.low = (u32)ptr;
  63#else
  64        *offset = ptr;
  65#endif
  66}
  67
  68static inline int desc_len(u32 *desc)
  69{
  70        return *desc & HDR_DESCLEN_MASK;
  71}
  72
  73static inline int desc_bytes(void *desc)
  74{
  75        return desc_len(desc) * CAAM_CMD_SZ;
  76}
  77
  78static inline u32 *desc_end(u32 *desc)
  79{
  80        return desc + desc_len(desc);
  81}
  82
  83static inline void *desc_pdb(u32 *desc)
  84{
  85        return desc + 1;
  86}
  87
  88static inline void init_desc(u32 *desc, u32 options)
  89{
  90        *desc = (options | HDR_ONE) + 1;
  91}
  92
  93static inline void init_job_desc(u32 *desc, u32 options)
  94{
  95        init_desc(desc, CMD_DESC_HDR | options);
  96}
  97
  98static inline void init_job_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes)
  99{
 100        u32 pdb_len = (pdb_bytes + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
 101
 102        init_job_desc(desc,
 103                      (((pdb_len + 1) << HDR_START_IDX_SHIFT) + pdb_len) |
 104                       options);
 105}
 106
 107static inline void append_ptr(u32 *desc, dma_addr_t ptr)
 108{
 109        dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
 110
 111#ifdef CONFIG_PHYS_64BIT
 112        /* The Position of low and high part of 64 bit address
 113         * will depend on the endianness of CAAM Block */
 114        union ptr_addr_t *ptr_addr = (union ptr_addr_t *)offset;
 115        ptr_addr->m_halfs.high = (u32)(ptr >> 32);
 116        ptr_addr->m_halfs.low = (u32)ptr;
 117#else
 118        *offset = ptr;
 119#endif
 120
 121        (*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ;
 122}
 123
 124static inline void append_data(u32 *desc, void *data, int len)
 125{
 126        u32 *offset = desc_end(desc);
 127
 128        if (len) /* avoid sparse warning: memcpy with byte count of 0 */
 129                memcpy(offset, data, len);
 130
 131        (*desc) += (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
 132}
 133
 134static inline void append_cmd(u32 *desc, u32 command)
 135{
 136        u32 *cmd = desc_end(desc);
 137
 138        *cmd = command;
 139
 140        (*desc)++;
 141}
 142
 143#define append_u32 append_cmd
 144
 145static inline void append_u64(u32 *desc, u64 data)
 146{
 147        u32 *offset = desc_end(desc);
 148
 149        *offset = upper_32_bits(data);
 150        *(++offset) = lower_32_bits(data);
 151
 152        (*desc) += 2;
 153}
 154
 155/* Write command without affecting header, and return pointer to next word */
 156static inline u32 *write_cmd(u32 *desc, u32 command)
 157{
 158        *desc = command;
 159
 160        return desc + 1;
 161}
 162
 163static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len,
 164                                  u32 command)
 165{
 166        append_cmd(desc, command | len);
 167        append_ptr(desc, ptr);
 168}
 169
 170/* Write length after pointer, rather than inside command */
 171static inline void append_cmd_ptr_extlen(u32 *desc, dma_addr_t ptr,
 172                                         unsigned int len, u32 command)
 173{
 174        append_cmd(desc, command);
 175        if (!(command & (SQIN_RTO | SQIN_PRE)))
 176                append_ptr(desc, ptr);
 177        append_cmd(desc, len);
 178}
 179
 180static inline void append_cmd_data(u32 *desc, void *data, int len,
 181                                   u32 command)
 182{
 183        append_cmd(desc, command | IMMEDIATE | len);
 184        append_data(desc, data, len);
 185}
 186
 187#define APPEND_CMD_RET(cmd, op) \
 188static inline u32 *append_##cmd(u32 *desc, u32 options) \
 189{ \
 190        u32 *cmd = desc_end(desc); \
 191        PRINT_POS; \
 192        append_cmd(desc, CMD_##op | options); \
 193        return cmd; \
 194}
 195APPEND_CMD_RET(jump, JUMP)
 196APPEND_CMD_RET(move, MOVE)
 197
 198static inline void set_jump_tgt_here(u32 *desc, u32 *jump_cmd)
 199{
 200        *jump_cmd = *jump_cmd | (desc_len(desc) - (jump_cmd - desc));
 201}
 202
 203static inline void set_move_tgt_here(u32 *desc, u32 *move_cmd)
 204{
 205        *move_cmd &= ~MOVE_OFFSET_MASK;
 206        *move_cmd = *move_cmd | ((desc_len(desc) << (MOVE_OFFSET_SHIFT + 2)) &
 207                                 MOVE_OFFSET_MASK);
 208}
 209
 210#define APPEND_CMD(cmd, op) \
 211static inline void append_##cmd(u32 *desc, u32 options) \
 212{ \
 213        PRINT_POS; \
 214        append_cmd(desc, CMD_##op | options); \
 215}
 216APPEND_CMD(operation, OPERATION)
 217
 218#define APPEND_CMD_LEN(cmd, op) \
 219static inline void append_##cmd(u32 *desc, unsigned int len, u32 options) \
 220{ \
 221        PRINT_POS; \
 222        append_cmd(desc, CMD_##op | len | options); \
 223}
 224APPEND_CMD_LEN(seq_store, SEQ_STORE)
 225APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
 226APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
 227
 228#define APPEND_CMD_PTR(cmd, op) \
 229static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \
 230                                u32 options) \
 231{ \
 232        PRINT_POS; \
 233        append_cmd_ptr(desc, ptr, len, CMD_##op | options); \
 234}
 235APPEND_CMD_PTR(key, KEY)
 236APPEND_CMD_PTR(load, LOAD)
 237APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
 238APPEND_CMD_PTR(fifo_store, FIFO_STORE)
 239
 240static inline void append_store(u32 *desc, dma_addr_t ptr, unsigned int len,
 241                                u32 options)
 242{
 243        u32 cmd_src;
 244
 245        cmd_src = options & LDST_SRCDST_MASK;
 246
 247        append_cmd(desc, CMD_STORE | options | len);
 248
 249        /* The following options do not require pointer */
 250        if (!(cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED ||
 251              cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB    ||
 252              cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB_WE ||
 253              cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED_WE))
 254                append_ptr(desc, ptr);
 255}
 256
 257#define APPEND_SEQ_PTR_INTLEN(cmd, op) \
 258static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, dma_addr_t ptr, \
 259                                                 unsigned int len, \
 260                                                 u32 options) \
 261{ \
 262        PRINT_POS; \
 263        if (options & (SQIN_RTO | SQIN_PRE)) \
 264                append_cmd(desc, CMD_SEQ_##op##_PTR | len | options); \
 265        else \
 266                append_cmd_ptr(desc, ptr, len, CMD_SEQ_##op##_PTR | options); \
 267}
 268APPEND_SEQ_PTR_INTLEN(in, IN)
 269APPEND_SEQ_PTR_INTLEN(out, OUT)
 270
 271#define APPEND_CMD_PTR_TO_IMM(cmd, op) \
 272static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
 273                                         unsigned int len, u32 options) \
 274{ \
 275        PRINT_POS; \
 276        append_cmd_data(desc, data, len, CMD_##op | options); \
 277}
 278APPEND_CMD_PTR_TO_IMM(load, LOAD);
 279APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
 280
 281#define APPEND_CMD_PTR_EXTLEN(cmd, op) \
 282static inline void append_##cmd##_extlen(u32 *desc, dma_addr_t ptr, \
 283                                         unsigned int len, u32 options) \
 284{ \
 285        PRINT_POS; \
 286        append_cmd_ptr_extlen(desc, ptr, len, CMD_##op | SQIN_EXT | options); \
 287}
 288APPEND_CMD_PTR_EXTLEN(seq_in_ptr, SEQ_IN_PTR)
 289APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR)
 290
 291/*
 292 * Determine whether to store length internally or externally depending on
 293 * the size of its type
 294 */
 295#define APPEND_CMD_PTR_LEN(cmd, op, type) \
 296static inline void append_##cmd(u32 *desc, dma_addr_t ptr, \
 297                                type len, u32 options) \
 298{ \
 299        PRINT_POS; \
 300        if (sizeof(type) > sizeof(u16)) \
 301                append_##cmd##_extlen(desc, ptr, len, options); \
 302        else \
 303                append_##cmd##_intlen(desc, ptr, len, options); \
 304}
 305APPEND_CMD_PTR_LEN(seq_in_ptr, SEQ_IN_PTR, u32)
 306APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_PTR, u32)
 307
 308/*
 309 * 2nd variant for commands whose specified immediate length differs
 310 * from length of immediate data provided, e.g., split keys
 311 */
 312#define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
 313static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
 314                                         unsigned int data_len, \
 315                                         unsigned int len, u32 options) \
 316{ \
 317        PRINT_POS; \
 318        append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \
 319        append_data(desc, data, data_len); \
 320}
 321APPEND_CMD_PTR_TO_IMM2(key, KEY);
 322
 323#define APPEND_CMD_RAW_IMM(cmd, op, type) \
 324static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \
 325                                             u32 options) \
 326{ \
 327        PRINT_POS; \
 328        append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \
 329        append_cmd(desc, immediate); \
 330}
 331APPEND_CMD_RAW_IMM(load, LOAD, u32);
 332