fsl_sec: Add hardware accelerated SHA256 and SHA1
authorRuchika Gupta <ruchika.gupta@freescale.com>
Wed, 15 Oct 2014 06:05:30 +0000 (11:35 +0530)
committerYork Sun <yorksun@freescale.com>
Thu, 16 Oct 2014 21:17:07 +0000 (14:17 -0700)
SHA-256 and SHA-1 accelerated using SEC hardware in Freescale SoC's
The driver for SEC (CAAM) IP is based on linux drivers/crypto/caam.
The platforms needto add the MACRO CONFIG_FSL_CAAM inorder to
enable initialization of this hardware IP.

Signed-off-by: Ruchika Gupta <ruchika.gupta@freescale.com>
Reviewed-by: York Sun <yorksun@freescale.com>
14 files changed:
arch/powerpc/cpu/mpc85xx/cpu_init.c
arch/powerpc/include/asm/immap_85xx.h
arch/powerpc/include/asm/types.h
drivers/crypto/Makefile
drivers/crypto/fsl/Makefile [new file with mode: 0644]
drivers/crypto/fsl/desc.h [new file with mode: 0644]
drivers/crypto/fsl/desc_constr.h [new file with mode: 0644]
drivers/crypto/fsl/error.c [new file with mode: 0644]
drivers/crypto/fsl/fsl_hash.c [new file with mode: 0644]
drivers/crypto/fsl/jobdesc.c [new file with mode: 0644]
drivers/crypto/fsl/jobdesc.h [new file with mode: 0644]
drivers/crypto/fsl/jr.c [new file with mode: 0644]
drivers/crypto/fsl/jr.h [new file with mode: 0644]
include/fsl_sec.h

index bf9fbbf1da030e54efdf97d6acb36455dfca41db..963e32676b3473fdcb7aafca4474822ba1476786 100644 (file)
@@ -27,6 +27,9 @@
 #include <hwconfig.h>
 #include <linux/compiler.h>
 #include "mp.h"
+#ifdef CONFIG_FSL_CAAM
+#include <fsl_sec.h>
+#endif
 #ifdef CONFIG_SYS_QE_FMAN_FW_IN_NAND
 #include <nand.h>
 #include <errno.h>
@@ -938,6 +941,10 @@ int cpu_init_r(void)
        fman_enet_init();
 #endif
 
+#ifdef CONFIG_FSL_CAAM
+       sec_init();
+#endif
+
 #if defined(CONFIG_FSL_SATA_V2) && defined(CONFIG_FSL_SATA_ERRATUM_A001)
        /*
         * For P1022/1013 Rev1.0 silicon, after power on SATA host
index e426314fdb6ba9dcc17b17d9f272b286b2ee80e8..88c1e08df5ecf904220116af1e37bd273b72c8ff 100644 (file)
@@ -2875,6 +2875,7 @@ struct ccsr_sfp_regs {
 #define CONFIG_SYS_MPC85xx_SATA1_OFFSET                0x220000
 #define CONFIG_SYS_MPC85xx_SATA2_OFFSET                0x221000
 #define CONFIG_SYS_FSL_SEC_OFFSET              0x300000
+#define CONFIG_SYS_FSL_JR0_OFFSET              0x301000
 #define CONFIG_SYS_FSL_CORENET_PME_OFFSET      0x316000
 #define CONFIG_SYS_FSL_QMAN_OFFSET             0x318000
 #define CONFIG_SYS_FSL_BMAN_OFFSET             0x31a000
@@ -2935,8 +2936,10 @@ struct ccsr_sfp_regs {
 #define CONFIG_SYS_MPC85xx_ESDHC_OFFSET                0x2e000
 #if defined(CONFIG_PPC_C29X)
 #define CONFIG_SYS_FSL_SEC_OFFSET              0x80000
+#define CONFIG_SYS_FSL_JR0_OFFSET               0x81000
 #else
 #define CONFIG_SYS_FSL_SEC_OFFSET              0x30000
+#define CONFIG_SYS_FSL_JR0_OFFSET               0x31000
 #endif
 #define CONFIG_SYS_MPC85xx_SERDES2_OFFSET      0xE3100
 #define CONFIG_SYS_MPC85xx_SERDES1_OFFSET      0xE3000
@@ -3041,6 +3044,8 @@ struct ccsr_sfp_regs {
        (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_USB2_PHY_OFFSET)
 #define CONFIG_SYS_FSL_SEC_ADDR \
        (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_SEC_OFFSET)
+#define CONFIG_SYS_FSL_JR0_ADDR \
+       (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_JR0_OFFSET)
 #define CONFIG_SYS_FSL_FM1_ADDR \
        (CONFIG_SYS_IMMR + CONFIG_SYS_FSL_FM1_OFFSET)
 #define CONFIG_SYS_FSL_FM1_DTSEC1_ADDR \
index b27a6b753a06cb02f55d187badc8e2f915af761d..b29ce792f7231a0b3e25cb1ff3b172c9fa522553 100644 (file)
@@ -41,8 +41,12 @@ typedef unsigned long long u64;
 
 #define BITS_PER_LONG 32
 
+#ifdef CONFIG_PHYS_64BIT
+typedef unsigned long long dma_addr_t;
+#else
 /* DMA addresses are 32-bits wide */
 typedef u32 dma_addr_t;
+#endif
 
 #ifdef CONFIG_PHYS_64BIT
 typedef unsigned long long phys_addr_t;
index b8077953c5617ed8c8b232570efabfa9c10e9fa2..7b792371811eb37e7dadcf39310e65f955237678 100644 (file)
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_EXYNOS_ACE_SHA)   += ace_sha.o
+obj-y += fsl/
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
new file mode 100644 (file)
index 0000000..59d9651
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Copyright 2014 Freescale Semiconductor, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# Version 2 as published by the Free Software Foundation.
+#
+
+obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h
new file mode 100644 (file)
index 0000000..504f2b0
--- /dev/null
@@ -0,0 +1,651 @@
+/*
+ * CAAM descriptor composition header
+ * Definitions to support CAAM descriptor instruction generation
+ *
+ * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Based on desc.h file in linux drivers/crypto/caam
+ */
+
+#ifndef DESC_H
+#define DESC_H
+
+/* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
+#define MAX_CAAM_DESCSIZE      64
+
+/* Block size of any entity covered/uncovered with a KEK/TKEK */
+#define KEK_BLOCKSIZE          16
+/*
+ * Supported descriptor command types as they show up
+ * inside a descriptor command word.
+ */
+#define CMD_SHIFT              27
+#define CMD_MASK               0xf8000000
+
+#define CMD_KEY                        (0x00 << CMD_SHIFT)
+#define CMD_SEQ_KEY            (0x01 << CMD_SHIFT)
+#define CMD_LOAD               (0x02 << CMD_SHIFT)
+#define CMD_SEQ_LOAD           (0x03 << CMD_SHIFT)
+#define CMD_FIFO_LOAD          (0x04 << CMD_SHIFT)
+#define CMD_SEQ_FIFO_LOAD      (0x05 << CMD_SHIFT)
+#define CMD_STORE              (0x0a << CMD_SHIFT)
+#define CMD_SEQ_STORE          (0x0b << CMD_SHIFT)
+#define CMD_FIFO_STORE         (0x0c << CMD_SHIFT)
+#define CMD_SEQ_FIFO_STORE     (0x0d << CMD_SHIFT)
+#define CMD_MOVE_LEN           (0x0e << CMD_SHIFT)
+#define CMD_MOVE               (0x0f << CMD_SHIFT)
+#define CMD_OPERATION          (0x10 << CMD_SHIFT)
+#define CMD_SIGNATURE          (0x12 << CMD_SHIFT)
+#define CMD_JUMP               (0x14 << CMD_SHIFT)
+#define CMD_MATH               (0x15 << CMD_SHIFT)
+#define CMD_DESC_HDR           (0x16 << CMD_SHIFT)
+#define CMD_SHARED_DESC_HDR    (0x17 << CMD_SHIFT)
+#define CMD_SEQ_IN_PTR         (0x1e << CMD_SHIFT)
+#define CMD_SEQ_OUT_PTR                (0x1f << CMD_SHIFT)
+
+/* General-purpose class selector for all commands */
+#define CLASS_SHIFT            25
+#define CLASS_MASK             (0x03 << CLASS_SHIFT)
+
+#define CLASS_NONE             (0x00 << CLASS_SHIFT)
+#define CLASS_1                        (0x01 << CLASS_SHIFT)
+#define CLASS_2                        (0x02 << CLASS_SHIFT)
+#define CLASS_BOTH             (0x03 << CLASS_SHIFT)
+
+/*
+ * Descriptor header command constructs
+ * Covers shared, job, and trusted descriptor headers
+ */
+
+/*
+ * Do Not Run - marks a descriptor inexecutable if there was
+ * a preceding error somewhere
+ */
+#define HDR_DNR                        0x01000000
+
+/*
+ * ONE - should always be set. Combination of ONE (always
+ * set) and ZRO (always clear) forms an endianness sanity check
+ */
+#define HDR_ONE                        0x00800000
+#define HDR_ZRO                        0x00008000
+
+/* Start Index or SharedDesc Length */
+#define HDR_START_IDX_MASK     0x3f
+#define HDR_START_IDX_SHIFT    16
+
+/* If shared descriptor header, 6-bit length */
+#define HDR_DESCLEN_SHR_MASK   0x3f
+
+/* If non-shared header, 7-bit length */
+#define HDR_DESCLEN_MASK       0x7f
+
+/* This is a TrustedDesc (if not SharedDesc) */
+#define HDR_TRUSTED            0x00004000
+
+/* Make into TrustedDesc (if not SharedDesc) */
+#define HDR_MAKE_TRUSTED       0x00002000
+
+/* Save context if self-shared (if SharedDesc) */
+#define HDR_SAVECTX            0x00001000
+
+/* Next item points to SharedDesc */
+#define HDR_SHARED             0x00001000
+
+/*
+ * Reverse Execution Order - execute JobDesc first, then
+ * execute SharedDesc (normally SharedDesc goes first).
+ */
+#define HDR_REVERSE            0x00000800
+
+/* Propogate DNR property to SharedDesc */
+#define HDR_PROP_DNR           0x00000800
+
+/* JobDesc/SharedDesc share property */
+#define HDR_SD_SHARE_MASK      0x03
+#define HDR_SD_SHARE_SHIFT     8
+#define HDR_JD_SHARE_MASK      0x07
+#define HDR_JD_SHARE_SHIFT     8
+
+#define HDR_SHARE_NEVER                (0x00 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_WAIT         (0x01 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_SERIAL       (0x02 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_ALWAYS       (0x03 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_DEFER                (0x04 << HDR_SD_SHARE_SHIFT)
+
+/* JobDesc/SharedDesc descriptor length */
+#define HDR_JD_LENGTH_MASK     0x7f
+#define HDR_SD_LENGTH_MASK     0x3f
+
+/*
+ * KEY/SEQ_KEY Command Constructs
+ */
+
+/* Key Destination Class: 01 = Class 1, 02 - Class 2 */
+#define KEY_DEST_CLASS_SHIFT   25      /* use CLASS_1 or CLASS_2 */
+#define KEY_DEST_CLASS_MASK    (0x03 << KEY_DEST_CLASS_SHIFT)
+
+/* Scatter-Gather Table/Variable Length Field */
+#define KEY_SGF                        0x01000000
+#define KEY_VLF                        0x01000000
+
+/* Immediate - Key follows command in the descriptor */
+#define KEY_IMM                        0x00800000
+
+/*
+ * Encrypted - Key is encrypted either with the KEK, or
+ * with the TDKEK if TK is set
+ */
+#define KEY_ENC                        0x00400000
+
+/*
+ * No Write Back - Do not allow key to be FIFO STOREd
+ */
+#define KEY_NWB                        0x00200000
+
+/*
+ * Enhanced Encryption of Key
+ */
+#define KEY_EKT                        0x00100000
+
+/*
+ * Encrypted with Trusted Key
+ */
+#define KEY_TK                 0x00008000
+
+/*
+ * KDEST - Key Destination: 0 - class key register,
+ * 1 - PKHA 'e', 2 - AFHA Sbox, 3 - MDHA split-key
+ */
+#define KEY_DEST_SHIFT         16
+#define KEY_DEST_MASK          (0x03 << KEY_DEST_SHIFT)
+
+#define KEY_DEST_CLASS_REG     (0x00 << KEY_DEST_SHIFT)
+#define KEY_DEST_PKHA_E                (0x01 << KEY_DEST_SHIFT)
+#define KEY_DEST_AFHA_SBOX     (0x02 << KEY_DEST_SHIFT)
+#define KEY_DEST_MDHA_SPLIT    (0x03 << KEY_DEST_SHIFT)
+
+/* Length in bytes */
+#define KEY_LENGTH_MASK                0x000003ff
+
+/*
+ * LOAD/SEQ_LOAD/STORE/SEQ_STORE Command Constructs
+ */
+
+/*
+ * Load/Store Destination: 0 = class independent CCB,
+ * 1 = class 1 CCB, 2 = class 2 CCB, 3 = DECO
+ */
+#define LDST_CLASS_SHIFT       25
+#define LDST_CLASS_MASK                (0x03 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_IND_CCB     (0x00 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_1_CCB       (0x01 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_2_CCB       (0x02 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_DECO                (0x03 << LDST_CLASS_SHIFT)
+
+/* Scatter-Gather Table/Variable Length Field */
+#define LDST_SGF               0x01000000
+#define LDST_VLF               LDST_SGF
+
+/* Immediate - Key follows this command in descriptor */
+#define LDST_IMM_MASK          1
+#define LDST_IMM_SHIFT         23
+#define LDST_IMM               (LDST_IMM_MASK << LDST_IMM_SHIFT)
+
+/* SRC/DST - Destination for LOAD, Source for STORE */
+#define LDST_SRCDST_SHIFT      16
+#define LDST_SRCDST_MASK       (0x7f << LDST_SRCDST_SHIFT)
+
+#define LDST_SRCDST_BYTE_CONTEXT       (0x20 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_KEY           (0x40 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_INFIFO                (0x7c << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_OUTFIFO       (0x7e << LDST_SRCDST_SHIFT)
+
+#define LDST_SRCDST_WORD_MODE_REG      (0x00 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_KEYSZ_REG     (0x01 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DATASZ_REG    (0x02 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_ICVSZ_REG     (0x03 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CHACTRL       (0x06 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECOCTRL      (0x06 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_IRQCTRL       (0x07 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_PCLOVRD  (0x07 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLRW          (0x08 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH0    (0x08 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_STAT          (0x09 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH1    (0x09 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH2    (0x0a << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_AAD_SZ   (0x0b << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH3    (0x0b << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLASS1_ICV_SZ (0x0c << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_ALTDS_CLASS1  (0x0f << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_A_SZ     (0x10 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_B_SZ     (0x11 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_N_SZ     (0x12 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_E_SZ     (0x13 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLASS_CTX     (0x20 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF       (0x40 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_JOB   (0x41 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_SHARED        (0x42 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_JOB_WE        (0x45 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF_SHARED_WE (0x46 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_INFO_FIFO     (0x7a << LDST_SRCDST_SHIFT)
+
+/* Offset in source/destination */
+#define LDST_OFFSET_SHIFT      8
+#define LDST_OFFSET_MASK       (0xff << LDST_OFFSET_SHIFT)
+
+/* LDOFF definitions used when DST = LDST_SRCDST_WORD_DECOCTRL */
+/* These could also be shifted by LDST_OFFSET_SHIFT - this reads better */
+#define LDOFF_CHG_SHARE_SHIFT          0
+#define LDOFF_CHG_SHARE_MASK           (0x3 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_NEVER          (0x1 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_OK_PROP                (0x2 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_OK_NO_PROP     (0x3 << LDOFF_CHG_SHARE_SHIFT)
+
+#define LDOFF_ENABLE_AUTO_NFIFO                (1 << 2)
+#define LDOFF_DISABLE_AUTO_NFIFO       (1 << 3)
+
+#define LDOFF_CHG_NONSEQLIODN_SHIFT    4
+#define LDOFF_CHG_NONSEQLIODN_MASK     (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_SEQ      (0x1 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_NON_SEQ  (0x2 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_TRUSTED  (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+
+#define LDOFF_CHG_SEQLIODN_SHIFT       6
+#define LDOFF_CHG_SEQLIODN_MASK                (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_SEQ         (0x1 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_NON_SEQ     (0x2 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_TRUSTED     (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
+
+/* Data length in bytes        */
+#define LDST_LEN_SHIFT         0
+#define LDST_LEN_MASK          (0xff << LDST_LEN_SHIFT)
+
+/* Special Length definitions when dst=deco-ctrl */
+#define LDLEN_ENABLE_OSL_COUNT         (1 << 7)
+#define LDLEN_RST_CHA_OFIFO_PTR                (1 << 6)
+#define LDLEN_RST_OFIFO                        (1 << 5)
+#define LDLEN_SET_OFIFO_OFF_VALID      (1 << 4)
+#define LDLEN_SET_OFIFO_OFF_RSVD       (1 << 3)
+#define LDLEN_SET_OFIFO_OFFSET_SHIFT   0
+#define LDLEN_SET_OFIFO_OFFSET_MASK    (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
+
+/*
+ * FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE
+ * Command Constructs
+ */
+
+/*
+ * Load Destination: 0 = skip (SEQ_FIFO_LOAD only),
+ * 1 = Load for Class1, 2 = Load for Class2, 3 = Load both
+ * Store Source: 0 = normal, 1 = Class1key, 2 = Class2key
+ */
+#define FIFOLD_CLASS_SHIFT     25
+#define FIFOLD_CLASS_MASK      (0x03 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_SKIP      (0x00 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_CLASS1    (0x01 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_CLASS2    (0x02 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_BOTH      (0x03 << FIFOLD_CLASS_SHIFT)
+
+#define FIFOST_CLASS_SHIFT     25
+#define FIFOST_CLASS_MASK      (0x03 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_NORMAL    (0x00 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_CLASS1KEY (0x01 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_CLASS2KEY (0x02 << FIFOST_CLASS_SHIFT)
+
+/*
+ * Scatter-Gather Table/Variable Length Field
+ * If set for FIFO_LOAD, refers to a SG table. Within
+ * SEQ_FIFO_LOAD, is variable input sequence
+ */
+#define FIFOLDST_SGF_SHIFT     24
+#define FIFOLDST_SGF_MASK      (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_VLF_MASK      (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_SGF           (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_VLF           (1 << FIFOLDST_SGF_SHIFT)
+
+/* Immediate - Data follows command in descriptor */
+#define FIFOLD_IMM_SHIFT       23
+#define FIFOLD_IMM_MASK                (1 << FIFOLD_IMM_SHIFT)
+#define FIFOLD_IMM             (1 << FIFOLD_IMM_SHIFT)
+
+/* Continue - Not the last FIFO store to come */
+#define FIFOST_CONT_SHIFT      23
+#define FIFOST_CONT_MASK       (1 << FIFOST_CONT_SHIFT)
+
+/*
+ * Extended Length - use 32-bit extended length that
+ * follows the pointer field. Illegal with IMM set
+ */
+#define FIFOLDST_EXT_SHIFT     22
+#define FIFOLDST_EXT_MASK      (1 << FIFOLDST_EXT_SHIFT)
+#define FIFOLDST_EXT           (1 << FIFOLDST_EXT_SHIFT)
+
+/* Input data type.*/
+#define FIFOLD_TYPE_SHIFT      16
+#define FIFOLD_CONT_TYPE_SHIFT 19 /* shift past last-flush bits */
+#define FIFOLD_TYPE_MASK       (0x3f << FIFOLD_TYPE_SHIFT)
+
+/* PK types */
+#define FIFOLD_TYPE_PK         (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_MASK    (0x30 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_TYPEMASK (0x0f << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A0      (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A1      (0x01 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A2      (0x02 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A3      (0x03 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B0      (0x04 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B1      (0x05 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B2      (0x06 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B3      (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_N       (0x08 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A       (0x0c << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B       (0x0d << FIFOLD_TYPE_SHIFT)
+
+/* Other types. Need to OR in last/flush bits as desired */
+#define FIFOLD_TYPE_MSG_MASK   (0x38 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG                (0x10 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG1OUT2   (0x18 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_IV         (0x20 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_BITDATA    (0x28 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_AAD                (0x30 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_ICV                (0x38 << FIFOLD_TYPE_SHIFT)
+
+/* Last/Flush bits for use with "other" types above */
+#define FIFOLD_TYPE_ACT_MASK   (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_NOACTION   (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_FLUSH1     (0x01 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST1      (0x02 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2FLUSH (0x03 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2      (0x04 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2FLUSH1 (0x05 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LASTBOTH   (0x06 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LASTBOTHFL (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_NOINFOFIFO (0x0F << FIFOLD_TYPE_SHIFT)
+
+#define FIFOLDST_LEN_MASK      0xffff
+#define FIFOLDST_EXT_LEN_MASK  0xffffffff
+
+/* Output data types */
+#define FIFOST_TYPE_SHIFT      16
+#define FIFOST_TYPE_MASK       (0x3f << FIFOST_TYPE_SHIFT)
+
+#define FIFOST_TYPE_PKHA_A0     (0x00 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A1     (0x01 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A2     (0x02 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A3     (0x03 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B0     (0x04 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B1     (0x05 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B2     (0x06 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B3     (0x07 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_N      (0x08 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A      (0x0c << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B      (0x0d << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_JKEK (0x10 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_E_JKEK         (0x22 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_E_TKEK         (0x23 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_KEK     (0x24 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_TKEK    (0x25 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SPLIT_KEK   (0x26 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SPLIT_TKEK  (0x27 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_OUTFIFO_KEK         (0x28 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_OUTFIFO_TKEK (0x29 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_RNGSTORE    (0x34 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_RNGFIFO     (0x35 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SKIP        (0x3f << FIFOST_TYPE_SHIFT)
+
+/*
+ * OPERATION Command Constructs
+ */
+
+/* Operation type selectors - OP TYPE */
+#define OP_TYPE_SHIFT          24
+#define OP_TYPE_MASK           (0x07 << OP_TYPE_SHIFT)
+
+#define OP_TYPE_UNI_PROTOCOL   (0x00 << OP_TYPE_SHIFT)
+#define OP_TYPE_PK             (0x01 << OP_TYPE_SHIFT)
+#define OP_TYPE_CLASS1_ALG     (0x02 << OP_TYPE_SHIFT)
+#define OP_TYPE_CLASS2_ALG     (0x04 << OP_TYPE_SHIFT)
+#define OP_TYPE_DECAP_PROTOCOL (0x06 << OP_TYPE_SHIFT)
+#define OP_TYPE_ENCAP_PROTOCOL (0x07 << OP_TYPE_SHIFT)
+
+/* ProtocolID selectors - PROTID */
+#define OP_PCLID_SHIFT         16
+#define OP_PCLID_MASK          (0xff << 16)
+
+/* Assuming OP_TYPE = OP_TYPE_UNI_PROTOCOL */
+#define OP_PCLID_BLOB          (0x0d << OP_PCLID_SHIFT)
+#define OP_PCLID_SECRETKEY     (0x11 << OP_PCLID_SHIFT)
+#define OP_PCLID_PUBLICKEYPAIR (0x14 << OP_PCLID_SHIFT)
+
+/* For non-protocol/alg-only op commands */
+#define OP_ALG_TYPE_SHIFT      24
+#define OP_ALG_TYPE_MASK       (0x7 << OP_ALG_TYPE_SHIFT)
+#define OP_ALG_TYPE_CLASS1     2
+#define OP_ALG_TYPE_CLASS2     4
+
+#define OP_ALG_ALGSEL_SHIFT    16
+#define OP_ALG_ALGSEL_MASK     (0xff << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SUBMASK  (0x0f << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_AES      (0x10 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_DES      (0x20 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_3DES     (0x21 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_ARC4     (0x30 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_MD5      (0x40 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA1     (0x41 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA224   (0x42 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA256   (0x43 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA384   (0x44 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA512   (0x45 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_RNG      (0x50 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW     (0x60 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW_F8  (0x60 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_KASUMI   (0x70 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_CRC      (0x90 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW_F9  (0xA0 << OP_ALG_ALGSEL_SHIFT)
+
+#define OP_ALG_AAI_SHIFT       4
+#define OP_ALG_AAI_MASK                (0x1ff << OP_ALG_AAI_SHIFT)
+
+/* randomizer AAI set */
+#define OP_ALG_AAI_RNG         (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_NZB     (0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_OBP     (0x20 << OP_ALG_AAI_SHIFT)
+
+/* RNG4 AAI set */
+#define OP_ALG_AAI_RNG4_SH_0   (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SH_1   (0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_PS     (0x40 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_AI     (0x80 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SK     (0x100 << OP_ALG_AAI_SHIFT)
+
+/* hmac/smac AAI set */
+#define OP_ALG_AAI_HASH                (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_HMAC                (0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_SMAC                (0x02 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_HMAC_PRECOMP        (0x04 << OP_ALG_AAI_SHIFT)
+
+#define OP_ALG_AS_SHIFT                2
+#define OP_ALG_AS_MASK         (0x3 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_UPDATE       (0 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_INIT         (1 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_FINALIZE     (2 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_INITFINAL    (3 << OP_ALG_AS_SHIFT)
+
+#define OP_ALG_ICV_SHIFT       1
+#define OP_ALG_ICV_MASK                (1 << OP_ALG_ICV_SHIFT)
+#define OP_ALG_ICV_OFF         (0 << OP_ALG_ICV_SHIFT)
+#define OP_ALG_ICV_ON          (1 << OP_ALG_ICV_SHIFT)
+
+#define OP_ALG_DIR_SHIFT       0
+#define OP_ALG_DIR_MASK                1
+#define OP_ALG_DECRYPT         0
+#define OP_ALG_ENCRYPT         1
+
+/* PKHA algorithm type set */
+#define OP_ALG_PK              0x00800000
+#define OP_ALG_PK_FUN_MASK     0x3f /* clrmem, modmath, or cpymem */
+
+/* PKHA mode modular-arithmetic functions */
+#define OP_ALG_PKMODE_MOD_EXPO         0x006
+
+/*
+ * SEQ_IN_PTR Command Constructs
+ */
+
+/* Release Buffers */
+#define SQIN_RBS       0x04000000
+
+/* Sequence pointer is really a descriptor */
+#define SQIN_INL       0x02000000
+
+/* Sequence pointer is a scatter-gather table */
+#define SQIN_SGF       0x01000000
+
+/* Appends to a previous pointer */
+#define SQIN_PRE       0x00800000
+
+/* Use extended length following pointer */
+#define SQIN_EXT       0x00400000
+
+/* Restore sequence with pointer/length */
+#define SQIN_RTO       0x00200000
+
+/* Replace job descriptor */
+#define SQIN_RJD       0x00100000
+
+#define SQIN_LEN_SHIFT          0
+#define SQIN_LEN_MASK          (0xffff << SQIN_LEN_SHIFT)
+
+/*
+ * SEQ_OUT_PTR Command Constructs
+ */
+
+/* Sequence pointer is a scatter-gather table */
+#define SQOUT_SGF      0x01000000
+
+/* Appends to a previous pointer */
+#define SQOUT_PRE      SQIN_PRE
+
+/* Restore sequence with pointer/length */
+#define SQOUT_RTO       SQIN_RTO
+
+/* Use extended length following pointer */
+#define SQOUT_EXT      0x00400000
+
+#define SQOUT_LEN_SHIFT                0
+#define SQOUT_LEN_MASK         (0xffff << SQOUT_LEN_SHIFT)
+
+/*
+ * MOVE Command Constructs
+ */
+
+#define MOVE_AUX_SHIFT         25
+#define MOVE_AUX_MASK          (3 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_MS            (2 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_LS            (1 << MOVE_AUX_SHIFT)
+
+#define MOVE_WAITCOMP_SHIFT    24
+#define MOVE_WAITCOMP_MASK     (1 << MOVE_WAITCOMP_SHIFT)
+#define MOVE_WAITCOMP          (1 << MOVE_WAITCOMP_SHIFT)
+
+#define MOVE_SRC_SHIFT         20
+#define MOVE_SRC_MASK          (0x0f << MOVE_SRC_SHIFT)
+#define MOVE_SRC_CLASS1CTX     (0x00 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_CLASS2CTX     (0x01 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_OUTFIFO       (0x02 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_DESCBUF       (0x03 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH0         (0x04 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH1         (0x05 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH2         (0x06 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH3         (0x07 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_INFIFO                (0x08 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_INFIFO_CL     (0x09 << MOVE_SRC_SHIFT)
+
+#define MOVE_DEST_SHIFT                16
+#define MOVE_DEST_MASK         (0x0f << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1CTX    (0x00 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2CTX    (0x01 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_OUTFIFO      (0x02 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_DESCBUF      (0x03 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH0                (0x04 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH1                (0x05 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH2                (0x06 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH3                (0x07 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1INFIFO (0x08 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2INFIFO (0x09 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_INFIFO_NOINFO (0x0a << MOVE_DEST_SHIFT)
+#define MOVE_DEST_PK_A         (0x0c << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1KEY    (0x0d << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2KEY    (0x0e << MOVE_DEST_SHIFT)
+
+#define MOVE_OFFSET_SHIFT      8
+#define MOVE_OFFSET_MASK       (0xff << MOVE_OFFSET_SHIFT)
+
+#define MOVE_LEN_SHIFT         0
+#define MOVE_LEN_MASK          (0xff << MOVE_LEN_SHIFT)
+
+#define MOVELEN_MRSEL_SHIFT    0
+#define MOVELEN_MRSEL_MASK     (0x3 << MOVE_LEN_SHIFT)
+
+/*
+ * JUMP Command Constructs
+ */
+
+#define JUMP_CLASS_SHIFT       25
+#define JUMP_CLASS_MASK                (3 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_NONE                0
+#define JUMP_CLASS_CLASS1      (1 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_CLASS2      (2 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_BOTH                (3 << JUMP_CLASS_SHIFT)
+
+#define JUMP_JSL_SHIFT         24
+#define JUMP_JSL_MASK          (1 << JUMP_JSL_SHIFT)
+#define JUMP_JSL               (1 << JUMP_JSL_SHIFT)
+
+#define JUMP_TYPE_SHIFT                22
+#define JUMP_TYPE_MASK         (0x03 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_LOCAL                (0x00 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_NONLOCAL     (0x01 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_HALT         (0x02 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_HALT_USER    (0x03 << JUMP_TYPE_SHIFT)
+
+#define JUMP_TEST_SHIFT                16
+#define JUMP_TEST_MASK         (0x03 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_ALL          (0x00 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_INVALL       (0x01 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_ANY          (0x02 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_INVANY       (0x03 << JUMP_TEST_SHIFT)
+
+/* Condition codes. JSL bit is factored in */
+#define JUMP_COND_SHIFT                8
+#define JUMP_COND_MASK         (0x100ff << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_0         (0x80 << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_GCD_1     (0x40 << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_PRIME     (0x20 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_N       (0x08 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_Z       (0x04 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_C       (0x02 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_NV      (0x01 << JUMP_COND_SHIFT)
+
+#define JUMP_COND_JRP          ((0x80 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_SHRD         ((0x40 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_SELF         ((0x20 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_CALM         ((0x10 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NIP          ((0x08 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NIFP         ((0x04 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NOP          ((0x02 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NCP          ((0x01 << JUMP_COND_SHIFT) | JUMP_JSL)
+
+#define JUMP_OFFSET_SHIFT      0
+#define JUMP_OFFSET_MASK       (0xff << JUMP_OFFSET_SHIFT)
+
+#define OP_ALG_RNG4_SHIFT      4
+#define OP_ALG_RNG4_MAS                (0x1f3 << OP_ALG_RNG4_SHIFT)
+#define OP_ALG_RNG4_SK         (0x100 << OP_ALG_RNG4_SHIFT)
+
+#endif /* DESC_H */
diff --git a/drivers/crypto/fsl/desc_constr.h b/drivers/crypto/fsl/desc_constr.h
new file mode 100644 (file)
index 0000000..f9cae91
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * caam descriptor construction helper functions
+ *
+ * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Based on desc_constr.h file in linux drivers/crypto/caam
+ */
+
+#include <linux/compat.h>
+#include "desc.h"
+
+#define IMMEDIATE (1 << 23)
+#define CAAM_CMD_SZ sizeof(u32)
+#define CAAM_PTR_SZ sizeof(dma_addr_t)
+#define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * MAX_CAAM_DESCSIZE)
+#define DESC_JOB_IO_LEN (CAAM_CMD_SZ * 5 + CAAM_PTR_SZ * 3)
+
+#ifdef DEBUG
+#define PRINT_POS do { printf("%02d: %s\n", desc_len(desc),\
+                             &__func__[sizeof("append")]); \
+                    } while (0)
+#else
+#define PRINT_POS
+#endif
+
+#define SET_OK_NO_PROP_ERRORS (IMMEDIATE | LDST_CLASS_DECO | \
+                              LDST_SRCDST_WORD_DECOCTRL | \
+                              (LDOFF_CHG_SHARE_OK_NO_PROP << \
+                               LDST_OFFSET_SHIFT))
+#define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
+                               LDST_SRCDST_WORD_DECOCTRL | \
+                               (LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
+#define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
+                              LDST_SRCDST_WORD_DECOCTRL | \
+                              (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
+
+static inline int desc_len(u32 *desc)
+{
+       return *desc & HDR_DESCLEN_MASK;
+}
+
+static inline int desc_bytes(void *desc)
+{
+       return desc_len(desc) * CAAM_CMD_SZ;
+}
+
+static inline u32 *desc_end(u32 *desc)
+{
+       return desc + desc_len(desc);
+}
+
+static inline void init_desc(u32 *desc, u32 options)
+{
+       *desc = (options | HDR_ONE) + 1;
+}
+
+static inline void init_job_desc(u32 *desc, u32 options)
+{
+       init_desc(desc, CMD_DESC_HDR | options);
+}
+
+static inline void append_ptr(u32 *desc, dma_addr_t ptr)
+{
+       dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
+
+       *offset = ptr;
+
+       (*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ;
+}
+
+static inline void append_data(u32 *desc, void *data, int len)
+{
+       u32 *offset = desc_end(desc);
+
+       if (len) /* avoid sparse warning: memcpy with byte count of 0 */
+               memcpy(offset, data, len);
+
+       (*desc) += (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
+}
+
+static inline void append_cmd(u32 *desc, u32 command)
+{
+       u32 *cmd = desc_end(desc);
+
+       *cmd = command;
+
+       (*desc)++;
+}
+
+#define append_u32 append_cmd
+
+static inline void append_u64(u32 *desc, u64 data)
+{
+       u32 *offset = desc_end(desc);
+
+       *offset = upper_32_bits(data);
+       *(++offset) = lower_32_bits(data);
+
+       (*desc) += 2;
+}
+
+/* Write command without affecting header, and return pointer to next word */
+static inline u32 *write_cmd(u32 *desc, u32 command)
+{
+       *desc = command;
+
+       return desc + 1;
+}
+
+static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len,
+                                 u32 command)
+{
+       append_cmd(desc, command | len);
+       append_ptr(desc, ptr);
+}
+
+/* Write length after pointer, rather than inside command */
+static inline void append_cmd_ptr_extlen(u32 *desc, dma_addr_t ptr,
+                                        unsigned int len, u32 command)
+{
+       append_cmd(desc, command);
+       if (!(command & (SQIN_RTO | SQIN_PRE)))
+               append_ptr(desc, ptr);
+       append_cmd(desc, len);
+}
+
+static inline void append_cmd_data(u32 *desc, void *data, int len,
+                                  u32 command)
+{
+       append_cmd(desc, command | IMMEDIATE | len);
+       append_data(desc, data, len);
+}
+
+#define APPEND_CMD_RET(cmd, op) \
+static inline u32 *append_##cmd(u32 *desc, u32 options) \
+{ \
+       u32 *cmd = desc_end(desc); \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | options); \
+       return cmd; \
+}
+APPEND_CMD_RET(jump, JUMP)
+APPEND_CMD_RET(move, MOVE)
+
+static inline void set_jump_tgt_here(u32 *desc, u32 *jump_cmd)
+{
+       *jump_cmd = *jump_cmd | (desc_len(desc) - (jump_cmd - desc));
+}
+
+static inline void set_move_tgt_here(u32 *desc, u32 *move_cmd)
+{
+       *move_cmd &= ~MOVE_OFFSET_MASK;
+       *move_cmd = *move_cmd | ((desc_len(desc) << (MOVE_OFFSET_SHIFT + 2)) &
+                                MOVE_OFFSET_MASK);
+}
+
+#define APPEND_CMD(cmd, op) \
+static inline void append_##cmd(u32 *desc, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | options); \
+}
+APPEND_CMD(operation, OPERATION)
+
+#define APPEND_CMD_LEN(cmd, op) \
+static inline void append_##cmd(u32 *desc, unsigned int len, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | len | options); \
+}
+APPEND_CMD_LEN(seq_store, SEQ_STORE)
+APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
+APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
+
+#define APPEND_CMD_PTR(cmd, op) \
+static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \
+                               u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd_ptr(desc, ptr, len, CMD_##op | options); \
+}
+APPEND_CMD_PTR(key, KEY)
+APPEND_CMD_PTR(load, LOAD)
+APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
+APPEND_CMD_PTR(fifo_store, FIFO_STORE)
+
+static inline void append_store(u32 *desc, dma_addr_t ptr, unsigned int len,
+                               u32 options)
+{
+       u32 cmd_src;
+
+       cmd_src = options & LDST_SRCDST_MASK;
+
+       append_cmd(desc, CMD_STORE | options | len);
+
+       /* The following options do not require pointer */
+       if (!(cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED ||
+             cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB    ||
+             cmd_src == LDST_SRCDST_WORD_DESCBUF_JOB_WE ||
+             cmd_src == LDST_SRCDST_WORD_DESCBUF_SHARED_WE))
+               append_ptr(desc, ptr);
+}
+
+#define APPEND_SEQ_PTR_INTLEN(cmd, op) \
+static inline void append_seq_##cmd##_ptr_intlen(u32 *desc, dma_addr_t ptr, \
+                                                unsigned int len, \
+                                                u32 options) \
+{ \
+       PRINT_POS; \
+       if (options & (SQIN_RTO | SQIN_PRE)) \
+               append_cmd(desc, CMD_SEQ_##op##_PTR | len | options); \
+       else \
+               append_cmd_ptr(desc, ptr, len, CMD_SEQ_##op##_PTR | options); \
+}
+APPEND_SEQ_PTR_INTLEN(in, IN)
+APPEND_SEQ_PTR_INTLEN(out, OUT)
+
+#define APPEND_CMD_PTR_TO_IMM(cmd, op) \
+static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
+                                        unsigned int len, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd_data(desc, data, len, CMD_##op | options); \
+}
+APPEND_CMD_PTR_TO_IMM(load, LOAD);
+APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
+
+#define APPEND_CMD_PTR_EXTLEN(cmd, op) \
+static inline void append_##cmd##_extlen(u32 *desc, dma_addr_t ptr, \
+                                        unsigned int len, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd_ptr_extlen(desc, ptr, len, CMD_##op | SQIN_EXT | options); \
+}
+APPEND_CMD_PTR_EXTLEN(seq_in_ptr, SEQ_IN_PTR)
+APPEND_CMD_PTR_EXTLEN(seq_out_ptr, SEQ_OUT_PTR)
+
+/*
+ * Determine whether to store length internally or externally depending on
+ * the size of its type
+ */
+#define APPEND_CMD_PTR_LEN(cmd, op, type) \
+static inline void append_##cmd(u32 *desc, dma_addr_t ptr, \
+                               type len, u32 options) \
+{ \
+       PRINT_POS; \
+       if (sizeof(type) > sizeof(u16)) \
+               append_##cmd##_extlen(desc, ptr, len, options); \
+       else \
+               append_##cmd##_intlen(desc, ptr, len, options); \
+}
+APPEND_CMD_PTR_LEN(seq_in_ptr, SEQ_IN_PTR, u32)
+APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_PTR, u32)
+
+/*
+ * 2nd variant for commands whose specified immediate length differs
+ * from length of immediate data provided, e.g., split keys
+ */
+#define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
+static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
+                                        unsigned int data_len, \
+                                        unsigned int len, u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \
+       append_data(desc, data, data_len); \
+}
+APPEND_CMD_PTR_TO_IMM2(key, KEY);
+
+#define APPEND_CMD_RAW_IMM(cmd, op, type) \
+static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \
+                                            u32 options) \
+{ \
+       PRINT_POS; \
+       append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \
+       append_cmd(desc, immediate); \
+}
+APPEND_CMD_RAW_IMM(load, LOAD, u32);
diff --git a/drivers/crypto/fsl/error.c b/drivers/crypto/fsl/error.c
new file mode 100644 (file)
index 0000000..28cdcdd
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * CAAM Error Reporting
+ *
+ * Copyright 2009-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Derived from error.c file in linux drivers/crypto/caam
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include "desc.h"
+#include "jr.h"
+
+#define CAAM_ERROR_STR_MAX 302
+
+#define JRSTA_SSRC_SHIFT            28
+#define JRSTA_CCBERR_CHAID_MASK     0x00f0
+#define JRSTA_CCBERR_CHAID_SHIFT    4
+#define JRSTA_CCBERR_ERRID_MASK     0x000
+#define JRSTA_CCBERR_CHAID_RNG      (0x05 << JRSTA_CCBERR_CHAID_SHIFT)
+
+#define JRSTA_DECOERR_JUMP          0x08000000
+#define JRSTA_DECOERR_INDEX_SHIFT   8
+#define JRSTA_DECOERR_INDEX_MASK    0xff00
+#define JRSTA_DECOERR_ERROR_MASK    0x00ff
+
+
+static const struct {
+       u8 value;
+       const char *error_text;
+} desc_error_list[] = {
+       { 0x00, "No error." },
+       { 0x01, "SGT Length Error. The descriptor is trying to read" \
+               " more data than is contained in the SGT table." },
+       { 0x02, "SGT Null Entry Error." },
+       { 0x03, "Job Ring Control Error. Bad value in Job Ring Control reg." },
+       { 0x04, "Invalid Descriptor Command." },
+       { 0x05, "Reserved." },
+       { 0x06, "Invalid KEY Command" },
+       { 0x07, "Invalid LOAD Command" },
+       { 0x08, "Invalid STORE Command" },
+       { 0x09, "Invalid OPERATION Command" },
+       { 0x0A, "Invalid FIFO LOAD Command" },
+       { 0x0B, "Invalid FIFO STORE Command" },
+       { 0x0C, "Invalid MOVE/MOVE_LEN Command" },
+       { 0x0D, "Invalid JUMP Command" },
+       { 0x0E, "Invalid MATH Command" },
+       { 0x0F, "Invalid SIGNATURE Command" },
+       { 0x10, "Invalid Sequence Command" },
+       { 0x11, "Skip data type invalid. The type must be 0xE or 0xF."},
+       { 0x12, "Shared Descriptor Header Error" },
+       { 0x13, "Header Error. Invalid length or parity, or other problems." },
+       { 0x14, "Burster Error. Burster has gotten to an illegal state" },
+       { 0x15, "Context Register Length Error" },
+       { 0x16, "DMA Error" },
+       { 0x17, "Reserved." },
+       { 0x1A, "Job failed due to JR reset" },
+       { 0x1B, "Job failed due to Fail Mode" },
+       { 0x1C, "DECO Watchdog timer timeout error" },
+       { 0x1D, "DECO tried to copy a key from another DECO but" \
+               " the other DECO's Key Registers were locked" },
+       { 0x1E, "DECO attempted to copy data from a DECO" \
+               "that had an unmasked Descriptor error" },
+       { 0x1F, "LIODN error" },
+       { 0x20, "DECO has completed a reset initiated via the DRR register" },
+       { 0x21, "Nonce error" },
+       { 0x22, "Meta data is too large (> 511 bytes) for TLS decap" },
+       { 0x23, "Read Input Frame error" },
+       { 0x24, "JDKEK, TDKEK or TDSK not loaded error" },
+       { 0x80, "DNR (do not run) error" },
+       { 0x81, "undefined protocol command" },
+       { 0x82, "invalid setting in PDB" },
+       { 0x83, "Anti-replay LATE error" },
+       { 0x84, "Anti-replay REPLAY error" },
+       { 0x85, "Sequence number overflow" },
+       { 0x86, "Sigver invalid signature" },
+       { 0x87, "DSA Sign Illegal test descriptor" },
+       { 0x88, "Protocol Format Error" },
+       { 0x89, "Protocol Size Error" },
+       { 0xC1, "Blob Command error: Undefined mode" },
+       { 0xC2, "Blob Command error: Secure Memory Blob mode error" },
+       { 0xC4, "Blob Command error: Black Blob key or input size error" },
+       { 0xC5, "Blob Command error: Invalid key destination" },
+       { 0xC8, "Blob Command error: Trusted/Secure mode error" },
+       { 0xF0, "IPsec TTL or hop limit field is 0, or was decremented to 0" },
+       { 0xF1, "3GPP HFN matches or exceeds the Threshold" },
+};
+
+static const char * const cha_id_list[] = {
+       "",
+       "AES",
+       "DES",
+       "ARC4",
+       "MDHA",
+       "RNG",
+       "SNOW f8",
+       "Kasumi f8/9",
+       "PKHA",
+       "CRCA",
+       "SNOW f9",
+       "ZUCE",
+       "ZUCA",
+};
+
+static const char * const err_id_list[] = {
+       "No error.",
+       "Mode error.",
+       "Data size error.",
+       "Key size error.",
+       "PKHA A memory size error.",
+       "PKHA B memory size error.",
+       "Data arrived out of sequence error.",
+       "PKHA divide-by-zero error.",
+       "PKHA modulus even error.",
+       "DES key parity error.",
+       "ICV check failed.",
+       "Hardware error.",
+       "Unsupported CCM AAD size.",
+       "Class 1 CHA is not reset",
+       "Invalid CHA combination was selected",
+       "Invalid CHA selected.",
+};
+
+static const char * const rng_err_id_list[] = {
+       "",
+       "",
+       "",
+       "Instantiate",
+       "Not instantiated",
+       "Test instantiate",
+       "Prediction resistance",
+       "Prediction resistance and test request",
+       "Uninstantiate",
+       "Secure key generation",
+};
+
+static void report_ccb_status(const u32 status,
+                             const char *error)
+{
+       u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >>
+                   JRSTA_CCBERR_CHAID_SHIFT;
+       u8 err_id = status & JRSTA_CCBERR_ERRID_MASK;
+       u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
+                 JRSTA_DECOERR_INDEX_SHIFT;
+       char *idx_str;
+       const char *cha_str = "unidentified cha_id value 0x";
+       char cha_err_code[3] = { 0 };
+       const char *err_str = "unidentified err_id value 0x";
+       char err_err_code[3] = { 0 };
+
+       if (status & JRSTA_DECOERR_JUMP)
+               idx_str = "jump tgt desc idx";
+       else
+               idx_str = "desc idx";
+
+       if (cha_id < ARRAY_SIZE(cha_id_list))
+               cha_str = cha_id_list[cha_id];
+       else
+               snprintf(cha_err_code, sizeof(cha_err_code), "%02x", cha_id);
+
+       if ((cha_id << JRSTA_CCBERR_CHAID_SHIFT) == JRSTA_CCBERR_CHAID_RNG &&
+           err_id < ARRAY_SIZE(rng_err_id_list) &&
+           strlen(rng_err_id_list[err_id])) {
+               /* RNG-only error */
+               err_str = rng_err_id_list[err_id];
+       } else if (err_id < ARRAY_SIZE(err_id_list)) {
+               err_str = err_id_list[err_id];
+       } else {
+               snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
+       }
+
+       debug("%08x: %s: %s %d: %s%s: %s%s\n",
+              status, error, idx_str, idx,
+               cha_str, cha_err_code,
+               err_str, err_err_code);
+}
+
+static void report_jump_status(const u32 status,
+                              const char *error)
+{
+       debug("%08x: %s: %s() not implemented\n",
+              status, error, __func__);
+}
+
+static void report_deco_status(const u32 status,
+                              const char *error)
+{
+       u8 err_id = status & JRSTA_DECOERR_ERROR_MASK;
+       u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
+                 JRSTA_DECOERR_INDEX_SHIFT;
+       char *idx_str;
+       const char *err_str = "unidentified error value 0x";
+       char err_err_code[3] = { 0 };
+       int i;
+
+       if (status & JRSTA_DECOERR_JUMP)
+               idx_str = "jump tgt desc idx";
+       else
+               idx_str = "desc idx";
+
+       for (i = 0; i < ARRAY_SIZE(desc_error_list); i++)
+               if (desc_error_list[i].value == err_id)
+                       break;
+
+       if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text)
+               err_str = desc_error_list[i].error_text;
+       else
+               snprintf(err_err_code, sizeof(err_err_code), "%02x", err_id);
+
+       debug("%08x: %s: %s %d: %s%s\n",
+              status, error, idx_str, idx, err_str, err_err_code);
+}
+
+static void report_jr_status(const u32 status,
+                            const char *error)
+{
+       debug("%08x: %s: %s() not implemented\n",
+              status, error, __func__);
+}
+
+static void report_cond_code_status(const u32 status,
+                                   const char *error)
+{
+       debug("%08x: %s: %s() not implemented\n",
+              status, error, __func__);
+}
+
+void caam_jr_strstatus(u32 status)
+{
+       static const struct stat_src {
+               void (*report_ssed)(const u32 status,
+                                   const char *error);
+               const char *error;
+       } status_src[] = {
+               { NULL, "No error" },
+               { NULL, NULL },
+               { report_ccb_status, "CCB" },
+               { report_jump_status, "Jump" },
+               { report_deco_status, "DECO" },
+               { NULL, NULL },
+               { report_jr_status, "Job Ring" },
+               { report_cond_code_status, "Condition Code" },
+       };
+       u32 ssrc = status >> JRSTA_SSRC_SHIFT;
+       const char *error = status_src[ssrc].error;
+
+       /*
+        * If there is no further error handling function, just
+        * print the error code, error string and exit. Otherwise
+        * call the handler function.
+        */
+       if (!status_src[ssrc].report_ssed)
+               debug("%08x: %s:\n", status, status_src[ssrc].error);
+       else
+               status_src[ssrc].report_ssed(status, error);
+}
diff --git a/drivers/crypto/fsl/fsl_hash.c b/drivers/crypto/fsl/fsl_hash.c
new file mode 100644 (file)
index 0000000..d77f257
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include "jobdesc.h"
+#include "desc.h"
+#include "jr.h"
+
+#define CRYPTO_MAX_ALG_NAME    80
+#define SHA1_DIGEST_SIZE        20
+#define SHA256_DIGEST_SIZE      32
+
+struct caam_hash_template {
+       char name[CRYPTO_MAX_ALG_NAME];
+       unsigned int digestsize;
+       u32 alg_type;
+};
+
+enum caam_hash_algos {
+       SHA1 = 0,
+       SHA256
+};
+
+static struct caam_hash_template driver_hash[] = {
+       {
+               .name = "sha1",
+               .digestsize = SHA1_DIGEST_SIZE,
+               .alg_type = OP_ALG_ALGSEL_SHA1,
+       },
+       {
+               .name = "sha256",
+               .digestsize = SHA256_DIGEST_SIZE,
+               .alg_type = OP_ALG_ALGSEL_SHA256,
+       },
+};
+
+int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
+             unsigned char *pout, enum caam_hash_algos algo)
+{
+       int ret = 0;
+       uint32_t *desc;
+
+       desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
+       if (!desc) {
+               debug("Not enough memory for descriptor allocation\n");
+               return -1;
+       }
+
+       inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout,
+                                 driver_hash[algo].alg_type,
+                                 driver_hash[algo].digestsize,
+                                 0);
+
+       ret = run_descriptor_jr(desc);
+
+       free(desc);
+       return ret;
+}
+
+void hw_sha256(const unsigned char *pbuf, unsigned int buf_len,
+                       unsigned char *pout, unsigned int chunk_size)
+{
+       if (caam_hash(pbuf, buf_len, pout, SHA256))
+               printf("CAAM was not setup properly or it is faulty\n");
+}
+
+void hw_sha1(const unsigned char *pbuf, unsigned int buf_len,
+                       unsigned char *pout, unsigned int chunk_size)
+{
+       if (caam_hash(pbuf, buf_len, pout, SHA1))
+               printf("CAAM was not setup properly or it is faulty\n");
+}
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
new file mode 100644 (file)
index 0000000..cbe5c30
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * SEC Descriptor Construction Library
+ * Basic job descriptor construction
+ *
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#include <common.h>
+#include "desc_constr.h"
+#include "jobdesc.h"
+
+void inline_cnstr_jobdesc_hash(uint32_t *desc,
+                         const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
+                         u32 alg_type, uint32_t alg_size, int sg_tbl)
+{
+       /* SHA 256 , output is of length 32 words */
+       uint32_t storelen = alg_size;
+       u32 options;
+       dma_addr_t dma_addr_in, dma_addr_out;
+
+       dma_addr_in = virt_to_phys((void *)msg);
+       dma_addr_out = virt_to_phys((void *)digest);
+
+       init_job_desc(desc, 0);
+       append_operation(desc, OP_TYPE_CLASS2_ALG |
+                        OP_ALG_AAI_HASH | OP_ALG_AS_INITFINAL |
+                        OP_ALG_ENCRYPT | OP_ALG_ICV_OFF | alg_type);
+
+       options = LDST_CLASS_2_CCB | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2;
+       if (sg_tbl)
+               options |= FIFOLDST_SGF;
+       if (msgsz > 0xffff) {
+               options |= FIFOLDST_EXT;
+               append_fifo_load(desc, dma_addr_in, 0, options);
+               append_cmd(desc, msgsz);
+       } else {
+               append_fifo_load(desc, dma_addr_in, msgsz, options);
+       }
+
+       append_store(desc, dma_addr_out, storelen,
+                    LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_CONTEXT);
+}
diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h
new file mode 100644 (file)
index 0000000..ed61579
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#ifndef __JOBDESC_H
+#define __JOBDESC_H
+
+#include <common.h>
+#include <asm/io.h>
+
+void inline_cnstr_jobdesc_hash(uint32_t *desc,
+                         const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
+                         u32 alg_type, uint32_t alg_size, int sg_tbl);
+
+#endif
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
new file mode 100644 (file)
index 0000000..a107e6a
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ * Based on CAAM driver in drivers/crypto/caam in Linux
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include "fsl_sec.h"
+#include "jr.h"
+
+#define CIRC_CNT(head, tail, size)     (((head) - (tail)) & (size - 1))
+#define CIRC_SPACE(head, tail, size)   CIRC_CNT((tail), (head) + 1, (size))
+
+struct jobring jr;
+
+static inline void start_jr0(void)
+{
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       u32 ctpr_ms = sec_in32(&sec->ctpr_ms);
+       u32 scfgr = sec_in32(&sec->scfgr);
+
+       if (ctpr_ms & SEC_CTPR_MS_VIRT_EN_INCL) {
+               /* VIRT_EN_INCL = 1 & VIRT_EN_POR = 1 or
+                * VIRT_EN_INCL = 1 & VIRT_EN_POR = 0 & SEC_SCFGR_VIRT_EN = 1
+                */
+               if ((ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) ||
+                   (!(ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR) &&
+                                       (scfgr & SEC_SCFGR_VIRT_EN)))
+                       sec_out32(&sec->jrstartr, CONFIG_JRSTARTR_JR0);
+       } else {
+               /* VIRT_EN_INCL = 0 && VIRT_EN_POR_VALUE = 1 */
+               if (ctpr_ms & SEC_CTPR_MS_VIRT_EN_POR)
+                       sec_out32(&sec->jrstartr, CONFIG_JRSTARTR_JR0);
+       }
+}
+
+static inline void jr_reset_liodn(void)
+{
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       sec_out32(&sec->jrliodnr[0].ls, 0);
+}
+
+static inline void jr_disable_irq(void)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       uint32_t jrcfg = sec_in32(&regs->jrcfg1);
+
+       jrcfg = jrcfg | JR_INTMASK;
+
+       sec_out32(&regs->jrcfg1, jrcfg);
+}
+
+static void jr_initregs(void)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       phys_addr_t ip_base = virt_to_phys((void *)jr.input_ring);
+       phys_addr_t op_base = virt_to_phys((void *)jr.output_ring);
+
+#ifdef CONFIG_PHYS_64BIT
+       sec_out32(&regs->irba_h, ip_base >> 32);
+#else
+       sec_out32(&regs->irba_h, 0x0);
+#endif
+       sec_out32(&regs->irba_l, (uint32_t)ip_base);
+#ifdef CONFIG_PHYS_64BIT
+       sec_out32(&regs->orba_h, op_base >> 32);
+#else
+       sec_out32(&regs->orba_h, 0x0);
+#endif
+       sec_out32(&regs->orba_l, (uint32_t)op_base);
+       sec_out32(&regs->ors, JR_SIZE);
+       sec_out32(&regs->irs, JR_SIZE);
+
+       if (!jr.irq)
+               jr_disable_irq();
+}
+
+static int jr_init(void)
+{
+       memset(&jr, 0, sizeof(struct jobring));
+
+       jr.jq_id = DEFAULT_JR_ID;
+       jr.irq = DEFAULT_IRQ;
+
+#ifdef CONFIG_FSL_CORENET
+       jr.liodn = DEFAULT_JR_LIODN;
+#endif
+       jr.size = JR_SIZE;
+       jr.input_ring = (dma_addr_t *)malloc(JR_SIZE * sizeof(dma_addr_t));
+       if (!jr.input_ring)
+               return -1;
+       jr.output_ring =
+           (struct op_ring *)malloc(JR_SIZE * sizeof(struct op_ring));
+       if (!jr.output_ring)
+               return -1;
+
+       memset(jr.input_ring, 0, JR_SIZE * sizeof(dma_addr_t));
+       memset(jr.output_ring, 0, JR_SIZE * sizeof(struct op_ring));
+
+       start_jr0();
+
+       jr_initregs();
+
+       return 0;
+}
+
+static int jr_sw_cleanup(void)
+{
+       jr.head = 0;
+       jr.tail = 0;
+       jr.read_idx = 0;
+       jr.write_idx = 0;
+       memset(jr.info, 0, sizeof(jr.info));
+       memset(jr.input_ring, 0, jr.size * sizeof(dma_addr_t));
+       memset(jr.output_ring, 0, jr.size * sizeof(struct op_ring));
+
+       return 0;
+}
+
+static int jr_hw_reset(void)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       uint32_t timeout = 100000;
+       uint32_t jrint, jrcr;
+
+       sec_out32(&regs->jrcr, JRCR_RESET);
+       do {
+               jrint = sec_in32(&regs->jrint);
+       } while (((jrint & JRINT_ERR_HALT_MASK) ==
+                 JRINT_ERR_HALT_INPROGRESS) && --timeout);
+
+       jrint = sec_in32(&regs->jrint);
+       if (((jrint & JRINT_ERR_HALT_MASK) !=
+            JRINT_ERR_HALT_INPROGRESS) && timeout == 0)
+               return -1;
+
+       timeout = 100000;
+       sec_out32(&regs->jrcr, JRCR_RESET);
+       do {
+               jrcr = sec_in32(&regs->jrcr);
+       } while ((jrcr & JRCR_RESET) && --timeout);
+
+       if (timeout == 0)
+               return -1;
+
+       return 0;
+}
+
+/* -1 --- error, can't enqueue -- no space available */
+static int jr_enqueue(uint32_t *desc_addr,
+              void (*callback)(uint32_t desc, uint32_t status, void *arg),
+              void *arg)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       int head = jr.head;
+       dma_addr_t desc_phys_addr = virt_to_phys(desc_addr);
+
+       if (sec_in32(&regs->irsa) == 0 ||
+           CIRC_SPACE(jr.head, jr.tail, jr.size) <= 0)
+               return -1;
+
+       jr.input_ring[head] = desc_phys_addr;
+       jr.info[head].desc_phys_addr = desc_phys_addr;
+       jr.info[head].desc_addr = (uint32_t)desc_addr;
+       jr.info[head].callback = (void *)callback;
+       jr.info[head].arg = arg;
+       jr.info[head].op_done = 0;
+
+       jr.head = (head + 1) & (jr.size - 1);
+
+       sec_out32(&regs->irja, 1);
+
+       return 0;
+}
+
+static int jr_dequeue(void)
+{
+       struct jr_regs *regs = (struct jr_regs *)CONFIG_SYS_FSL_JR0_ADDR;
+       int head = jr.head;
+       int tail = jr.tail;
+       int idx, i, found;
+       void (*callback)(uint32_t desc, uint32_t status, void *arg);
+       void *arg = NULL;
+
+       while (sec_in32(&regs->orsf) && CIRC_CNT(jr.head, jr.tail, jr.size)) {
+               found = 0;
+
+               dma_addr_t op_desc = jr.output_ring[jr.tail].desc;
+               uint32_t status = jr.output_ring[jr.tail].status;
+               uint32_t desc_virt;
+
+               for (i = 0; CIRC_CNT(head, tail + i, jr.size) >= 1; i++) {
+                       idx = (tail + i) & (jr.size - 1);
+                       if (op_desc == jr.info[idx].desc_phys_addr) {
+                               desc_virt = jr.info[idx].desc_addr;
+                               found = 1;
+                               break;
+                       }
+               }
+
+               /* Error condition if match not found */
+               if (!found)
+                       return -1;
+
+               jr.info[idx].op_done = 1;
+               callback = (void *)jr.info[idx].callback;
+               arg = jr.info[idx].arg;
+
+               /* When the job on tail idx gets done, increment
+                * tail till the point where job completed out of oredr has
+                * been taken into account
+                */
+               if (idx == tail)
+                       do {
+                               tail = (tail + 1) & (jr.size - 1);
+                       } while (jr.info[tail].op_done);
+
+               jr.tail = tail;
+               jr.read_idx = (jr.read_idx + 1) & (jr.size - 1);
+
+               sec_out32(&regs->orjr, 1);
+               jr.info[idx].op_done = 0;
+
+               callback(desc_virt, status, arg);
+       }
+
+       return 0;
+}
+
+static void desc_done(uint32_t desc, uint32_t status, void *arg)
+{
+       struct result *x = arg;
+       x->status = status;
+       caam_jr_strstatus(status);
+       x->done = 1;
+}
+
+int run_descriptor_jr(uint32_t *desc)
+{
+       unsigned long long timeval = get_ticks();
+       unsigned long long timeout = usec2ticks(CONFIG_SEC_DEQ_TIMEOUT);
+       struct result op;
+       int ret = 0;
+
+       memset(&op, sizeof(op), 0);
+
+       ret = jr_enqueue(desc, desc_done, &op);
+       if (ret) {
+               debug("Error in SEC enq\n");
+               ret = JQ_ENQ_ERR;
+               goto out;
+       }
+
+       timeval = get_ticks();
+       timeout = usec2ticks(CONFIG_SEC_DEQ_TIMEOUT);
+       while (op.done != 1) {
+               ret = jr_dequeue();
+               if (ret) {
+                       debug("Error in SEC deq\n");
+                       ret = JQ_DEQ_ERR;
+                       goto out;
+               }
+
+               if ((get_ticks() - timeval) > timeout) {
+                       debug("SEC Dequeue timed out\n");
+                       ret = JQ_DEQ_TO_ERR;
+                       goto out;
+               }
+       }
+
+       if (!op.status) {
+               debug("Error %x\n", op.status);
+               ret = op.status;
+       }
+out:
+       return ret;
+}
+
+int jr_reset(void)
+{
+       if (jr_hw_reset() < 0)
+               return -1;
+
+       /* Clean up the jobring structure maintained by software */
+       jr_sw_cleanup();
+
+       return 0;
+}
+
+int sec_reset(void)
+{
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       uint32_t mcfgr = sec_in32(&sec->mcfgr);
+       uint32_t timeout = 100000;
+
+       mcfgr |= MCFGR_SWRST;
+       sec_out32(&sec->mcfgr, mcfgr);
+
+       mcfgr |= MCFGR_DMA_RST;
+       sec_out32(&sec->mcfgr, mcfgr);
+       do {
+               mcfgr = sec_in32(&sec->mcfgr);
+       } while ((mcfgr & MCFGR_DMA_RST) == MCFGR_DMA_RST && --timeout);
+
+       if (timeout == 0)
+               return -1;
+
+       timeout = 100000;
+       do {
+               mcfgr = sec_in32(&sec->mcfgr);
+       } while ((mcfgr & MCFGR_SWRST) == MCFGR_SWRST && --timeout);
+
+       if (timeout == 0)
+               return -1;
+
+       return 0;
+}
+
+int sec_init(void)
+{
+       int ret = 0;
+
+#ifdef CONFIG_PHYS_64BIT
+       ccsr_sec_t *sec = (void *)CONFIG_SYS_FSL_SEC_ADDR;
+       uint32_t mcr = sec_in32(&sec->mcfgr);
+
+       sec_out32(&sec->mcfgr, mcr | 1 << MCFGR_PS_SHIFT);
+#endif
+       ret = jr_init();
+       if (ret < 0)
+               return -1;
+
+       return ret;
+}
diff --git a/drivers/crypto/fsl/jr.h b/drivers/crypto/fsl/jr.h
new file mode 100644 (file)
index 0000000..cce2c58
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2008-2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#ifndef __JR_H
+#define __JR_H
+
+#include <linux/compiler.h>
+
+#define JR_SIZE 4
+/* Timeout currently defined as 90 sec */
+#define CONFIG_SEC_DEQ_TIMEOUT 90000000U
+
+#define DEFAULT_JR_ID          0
+#define DEFAULT_JR_LIODN       0
+#define DEFAULT_IRQ            0       /* Interrupts not to be configured */
+
+#define MCFGR_SWRST       ((uint32_t)(1)<<31) /* Software Reset */
+#define MCFGR_DMA_RST     ((uint32_t)(1)<<28) /* DMA Reset */
+#define MCFGR_PS_SHIFT          16
+#define JR_INTMASK       0x00000001
+#define JRCR_RESET                  0x01
+#define JRINT_ERR_HALT_INPROGRESS   0x4
+#define JRINT_ERR_HALT_MASK         0xc
+#define JRNSLIODN_SHIFT                16
+#define JRNSLIODN_MASK         0x0fff0000
+#define JRSLIODN_SHIFT         0
+#define JRSLIODN_MASK          0x00000fff
+
+#define JQ_DEQ_ERR             -1
+#define JQ_DEQ_TO_ERR          -2
+#define JQ_ENQ_ERR             -3
+
+struct op_ring {
+       dma_addr_t desc;
+       uint32_t status;
+} __packed;
+
+struct jr_info {
+       void (*callback)(dma_addr_t desc, uint32_t status, void *arg);
+       dma_addr_t desc_phys_addr;
+       uint32_t desc_addr;
+       uint32_t desc_len;
+       uint32_t op_done;
+       void *arg;
+};
+
+struct jobring {
+       int jq_id;
+       int irq;
+       int liodn;
+       /* Head is the index where software would enq the descriptor in
+        * the i/p ring
+        */
+       int head;
+       /* Tail index would be used by s/w ehile enqueuing to determine if
+        * there is any space left in the s/w maintained i/p rings
+        */
+       /* Also in case of deq tail will be incremented only in case of
+        * in-order job completion
+        */
+       int tail;
+       /* Read index of the output ring. It may not match with tail in case
+        * of out of order completetion
+        */
+       int read_idx;
+       /* Write index to input ring. Would be always equal to head */
+       int write_idx;
+       /* Size of the rings. */
+       int size;
+       /* The ip and output rings have to be accessed by SEC. So the
+        * pointers will ahve to point to the housekeeping region provided
+        * by SEC
+        */
+       /*Circular  Ring of i/p descriptors */
+       dma_addr_t *input_ring;
+       /* Circular Ring of o/p descriptors */
+       /* Circula Ring containing info regarding descriptors in i/p
+        * and o/p ring
+        */
+       /* This ring can be on the stack */
+       struct jr_info info[JR_SIZE];
+       struct op_ring *output_ring;
+};
+
+struct result {
+       int done;
+       uint32_t status;
+};
+
+void caam_jr_strstatus(u32 status);
+int run_descriptor_jr(uint32_t *desc);
+
+#endif
index a11f58dc81539f2e582a1ddbe44f62f6905a52af..2a26d85ee8dd1765e720097ba1b2c2da0f97051a 100644 (file)
@@ -99,6 +99,51 @@ typedef struct ccsr_sec {
 #define SEC_SCFGR_VIRT_EN              0x00008000
 #define SEC_CHAVID_LS_RNG_SHIFT                16
 #define SEC_CHAVID_RNG_LS_MASK         0x000f0000
+
+#define CONFIG_JRSTARTR_JR0            0x00000001
+
+struct jr_regs {
+#ifdef CONFIG_SYS_FSL_SEC_LE
+       u32 irba_l;
+       u32 irba_h;
+#else
+       u32 irba_h;
+       u32 irba_l;
+#endif
+       u32 rsvd1;
+       u32 irs;
+       u32 rsvd2;
+       u32 irsa;
+       u32 rsvd3;
+       u32 irja;
+#ifdef CONFIG_SYS_FSL_SEC_LE
+       u32 orba_l;
+       u32 orba_h;
+#else
+       u32 orba_h;
+       u32 orba_l;
+#endif
+       u32 rsvd4;
+       u32 ors;
+       u32 rsvd5;
+       u32 orjr;
+       u32 rsvd6;
+       u32 orsf;
+       u32 rsvd7;
+       u32 jrsta;
+       u32 rsvd8;
+       u32 jrint;
+       u32 jrcfg0;
+       u32 jrcfg1;
+       u32 rsvd9;
+       u32 irri;
+       u32 rsvd10;
+       u32 orwi;
+       u32 rsvd11;
+       u32 jrcr;
+};
+
+int sec_init(void);
 #endif
 
 #endif /* __FSL_SEC_H */