From 5159d71983e649a89568e46d9ff02731beedd571 Mon Sep 17 00:00:00 2001 From: Biwen Li Date: Mon, 6 May 2019 12:13:14 +0800 Subject: layerscape: update patches-4.14 to LSDK 19.03 All patches of LSDK 19.03 were ported to Openwrt kernel. We still used an all-in-one patch for each IP/feature for OpenWrt. Below are the changes this patch introduced. - Updated original IP/feature patches to LSDK 19.03. - Added new IP/feature patches for eTSEC/PTP/TMU. - Squashed scattered patches into IP/feature patches. - Updated config-4.14 correspondingly. - Refreshed all patches. More info about LSDK and the kernel: - https://lsdk.github.io/components.html - https://source.codeaurora.org/external/qoriq/qoriq-components/linux Signed-off-by: Biwen Li Signed-off-by: Yangbo Lu --- .../patches-4.14/820-sec-support-layerscape.patch | 3920 +++++++++++++++++--- 1 file changed, 3411 insertions(+), 509 deletions(-) (limited to 'target/linux/layerscape/patches-4.14/820-sec-support-layerscape.patch') diff --git a/target/linux/layerscape/patches-4.14/820-sec-support-layerscape.patch b/target/linux/layerscape/patches-4.14/820-sec-support-layerscape.patch index ff0fe8daa4..0d26aca797 100644 --- a/target/linux/layerscape/patches-4.14/820-sec-support-layerscape.patch +++ b/target/linux/layerscape/patches-4.14/820-sec-support-layerscape.patch @@ -1,59 +1,69 @@ -From 936d5f485f2ff837cdd7d49839771bd3367e8b92 Mon Sep 17 00:00:00 2001 +From ba8e92b322a3763880fdc4d19e9c7085f5504be7 Mon Sep 17 00:00:00 2001 From: Biwen Li -Date: Tue, 30 Oct 2018 18:28:03 +0800 -Subject: [PATCH 37/40] sec: support layerscape +Date: Tue, 23 Apr 2019 17:41:43 +0800 +Subject: [PATCH] sec: support layerscape +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + This is an integrated patch of sec for layerscape Signed-off-by: Alex Porosanu +Signed-off-by: Arnd Bergmann +Signed-off-by: Biwen Li +Signed-off-by: Carmen Iorga Signed-off-by: Cristian Stoica Signed-off-by: Guanhua Gao Signed-off-by: Herbert Xu Signed-off-by: Horia Geantă -Signed-off-by: Horia Geantă horia.geanta@nxp.com +Signed-off-by: Ioana Ciornei Signed-off-by: Radu Alexe Signed-off-by: Tudor Ambarus Signed-off-by: Yangbo Lu Signed-off-by: Zhao Qiang -Signed-off-by: Biwen Li --- crypto/Kconfig | 20 + crypto/Makefile | 1 + + crypto/chacha20poly1305.c | 2 - crypto/tcrypt.c | 27 +- crypto/testmgr.c | 244 ++ crypto/testmgr.h | 219 ++ - crypto/tls.c | 607 +++ + crypto/tls.c | 607 ++++ drivers/crypto/Makefile | 2 +- - drivers/crypto/caam/Kconfig | 57 +- - drivers/crypto/caam/Makefile | 10 +- - drivers/crypto/caam/caamalg.c | 131 +- - drivers/crypto/caam/caamalg_desc.c | 761 +++- - drivers/crypto/caam/caamalg_desc.h | 47 +- - drivers/crypto/caam/caamalg_qi.c | 927 ++++- - drivers/crypto/caam/caamalg_qi2.c | 5691 +++++++++++++++++++++++++++ - drivers/crypto/caam/caamalg_qi2.h | 274 ++ - drivers/crypto/caam/caamhash.c | 132 +- + drivers/crypto/caam/Kconfig | 85 +- + drivers/crypto/caam/Makefile | 26 +- + drivers/crypto/caam/caamalg.c | 468 +++- + drivers/crypto/caam/caamalg_desc.c | 903 +++++- + drivers/crypto/caam/caamalg_desc.h | 52 +- + drivers/crypto/caam/caamalg_qi.c | 1060 ++++++- + drivers/crypto/caam/caamalg_qi2.c | 5843 +++++++++++++++++++++++++++++++++++ + drivers/crypto/caam/caamalg_qi2.h | 276 ++ + drivers/crypto/caam/caamhash.c | 192 +- drivers/crypto/caam/caamhash_desc.c | 108 + drivers/crypto/caam/caamhash_desc.h | 49 + - drivers/crypto/caam/compat.h | 2 + - drivers/crypto/caam/ctrl.c | 23 +- - drivers/crypto/caam/desc.h | 62 +- - drivers/crypto/caam/desc_constr.h | 52 +- - drivers/crypto/caam/dpseci.c | 865 ++++ - drivers/crypto/caam/dpseci.h | 433 ++ + drivers/crypto/caam/caampkc.c | 52 +- + drivers/crypto/caam/caamrng.c | 52 +- + drivers/crypto/caam/compat.h | 4 + + drivers/crypto/caam/ctrl.c | 194 +- + drivers/crypto/caam/desc.h | 89 +- + drivers/crypto/caam/desc_constr.h | 59 +- + drivers/crypto/caam/dpseci.c | 865 ++++++ + drivers/crypto/caam/dpseci.h | 433 +++ drivers/crypto/caam/dpseci_cmd.h | 287 ++ - drivers/crypto/caam/error.c | 75 +- + drivers/crypto/caam/error.c | 81 +- drivers/crypto/caam/error.h | 6 +- - drivers/crypto/caam/intern.h | 1 + - drivers/crypto/caam/jr.c | 42 + + drivers/crypto/caam/intern.h | 102 +- + drivers/crypto/caam/jr.c | 84 + drivers/crypto/caam/jr.h | 2 + drivers/crypto/caam/key_gen.c | 30 - drivers/crypto/caam/key_gen.h | 30 + - drivers/crypto/caam/qi.c | 85 +- + drivers/crypto/caam/qi.c | 134 +- drivers/crypto/caam/qi.h | 2 +- - drivers/crypto/caam/regs.h | 2 + + drivers/crypto/caam/regs.h | 76 +- drivers/crypto/caam/sg_sw_qm.h | 46 +- drivers/crypto/talitos.c | 8 + - 37 files changed, 11006 insertions(+), 354 deletions(-) + include/crypto/chacha20.h | 1 + + 41 files changed, 12088 insertions(+), 733 deletions(-) create mode 100644 crypto/tls.c create mode 100644 drivers/crypto/caam/caamalg_qi2.c create mode 100644 drivers/crypto/caam/caamalg_qi2.h @@ -102,6 +112,17 @@ Signed-off-by: Biwen Li obj-$(CONFIG_CRYPTO_LZO) += lzo.o obj-$(CONFIG_CRYPTO_LZ4) += lz4.o obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o +--- a/crypto/chacha20poly1305.c ++++ b/crypto/chacha20poly1305.c +@@ -22,8 +22,6 @@ + + #include "internal.h" + +-#define CHACHAPOLY_IV_SIZE 12 +- + struct chachapoly_instance_ctx { + struct crypto_skcipher_spawn chacha; + struct crypto_ahash_spawn poly; --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -76,7 +76,7 @@ static char *check[] = { @@ -1316,9 +1337,15 @@ Signed-off-by: Biwen Li obj-$(CONFIG_CRYPTO_DEV_IMGTEC_HASH) += img-hash.o --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig -@@ -1,7 +1,11 @@ +@@ -1,7 +1,17 @@ +config CRYPTO_DEV_FSL_CAAM_COMMON + tristate ++ ++config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC ++ tristate ++ ++config CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC ++ tristate + config CRYPTO_DEV_FSL_CAAM - tristate "Freescale CAAM-Multicore driver backend" @@ -1329,7 +1356,7 @@ Signed-off-by: Biwen Li help Enables the driver module for Freescale's Cryptographic Accelerator and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). -@@ -12,9 +16,16 @@ config CRYPTO_DEV_FSL_CAAM +@@ -12,9 +22,16 @@ config CRYPTO_DEV_FSL_CAAM To compile this driver as a module, choose M here: the module will be called caam. @@ -1347,7 +1374,7 @@ Signed-off-by: Biwen Li default y help Enables the driver module for Job Rings which are part of -@@ -25,9 +36,10 @@ config CRYPTO_DEV_FSL_CAAM_JR +@@ -25,9 +42,10 @@ config CRYPTO_DEV_FSL_CAAM_JR To compile this driver as a module, choose M here: the module will be called caam_jr. @@ -1359,7 +1386,7 @@ Signed-off-by: Biwen Li range 2 9 default "9" help -@@ -45,7 +57,6 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE +@@ -45,7 +63,6 @@ config CRYPTO_DEV_FSL_CAAM_RINGSIZE config CRYPTO_DEV_FSL_CAAM_INTC bool "Job Ring interrupt coalescing" @@ -1367,50 +1394,83 @@ Signed-off-by: Biwen Li help Enable the Job Ring's interrupt coalescing feature. -@@ -75,7 +86,6 @@ config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THL +@@ -74,9 +91,9 @@ config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THL + threshold. Range is 1-65535. config CRYPTO_DEV_FSL_CAAM_CRYPTO_API - tristate "Register algorithm implementations with the Crypto API" +- tristate "Register algorithm implementations with the Crypto API" - depends on CRYPTO_DEV_FSL_CAAM_JR ++ bool "Register algorithm implementations with the Crypto API" default y ++ select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC select CRYPTO_AEAD select CRYPTO_AUTHENC -@@ -90,7 +100,7 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API + select CRYPTO_BLKCIPHER +@@ -85,13 +102,11 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API + scatterlist crypto API (such as the linux native IPSec + stack) to the SEC4 via job ring. +- To compile this as a module, choose M here: the module +- will be called caamalg. +- config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI - tristate "Queue Interface as Crypto API backend" +- tristate "Queue Interface as Crypto API backend" - depends on CRYPTO_DEV_FSL_CAAM_JR && FSL_DPAA && NET ++ bool "Queue Interface as Crypto API backend" + depends on FSL_SDK_DPA && NET default y ++ select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC select CRYPTO_AUTHENC select CRYPTO_BLKCIPHER -@@ -107,7 +117,6 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI + help +@@ -102,36 +117,26 @@ config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI + assigned to the kernel should also be more than the number of + job rings. +- To compile this as a module, choose M here: the module +- will be called caamalg_qi. +- config CRYPTO_DEV_FSL_CAAM_AHASH_API - tristate "Register hash algorithm implementations with Crypto API" +- tristate "Register hash algorithm implementations with Crypto API" - depends on CRYPTO_DEV_FSL_CAAM_JR ++ bool "Register hash algorithm implementations with Crypto API" default y ++ select CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC select CRYPTO_HASH help -@@ -119,7 +128,6 @@ config CRYPTO_DEV_FSL_CAAM_AHASH_API + Selecting this will offload ahash for users of the + scatterlist crypto API to the SEC4 via job ring. +- To compile this as a module, choose M here: the module +- will be called caamhash. +- config CRYPTO_DEV_FSL_CAAM_PKC_API - tristate "Register public key cryptography implementations with Crypto API" +- tristate "Register public key cryptography implementations with Crypto API" - depends on CRYPTO_DEV_FSL_CAAM_JR ++ bool "Register public key cryptography implementations with Crypto API" default y select CRYPTO_RSA help -@@ -131,7 +139,6 @@ config CRYPTO_DEV_FSL_CAAM_PKC_API + Selecting this will allow SEC Public key support for RSA. + Supported cryptographic primitives: encryption, decryption, + signature and verification. +- To compile this as a module, choose M here: the module +- will be called caam_pkc. config CRYPTO_DEV_FSL_CAAM_RNG_API - tristate "Register caam device for hwrng API" +- tristate "Register caam device for hwrng API" - depends on CRYPTO_DEV_FSL_CAAM_JR ++ bool "Register caam device for hwrng API" default y select CRYPTO_RNG select HW_RANDOM -@@ -142,13 +149,31 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API - To compile this as a module, choose M here: the module - will be called caamrng. +@@ -139,16 +144,24 @@ config CRYPTO_DEV_FSL_CAAM_RNG_API + Selecting this will register the SEC4 hardware rng to + the hw_random API for suppying the kernel entropy pool. + +- To compile this as a module, choose M here: the module +- will be called caamrng. ++endif # CRYPTO_DEV_FSL_CAAM_JR -config CRYPTO_DEV_FSL_CAAM_DEBUG - bool "Enable debug output in CAAM driver" @@ -1418,14 +1478,17 @@ Signed-off-by: Biwen Li - help - Selecting this will enable printing of various debug - information in the CAAM driver. -+endif # CRYPTO_DEV_FSL_CAAM_JR -+ +endif # CRYPTO_DEV_FSL_CAAM -+ + +-config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC +- def_tristate (CRYPTO_DEV_FSL_CAAM_CRYPTO_API || \ +- CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) +config CRYPTO_DEV_FSL_DPAA2_CAAM + tristate "QorIQ DPAA2 CAAM (DPSECI) driver" + depends on FSL_MC_DPIO + select CRYPTO_DEV_FSL_CAAM_COMMON ++ select CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC ++ select CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC + select CRYPTO_BLKCIPHER + select CRYPTO_AUTHENC + select CRYPTO_AEAD @@ -1437,16 +1500,6 @@ Signed-off-by: Biwen Li + + To compile this as a module, choose M here: the module + will be called dpaa2_caam. - - config CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC - def_tristate (CRYPTO_DEV_FSL_CAAM_CRYPTO_API || \ -- CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) -+ CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI || \ -+ CRYPTO_DEV_FSL_DPAA2_CAAM) -+ -+config CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC -+ def_tristate (CRYPTO_DEV_FSL_CAAM_AHASH_API || \ -+ CRYPTO_DEV_FSL_DPAA2_CAAM) --- a/drivers/crypto/caam/Makefile +++ b/drivers/crypto/caam/Makefile @@ -6,19 +6,27 @@ ifeq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG @@ -1458,21 +1511,30 @@ Signed-off-by: Biwen Li +obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON) += error.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_JR) += caam_jr.o - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o +-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o +-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC) += caamalg_desc.o - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o -+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o - obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caam_pkc.o - - caam-objs := ctrl.o +-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o +-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o +-obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caam_pkc.o +- +-caam-objs := ctrl.o -caam_jr-objs := jr.o key_gen.o error.o -+caam_jr-objs := jr.o key_gen.o - caam_pkc-y := caampkc.o pkc_desc.o +-caam_pkc-y := caampkc.o pkc_desc.o ++obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC) += caamhash_desc.o ++ ++caam-y := ctrl.o ++caam_jr-y := jr.o key_gen.o ++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o ++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += caamalg_qi.o ++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API) += caamhash.o ++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API) += caamrng.o ++caam_jr-$(CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API) += caampkc.o pkc_desc.o ++ ++caam-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI) += qi.o ifneq ($(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI),) ccflags-y += -DCONFIG_CAAM_QI - caam-objs += qi.o +- caam-objs += qi.o endif + +obj-$(CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM) += dpaa2_caam.o @@ -1480,7 +1542,16 @@ Signed-off-by: Biwen Li +dpaa2_caam-y := caamalg_qi2.o dpseci.o --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c -@@ -108,6 +108,7 @@ struct caam_ctx { +@@ -71,6 +71,8 @@ + #define AUTHENC_DESC_JOB_IO_LEN (AEAD_DESC_JOB_IO_LEN + \ + CAAM_CMD_SZ * 5) + ++#define CHACHAPOLY_DESC_JOB_IO_LEN (AEAD_DESC_JOB_IO_LEN + CAAM_CMD_SZ * 6) ++ + #define DESC_MAX_USED_BYTES (CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN) + #define DESC_MAX_USED_LEN (DESC_MAX_USED_BYTES / CAAM_CMD_SZ) + +@@ -108,6 +110,7 @@ struct caam_ctx { dma_addr_t sh_desc_dec_dma; dma_addr_t sh_desc_givenc_dma; dma_addr_t key_dma; @@ -1488,7 +1559,7 @@ Signed-off-by: Biwen Li struct device *jrdev; struct alginfo adata; struct alginfo cdata; -@@ -118,6 +119,7 @@ static int aead_null_set_sh_desc(struct +@@ -118,6 +121,7 @@ static int aead_null_set_sh_desc(struct { struct caam_ctx *ctx = crypto_aead_ctx(aead); struct device *jrdev = ctx->jrdev; @@ -1496,7 +1567,7 @@ Signed-off-by: Biwen Li u32 *desc; int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN - ctx->adata.keylen_pad; -@@ -136,9 +138,10 @@ static int aead_null_set_sh_desc(struct +@@ -136,9 +140,10 @@ static int aead_null_set_sh_desc(struct /* aead_encrypt shared descriptor */ desc = ctx->sh_desc_enc; @@ -1509,7 +1580,7 @@ Signed-off-by: Biwen Li /* * Job Descriptor and Shared Descriptors -@@ -154,9 +157,10 @@ static int aead_null_set_sh_desc(struct +@@ -154,9 +159,10 @@ static int aead_null_set_sh_desc(struct /* aead_decrypt shared descriptor */ desc = ctx->sh_desc_dec; @@ -1522,7 +1593,7 @@ Signed-off-by: Biwen Li return 0; } -@@ -168,6 +172,7 @@ static int aead_set_sh_desc(struct crypt +@@ -168,6 +174,7 @@ static int aead_set_sh_desc(struct crypt unsigned int ivsize = crypto_aead_ivsize(aead); struct caam_ctx *ctx = crypto_aead_ctx(aead); struct device *jrdev = ctx->jrdev; @@ -1530,7 +1601,7 @@ Signed-off-by: Biwen Li u32 ctx1_iv_off = 0; u32 *desc, *nonce = NULL; u32 inl_mask; -@@ -234,9 +239,9 @@ static int aead_set_sh_desc(struct crypt +@@ -234,9 +241,9 @@ static int aead_set_sh_desc(struct crypt desc = ctx->sh_desc_enc; cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize, ctx->authsize, is_rfc3686, nonce, ctx1_iv_off, @@ -1542,7 +1613,7 @@ Signed-off-by: Biwen Li skip_enc: /* -@@ -266,9 +271,9 @@ skip_enc: +@@ -266,9 +273,9 @@ skip_enc: desc = ctx->sh_desc_dec; cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize, ctx->authsize, alg->caam.geniv, is_rfc3686, @@ -1554,7 +1625,7 @@ Signed-off-by: Biwen Li if (!alg->caam.geniv) goto skip_givenc; -@@ -300,9 +305,9 @@ skip_enc: +@@ -300,9 +307,9 @@ skip_enc: desc = ctx->sh_desc_enc; cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize, ctx->authsize, is_rfc3686, nonce, @@ -1566,7 +1637,7 @@ Signed-off-by: Biwen Li skip_givenc: return 0; -@@ -323,6 +328,7 @@ static int gcm_set_sh_desc(struct crypto +@@ -323,6 +330,7 @@ static int gcm_set_sh_desc(struct crypto { struct caam_ctx *ctx = crypto_aead_ctx(aead); struct device *jrdev = ctx->jrdev; @@ -1574,7 +1645,7 @@ Signed-off-by: Biwen Li u32 *desc; int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN - ctx->cdata.keylen; -@@ -344,9 +350,9 @@ static int gcm_set_sh_desc(struct crypto +@@ -344,9 +352,9 @@ static int gcm_set_sh_desc(struct crypto } desc = ctx->sh_desc_enc; @@ -1586,7 +1657,7 @@ Signed-off-by: Biwen Li /* * Job Descriptor and Shared Descriptors -@@ -361,9 +367,9 @@ static int gcm_set_sh_desc(struct crypto +@@ -361,9 +369,9 @@ static int gcm_set_sh_desc(struct crypto } desc = ctx->sh_desc_dec; @@ -1598,7 +1669,7 @@ Signed-off-by: Biwen Li return 0; } -@@ -382,6 +388,7 @@ static int rfc4106_set_sh_desc(struct cr +@@ -382,6 +390,7 @@ static int rfc4106_set_sh_desc(struct cr { struct caam_ctx *ctx = crypto_aead_ctx(aead); struct device *jrdev = ctx->jrdev; @@ -1606,7 +1677,7 @@ Signed-off-by: Biwen Li u32 *desc; int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN - ctx->cdata.keylen; -@@ -403,9 +410,10 @@ static int rfc4106_set_sh_desc(struct cr +@@ -403,9 +412,10 @@ static int rfc4106_set_sh_desc(struct cr } desc = ctx->sh_desc_enc; @@ -1619,7 +1690,7 @@ Signed-off-by: Biwen Li /* * Job Descriptor and Shared Descriptors -@@ -420,9 +428,10 @@ static int rfc4106_set_sh_desc(struct cr +@@ -420,9 +430,10 @@ static int rfc4106_set_sh_desc(struct cr } desc = ctx->sh_desc_dec; @@ -1632,7 +1703,7 @@ Signed-off-by: Biwen Li return 0; } -@@ -442,6 +451,7 @@ static int rfc4543_set_sh_desc(struct cr +@@ -442,6 +453,7 @@ static int rfc4543_set_sh_desc(struct cr { struct caam_ctx *ctx = crypto_aead_ctx(aead); struct device *jrdev = ctx->jrdev; @@ -1640,7 +1711,7 @@ Signed-off-by: Biwen Li u32 *desc; int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN - ctx->cdata.keylen; -@@ -463,9 +473,10 @@ static int rfc4543_set_sh_desc(struct cr +@@ -463,9 +475,10 @@ static int rfc4543_set_sh_desc(struct cr } desc = ctx->sh_desc_enc; @@ -1653,7 +1724,7 @@ Signed-off-by: Biwen Li /* * Job Descriptor and Shared Descriptors -@@ -480,9 +491,10 @@ static int rfc4543_set_sh_desc(struct cr +@@ -480,9 +493,10 @@ static int rfc4543_set_sh_desc(struct cr } desc = ctx->sh_desc_dec; @@ -1666,7 +1737,67 @@ Signed-off-by: Biwen Li return 0; } -@@ -503,6 +515,7 @@ static int aead_setkey(struct crypto_aea +@@ -498,11 +512,67 @@ static int rfc4543_setauthsize(struct cr + return 0; + } + ++static int chachapoly_set_sh_desc(struct crypto_aead *aead) ++{ ++ struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ struct device *jrdev = ctx->jrdev; ++ unsigned int ivsize = crypto_aead_ivsize(aead); ++ u32 *desc; ++ ++ if (!ctx->cdata.keylen || !ctx->authsize) ++ return 0; ++ ++ desc = ctx->sh_desc_enc; ++ cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize, ++ ctx->authsize, true, false); ++ dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma, ++ desc_bytes(desc), ctx->dir); ++ ++ desc = ctx->sh_desc_dec; ++ cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize, ++ ctx->authsize, false, false); ++ dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma, ++ desc_bytes(desc), ctx->dir); ++ ++ return 0; ++} ++ ++static int chachapoly_setauthsize(struct crypto_aead *aead, ++ unsigned int authsize) ++{ ++ struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ ++ if (authsize != POLY1305_DIGEST_SIZE) ++ return -EINVAL; ++ ++ ctx->authsize = authsize; ++ return chachapoly_set_sh_desc(aead); ++} ++ ++static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, ++ unsigned int keylen) ++{ ++ struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ unsigned int ivsize = crypto_aead_ivsize(aead); ++ unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize; ++ ++ if (keylen != CHACHA20_KEY_SIZE + saltlen) { ++ crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ return -EINVAL; ++ } ++ ++ ctx->cdata.key_virt = key; ++ ctx->cdata.keylen = keylen - saltlen; ++ ++ return chachapoly_set_sh_desc(aead); ++} ++ + static int aead_setkey(struct crypto_aead *aead, + const u8 *key, unsigned int keylen) { struct caam_ctx *ctx = crypto_aead_ctx(aead); struct device *jrdev = ctx->jrdev; @@ -1674,7 +1805,7 @@ Signed-off-by: Biwen Li struct crypto_authenc_keys keys; int ret = 0; -@@ -517,6 +530,27 @@ static int aead_setkey(struct crypto_aea +@@ -517,6 +587,27 @@ static int aead_setkey(struct crypto_aea DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); #endif @@ -1702,7 +1833,7 @@ Signed-off-by: Biwen Li ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey, keys.authkeylen, CAAM_MAX_KEY_SIZE - keys.enckeylen); -@@ -527,12 +561,14 @@ static int aead_setkey(struct crypto_aea +@@ -527,12 +618,14 @@ static int aead_setkey(struct crypto_aea /* postpend encryption key to auth split key */ memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen); dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad + @@ -1718,7 +1849,7 @@ Signed-off-by: Biwen Li ctx->cdata.keylen = keys.enckeylen; return aead_set_sh_desc(aead); badkey: -@@ -552,7 +588,7 @@ static int gcm_setkey(struct crypto_aead +@@ -552,7 +645,7 @@ static int gcm_setkey(struct crypto_aead #endif memcpy(ctx->key, key, keylen); @@ -1727,7 +1858,7 @@ Signed-off-by: Biwen Li ctx->cdata.keylen = keylen; return gcm_set_sh_desc(aead); -@@ -580,7 +616,7 @@ static int rfc4106_setkey(struct crypto_ +@@ -580,7 +673,7 @@ static int rfc4106_setkey(struct crypto_ */ ctx->cdata.keylen = keylen - 4; dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen, @@ -1736,7 +1867,7 @@ Signed-off-by: Biwen Li return rfc4106_set_sh_desc(aead); } -@@ -606,7 +642,7 @@ static int rfc4543_setkey(struct crypto_ +@@ -606,7 +699,7 @@ static int rfc4543_setkey(struct crypto_ */ ctx->cdata.keylen = keylen - 4; dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen, @@ -1745,7 +1876,7 @@ Signed-off-by: Biwen Li return rfc4543_set_sh_desc(aead); } -@@ -658,21 +694,21 @@ static int ablkcipher_setkey(struct cryp +@@ -658,21 +751,21 @@ static int ablkcipher_setkey(struct cryp cnstr_shdsc_ablkcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686, ctx1_iv_off); dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma, @@ -1770,7 +1901,7 @@ Signed-off-by: Biwen Li return 0; } -@@ -701,13 +737,13 @@ static int xts_ablkcipher_setkey(struct +@@ -701,13 +794,13 @@ static int xts_ablkcipher_setkey(struct desc = ctx->sh_desc_enc; cnstr_shdsc_xts_ablkcipher_encap(desc, &ctx->cdata); dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma, @@ -1786,7 +1917,7 @@ Signed-off-by: Biwen Li return 0; } -@@ -987,9 +1023,6 @@ static void init_aead_job(struct aead_re +@@ -987,9 +1080,6 @@ static void init_aead_job(struct aead_re append_seq_out_ptr(desc, dst_dma, req->assoclen + req->cryptlen - authsize, out_options); @@ -1796,7 +1927,7 @@ Signed-off-by: Biwen Li } static void init_gcm_job(struct aead_request *req, -@@ -1004,6 +1037,7 @@ static void init_gcm_job(struct aead_req +@@ -1004,6 +1094,7 @@ static void init_gcm_job(struct aead_req unsigned int last; init_aead_job(req, edesc, all_contig, encrypt); @@ -1804,7 +1935,48 @@ Signed-off-by: Biwen Li /* BUG This should not be specific to generic GCM. */ last = 0; -@@ -1030,6 +1064,7 @@ static void init_authenc_job(struct aead +@@ -1021,6 +1112,40 @@ static void init_gcm_job(struct aead_req + /* End of blank commands */ + } + ++static void init_chachapoly_job(struct aead_request *req, ++ struct aead_edesc *edesc, bool all_contig, ++ bool encrypt) ++{ ++ struct crypto_aead *aead = crypto_aead_reqtfm(req); ++ unsigned int ivsize = crypto_aead_ivsize(aead); ++ unsigned int assoclen = req->assoclen; ++ u32 *desc = edesc->hw_desc; ++ u32 ctx_iv_off = 4; ++ ++ init_aead_job(req, edesc, all_contig, encrypt); ++ ++ if (ivsize != CHACHAPOLY_IV_SIZE) { ++ /* IPsec specific: CONTEXT1[223:128] = {NONCE, IV} */ ++ ctx_iv_off += 4; ++ ++ /* ++ * The associated data comes already with the IV but we need ++ * to skip it when we authenticate or encrypt... ++ */ ++ assoclen -= ivsize; ++ } ++ ++ append_math_add_imm_u32(desc, REG3, ZERO, IMM, assoclen); ++ ++ /* ++ * For IPsec load the IV further in the same register. ++ * For RFC7539 simply load the 12 bytes nonce in a single operation ++ */ ++ append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB | ++ LDST_SRCDST_BYTE_CONTEXT | ++ ctx_iv_off << LDST_OFFSET_SHIFT); ++} ++ + static void init_authenc_job(struct aead_request *req, + struct aead_edesc *edesc, + bool all_contig, bool encrypt) +@@ -1030,6 +1155,7 @@ static void init_authenc_job(struct aead struct caam_aead_alg, aead); unsigned int ivsize = crypto_aead_ivsize(aead); struct caam_ctx *ctx = crypto_aead_ctx(aead); @@ -1812,7 +1984,7 @@ Signed-off-by: Biwen Li const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == OP_ALG_AAI_CTR_MOD128); const bool is_rfc3686 = alg->caam.rfc3686; -@@ -1053,6 +1088,15 @@ static void init_authenc_job(struct aead +@@ -1053,6 +1179,15 @@ static void init_authenc_job(struct aead init_aead_job(req, edesc, all_contig, encrypt); @@ -1828,7 +2000,176 @@ Signed-off-by: Biwen Li if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv)) append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB | -@@ -3204,9 +3248,11 @@ struct caam_crypto_alg { +@@ -1225,8 +1360,16 @@ static struct aead_edesc *aead_edesc_all + } + } + ++ /* ++ * HW reads 4 S/G entries at a time; make sure the reads don't go beyond ++ * the end of the table by allocating more S/G entries. ++ */ + sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0; +- sec4_sg_len += mapped_dst_nents > 1 ? mapped_dst_nents : 0; ++ if (mapped_dst_nents > 1) ++ sec4_sg_len += ALIGN(mapped_dst_nents, 4); ++ else ++ sec4_sg_len = ALIGN(sec4_sg_len, 4); ++ + sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry); + + /* allocate space for base edesc and hw desc commands, link tables */ +@@ -1307,6 +1450,72 @@ static int gcm_encrypt(struct aead_reque + return ret; + } + ++static int chachapoly_encrypt(struct aead_request *req) ++{ ++ struct aead_edesc *edesc; ++ struct crypto_aead *aead = crypto_aead_reqtfm(req); ++ struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ struct device *jrdev = ctx->jrdev; ++ bool all_contig; ++ u32 *desc; ++ int ret; ++ ++ edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig, ++ true); ++ if (IS_ERR(edesc)) ++ return PTR_ERR(edesc); ++ ++ desc = edesc->hw_desc; ++ ++ init_chachapoly_job(req, edesc, all_contig, true); ++ print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ", ++ DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), ++ 1); ++ ++ ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req); ++ if (!ret) { ++ ret = -EINPROGRESS; ++ } else { ++ aead_unmap(jrdev, edesc, req); ++ kfree(edesc); ++ } ++ ++ return ret; ++} ++ ++static int chachapoly_decrypt(struct aead_request *req) ++{ ++ struct aead_edesc *edesc; ++ struct crypto_aead *aead = crypto_aead_reqtfm(req); ++ struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ struct device *jrdev = ctx->jrdev; ++ bool all_contig; ++ u32 *desc; ++ int ret; ++ ++ edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig, ++ false); ++ if (IS_ERR(edesc)) ++ return PTR_ERR(edesc); ++ ++ desc = edesc->hw_desc; ++ ++ init_chachapoly_job(req, edesc, all_contig, false); ++ print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ", ++ DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), ++ 1); ++ ++ ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req); ++ if (!ret) { ++ ret = -EINPROGRESS; ++ } else { ++ aead_unmap(jrdev, edesc, req); ++ kfree(edesc); ++ } ++ ++ return ret; ++} ++ + static int ipsec_gcm_encrypt(struct aead_request *req) + { + if (req->assoclen < 8) +@@ -1494,7 +1703,25 @@ static struct ablkcipher_edesc *ablkciph + + sec4_sg_ents = 1 + mapped_src_nents; + dst_sg_idx = sec4_sg_ents; +- sec4_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0; ++ ++ /* ++ * HW reads 4 S/G entries at a time; make sure the reads don't go beyond ++ * the end of the table by allocating more S/G entries. Logic: ++ * if (src != dst && output S/G) ++ * pad output S/G, if needed ++ * else if (src == dst && S/G) ++ * overlapping S/Gs; pad one of them ++ * else if (input S/G) ... ++ * pad input S/G, if needed ++ */ ++ if (mapped_dst_nents > 1) ++ sec4_sg_ents += ALIGN(mapped_dst_nents, 4); ++ else if ((req->src == req->dst) && (mapped_src_nents > 1)) ++ sec4_sg_ents = max(ALIGN(sec4_sg_ents, 4), ++ 1 + ALIGN(mapped_src_nents, 4)); ++ else ++ sec4_sg_ents = ALIGN(sec4_sg_ents, 4); ++ + sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry); + + /* +@@ -3196,6 +3423,50 @@ static struct caam_aead_alg driver_aeads + .geniv = true, + }, + }, ++ { ++ .aead = { ++ .base = { ++ .cra_name = "rfc7539(chacha20,poly1305)", ++ .cra_driver_name = "rfc7539-chacha20-poly1305-" ++ "caam", ++ .cra_blocksize = 1, ++ }, ++ .setkey = chachapoly_setkey, ++ .setauthsize = chachapoly_setauthsize, ++ .encrypt = chachapoly_encrypt, ++ .decrypt = chachapoly_decrypt, ++ .ivsize = CHACHAPOLY_IV_SIZE, ++ .maxauthsize = POLY1305_DIGEST_SIZE, ++ }, ++ .caam = { ++ .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 | ++ OP_ALG_AAI_AEAD, ++ .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | ++ OP_ALG_AAI_AEAD, ++ }, ++ }, ++ { ++ .aead = { ++ .base = { ++ .cra_name = "rfc7539esp(chacha20,poly1305)", ++ .cra_driver_name = "rfc7539esp-chacha20-" ++ "poly1305-caam", ++ .cra_blocksize = 1, ++ }, ++ .setkey = chachapoly_setkey, ++ .setauthsize = chachapoly_setauthsize, ++ .encrypt = chachapoly_encrypt, ++ .decrypt = chachapoly_decrypt, ++ .ivsize = 8, ++ .maxauthsize = POLY1305_DIGEST_SIZE, ++ }, ++ .caam = { ++ .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 | ++ OP_ALG_AAI_AEAD, ++ .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | ++ OP_ALG_AAI_AEAD, ++ }, ++ }, + }; + + struct caam_crypto_alg { +@@ -3204,9 +3475,11 @@ struct caam_crypto_alg { struct caam_alg_entry caam; }; @@ -1841,7 +2182,7 @@ Signed-off-by: Biwen Li ctx->jrdev = caam_jr_alloc(); if (IS_ERR(ctx->jrdev)) { -@@ -3214,10 +3260,16 @@ static int caam_init_common(struct caam_ +@@ -3214,10 +3487,16 @@ static int caam_init_common(struct caam_ return PTR_ERR(ctx->jrdev); } @@ -1859,7 +2200,7 @@ Signed-off-by: Biwen Li if (dma_mapping_error(ctx->jrdev, dma_addr)) { dev_err(ctx->jrdev, "unable to map key, shared descriptors\n"); caam_jr_free(ctx->jrdev); -@@ -3245,7 +3297,7 @@ static int caam_cra_init(struct crypto_t +@@ -3245,7 +3524,7 @@ static int caam_cra_init(struct crypto_t container_of(alg, struct caam_crypto_alg, crypto_alg); struct caam_ctx *ctx = crypto_tfm_ctx(tfm); @@ -1868,7 +2209,7 @@ Signed-off-by: Biwen Li } static int caam_aead_init(struct crypto_aead *tfm) -@@ -3255,14 +3307,15 @@ static int caam_aead_init(struct crypto_ +@@ -3255,14 +3534,15 @@ static int caam_aead_init(struct crypto_ container_of(alg, struct caam_aead_alg, aead); struct caam_ctx *ctx = crypto_aead_ctx(tfm); @@ -1886,6 +2227,166 @@ Signed-off-by: Biwen Li caam_jr_free(ctx->jrdev); } +@@ -3276,7 +3556,7 @@ static void caam_aead_exit(struct crypto + caam_exit_common(crypto_aead_ctx(tfm)); + } + +-static void __exit caam_algapi_exit(void) ++void caam_algapi_exit(void) + { + + struct caam_crypto_alg *t_alg, *n; +@@ -3355,56 +3635,52 @@ static void caam_aead_alg_init(struct ca + alg->exit = caam_aead_exit; + } + +-static int __init caam_algapi_init(void) ++int caam_algapi_init(struct device *ctrldev) + { +- struct device_node *dev_node; +- struct platform_device *pdev; +- struct device *ctrldev; +- struct caam_drv_private *priv; ++ struct caam_drv_private *priv = dev_get_drvdata(ctrldev); + int i = 0, err = 0; +- u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst; ++ u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst; + unsigned int md_limit = SHA512_DIGEST_SIZE; + bool registered = false; + +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); +- if (!dev_node) { +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); +- if (!dev_node) +- return -ENODEV; +- } +- +- pdev = of_find_device_by_node(dev_node); +- if (!pdev) { +- of_node_put(dev_node); +- return -ENODEV; +- } +- +- ctrldev = &pdev->dev; +- priv = dev_get_drvdata(ctrldev); +- of_node_put(dev_node); +- +- /* +- * If priv is NULL, it's probably because the caam driver wasn't +- * properly initialized (e.g. RNG4 init failed). Thus, bail out here. +- */ +- if (!priv) +- return -ENODEV; +- +- + INIT_LIST_HEAD(&alg_list); + + /* + * Register crypto algorithms the device supports. + * First, detect presence and attributes of DES, AES, and MD blocks. + */ +- cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls); +- cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls); +- des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT; +- aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT; +- md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; ++ if (priv->era < 10) { ++ u32 cha_vid, cha_inst; ++ ++ cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls); ++ aes_vid = cha_vid & CHA_ID_LS_AES_MASK; ++ md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; ++ ++ cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls); ++ des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> ++ CHA_ID_LS_DES_SHIFT; ++ aes_inst = cha_inst & CHA_ID_LS_AES_MASK; ++ md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; ++ ccha_inst = 0; ++ ptha_inst = 0; ++ } else { ++ u32 aesa, mdha; ++ ++ aesa = rd_reg32(&priv->ctrl->vreg.aesa); ++ mdha = rd_reg32(&priv->ctrl->vreg.mdha); ++ ++ aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT; ++ md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT; ++ ++ des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK; ++ aes_inst = aesa & CHA_VER_NUM_MASK; ++ md_inst = mdha & CHA_VER_NUM_MASK; ++ ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK; ++ ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK; ++ } + + /* If MD is present, limit digest size based on LP256 */ +- if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256)) ++ if (md_inst && md_vid == CHA_VER_VID_MD_LP256) + md_limit = SHA256_DIGEST_SIZE; + + for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { +@@ -3426,10 +3702,10 @@ static int __init caam_algapi_init(void) + * Check support for AES modes not available + * on LP devices. + */ +- if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP) +- if ((alg->class1_alg_type & OP_ALG_AAI_MASK) == +- OP_ALG_AAI_XTS) +- continue; ++ if (aes_vid == CHA_VER_VID_AES_LP && ++ (alg->class1_alg_type & OP_ALG_AAI_MASK) == ++ OP_ALG_AAI_XTS) ++ continue; + + t_alg = caam_alg_alloc(alg); + if (IS_ERR(t_alg)) { +@@ -3468,21 +3744,28 @@ static int __init caam_algapi_init(void) + if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES)) + continue; + ++ /* Skip CHACHA20 algorithms if not supported by device */ ++ if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && !ccha_inst) ++ continue; ++ ++ /* Skip POLY1305 algorithms if not supported by device */ ++ if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst) ++ continue; ++ + /* + * Check support for AES algorithms not available + * on LP devices. + */ +- if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP) +- if (alg_aai == OP_ALG_AAI_GCM) +- continue; ++ if (aes_vid == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM) ++ continue; + + /* + * Skip algorithms requiring message digests + * if MD or MD size is not supported by device. + */ +- if (c2_alg_sel && +- (!md_inst || (t_alg->aead.maxauthsize > md_limit))) +- continue; ++ if ((c2_alg_sel & ~OP_ALG_ALGSEL_SUBMASK) == 0x40 && ++ (!md_inst || t_alg->aead.maxauthsize > md_limit)) ++ continue; + + caam_aead_alg_init(t_alg); + +@@ -3502,10 +3785,3 @@ static int __init caam_algapi_init(void) + + return err; + } +- +-module_init(caam_algapi_init); +-module_exit(caam_algapi_exit); +- +-MODULE_LICENSE("GPL"); +-MODULE_DESCRIPTION("FSL CAAM support for crypto API"); +-MODULE_AUTHOR("Freescale Semiconductor - NMG/STC"); --- a/drivers/crypto/caam/caamalg_desc.c +++ b/drivers/crypto/caam/caamalg_desc.c @@ -45,16 +45,16 @@ static inline void append_dec_op1(u32 *d @@ -2881,6 +3382,15 @@ Signed-off-by: Biwen Li /* assoclen + cryptlen = seqinlen */ append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ); +@@ -931,7 +1507,7 @@ void cnstr_shdsc_rfc4543_encap(u32 * con + read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 | + (0x6 << MOVE_LEN_SHIFT)); + write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF | +- (0x8 << MOVE_LEN_SHIFT)); ++ (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP); + + /* Will read assoclen + cryptlen bytes */ + append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); @@ -966,10 +1542,13 @@ EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap) * @desc: pointer to buffer used for descriptor construction * @cdata: pointer to block cipher transform definitions @@ -2915,47 +3425,215 @@ Signed-off-by: Biwen Li /* assoclen + cryptlen = seqoutlen */ append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ); -@@ -1075,7 +1666,7 @@ void cnstr_shdsc_ablkcipher_encap(u32 * - - /* Load nonce into CONTEXT1 reg */ - if (is_rfc3686) { -- u8 *nonce = cdata->key_virt + cdata->keylen; -+ const u8 *nonce = cdata->key_virt + cdata->keylen; - - append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE, - LDST_CLASS_IND_CCB | -@@ -1140,7 +1731,7 @@ void cnstr_shdsc_ablkcipher_decap(u32 * - - /* Load nonce into CONTEXT1 reg */ - if (is_rfc3686) { -- u8 *nonce = cdata->key_virt + cdata->keylen; -+ const u8 *nonce = cdata->key_virt + cdata->keylen; - - append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE, - LDST_CLASS_IND_CCB | -@@ -1209,7 +1800,7 @@ void cnstr_shdsc_ablkcipher_givencap(u32 - - /* Load Nonce into CONTEXT1 reg */ - if (is_rfc3686) { -- u8 *nonce = cdata->key_virt + cdata->keylen; -+ const u8 *nonce = cdata->key_virt + cdata->keylen; - - append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE, - LDST_CLASS_IND_CCB | ---- a/drivers/crypto/caam/caamalg_desc.h -+++ b/drivers/crypto/caam/caamalg_desc.h -@@ -17,6 +17,9 @@ - #define DESC_QI_AEAD_DEC_LEN (DESC_AEAD_DEC_LEN + 3 * CAAM_CMD_SZ) - #define DESC_QI_AEAD_GIVENC_LEN (DESC_AEAD_GIVENC_LEN + 3 * CAAM_CMD_SZ) +@@ -1001,7 +1592,7 @@ void cnstr_shdsc_rfc4543_decap(u32 * con + read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 | + (0x6 << MOVE_LEN_SHIFT)); + write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF | +- (0x8 << MOVE_LEN_SHIFT)); ++ (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP); -+#define DESC_TLS_BASE (4 * CAAM_CMD_SZ) -+#define DESC_TLS10_ENC_LEN (DESC_TLS_BASE + 29 * CAAM_CMD_SZ) -+ - /* Note: Nonce is counted in cdata.keylen */ - #define DESC_AEAD_CTR_RFC3686_LEN (4 * CAAM_CMD_SZ) + /* Will read assoclen + cryptlen bytes */ + append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ); +@@ -1035,6 +1626,138 @@ void cnstr_shdsc_rfc4543_decap(u32 * con + } + EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap); -@@ -27,14 +30,20 @@ - #define DESC_GCM_BASE (3 * CAAM_CMD_SZ) ++/** ++ * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and ++ * IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared ++ * descriptor (non-protocol). ++ * @desc: pointer to buffer used for descriptor construction ++ * @cdata: pointer to block cipher transform definitions ++ * Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with ++ * OP_ALG_AAI_AEAD. ++ * @adata: pointer to authentication transform definitions ++ * Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with ++ * OP_ALG_AAI_AEAD. ++ * @ivsize: initialization vector size ++ * @icvsize: integrity check value (ICV) size (truncated or full) ++ * @encap: true if encapsulation, false if decapsulation ++ * @is_qi: true when called from caam/qi ++ */ ++void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata, ++ struct alginfo *adata, unsigned int ivsize, ++ unsigned int icvsize, const bool encap, ++ const bool is_qi) ++{ ++ u32 *key_jump_cmd, *wait_cmd; ++ u32 nfifo; ++ const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE); ++ ++ /* Note: Context registers are saved. */ ++ init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX); ++ ++ /* skip key loading if they are loaded due to sharing */ ++ key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | ++ JUMP_COND_SHRD); ++ ++ append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen, ++ CLASS_1 | KEY_DEST_CLASS_REG); ++ ++ /* For IPsec load the salt from keymat in the context register */ ++ if (is_ipsec) ++ append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4, ++ LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT | ++ 4 << LDST_OFFSET_SHIFT); ++ ++ set_jump_tgt_here(desc, key_jump_cmd); ++ ++ /* Class 2 and 1 operations: Poly & ChaCha */ ++ if (encap) { ++ append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL | ++ OP_ALG_ENCRYPT); ++ append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL | ++ OP_ALG_ENCRYPT); ++ } else { ++ append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL | ++ OP_ALG_DECRYPT | OP_ALG_ICV_ON); ++ append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL | ++ OP_ALG_DECRYPT); ++ } ++ ++ if (is_qi) { ++ u32 *wait_load_cmd; ++ u32 ctx1_iv_off = is_ipsec ? 8 : 4; ++ ++ /* REG3 = assoclen */ ++ append_seq_load(desc, 4, LDST_CLASS_DECO | ++ LDST_SRCDST_WORD_DECO_MATH3 | ++ 4 << LDST_OFFSET_SHIFT); ++ ++ wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | ++ JUMP_COND_CALM | JUMP_COND_NCP | ++ JUMP_COND_NOP | JUMP_COND_NIP | ++ JUMP_COND_NIFP); ++ set_jump_tgt_here(desc, wait_load_cmd); ++ ++ append_seq_load(desc, ivsize, LDST_CLASS_1_CCB | ++ LDST_SRCDST_BYTE_CONTEXT | ++ ctx1_iv_off << LDST_OFFSET_SHIFT); ++ } ++ ++ /* ++ * MAGIC with NFIFO ++ * Read associated data from the input and send them to class1 and ++ * class2 alignment blocks. From class1 send data to output fifo and ++ * then write it to memory since we don't need to encrypt AD. ++ */ ++ nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 | ++ NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND; ++ append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB | ++ LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3); ++ ++ append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); ++ append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); ++ append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO | ++ FIFOLD_CLASS_CLASS1 | LDST_VLF); ++ append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK | ++ MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3); ++ append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF); ++ ++ /* IPsec - copy IV at the output */ ++ if (is_ipsec) ++ append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA | ++ 0x2 << 25); ++ ++ wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL | ++ JUMP_COND_NOP | JUMP_TEST_ALL); ++ set_jump_tgt_here(desc, wait_cmd); ++ ++ if (encap) { ++ /* Read and write cryptlen bytes */ ++ append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ); ++ append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, ++ CAAM_CMD_SZ); ++ aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2); ++ ++ /* Write ICV */ ++ append_seq_store(desc, icvsize, LDST_CLASS_2_CCB | ++ LDST_SRCDST_BYTE_CONTEXT); ++ } else { ++ /* Read and write cryptlen bytes */ ++ append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ); ++ append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, ++ CAAM_CMD_SZ); ++ aead_append_src_dst(desc, FIFOLD_TYPE_MSG); ++ ++ /* Load ICV for verification */ ++ append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 | ++ FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV); ++ } ++ ++ print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ", ++ DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), ++ 1); ++} ++EXPORT_SYMBOL(cnstr_shdsc_chachapoly); ++ + /* + * For ablkcipher encrypt and decrypt, read from req->src and + * write to req->dst +@@ -1053,7 +1776,8 @@ static inline void ablkcipher_append_src + * @desc: pointer to buffer used for descriptor construction + * @cdata: pointer to block cipher transform definitions + * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed +- * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128. ++ * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128 ++ * - OP_ALG_ALGSEL_CHACHA20 + * @ivsize: initialization vector size + * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template + * @ctx1_iv_off: IV offset in CONTEXT1 register +@@ -1075,7 +1799,7 @@ void cnstr_shdsc_ablkcipher_encap(u32 * + + /* Load nonce into CONTEXT1 reg */ + if (is_rfc3686) { +- u8 *nonce = cdata->key_virt + cdata->keylen; ++ const u8 *nonce = cdata->key_virt + cdata->keylen; + + append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE, + LDST_CLASS_IND_CCB | +@@ -1118,7 +1842,8 @@ EXPORT_SYMBOL(cnstr_shdsc_ablkcipher_enc + * @desc: pointer to buffer used for descriptor construction + * @cdata: pointer to block cipher transform definitions + * Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed +- * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128. ++ * with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128 ++ * - OP_ALG_ALGSEL_CHACHA20 + * @ivsize: initialization vector size + * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template + * @ctx1_iv_off: IV offset in CONTEXT1 register +@@ -1140,7 +1865,7 @@ void cnstr_shdsc_ablkcipher_decap(u32 * + + /* Load nonce into CONTEXT1 reg */ + if (is_rfc3686) { +- u8 *nonce = cdata->key_virt + cdata->keylen; ++ const u8 *nonce = cdata->key_virt + cdata->keylen; + + append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE, + LDST_CLASS_IND_CCB | +@@ -1209,7 +1934,7 @@ void cnstr_shdsc_ablkcipher_givencap(u32 + + /* Load Nonce into CONTEXT1 reg */ + if (is_rfc3686) { +- u8 *nonce = cdata->key_virt + cdata->keylen; ++ const u8 *nonce = cdata->key_virt + cdata->keylen; + + append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE, + LDST_CLASS_IND_CCB | +--- a/drivers/crypto/caam/caamalg_desc.h ++++ b/drivers/crypto/caam/caamalg_desc.h +@@ -17,6 +17,9 @@ + #define DESC_QI_AEAD_DEC_LEN (DESC_AEAD_DEC_LEN + 3 * CAAM_CMD_SZ) + #define DESC_QI_AEAD_GIVENC_LEN (DESC_AEAD_GIVENC_LEN + 3 * CAAM_CMD_SZ) + ++#define DESC_TLS_BASE (4 * CAAM_CMD_SZ) ++#define DESC_TLS10_ENC_LEN (DESC_TLS_BASE + 29 * CAAM_CMD_SZ) ++ + /* Note: Nonce is counted in cdata.keylen */ + #define DESC_AEAD_CTR_RFC3686_LEN (4 * CAAM_CMD_SZ) + +@@ -27,14 +30,20 @@ + #define DESC_GCM_BASE (3 * CAAM_CMD_SZ) #define DESC_GCM_ENC_LEN (DESC_GCM_BASE + 16 * CAAM_CMD_SZ) #define DESC_GCM_DEC_LEN (DESC_GCM_BASE + 12 * CAAM_CMD_SZ) +#define DESC_QI_GCM_ENC_LEN (DESC_GCM_ENC_LEN + 6 * CAAM_CMD_SZ) @@ -2975,7 +3653,7 @@ Signed-off-by: Biwen Li #define DESC_ABLKCIPHER_BASE (3 * CAAM_CMD_SZ) #define DESC_ABLKCIPHER_ENC_LEN (DESC_ABLKCIPHER_BASE + \ -@@ -43,46 +52,62 @@ +@@ -43,46 +52,67 @@ 15 * CAAM_CMD_SZ) void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata, @@ -3046,6 +3724,11 @@ Signed-off-by: Biwen Li - unsigned int icvsize); + unsigned int ivsize, unsigned int icvsize, + const bool is_qi); ++ ++void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata, ++ struct alginfo *adata, unsigned int ivsize, ++ unsigned int icvsize, const bool encap, ++ const bool is_qi); void cnstr_shdsc_ablkcipher_encap(u32 * const desc, struct alginfo *cdata, unsigned int ivsize, const bool is_rfc3686, @@ -3131,7 +3814,7 @@ Signed-off-by: Biwen Li + memcpy(ctx->key, keys.authkey, keys.authkeylen); + memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, + keys.enckeylen); -+ dma_sync_single_for_device(jrdev, ctx->key_dma, ++ dma_sync_single_for_device(jrdev->parent, ctx->key_dma, + ctx->adata.keylen_pad + + keys.enckeylen, ctx->dir); + goto skip_split_key; @@ -3156,12 +3839,17 @@ Signed-off-by: Biwen Li ctx->cdata.keylen = keys.enckeylen; ret = aead_set_sh_desc(aead); -@@ -258,6 +284,468 @@ badkey: +@@ -258,55 +284,139 @@ badkey: return -EINVAL; } +-static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, +- const u8 *key, unsigned int keylen) +static int tls_set_sh_desc(struct crypto_aead *tls) -+{ + { +- struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); +- struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher); +- const char *alg_name = crypto_tfm_alg_name(tfm); + struct caam_ctx *ctx = crypto_aead_ctx(tls); + unsigned int ivsize = crypto_aead_ivsize(tls); + unsigned int blocksize = crypto_aead_blocksize(tls); @@ -3231,26 +3919,45 @@ Signed-off-by: Biwen Li + unsigned int keylen) +{ + struct caam_ctx *ctx = crypto_aead_ctx(tls); -+ struct device *jrdev = ctx->jrdev; + struct device *jrdev = ctx->jrdev; +- unsigned int ivsize = crypto_ablkcipher_ivsize(ablkcipher); +- u32 ctx1_iv_off = 0; +- const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == +- OP_ALG_AAI_CTR_MOD128); +- const bool is_rfc3686 = (ctr_mode && strstr(alg_name, "rfc3686")); + struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent); + struct crypto_authenc_keys keys; -+ int ret = 0; -+ + int ret = 0; + +- memcpy(ctx->key, key, keylen); + if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) + goto badkey; + -+#ifdef DEBUG + #ifdef DEBUG + dev_err(jrdev, "keylen %d enckeylen %d authkeylen %d\n", + keys.authkeylen + keys.enckeylen, keys.enckeylen, + keys.authkeylen); -+ print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ", -+ DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); -+#endif -+ -+ /* + print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ", + DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); + #endif +- /* +- * AES-CTR needs to load IV in CONTEXT1 reg +- * at an offset of 128bits (16bytes) +- * CONTEXT1[255:128] = IV +- */ +- if (ctr_mode) +- ctx1_iv_off = 16; + + /* +- * RFC3686 specific: +- * | CONTEXT1[255:128] = {NONCE, IV, COUNTER} +- * | *key = {KEY, NONCE} + * If DKP is supported, use it in the shared descriptor to generate + * the split key. -+ */ + */ +- if (is_rfc3686) { +- ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE; +- keylen -= CTR_RFC3686_NONCE_SIZE; + if (ctrlpriv->era >= 6) { + ctx->adata.keylen = keys.authkeylen; + ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype & @@ -3266,14 +3973,25 @@ Signed-off-by: Biwen Li + ctx->adata.keylen_pad + + keys.enckeylen, ctx->dir); + goto skip_split_key; -+ } -+ + } + +- dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE); +- ctx->cdata.keylen = keylen; +- ctx->cdata.key_virt = ctx->key; +- ctx->cdata.key_inline = true; + ret = gen_split_key(jrdev, ctx->key, &ctx->adata, keys.authkey, + keys.authkeylen, CAAM_MAX_KEY_SIZE - + keys.enckeylen); + if (ret) + goto badkey; -+ + +- /* ablkcipher encrypt, decrypt, givencrypt shared descriptors */ +- cnstr_shdsc_ablkcipher_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize, +- is_rfc3686, ctx1_iv_off); +- cnstr_shdsc_ablkcipher_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize, +- is_rfc3686, ctx1_iv_off); +- cnstr_shdsc_ablkcipher_givencap(ctx->sh_desc_givenc, &ctx->cdata, +- ivsize, is_rfc3686, ctx1_iv_off); + /* postpend encryption key to auth split key */ + memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen); + dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad + @@ -3293,39 +4011,44 @@ Signed-off-by: Biwen Li + ret = tls_set_sh_desc(tls); + if (ret) + goto badkey; -+ -+ /* Now update the driver contexts with the new shared descriptor */ -+ if (ctx->drv_ctx[ENCRYPT]) { -+ ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT], -+ ctx->sh_desc_enc); -+ if (ret) { -+ dev_err(jrdev, "driver enc context update failed\n"); -+ goto badkey; -+ } -+ } -+ -+ if (ctx->drv_ctx[DECRYPT]) { -+ ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT], -+ ctx->sh_desc_dec); -+ if (ret) { -+ dev_err(jrdev, "driver dec context update failed\n"); -+ goto badkey; -+ } -+ } -+ -+ return ret; -+badkey: + + /* Now update the driver contexts with the new shared descriptor */ + if (ctx->drv_ctx[ENCRYPT]) { +@@ -327,42 +437,84 @@ static int ablkcipher_setkey(struct cryp + } + } + +- if (ctx->drv_ctx[GIVENCRYPT]) { +- ret = caam_drv_ctx_update(ctx->drv_ctx[GIVENCRYPT], +- ctx->sh_desc_givenc); +- if (ret) { +- dev_err(jrdev, "driver givenc context update failed\n"); +- goto badkey; +- } +- } +- + return ret; + badkey: +- crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN); + crypto_aead_set_flags(tls, CRYPTO_TFM_RES_BAD_KEY_LEN); -+ return -EINVAL; -+} -+ + return -EINVAL; + } + +-static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, +- const u8 *key, unsigned int keylen) +static int gcm_set_sh_desc(struct crypto_aead *aead) -+{ + { +- struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); +- struct device *jrdev = ctx->jrdev; +- int ret = 0; + struct caam_ctx *ctx = crypto_aead_ctx(aead); + unsigned int ivsize = crypto_aead_ivsize(aead); + int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN - + ctx->cdata.keylen; -+ + +- if (keylen != 2 * AES_MIN_KEY_SIZE && keylen != 2 * AES_MAX_KEY_SIZE) { +- dev_err(jrdev, "key size mismatch\n"); +- goto badkey; + if (!ctx->cdata.keylen || !ctx->authsize) + return 0; + @@ -3354,8 +4077,8 @@ Signed-off-by: Biwen Li + } else { + ctx->cdata.key_inline = false; + ctx->cdata.key_dma = ctx->key_dma; -+ } -+ + } + + cnstr_shdsc_gcm_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize, + ctx->authsize, true); + @@ -3384,62 +4107,129 @@ Signed-off-by: Biwen Li + DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); +#endif + -+ memcpy(ctx->key, key, keylen); + memcpy(ctx->key, key, keylen); +- dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE); + dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir); -+ ctx->cdata.keylen = keylen; -+ + ctx->cdata.keylen = keylen; +- ctx->cdata.key_virt = ctx->key; +- ctx->cdata.key_inline = true; + +- /* xts ablkcipher encrypt, decrypt shared descriptors */ +- cnstr_shdsc_xts_ablkcipher_encap(ctx->sh_desc_enc, &ctx->cdata); +- cnstr_shdsc_xts_ablkcipher_decap(ctx->sh_desc_dec, &ctx->cdata); + ret = gcm_set_sh_desc(aead); + if (ret) + return ret; -+ -+ /* Now update the driver contexts with the new shared descriptor */ -+ if (ctx->drv_ctx[ENCRYPT]) { -+ ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT], -+ ctx->sh_desc_enc); -+ if (ret) { -+ dev_err(jrdev, "driver enc context update failed\n"); + + /* Now update the driver contexts with the new shared descriptor */ + if (ctx->drv_ctx[ENCRYPT]) { +@@ -370,7 +522,7 @@ static int xts_ablkcipher_setkey(struct + ctx->sh_desc_enc); + if (ret) { + dev_err(jrdev, "driver enc context update failed\n"); +- goto badkey; + return ret; -+ } -+ } -+ -+ if (ctx->drv_ctx[DECRYPT]) { -+ ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT], -+ ctx->sh_desc_dec); -+ if (ret) { -+ dev_err(jrdev, "driver dec context update failed\n"); + } + } + +@@ -379,151 +531,829 @@ static int xts_ablkcipher_setkey(struct + ctx->sh_desc_dec); + if (ret) { + dev_err(jrdev, "driver dec context update failed\n"); +- goto badkey; + return ret; -+ } -+ } -+ + } + } + +- return ret; +-badkey: +- crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN); +- return -EINVAL; + return 0; -+} -+ + } + +-/* +- * aead_edesc - s/w-extended aead descriptor +- * @src_nents: number of segments in input scatterlist +- * @dst_nents: number of segments in output scatterlist +- * @iv_dma: dma address of iv for checking continuity and link table +- * @qm_sg_bytes: length of dma mapped h/w link table +- * @qm_sg_dma: bus physical mapped address of h/w link table +- * @assoclen: associated data length, in CAAM endianness +- * @assoclen_dma: bus physical mapped address of req->assoclen +- * @drv_req: driver-specific request structure +- * @sgt: the h/w link table, followed by IV +- */ +-struct aead_edesc { +- int src_nents; +- int dst_nents; +- dma_addr_t iv_dma; +- int qm_sg_bytes; +- dma_addr_t qm_sg_dma; +- unsigned int assoclen; +- dma_addr_t assoclen_dma; +- struct caam_drv_req drv_req; +- struct qm_sg_entry sgt[0]; +-}; +static int rfc4106_set_sh_desc(struct crypto_aead *aead) +{ + struct caam_ctx *ctx = crypto_aead_ctx(aead); + unsigned int ivsize = crypto_aead_ivsize(aead); + int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN - + ctx->cdata.keylen; -+ + +-/* +- * ablkcipher_edesc - s/w-extended ablkcipher descriptor +- * @src_nents: number of segments in input scatterlist +- * @dst_nents: number of segments in output scatterlist +- * @iv_dma: dma address of iv for checking continuity and link table +- * @qm_sg_bytes: length of dma mapped h/w link table +- * @qm_sg_dma: bus physical mapped address of h/w link table +- * @drv_req: driver-specific request structure +- * @sgt: the h/w link table, followed by IV +- */ +-struct ablkcipher_edesc { +- int src_nents; +- int dst_nents; +- dma_addr_t iv_dma; +- int qm_sg_bytes; +- dma_addr_t qm_sg_dma; +- struct caam_drv_req drv_req; +- struct qm_sg_entry sgt[0]; +-}; + if (!ctx->cdata.keylen || !ctx->authsize) + return 0; + + ctx->cdata.key_virt = ctx->key; -+ -+ /* + +-static struct caam_drv_ctx *get_drv_ctx(struct caam_ctx *ctx, +- enum optype type) +-{ + /* +- * This function is called on the fast path with values of 'type' +- * known at compile time. Invalid arguments are not expected and +- * thus no checks are made. + * Job Descriptor and Shared Descriptor + * must fit into the 64-word Descriptor h/w Buffer -+ */ + */ +- struct caam_drv_ctx *drv_ctx = ctx->drv_ctx[type]; +- u32 *desc; + if (rem_bytes >= DESC_QI_RFC4106_ENC_LEN) { + ctx->cdata.key_inline = true; + } else { + ctx->cdata.key_inline = false; + ctx->cdata.key_dma = ctx->key_dma; + } -+ + +- if (unlikely(!drv_ctx)) { +- spin_lock(&ctx->lock); + cnstr_shdsc_rfc4106_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize, + ctx->authsize, true); -+ + +- /* Read again to check if some other core init drv_ctx */ +- drv_ctx = ctx->drv_ctx[type]; +- if (!drv_ctx) { +- int cpu; + /* + * Job Descriptor and Shared Descriptor + * must fit into the 64-word Descriptor h/w Buffer @@ -3450,7 +4240,13 @@ Signed-off-by: Biwen Li + ctx->cdata.key_inline = false; + ctx->cdata.key_dma = ctx->key_dma; + } -+ + +- if (type == ENCRYPT) +- desc = ctx->sh_desc_enc; +- else if (type == DECRYPT) +- desc = ctx->sh_desc_dec; +- else /* (type == GIVENCRYPT) */ +- desc = ctx->sh_desc_givenc; + cnstr_shdsc_rfc4106_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize, + ctx->authsize, true); + @@ -3622,43 +4418,279 @@ Signed-off-by: Biwen Li + return 0; +} + - static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, - const u8 *key, unsigned int keylen) - { -@@ -414,6 +902,29 @@ struct aead_edesc { - }; - - /* -+ * tls_edesc - s/w-extended tls descriptor -+ * @src_nents: number of segments in input scatterlist -+ * @dst_nents: number of segments in output scatterlist -+ * @iv_dma: dma address of iv for checking continuity and link table -+ * @qm_sg_bytes: length of dma mapped h/w link table -+ * @tmp: array of scatterlists used by 'scatterwalk_ffwd' -+ * @qm_sg_dma: bus physical mapped address of h/w link table -+ * @drv_req: driver-specific request structure -+ * @sgt: the h/w link table, followed by IV -+ */ -+struct tls_edesc { -+ int src_nents; -+ int dst_nents; -+ dma_addr_t iv_dma; -+ int qm_sg_bytes; -+ dma_addr_t qm_sg_dma; -+ struct scatterlist tmp[2]; -+ struct scatterlist *dst; ++static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, ++ const u8 *key, unsigned int keylen) ++{ ++ struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); ++ struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher); ++ const char *alg_name = crypto_tfm_alg_name(tfm); ++ struct device *jrdev = ctx->jrdev; ++ unsigned int ivsize = crypto_ablkcipher_ivsize(ablkcipher); ++ u32 ctx1_iv_off = 0; ++ const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == ++ OP_ALG_AAI_CTR_MOD128); ++ const bool is_rfc3686 = (ctr_mode && strstr(alg_name, "rfc3686")); ++ int ret = 0; ++ ++ memcpy(ctx->key, key, keylen); ++#ifdef DEBUG ++ print_hex_dump(KERN_ERR, "key in @" __stringify(__LINE__)": ", ++ DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); ++#endif ++ /* ++ * AES-CTR needs to load IV in CONTEXT1 reg ++ * at an offset of 128bits (16bytes) ++ * CONTEXT1[255:128] = IV ++ */ ++ if (ctr_mode) ++ ctx1_iv_off = 16; ++ ++ /* ++ * RFC3686 specific: ++ * | CONTEXT1[255:128] = {NONCE, IV, COUNTER} ++ * | *key = {KEY, NONCE} ++ */ ++ if (is_rfc3686) { ++ ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE; ++ keylen -= CTR_RFC3686_NONCE_SIZE; ++ } ++ ++ dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE); ++ ctx->cdata.keylen = keylen; ++ ctx->cdata.key_virt = ctx->key; ++ ctx->cdata.key_inline = true; ++ ++ /* ablkcipher encrypt, decrypt, givencrypt shared descriptors */ ++ cnstr_shdsc_ablkcipher_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize, ++ is_rfc3686, ctx1_iv_off); ++ cnstr_shdsc_ablkcipher_decap(ctx->sh_desc_dec, &ctx->cdata, ivsize, ++ is_rfc3686, ctx1_iv_off); ++ cnstr_shdsc_ablkcipher_givencap(ctx->sh_desc_givenc, &ctx->cdata, ++ ivsize, is_rfc3686, ctx1_iv_off); ++ ++ /* Now update the driver contexts with the new shared descriptor */ ++ if (ctx->drv_ctx[ENCRYPT]) { ++ ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT], ++ ctx->sh_desc_enc); ++ if (ret) { ++ dev_err(jrdev, "driver enc context update failed\n"); ++ goto badkey; ++ } ++ } ++ ++ if (ctx->drv_ctx[DECRYPT]) { ++ ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT], ++ ctx->sh_desc_dec); ++ if (ret) { ++ dev_err(jrdev, "driver dec context update failed\n"); ++ goto badkey; ++ } ++ } ++ ++ if (ctx->drv_ctx[GIVENCRYPT]) { ++ ret = caam_drv_ctx_update(ctx->drv_ctx[GIVENCRYPT], ++ ctx->sh_desc_givenc); ++ if (ret) { ++ dev_err(jrdev, "driver givenc context update failed\n"); ++ goto badkey; ++ } ++ } ++ ++ return ret; ++badkey: ++ crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ return -EINVAL; ++} ++ ++static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher, ++ const u8 *key, unsigned int keylen) ++{ ++ struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher); ++ struct device *jrdev = ctx->jrdev; ++ int ret = 0; ++ ++ if (keylen != 2 * AES_MIN_KEY_SIZE && keylen != 2 * AES_MAX_KEY_SIZE) { ++ dev_err(jrdev, "key size mismatch\n"); ++ goto badkey; ++ } ++ ++ memcpy(ctx->key, key, keylen); ++ dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE); ++ ctx->cdata.keylen = keylen; ++ ctx->cdata.key_virt = ctx->key; ++ ctx->cdata.key_inline = true; ++ ++ /* xts ablkcipher encrypt, decrypt shared descriptors */ ++ cnstr_shdsc_xts_ablkcipher_encap(ctx->sh_desc_enc, &ctx->cdata); ++ cnstr_shdsc_xts_ablkcipher_decap(ctx->sh_desc_dec, &ctx->cdata); ++ ++ /* Now update the driver contexts with the new shared descriptor */ ++ if (ctx->drv_ctx[ENCRYPT]) { ++ ret = caam_drv_ctx_update(ctx->drv_ctx[ENCRYPT], ++ ctx->sh_desc_enc); ++ if (ret) { ++ dev_err(jrdev, "driver enc context update failed\n"); ++ goto badkey; ++ } ++ } ++ ++ if (ctx->drv_ctx[DECRYPT]) { ++ ret = caam_drv_ctx_update(ctx->drv_ctx[DECRYPT], ++ ctx->sh_desc_dec); ++ if (ret) { ++ dev_err(jrdev, "driver dec context update failed\n"); ++ goto badkey; ++ } ++ } ++ ++ return ret; ++badkey: ++ crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ return -EINVAL; ++} ++ ++/* ++ * aead_edesc - s/w-extended aead descriptor ++ * @src_nents: number of segments in input scatterlist ++ * @dst_nents: number of segments in output scatterlist ++ * @iv_dma: dma address of iv for checking continuity and link table ++ * @qm_sg_bytes: length of dma mapped h/w link table ++ * @qm_sg_dma: bus physical mapped address of h/w link table ++ * @assoclen: associated data length, in CAAM endianness ++ * @assoclen_dma: bus physical mapped address of req->assoclen ++ * @drv_req: driver-specific request structure ++ * @sgt: the h/w link table, followed by IV ++ */ ++struct aead_edesc { ++ int src_nents; ++ int dst_nents; ++ dma_addr_t iv_dma; ++ int qm_sg_bytes; ++ dma_addr_t qm_sg_dma; ++ unsigned int assoclen; ++ dma_addr_t assoclen_dma; + struct caam_drv_req drv_req; + struct qm_sg_entry sgt[0]; +}; + +/* - * ablkcipher_edesc - s/w-extended ablkcipher descriptor - * @src_nents: number of segments in input scatterlist - * @dst_nents: number of segments in output scatterlist -@@ -508,6 +1019,19 @@ static void aead_unmap(struct device *de - dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); - } - ++ * tls_edesc - s/w-extended tls descriptor ++ * @src_nents: number of segments in input scatterlist ++ * @dst_nents: number of segments in output scatterlist ++ * @iv_dma: dma address of iv for checking continuity and link table ++ * @qm_sg_bytes: length of dma mapped h/w link table ++ * @tmp: array of scatterlists used by 'scatterwalk_ffwd' ++ * @qm_sg_dma: bus physical mapped address of h/w link table ++ * @drv_req: driver-specific request structure ++ * @sgt: the h/w link table, followed by IV ++ */ ++struct tls_edesc { ++ int src_nents; ++ int dst_nents; ++ dma_addr_t iv_dma; ++ int qm_sg_bytes; ++ dma_addr_t qm_sg_dma; ++ struct scatterlist tmp[2]; ++ struct scatterlist *dst; ++ struct caam_drv_req drv_req; ++ struct qm_sg_entry sgt[0]; ++}; ++ ++/* ++ * ablkcipher_edesc - s/w-extended ablkcipher descriptor ++ * @src_nents: number of segments in input scatterlist ++ * @dst_nents: number of segments in output scatterlist ++ * @iv_dma: dma address of iv for checking continuity and link table ++ * @qm_sg_bytes: length of dma mapped h/w link table ++ * @qm_sg_dma: bus physical mapped address of h/w link table ++ * @drv_req: driver-specific request structure ++ * @sgt: the h/w link table, followed by IV ++ */ ++struct ablkcipher_edesc { ++ int src_nents; ++ int dst_nents; ++ dma_addr_t iv_dma; ++ int qm_sg_bytes; ++ dma_addr_t qm_sg_dma; ++ struct caam_drv_req drv_req; ++ struct qm_sg_entry sgt[0]; ++}; ++ ++static struct caam_drv_ctx *get_drv_ctx(struct caam_ctx *ctx, ++ enum optype type) ++{ ++ /* ++ * This function is called on the fast path with values of 'type' ++ * known at compile time. Invalid arguments are not expected and ++ * thus no checks are made. ++ */ ++ struct caam_drv_ctx *drv_ctx = ctx->drv_ctx[type]; ++ u32 *desc; ++ ++ if (unlikely(!drv_ctx)) { ++ spin_lock(&ctx->lock); ++ ++ /* Read again to check if some other core init drv_ctx */ ++ drv_ctx = ctx->drv_ctx[type]; ++ if (!drv_ctx) { ++ int cpu; ++ ++ if (type == ENCRYPT) ++ desc = ctx->sh_desc_enc; ++ else if (type == DECRYPT) ++ desc = ctx->sh_desc_dec; ++ else /* (type == GIVENCRYPT) */ ++ desc = ctx->sh_desc_givenc; ++ ++ cpu = smp_processor_id(); ++ drv_ctx = caam_drv_ctx_init(ctx->qidev, &cpu, desc); ++ if (likely(!IS_ERR_OR_NULL(drv_ctx))) ++ drv_ctx->op_type = type; ++ ++ ctx->drv_ctx[type] = drv_ctx; ++ } ++ ++ spin_unlock(&ctx->lock); ++ } ++ ++ return drv_ctx; ++} ++ ++static void caam_unmap(struct device *dev, struct scatterlist *src, ++ struct scatterlist *dst, int src_nents, ++ int dst_nents, dma_addr_t iv_dma, int ivsize, ++ enum optype op_type, dma_addr_t qm_sg_dma, ++ int qm_sg_bytes) ++{ ++ if (dst != src) { ++ if (src_nents) ++ dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE); ++ dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE); ++ } else { ++ dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL); ++ } ++ ++ if (iv_dma) ++ dma_unmap_single(dev, iv_dma, ivsize, ++ op_type == GIVENCRYPT ? DMA_FROM_DEVICE : ++ DMA_TO_DEVICE); ++ if (qm_sg_bytes) ++ dma_unmap_single(dev, qm_sg_dma, qm_sg_bytes, DMA_TO_DEVICE); ++} ++ ++static void aead_unmap(struct device *dev, ++ struct aead_edesc *edesc, ++ struct aead_request *req) ++{ ++ struct crypto_aead *aead = crypto_aead_reqtfm(req); ++ int ivsize = crypto_aead_ivsize(aead); ++ ++ caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, ++ edesc->iv_dma, ivsize, edesc->drv_req.drv_ctx->op_type, ++ edesc->qm_sg_dma, edesc->qm_sg_bytes); ++ dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); ++} ++ +static void tls_unmap(struct device *dev, + struct tls_edesc *edesc, + struct aead_request *req) @@ -3672,53 +4704,22 @@ Signed-off-by: Biwen Li + edesc->qm_sg_bytes); +} + - static void ablkcipher_unmap(struct device *dev, - struct ablkcipher_edesc *edesc, - struct ablkcipher_request *req) -@@ -532,8 +1056,18 @@ static void aead_done(struct caam_drv_re - qidev = caam_ctx->qidev; - - if (unlikely(status)) { -+ u32 ssrc = status & JRSTA_SSRC_MASK; -+ u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; -+ - caam_jr_strstatus(qidev, status); -- ecode = -EIO; -+ /* -+ * verify hw auth check passed else return -EBADMSG -+ */ -+ if (ssrc == JRSTA_SSRC_CCB_ERROR && -+ err_id == JRSTA_CCBERR_ERRID_ICVCHK) -+ ecode = -EBADMSG; -+ else -+ ecode = -EIO; - } - - edesc = container_of(drv_req, typeof(*edesc), drv_req); -@@ -785,6 +1319,260 @@ static int aead_decrypt(struct aead_requ - return aead_crypt(req, false); - } - -+static int ipsec_gcm_encrypt(struct aead_request *req) ++static void ablkcipher_unmap(struct device *dev, ++ struct ablkcipher_edesc *edesc, ++ struct ablkcipher_request *req) +{ -+ if (req->assoclen < 8) -+ return -EINVAL; ++ struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); ++ int ivsize = crypto_ablkcipher_ivsize(ablkcipher); + -+ return aead_crypt(req, true); ++ caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, ++ edesc->iv_dma, ivsize, edesc->drv_req.drv_ctx->op_type, ++ edesc->qm_sg_dma, edesc->qm_sg_bytes); +} + -+static int ipsec_gcm_decrypt(struct aead_request *req) -+{ -+ if (req->assoclen < 8) -+ return -EINVAL; -+ -+ return aead_crypt(req, false); -+} -+ -+static void tls_done(struct caam_drv_req *drv_req, u32 status) ++static void aead_done(struct caam_drv_req *drv_req, u32 status) +{ + struct device *qidev; -+ struct tls_edesc *edesc; ++ struct aead_edesc *edesc; + struct aead_request *aead_req = drv_req->app_ctx; + struct crypto_aead *aead = crypto_aead_reqtfm(aead_req); + struct caam_ctx *caam_ctx = crypto_aead_ctx(aead); @@ -3727,56 +4728,56 @@ Signed-off-by: Biwen Li + qidev = caam_ctx->qidev; + + if (unlikely(status)) { ++ u32 ssrc = status & JRSTA_SSRC_MASK; ++ u8 err_id = status & JRSTA_CCBERR_ERRID_MASK; ++ + caam_jr_strstatus(qidev, status); -+ ecode = -EIO; ++ /* ++ * verify hw auth check passed else return -EBADMSG ++ */ ++ if (ssrc == JRSTA_SSRC_CCB_ERROR && ++ err_id == JRSTA_CCBERR_ERRID_ICVCHK) ++ ecode = -EBADMSG; ++ else ++ ecode = -EIO; + } + + edesc = container_of(drv_req, typeof(*edesc), drv_req); -+ tls_unmap(qidev, edesc, aead_req); ++ aead_unmap(qidev, edesc, aead_req); + + aead_request_complete(aead_req, ecode); + qi_cache_free(edesc); +} + +/* -+ * allocate and map the tls extended descriptor ++ * allocate and map the aead extended descriptor + */ -+static struct tls_edesc *tls_edesc_alloc(struct aead_request *req, bool encrypt) ++static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, ++ bool encrypt) +{ + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct caam_ctx *ctx = crypto_aead_ctx(aead); -+ unsigned int blocksize = crypto_aead_blocksize(aead); -+ unsigned int padsize, authsize; + struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead), + typeof(*alg), aead); + struct device *qidev = ctx->qidev; + gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? -+ GFP_KERNEL : GFP_ATOMIC; ++ GFP_KERNEL : GFP_ATOMIC; + int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; -+ struct tls_edesc *edesc; -+ dma_addr_t qm_sg_dma, iv_dma = 0; -+ int ivsize = 0; -+ u8 *iv; -+ int qm_sg_index, qm_sg_ents = 0, qm_sg_bytes; -+ int in_len, out_len; -+ struct qm_sg_entry *sg_table, *fd_sgt; -+ struct caam_drv_ctx *drv_ctx; -+ enum optype op_type = encrypt ? ENCRYPT : DECRYPT; -+ struct scatterlist *dst; -+ -+ if (encrypt) { -+ padsize = blocksize - ((req->cryptlen + ctx->authsize) % -+ blocksize); -+ authsize = ctx->authsize + padsize; -+ } else { -+ authsize = ctx->authsize; -+ } ++ struct aead_edesc *edesc; ++ dma_addr_t qm_sg_dma, iv_dma = 0; ++ int ivsize = 0; ++ unsigned int authsize = ctx->authsize; ++ int qm_sg_index = 0, qm_sg_ents = 0, qm_sg_bytes; ++ int in_len, out_len; ++ struct qm_sg_entry *sg_table, *fd_sgt; ++ struct caam_drv_ctx *drv_ctx; ++ enum optype op_type = encrypt ? ENCRYPT : DECRYPT; + + drv_ctx = get_drv_ctx(ctx, op_type); + if (unlikely(IS_ERR_OR_NULL(drv_ctx))) -+ return (struct tls_edesc *)drv_ctx; ++ return (struct aead_edesc *)drv_ctx; + -+ /* allocate space for base edesc, link tables and IV */ ++ /* allocate space for base edesc and hw desc commands, link tables */ + edesc = qi_cache_alloc(GFP_DMA | flags); + if (unlikely(!edesc)) { + dev_err(qidev, "could not allocate extended descriptor\n"); @@ -3786,7 +4787,7 @@ Signed-off-by: Biwen Li + if (likely(req->src == req->dst)) { + src_nents = sg_nents_for_len(req->src, req->assoclen + + req->cryptlen + -+ (encrypt ? authsize : 0)); ++ (encrypt ? authsize : 0)); + if (unlikely(src_nents < 0)) { + dev_err(qidev, "Insufficient bytes (%d) in src S/G\n", + req->assoclen + req->cryptlen + @@ -3802,7 +4803,6 @@ Signed-off-by: Biwen Li + qi_cache_free(edesc); + return ERR_PTR(-ENOMEM); + } -+ dst = req->dst; + } else { + src_nents = sg_nents_for_len(req->src, req->assoclen + + req->cryptlen); @@ -3813,13 +4813,14 @@ Signed-off-by: Biwen Li + return ERR_PTR(src_nents); + } + -+ dst = scatterwalk_ffwd(edesc->tmp, req->dst, req->assoclen); -+ dst_nents = sg_nents_for_len(dst, req->cryptlen + -+ (encrypt ? authsize : 0)); ++ dst_nents = sg_nents_for_len(req->dst, req->assoclen + ++ req->cryptlen + ++ (encrypt ? authsize : ++ (-authsize))); + if (unlikely(dst_nents < 0)) { + dev_err(qidev, "Insufficient bytes (%d) in dst S/G\n", -+ req->cryptlen + -+ (encrypt ? authsize : 0)); ++ req->assoclen + req->cryptlen + ++ (encrypt ? authsize : (-authsize))); + qi_cache_free(edesc); + return ERR_PTR(dst_nents); + } @@ -3836,7 +4837,7 @@ Signed-off-by: Biwen Li + mapped_src_nents = 0; + } + -+ mapped_dst_nents = dma_map_sg(qidev, dst, dst_nents, ++ mapped_dst_nents = dma_map_sg(qidev, req->dst, dst_nents, + DMA_FROM_DEVICE); + if (unlikely(!mapped_dst_nents)) { + dev_err(qidev, "unable to map destination\n"); @@ -3846,51 +4847,95 @@ Signed-off-by: Biwen Li + } + } + ++ if ((alg->caam.rfc3686 && encrypt) || !alg->caam.geniv) ++ ivsize = crypto_aead_ivsize(aead); ++ + /* -+ * Create S/G table: IV, src, dst. ++ * Create S/G table: req->assoclen, [IV,] req->src [, req->dst]. + * Input is not contiguous. ++ * HW reads 4 S/G entries at a time; make sure the reads don't go beyond ++ * the end of the table by allocating more S/G entries. Logic: ++ * if (src != dst && output S/G) ++ * pad output S/G, if needed ++ * else if (src == dst && S/G) ++ * overlapping S/Gs; pad one of them ++ * else if (input S/G) ... ++ * pad input S/G, if needed + */ -+ qm_sg_ents = 1 + mapped_src_nents + -+ (mapped_dst_nents > 1 ? mapped_dst_nents : 0); ++ qm_sg_ents = 1 + !!ivsize + mapped_src_nents; ++ if (mapped_dst_nents > 1) ++ qm_sg_ents += ALIGN(mapped_dst_nents, 4); ++ else if ((req->src == req->dst) && (mapped_src_nents > 1)) ++ qm_sg_ents = max(ALIGN(qm_sg_ents, 4), ++ 1 + !!ivsize + ALIGN(mapped_src_nents, 4)); ++ else ++ qm_sg_ents = ALIGN(qm_sg_ents, 4); ++ + sg_table = &edesc->sgt[0]; + qm_sg_bytes = qm_sg_ents * sizeof(*sg_table); -+ -+ ivsize = crypto_aead_ivsize(aead); -+ iv = (u8 *)(sg_table + qm_sg_ents); -+ /* Make sure IV is located in a DMAable area */ -+ memcpy(iv, req->iv, ivsize); -+ iv_dma = dma_map_single(qidev, iv, ivsize, DMA_TO_DEVICE); -+ if (dma_mapping_error(qidev, iv_dma)) { -+ dev_err(qidev, "unable to map IV\n"); -+ caam_unmap(qidev, req->src, dst, src_nents, dst_nents, 0, 0, 0, -+ 0, 0); ++ if (unlikely(offsetof(struct aead_edesc, sgt) + qm_sg_bytes + ivsize > ++ CAAM_QI_MEMCACHE_SIZE)) { ++ dev_err(qidev, "No space for %d S/G entries and/or %dB IV\n", ++ qm_sg_ents, ivsize); ++ caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, 0, ++ 0, 0, 0, 0); + qi_cache_free(edesc); + return ERR_PTR(-ENOMEM); + } + ++ if (ivsize) { ++ u8 *iv = (u8 *)(sg_table + qm_sg_ents); ++ ++ /* Make sure IV is located in a DMAable area */ ++ memcpy(iv, req->iv, ivsize); ++ ++ iv_dma = dma_map_single(qidev, iv, ivsize, DMA_TO_DEVICE); ++ if (dma_mapping_error(qidev, iv_dma)) { ++ dev_err(qidev, "unable to map IV\n"); ++ caam_unmap(qidev, req->src, req->dst, src_nents, ++ dst_nents, 0, 0, 0, 0, 0); ++ qi_cache_free(edesc); ++ return ERR_PTR(-ENOMEM); ++ } ++ } ++ + edesc->src_nents = src_nents; + edesc->dst_nents = dst_nents; -+ edesc->dst = dst; + edesc->iv_dma = iv_dma; + edesc->drv_req.app_ctx = req; -+ edesc->drv_req.cbk = tls_done; ++ edesc->drv_req.cbk = aead_done; + edesc->drv_req.drv_ctx = drv_ctx; + -+ dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0); -+ qm_sg_index = 1; ++ edesc->assoclen = cpu_to_caam32(req->assoclen); ++ edesc->assoclen_dma = dma_map_single(qidev, &edesc->assoclen, 4, ++ DMA_TO_DEVICE); ++ if (dma_mapping_error(qidev, edesc->assoclen_dma)) { ++ dev_err(qidev, "unable to map assoclen\n"); ++ caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, ++ iv_dma, ivsize, op_type, 0, 0); ++ qi_cache_free(edesc); ++ return ERR_PTR(-ENOMEM); ++ } + ++ dma_to_qm_sg_one(sg_table, edesc->assoclen_dma, 4, 0); ++ qm_sg_index++; ++ if (ivsize) { ++ dma_to_qm_sg_one(sg_table + qm_sg_index, iv_dma, ivsize, 0); ++ qm_sg_index++; ++ } + sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + qm_sg_index, 0); + qm_sg_index += mapped_src_nents; + + if (mapped_dst_nents > 1) -+ sg_to_qm_sg_last(dst, mapped_dst_nents, sg_table + ++ sg_to_qm_sg_last(req->dst, mapped_dst_nents, sg_table + + qm_sg_index, 0); + + qm_sg_dma = dma_map_single(qidev, sg_table, qm_sg_bytes, DMA_TO_DEVICE); + if (dma_mapping_error(qidev, qm_sg_dma)) { + dev_err(qidev, "unable to map S/G table\n"); -+ caam_unmap(qidev, req->src, dst, src_nents, dst_nents, iv_dma, -+ ivsize, op_type, 0, 0); ++ dma_unmap_single(qidev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); ++ caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, ++ iv_dma, ivsize, op_type, 0, 0); + qi_cache_free(edesc); + return ERR_PTR(-ENOMEM); + } @@ -3898,65 +4943,458 @@ Signed-off-by: Biwen Li + edesc->qm_sg_dma = qm_sg_dma; + edesc->qm_sg_bytes = qm_sg_bytes; + -+ out_len = req->cryptlen + (encrypt ? authsize : 0); -+ in_len = ivsize + req->assoclen + req->cryptlen; ++ out_len = req->assoclen + req->cryptlen + ++ (encrypt ? ctx->authsize : (-ctx->authsize)); ++ in_len = 4 + ivsize + req->assoclen + req->cryptlen; + + fd_sgt = &edesc->drv_req.fd_sgt[0]; -+ + dma_to_qm_sg_one_last_ext(&fd_sgt[1], qm_sg_dma, in_len, 0); + -+ if (req->dst == req->src) -+ dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + -+ (sg_nents_for_len(req->src, req->assoclen) + -+ 1) * sizeof(*sg_table), out_len, 0); -+ else if (mapped_dst_nents == 1) -+ dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(dst), out_len, 0); -+ else ++ if (req->dst == req->src) { ++ if (mapped_src_nents == 1) ++ dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(req->src), ++ out_len, 0); ++ else ++ dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + ++ (1 + !!ivsize) * sizeof(*sg_table), ++ out_len, 0); ++ } else if (mapped_dst_nents == 1) { ++ dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(req->dst), out_len, ++ 0); ++ } else { + dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + sizeof(*sg_table) * + qm_sg_index, out_len, 0); ++ } + + return edesc; +} -+ -+static int tls_crypt(struct aead_request *req, bool encrypt) + +- cpu = smp_processor_id(); +- drv_ctx = caam_drv_ctx_init(ctx->qidev, &cpu, desc); +- if (likely(!IS_ERR_OR_NULL(drv_ctx))) +- drv_ctx->op_type = type; ++static inline int aead_crypt(struct aead_request *req, bool encrypt) +{ -+ struct tls_edesc *edesc; ++ struct aead_edesc *edesc; + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + int ret; -+ + +- ctx->drv_ctx[type] = drv_ctx; +- } + if (unlikely(caam_congested)) + return -EAGAIN; -+ -+ edesc = tls_edesc_alloc(req, encrypt); + +- spin_unlock(&ctx->lock); ++ /* allocate extended descriptor */ ++ edesc = aead_edesc_alloc(req, encrypt); + if (IS_ERR_OR_NULL(edesc)) + return PTR_ERR(edesc); + ++ /* Create and submit job descriptor */ + ret = caam_qi_enqueue(ctx->qidev, &edesc->drv_req); + if (!ret) { + ret = -EINPROGRESS; + } else { -+ tls_unmap(ctx->qidev, edesc, req); ++ aead_unmap(ctx->qidev, edesc, req); + qi_cache_free(edesc); -+ } -+ + } + +- return drv_ctx; + return ret; + } + +-static void caam_unmap(struct device *dev, struct scatterlist *src, +- struct scatterlist *dst, int src_nents, +- int dst_nents, dma_addr_t iv_dma, int ivsize, +- enum optype op_type, dma_addr_t qm_sg_dma, +- int qm_sg_bytes) ++static int aead_encrypt(struct aead_request *req) + { +- if (dst != src) { +- if (src_nents) +- dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE); +- dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE); +- } else { +- dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL); +- } ++ return aead_crypt(req, true); +} + +- if (iv_dma) +- dma_unmap_single(dev, iv_dma, ivsize, +- op_type == GIVENCRYPT ? DMA_FROM_DEVICE : +- DMA_TO_DEVICE); +- if (qm_sg_bytes) +- dma_unmap_single(dev, qm_sg_dma, qm_sg_bytes, DMA_TO_DEVICE); ++static int aead_decrypt(struct aead_request *req) ++{ ++ return aead_crypt(req, false); + } + +-static void aead_unmap(struct device *dev, +- struct aead_edesc *edesc, +- struct aead_request *req) ++static int ipsec_gcm_encrypt(struct aead_request *req) + { +- struct crypto_aead *aead = crypto_aead_reqtfm(req); +- int ivsize = crypto_aead_ivsize(aead); ++ if (req->assoclen < 8) ++ return -EINVAL; + +- caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, +- edesc->iv_dma, ivsize, edesc->drv_req.drv_ctx->op_type, +- edesc->qm_sg_dma, edesc->qm_sg_bytes); +- dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); ++ return aead_crypt(req, true); + } + +-static void ablkcipher_unmap(struct device *dev, +- struct ablkcipher_edesc *edesc, +- struct ablkcipher_request *req) ++static int ipsec_gcm_decrypt(struct aead_request *req) + { +- struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req); +- int ivsize = crypto_ablkcipher_ivsize(ablkcipher); ++ if (req->assoclen < 8) ++ return -EINVAL; + +- caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, +- edesc->iv_dma, ivsize, edesc->drv_req.drv_ctx->op_type, +- edesc->qm_sg_dma, edesc->qm_sg_bytes); ++ return aead_crypt(req, false); + } + +-static void aead_done(struct caam_drv_req *drv_req, u32 status) ++static void tls_done(struct caam_drv_req *drv_req, u32 status) + { + struct device *qidev; +- struct aead_edesc *edesc; ++ struct tls_edesc *edesc; + struct aead_request *aead_req = drv_req->app_ctx; + struct crypto_aead *aead = crypto_aead_reqtfm(aead_req); + struct caam_ctx *caam_ctx = crypto_aead_ctx(aead); +@@ -537,41 +1367,51 @@ static void aead_done(struct caam_drv_re + } + + edesc = container_of(drv_req, typeof(*edesc), drv_req); +- aead_unmap(qidev, edesc, aead_req); ++ tls_unmap(qidev, edesc, aead_req); + + aead_request_complete(aead_req, ecode); + qi_cache_free(edesc); + } + + /* +- * allocate and map the aead extended descriptor ++ * allocate and map the tls extended descriptor + */ +-static struct aead_edesc *aead_edesc_alloc(struct aead_request *req, +- bool encrypt) ++static struct tls_edesc *tls_edesc_alloc(struct aead_request *req, bool encrypt) + { + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ unsigned int blocksize = crypto_aead_blocksize(aead); ++ unsigned int padsize, authsize; + struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead), + typeof(*alg), aead); + struct device *qidev = ctx->qidev; + gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? +- GFP_KERNEL : GFP_ATOMIC; ++ GFP_KERNEL : GFP_ATOMIC; + int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; +- struct aead_edesc *edesc; ++ struct tls_edesc *edesc; + dma_addr_t qm_sg_dma, iv_dma = 0; + int ivsize = 0; +- unsigned int authsize = ctx->authsize; +- int qm_sg_index = 0, qm_sg_ents = 0, qm_sg_bytes; ++ u8 *iv; ++ int qm_sg_index, qm_sg_ents = 0, qm_sg_bytes; + int in_len, out_len; + struct qm_sg_entry *sg_table, *fd_sgt; + struct caam_drv_ctx *drv_ctx; + enum optype op_type = encrypt ? ENCRYPT : DECRYPT; ++ struct scatterlist *dst; ++ ++ if (encrypt) { ++ padsize = blocksize - ((req->cryptlen + ctx->authsize) % ++ blocksize); ++ authsize = ctx->authsize + padsize; ++ } else { ++ authsize = ctx->authsize; ++ } + + drv_ctx = get_drv_ctx(ctx, op_type); + if (unlikely(IS_ERR_OR_NULL(drv_ctx))) +- return (struct aead_edesc *)drv_ctx; ++ return (struct tls_edesc *)drv_ctx; + +- /* allocate space for base edesc and hw desc commands, link tables */ ++ /* allocate space for base edesc, link tables and IV */ + edesc = qi_cache_alloc(GFP_DMA | flags); + if (unlikely(!edesc)) { + dev_err(qidev, "could not allocate extended descriptor\n"); +@@ -581,7 +1421,7 @@ static struct aead_edesc *aead_edesc_all + if (likely(req->src == req->dst)) { + src_nents = sg_nents_for_len(req->src, req->assoclen + + req->cryptlen + +- (encrypt ? authsize : 0)); ++ (encrypt ? authsize : 0)); + if (unlikely(src_nents < 0)) { + dev_err(qidev, "Insufficient bytes (%d) in src S/G\n", + req->assoclen + req->cryptlen + +@@ -597,6 +1437,7 @@ static struct aead_edesc *aead_edesc_all + qi_cache_free(edesc); + return ERR_PTR(-ENOMEM); + } ++ dst = req->dst; + } else { + src_nents = sg_nents_for_len(req->src, req->assoclen + + req->cryptlen); +@@ -607,14 +1448,13 @@ static struct aead_edesc *aead_edesc_all + return ERR_PTR(src_nents); + } + +- dst_nents = sg_nents_for_len(req->dst, req->assoclen + +- req->cryptlen + +- (encrypt ? authsize : +- (-authsize))); ++ dst = scatterwalk_ffwd(edesc->tmp, req->dst, req->assoclen); ++ dst_nents = sg_nents_for_len(dst, req->cryptlen + ++ (encrypt ? authsize : 0)); + if (unlikely(dst_nents < 0)) { + dev_err(qidev, "Insufficient bytes (%d) in dst S/G\n", +- req->assoclen + req->cryptlen + +- (encrypt ? authsize : (-authsize))); ++ req->cryptlen + ++ (encrypt ? authsize : 0)); + qi_cache_free(edesc); + return ERR_PTR(dst_nents); + } +@@ -631,7 +1471,7 @@ static struct aead_edesc *aead_edesc_all + mapped_src_nents = 0; + } + +- mapped_dst_nents = dma_map_sg(qidev, req->dst, dst_nents, ++ mapped_dst_nents = dma_map_sg(qidev, dst, dst_nents, + DMA_FROM_DEVICE); + if (unlikely(!mapped_dst_nents)) { + dev_err(qidev, "unable to map destination\n"); +@@ -641,80 +1481,51 @@ static struct aead_edesc *aead_edesc_all + } + } + +- if ((alg->caam.rfc3686 && encrypt) || !alg->caam.geniv) +- ivsize = crypto_aead_ivsize(aead); +- + /* +- * Create S/G table: req->assoclen, [IV,] req->src [, req->dst]. ++ * Create S/G table: IV, src, dst. + * Input is not contiguous. + */ +- qm_sg_ents = 1 + !!ivsize + mapped_src_nents + ++ qm_sg_ents = 1 + mapped_src_nents + + (mapped_dst_nents > 1 ? mapped_dst_nents : 0); + sg_table = &edesc->sgt[0]; + qm_sg_bytes = qm_sg_ents * sizeof(*sg_table); +- if (unlikely(offsetof(struct aead_edesc, sgt) + qm_sg_bytes + ivsize > +- CAAM_QI_MEMCACHE_SIZE)) { +- dev_err(qidev, "No space for %d S/G entries and/or %dB IV\n", +- qm_sg_ents, ivsize); +- caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, 0, +- 0, 0, 0, 0); ++ ++ ivsize = crypto_aead_ivsize(aead); ++ iv = (u8 *)(sg_table + qm_sg_ents); ++ /* Make sure IV is located in a DMAable area */ ++ memcpy(iv, req->iv, ivsize); ++ iv_dma = dma_map_single(qidev, iv, ivsize, DMA_TO_DEVICE); ++ if (dma_mapping_error(qidev, iv_dma)) { ++ dev_err(qidev, "unable to map IV\n"); ++ caam_unmap(qidev, req->src, dst, src_nents, dst_nents, 0, 0, 0, ++ 0, 0); + qi_cache_free(edesc); + return ERR_PTR(-ENOMEM); + } + +- if (ivsize) { +- u8 *iv = (u8 *)(sg_table + qm_sg_ents); +- +- /* Make sure IV is located in a DMAable area */ +- memcpy(iv, req->iv, ivsize); +- +- iv_dma = dma_map_single(qidev, iv, ivsize, DMA_TO_DEVICE); +- if (dma_mapping_error(qidev, iv_dma)) { +- dev_err(qidev, "unable to map IV\n"); +- caam_unmap(qidev, req->src, req->dst, src_nents, +- dst_nents, 0, 0, 0, 0, 0); +- qi_cache_free(edesc); +- return ERR_PTR(-ENOMEM); +- } +- } +- + edesc->src_nents = src_nents; + edesc->dst_nents = dst_nents; ++ edesc->dst = dst; + edesc->iv_dma = iv_dma; + edesc->drv_req.app_ctx = req; +- edesc->drv_req.cbk = aead_done; ++ edesc->drv_req.cbk = tls_done; + edesc->drv_req.drv_ctx = drv_ctx; + +- edesc->assoclen = cpu_to_caam32(req->assoclen); +- edesc->assoclen_dma = dma_map_single(qidev, &edesc->assoclen, 4, +- DMA_TO_DEVICE); +- if (dma_mapping_error(qidev, edesc->assoclen_dma)) { +- dev_err(qidev, "unable to map assoclen\n"); +- caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, +- iv_dma, ivsize, op_type, 0, 0); +- qi_cache_free(edesc); +- return ERR_PTR(-ENOMEM); +- } ++ dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0); ++ qm_sg_index = 1; + +- dma_to_qm_sg_one(sg_table, edesc->assoclen_dma, 4, 0); +- qm_sg_index++; +- if (ivsize) { +- dma_to_qm_sg_one(sg_table + qm_sg_index, iv_dma, ivsize, 0); +- qm_sg_index++; +- } + sg_to_qm_sg_last(req->src, mapped_src_nents, sg_table + qm_sg_index, 0); + qm_sg_index += mapped_src_nents; + + if (mapped_dst_nents > 1) +- sg_to_qm_sg_last(req->dst, mapped_dst_nents, sg_table + ++ sg_to_qm_sg_last(dst, mapped_dst_nents, sg_table + + qm_sg_index, 0); + + qm_sg_dma = dma_map_single(qidev, sg_table, qm_sg_bytes, DMA_TO_DEVICE); + if (dma_mapping_error(qidev, qm_sg_dma)) { + dev_err(qidev, "unable to map S/G table\n"); +- dma_unmap_single(qidev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); +- caam_unmap(qidev, req->src, req->dst, src_nents, dst_nents, +- iv_dma, ivsize, op_type, 0, 0); ++ caam_unmap(qidev, req->src, dst, src_nents, dst_nents, iv_dma, ++ ivsize, op_type, 0, 0); + qi_cache_free(edesc); + return ERR_PTR(-ENOMEM); + } +@@ -722,35 +1533,29 @@ static struct aead_edesc *aead_edesc_all + edesc->qm_sg_dma = qm_sg_dma; + edesc->qm_sg_bytes = qm_sg_bytes; + +- out_len = req->assoclen + req->cryptlen + +- (encrypt ? ctx->authsize : (-ctx->authsize)); +- in_len = 4 + ivsize + req->assoclen + req->cryptlen; ++ out_len = req->cryptlen + (encrypt ? authsize : 0); ++ in_len = ivsize + req->assoclen + req->cryptlen; + + fd_sgt = &edesc->drv_req.fd_sgt[0]; + + dma_to_qm_sg_one_last_ext(&fd_sgt[1], qm_sg_dma, in_len, 0); + +- if (req->dst == req->src) { +- if (mapped_src_nents == 1) +- dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(req->src), +- out_len, 0); +- else +- dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + +- (1 + !!ivsize) * sizeof(*sg_table), +- out_len, 0); +- } else if (mapped_dst_nents == 1) { +- dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(req->dst), out_len, +- 0); +- } else { ++ if (req->dst == req->src) ++ dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + ++ (sg_nents_for_len(req->src, req->assoclen) + ++ 1) * sizeof(*sg_table), out_len, 0); ++ else if (mapped_dst_nents == 1) ++ dma_to_qm_sg_one(&fd_sgt[0], sg_dma_address(dst), out_len, 0); ++ else + dma_to_qm_sg_one_ext(&fd_sgt[0], qm_sg_dma + sizeof(*sg_table) * + qm_sg_index, out_len, 0); +- } + + return edesc; + } + +-static inline int aead_crypt(struct aead_request *req, bool encrypt) ++static int tls_crypt(struct aead_request *req, bool encrypt) + { +- struct aead_edesc *edesc; ++ struct tls_edesc *edesc; + struct crypto_aead *aead = crypto_aead_reqtfm(req); + struct caam_ctx *ctx = crypto_aead_ctx(aead); + int ret; +@@ -758,31 +1563,29 @@ static inline int aead_crypt(struct aead + if (unlikely(caam_congested)) + return -EAGAIN; + +- /* allocate extended descriptor */ +- edesc = aead_edesc_alloc(req, encrypt); ++ edesc = tls_edesc_alloc(req, encrypt); + if (IS_ERR_OR_NULL(edesc)) + return PTR_ERR(edesc); + +- /* Create and submit job descriptor */ + ret = caam_qi_enqueue(ctx->qidev, &edesc->drv_req); + if (!ret) { + ret = -EINPROGRESS; + } else { +- aead_unmap(ctx->qidev, edesc, req); ++ tls_unmap(ctx->qidev, edesc, req); + qi_cache_free(edesc); + } + + return ret; + } + +-static int aead_encrypt(struct aead_request *req) +static int tls_encrypt(struct aead_request *req) -+{ + { +- return aead_crypt(req, true); + return tls_crypt(req, true); -+} -+ + } + +-static int aead_decrypt(struct aead_request *req) +static int tls_decrypt(struct aead_request *req) -+{ + { +- return aead_crypt(req, false); + return tls_crypt(req, false); -+} -+ + } + static void ablkcipher_done(struct caam_drv_req *drv_req, u32 status) - { - struct ablkcipher_edesc *edesc; -@@ -1308,6 +2096,61 @@ static struct caam_alg_template driver_a +@@ -900,7 +1703,24 @@ static struct ablkcipher_edesc *ablkciph + qm_sg_ents = 1 + mapped_src_nents; + dst_sg_idx = qm_sg_ents; + +- qm_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0; ++ /* ++ * HW reads 4 S/G entries at a time; make sure the reads don't go beyond ++ * the end of the table by allocating more S/G entries. Logic: ++ * if (src != dst && output S/G) ++ * pad output S/G, if needed ++ * else if (src == dst && S/G) ++ * overlapping S/Gs; pad one of them ++ * else if (input S/G) ... ++ * pad input S/G, if needed ++ */ ++ if (mapped_dst_nents > 1) ++ qm_sg_ents += ALIGN(mapped_dst_nents, 4); ++ else if ((req->src == req->dst) && (mapped_src_nents > 1)) ++ qm_sg_ents = max(ALIGN(qm_sg_ents, 4), ++ 1 + ALIGN(mapped_src_nents, 4)); ++ else ++ qm_sg_ents = ALIGN(qm_sg_ents, 4); ++ + qm_sg_bytes = qm_sg_ents * sizeof(struct qm_sg_entry); + if (unlikely(offsetof(struct ablkcipher_edesc, sgt) + qm_sg_bytes + + ivsize > CAAM_QI_MEMCACHE_SIZE)) { +@@ -1308,6 +2128,61 @@ static struct caam_alg_template driver_a }; static struct caam_aead_alg driver_aeads[] = { @@ -4018,7 +5456,7 @@ Signed-off-by: Biwen Li /* single-pass ipsec_esp descriptor */ { .aead = { -@@ -2118,6 +2961,26 @@ static struct caam_aead_alg driver_aeads +@@ -2118,6 +2993,26 @@ static struct caam_aead_alg driver_aeads .geniv = true, } }, @@ -4045,7 +5483,7 @@ Signed-off-by: Biwen Li }; struct caam_crypto_alg { -@@ -2126,9 +2989,20 @@ struct caam_crypto_alg { +@@ -2126,9 +3021,21 @@ struct caam_crypto_alg { struct caam_alg_entry caam; }; @@ -4054,6 +5492,7 @@ Signed-off-by: Biwen Li + bool uses_dkp) { struct caam_drv_private *priv; ++ struct device *dev; + /* Digest sizes for MD5, SHA1, SHA-224, SHA-256, SHA-384, SHA-512 */ + static const u8 digest_size[] = { + MD5_DIGEST_SIZE, @@ -4067,27 +5506,36 @@ Signed-off-by: Biwen Li /* * distribute tfms across job rings to ensure in-order -@@ -2140,8 +3014,14 @@ static int caam_init_common(struct caam_ +@@ -2140,10 +3047,19 @@ static int caam_init_common(struct caam_ return PTR_ERR(ctx->jrdev); } +- ctx->key_dma = dma_map_single(ctx->jrdev, ctx->key, sizeof(ctx->key), +- DMA_TO_DEVICE); +- if (dma_mapping_error(ctx->jrdev, ctx->key_dma)) { +- dev_err(ctx->jrdev, "unable to map key\n"); + priv = dev_get_drvdata(ctx->jrdev->parent); -+ if (priv->era >= 6 && uses_dkp) ++ if (priv->era >= 6 && uses_dkp) { + ctx->dir = DMA_BIDIRECTIONAL; -+ else ++ dev = ctx->jrdev->parent; ++ } else { + ctx->dir = DMA_TO_DEVICE; ++ dev = ctx->jrdev; ++ } + - ctx->key_dma = dma_map_single(ctx->jrdev, ctx->key, sizeof(ctx->key), -- DMA_TO_DEVICE); ++ ctx->key_dma = dma_map_single(dev, ctx->key, sizeof(ctx->key), + ctx->dir); - if (dma_mapping_error(ctx->jrdev, ctx->key_dma)) { - dev_err(ctx->jrdev, "unable to map key\n"); ++ if (dma_mapping_error(dev, ctx->key_dma)) { ++ dev_err(dev, "unable to map key\n"); caam_jr_free(ctx->jrdev); -@@ -2152,7 +3032,22 @@ static int caam_init_common(struct caam_ + return -ENOMEM; + } +@@ -2152,8 +3068,23 @@ static int caam_init_common(struct caam_ ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type; ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type; - priv = dev_get_drvdata(ctx->jrdev->parent); +- ctx->qidev = priv->qidev; + if (ctx->adata.algtype) { + op_id = (ctx->adata.algtype & OP_ALG_ALGSEL_SUBMASK) + >> OP_ALG_ALGSEL_SHIFT; @@ -4104,10 +5552,11 @@ Signed-off-by: Biwen Li + ctx->authsize = 0; + } + - ctx->qidev = priv->qidev; ++ ctx->qidev = ctx->jrdev->parent; spin_lock_init(&ctx->lock); -@@ -2170,7 +3065,7 @@ static int caam_cra_init(struct crypto_t + ctx->drv_ctx[ENCRYPT] = NULL; +@@ -2170,7 +3101,7 @@ static int caam_cra_init(struct crypto_t crypto_alg); struct caam_ctx *ctx = crypto_tfm_ctx(tfm); @@ -4116,7 +5565,7 @@ Signed-off-by: Biwen Li } static int caam_aead_init(struct crypto_aead *tfm) -@@ -2180,7 +3075,9 @@ static int caam_aead_init(struct crypto_ +@@ -2180,17 +3111,25 @@ static int caam_aead_init(struct crypto_ aead); struct caam_ctx *ctx = crypto_aead_ctx(tfm); @@ -4127,31 +5576,162 @@ Signed-off-by: Biwen Li } static void caam_exit_common(struct caam_ctx *ctx) -@@ -2189,8 +3086,7 @@ static void caam_exit_common(struct caam + { ++ struct device *dev; ++ + caam_drv_ctx_rel(ctx->drv_ctx[ENCRYPT]); caam_drv_ctx_rel(ctx->drv_ctx[DECRYPT]); caam_drv_ctx_rel(ctx->drv_ctx[GIVENCRYPT]); - dma_unmap_single(ctx->jrdev, ctx->key_dma, sizeof(ctx->key), - DMA_TO_DEVICE); -+ dma_unmap_single(ctx->jrdev, ctx->key_dma, sizeof(ctx->key), ctx->dir); ++ if (ctx->dir == DMA_BIDIRECTIONAL) ++ dev = ctx->jrdev->parent; ++ else ++ dev = ctx->jrdev; ++ ++ dma_unmap_single(dev, ctx->key_dma, sizeof(ctx->key), ctx->dir); caam_jr_free(ctx->jrdev); } -@@ -2315,6 +3211,11 @@ static int __init caam_qi_algapi_init(vo - if (!priv || !priv->qi_present) - return -ENODEV; +@@ -2206,7 +3145,7 @@ static void caam_aead_exit(struct crypto + } -+ if (caam_dpaa2) { -+ dev_info(ctrldev, "caam/qi frontend driver not suitable for DPAA 2.x, aborting...\n"); -+ return -ENODEV; -+ } -+ + static struct list_head alg_list; +-static void __exit caam_qi_algapi_exit(void) ++void caam_qi_algapi_exit(void) + { + struct caam_crypto_alg *t_alg, *n; + int i; +@@ -2282,53 +3221,48 @@ static void caam_aead_alg_init(struct ca + alg->exit = caam_aead_exit; + } + +-static int __init caam_qi_algapi_init(void) ++int caam_qi_algapi_init(struct device *ctrldev) + { +- struct device_node *dev_node; +- struct platform_device *pdev; +- struct device *ctrldev; +- struct caam_drv_private *priv; ++ struct caam_drv_private *priv = dev_get_drvdata(ctrldev); + int i = 0, err = 0; +- u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst; ++ u32 aes_vid, aes_inst, des_inst, md_vid, md_inst; + unsigned int md_limit = SHA512_DIGEST_SIZE; + bool registered = false; + +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); +- if (!dev_node) { +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); +- if (!dev_node) +- return -ENODEV; +- } +- +- pdev = of_find_device_by_node(dev_node); +- of_node_put(dev_node); +- if (!pdev) +- return -ENODEV; +- +- ctrldev = &pdev->dev; +- priv = dev_get_drvdata(ctrldev); +- +- /* +- * If priv is NULL, it's probably because the caam driver wasn't +- * properly initialized (e.g. RNG4 init failed). Thus, bail out here. +- */ +- if (!priv || !priv->qi_present) +- return -ENODEV; +- INIT_LIST_HEAD(&alg_list); /* + * Register crypto algorithms the device supports. + * First, detect presence and attributes of DES, AES, and MD blocks. + */ +- cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls); +- cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls); +- des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT; +- aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT; +- md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; ++ if (priv->era < 10) { ++ u32 cha_vid, cha_inst; ++ ++ cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls); ++ aes_vid = cha_vid & CHA_ID_LS_AES_MASK; ++ md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; ++ ++ cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls); ++ des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> ++ CHA_ID_LS_DES_SHIFT; ++ aes_inst = cha_inst & CHA_ID_LS_AES_MASK; ++ md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; ++ } else { ++ u32 aesa, mdha; ++ ++ aesa = rd_reg32(&priv->ctrl->vreg.aesa); ++ mdha = rd_reg32(&priv->ctrl->vreg.mdha); ++ ++ aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT; ++ md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT; ++ ++ des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK; ++ aes_inst = aesa & CHA_VER_NUM_MASK; ++ md_inst = mdha & CHA_VER_NUM_MASK; ++ } + + /* If MD is present, limit digest size based on LP256 */ +- if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256)) ++ if (md_inst && md_vid == CHA_VER_VID_MD_LP256) + md_limit = SHA256_DIGEST_SIZE; + + for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { +@@ -2349,14 +3283,14 @@ static int __init caam_qi_algapi_init(vo + t_alg = caam_alg_alloc(alg); + if (IS_ERR(t_alg)) { + err = PTR_ERR(t_alg); +- dev_warn(priv->qidev, "%s alg allocation failed\n", ++ dev_warn(ctrldev, "%s alg allocation failed\n", + alg->driver_name); + continue; + } + + err = crypto_register_alg(&t_alg->crypto_alg); + if (err) { +- dev_warn(priv->qidev, "%s alg registration failed\n", ++ dev_warn(ctrldev, "%s alg registration failed\n", + t_alg->crypto_alg.cra_driver_name); + kfree(t_alg); + continue; +@@ -2388,8 +3322,7 @@ static int __init caam_qi_algapi_init(vo + * Check support for AES algorithms not available + * on LP devices. + */ +- if (((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP) && +- (alg_aai == OP_ALG_AAI_GCM)) ++ if (aes_vid == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM) + continue; + + /* +@@ -2414,14 +3347,7 @@ static int __init caam_qi_algapi_init(vo + } + + if (registered) +- dev_info(priv->qidev, "algorithms registered in /proc/crypto\n"); ++ dev_info(ctrldev, "algorithms registered in /proc/crypto\n"); + + return err; + } +- +-module_init(caam_qi_algapi_init); +-module_exit(caam_qi_algapi_exit); +- +-MODULE_LICENSE("GPL"); +-MODULE_DESCRIPTION("Support for crypto API using CAAM-QI backend"); +-MODULE_AUTHOR("Freescale Semiconductor"); --- /dev/null +++ b/drivers/crypto/caam/caamalg_qi2.c -@@ -0,0 +1,5691 @@ +@@ -0,0 +1,5843 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright 2015-2016 Freescale Semiconductor Inc. @@ -4179,13 +5759,6 @@ Signed-off-by: Biwen Li +#define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE + \ + SHA512_DIGEST_SIZE * 2) + -+#ifndef CONFIG_CRYPTO_DEV_FSL_CAAM -+bool caam_little_end; -+EXPORT_SYMBOL(caam_little_end); -+bool caam_imx; -+EXPORT_SYMBOL(caam_imx); -+#endif -+ +/* + * This is a a cache of buffers, from which the users of CAAM QI driver + * can allocate short buffers. It's speedier than doing kmalloc on the hotpath. @@ -4639,7 +6212,15 @@ Signed-off-by: Biwen Li + edesc->dst_nents = dst_nents; + edesc->iv_dma = iv_dma; + -+ edesc->assoclen = cpu_to_caam32(req->assoclen); ++ if ((alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK) == ++ OP_ALG_ALGSEL_CHACHA20 && ivsize != CHACHAPOLY_IV_SIZE) ++ /* ++ * The associated data comes already with the IV but we need ++ * to skip it when we authenticate or encrypt... ++ */ ++ edesc->assoclen = cpu_to_caam32(req->assoclen - ivsize); ++ else ++ edesc->assoclen = cpu_to_caam32(req->assoclen); + edesc->assoclen_dma = dma_map_single(dev, &edesc->assoclen, 4, + DMA_TO_DEVICE); + if (dma_mapping_error(dev, edesc->assoclen_dma)) { @@ -4709,6 +6290,68 @@ Signed-off-by: Biwen Li + return edesc; +} + ++static int chachapoly_set_sh_desc(struct crypto_aead *aead) ++{ ++ struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ unsigned int ivsize = crypto_aead_ivsize(aead); ++ struct device *dev = ctx->dev; ++ struct caam_flc *flc; ++ u32 *desc; ++ ++ if (!ctx->cdata.keylen || !ctx->authsize) ++ return 0; ++ ++ flc = &ctx->flc[ENCRYPT]; ++ desc = flc->sh_desc; ++ cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize, ++ ctx->authsize, true, true); ++ flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ ++ dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], ++ sizeof(flc->flc) + desc_bytes(desc), ++ ctx->dir); ++ ++ flc = &ctx->flc[DECRYPT]; ++ desc = flc->sh_desc; ++ cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize, ++ ctx->authsize, false, true); ++ flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ ++ dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], ++ sizeof(flc->flc) + desc_bytes(desc), ++ ctx->dir); ++ ++ return 0; ++} ++ ++static int chachapoly_setauthsize(struct crypto_aead *aead, ++ unsigned int authsize) ++{ ++ struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ ++ if (authsize != POLY1305_DIGEST_SIZE) ++ return -EINVAL; ++ ++ ctx->authsize = authsize; ++ return chachapoly_set_sh_desc(aead); ++} ++ ++static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, ++ unsigned int keylen) ++{ ++ struct caam_ctx *ctx = crypto_aead_ctx(aead); ++ unsigned int ivsize = crypto_aead_ivsize(aead); ++ unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize; ++ ++ if (keylen != CHACHA20_KEY_SIZE + saltlen) { ++ crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN); ++ return -EINVAL; ++ } ++ ++ ctx->cdata.key_virt = key; ++ ctx->cdata.keylen = keylen - saltlen; ++ ++ return chachapoly_set_sh_desc(aead); ++} ++ +static struct tls_edesc *tls_edesc_alloc(struct aead_request *req, + bool encrypt) +{ @@ -5303,7 +6946,9 @@ Signed-off-by: Biwen Li + u32 *desc; + u32 ctx1_iv_off = 0; + const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == -+ OP_ALG_AAI_CTR_MOD128); ++ OP_ALG_AAI_CTR_MOD128) && ++ ((ctx->cdata.algtype & OP_ALG_ALGSEL_MASK) != ++ OP_ALG_ALGSEL_CHACHA20); + const bool is_rfc3686 = alg->caam.rfc3686; + +#ifdef DEBUG @@ -6119,7 +7764,23 @@ Signed-off-by: Biwen Li + .ivsize = AES_BLOCK_SIZE, + }, + .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS, -+ } ++ }, ++ { ++ .skcipher = { ++ .base = { ++ .cra_name = "chacha20", ++ .cra_driver_name = "chacha20-caam-qi2", ++ .cra_blocksize = 1, ++ }, ++ .setkey = skcipher_setkey, ++ .encrypt = skcipher_encrypt, ++ .decrypt = skcipher_decrypt, ++ .min_keysize = CHACHA20_KEY_SIZE, ++ .max_keysize = CHACHA20_KEY_SIZE, ++ .ivsize = CHACHA20_IV_SIZE, ++ }, ++ .caam.class1_alg_type = OP_ALG_ALGSEL_CHACHA20, ++ }, +}; + +static struct caam_aead_alg driver_aeads[] = { @@ -7236,6 +8897,50 @@ Signed-off-by: Biwen Li + { + .aead = { + .base = { ++ .cra_name = "rfc7539(chacha20,poly1305)", ++ .cra_driver_name = "rfc7539-chacha20-poly1305-" ++ "caam-qi2", ++ .cra_blocksize = 1, ++ }, ++ .setkey = chachapoly_setkey, ++ .setauthsize = chachapoly_setauthsize, ++ .encrypt = aead_encrypt, ++ .decrypt = aead_decrypt, ++ .ivsize = CHACHAPOLY_IV_SIZE, ++ .maxauthsize = POLY1305_DIGEST_SIZE, ++ }, ++ .caam = { ++ .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 | ++ OP_ALG_AAI_AEAD, ++ .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | ++ OP_ALG_AAI_AEAD, ++ }, ++ }, ++ { ++ .aead = { ++ .base = { ++ .cra_name = "rfc7539esp(chacha20,poly1305)", ++ .cra_driver_name = "rfc7539esp-chacha20-" ++ "poly1305-caam-qi2", ++ .cra_blocksize = 1, ++ }, ++ .setkey = chachapoly_setkey, ++ .setauthsize = chachapoly_setauthsize, ++ .encrypt = aead_encrypt, ++ .decrypt = aead_decrypt, ++ .ivsize = 8, ++ .maxauthsize = POLY1305_DIGEST_SIZE, ++ }, ++ .caam = { ++ .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 | ++ OP_ALG_AAI_AEAD, ++ .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | ++ OP_ALG_AAI_AEAD, ++ }, ++ }, ++ { ++ .aead = { ++ .base = { + .cra_name = "authenc(hmac(sha512)," + "rfc3686(ctr(aes)))", + .cra_driver_name = "authenc-hmac-sha512-" @@ -9040,7 +10745,8 @@ Signed-off-by: Biwen Li + nctx->cb = dpaa2_caam_fqdan_cb; + + /* Register notification callbacks */ -+ err = dpaa2_io_service_register(NULL, nctx); ++ ppriv->dpio = dpaa2_io_service_select(cpu); ++ err = dpaa2_io_service_register(ppriv->dpio, nctx, dev); + if (unlikely(err)) { + dev_dbg(dev, "No affine DPIO for cpu %d\n", cpu); + nctx->cb = NULL; @@ -9058,6 +10764,7 @@ Signed-off-by: Biwen Li + dev); + if (unlikely(!ppriv->store)) { + dev_err(dev, "dpaa2_io_store_create() failed\n"); ++ err = -ENOMEM; + goto err; + } + @@ -9072,7 +10779,7 @@ Signed-off-by: Biwen Li + ppriv = per_cpu_ptr(priv->ppriv, cpu); + if (!ppriv->nctx.cb) + break; -+ dpaa2_io_service_deregister(NULL, &ppriv->nctx); ++ dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, dev); + } + + for_each_online_cpu(cpu) { @@ -9088,11 +10795,12 @@ Signed-off-by: Biwen Li +static void __cold dpaa2_dpseci_dpio_free(struct dpaa2_caam_priv *priv) +{ + struct dpaa2_caam_priv_per_cpu *ppriv; ++ struct device *dev = priv->dev; + int i = 0, cpu; + + for_each_online_cpu(cpu) { + ppriv = per_cpu_ptr(priv->ppriv, cpu); -+ dpaa2_io_service_deregister(NULL, &ppriv->nctx); ++ dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, dev); + dpaa2_io_store_destroy(ppriv->store); + + if (++i == priv->num_pairs) @@ -9190,7 +10898,7 @@ Signed-off-by: Biwen Li + + /* Retry while portal is busy */ + do { -+ err = dpaa2_io_service_pull_fq(NULL, ppriv->rsp_fqid, ++ err = dpaa2_io_service_pull_fq(ppriv->dpio, ppriv->rsp_fqid, + ppriv->store); + } while (err == -EBUSY); + @@ -9258,7 +10966,7 @@ Signed-off-by: Biwen Li + + if (cleaned < budget) { + napi_complete_done(napi, cleaned); -+ err = dpaa2_io_service_rearm(NULL, &ppriv->nctx); ++ err = dpaa2_io_service_rearm(ppriv->dpio, &ppriv->nctx); + if (unlikely(err)) + dev_err(priv->dev, "Notification rearm failed: %d\n", + err); @@ -9399,21 +11107,31 @@ Signed-off-by: Biwen Li + + i = 0; + for_each_online_cpu(cpu) { -+ dev_info(dev, "pair %d: rx queue %d, tx queue %d\n", i, -+ priv->rx_queue_attr[i].fqid, -+ priv->tx_queue_attr[i].fqid); ++ u8 j; ++ ++ j = i % priv->num_pairs; + + ppriv = per_cpu_ptr(priv->ppriv, cpu); -+ ppriv->req_fqid = priv->tx_queue_attr[i].fqid; -+ ppriv->rsp_fqid = priv->rx_queue_attr[i].fqid; -+ ppriv->prio = i; ++ ppriv->req_fqid = priv->tx_queue_attr[j].fqid; ++ ++ /* ++ * Allow all cores to enqueue, while only some of them ++ * will take part in dequeuing. ++ */ ++ if (++i > priv->num_pairs) ++ continue; ++ ++ ppriv->rsp_fqid = priv->rx_queue_attr[j].fqid; ++ ppriv->prio = j; ++ ++ dev_info(dev, "pair %d: rx queue %d, tx queue %d\n", j, ++ priv->rx_queue_attr[j].fqid, ++ priv->tx_queue_attr[j].fqid); + + ppriv->net_dev.dev = *dev; + INIT_LIST_HEAD(&ppriv->net_dev.napi_list); + netif_napi_add(&ppriv->net_dev, &ppriv->napi, dpaa2_dpseci_poll, + DPAA2_CAAM_NAPI_WEIGHT); -+ if (++i == priv->num_pairs) -+ break; + } + + return 0; @@ -9538,12 +11256,13 @@ Signed-off-by: Biwen Li + priv->ppriv = alloc_percpu(*priv->ppriv); + if (!priv->ppriv) { + dev_err(dev, "alloc_percpu() failed\n"); ++ err = -ENOMEM; + goto err_alloc_ppriv; + } + + /* DPSECI initialization */ + err = dpaa2_dpseci_setup(dpseci_dev); -+ if (err < 0) { ++ if (err) { + dev_err(dev, "dpaa2_dpseci_setup() failed\n"); + goto err_dpseci_setup; + } @@ -9551,7 +11270,8 @@ Signed-off-by: Biwen Li + /* DPIO */ + err = dpaa2_dpseci_dpio_setup(priv); + if (err) { -+ dev_err(dev, "dpaa2_dpseci_dpio_setup() failed\n"); ++ if (err != -EPROBE_DEFER) ++ dev_err(dev, "dpaa2_dpseci_dpio_setup() failed\n"); + goto err_dpio_setup; + } + @@ -9585,6 +11305,11 @@ Signed-off-by: Biwen Li + (alg_sel == OP_ALG_ALGSEL_AES)) + continue; + ++ /* Skip CHACHA20 algorithms if not supported by device */ ++ if (alg_sel == OP_ALG_ALGSEL_CHACHA20 && ++ !priv->sec_attr.ccha_acc_num) ++ continue; ++ + t_alg->caam.dev = dev; + caam_skcipher_alg_init(t_alg); + @@ -9617,11 +11342,22 @@ Signed-off-by: Biwen Li + (c1_alg_sel == OP_ALG_ALGSEL_AES)) + continue; + ++ /* Skip CHACHA20 algorithms if not supported by device */ ++ if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && ++ !priv->sec_attr.ccha_acc_num) ++ continue; ++ ++ /* Skip POLY1305 algorithms if not supported by device */ ++ if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && ++ !priv->sec_attr.ptha_acc_num) ++ continue; ++ + /* + * Skip algorithms requiring message digests + * if MD not supported by device. + */ -+ if (!priv->sec_attr.md_acc_num && c2_alg_sel) ++ if ((c2_alg_sel & ~OP_ALG_ALGSEL_SUBMASK) == 0x40 && ++ !priv->sec_attr.md_acc_num) + continue; + + t_alg->caam.dev = dev; @@ -9761,7 +11497,8 @@ Signed-off-by: Biwen Li +{ + struct dpaa2_fd fd; + struct dpaa2_caam_priv *priv = dev_get_drvdata(dev); -+ int err = 0, i, id; ++ struct dpaa2_caam_priv_per_cpu *ppriv; ++ int err = 0, i; + + if (IS_ERR(req)) + return PTR_ERR(req); @@ -9791,23 +11528,18 @@ Signed-off-by: Biwen Li + dpaa2_fd_set_len(&fd, dpaa2_fl_get_len(&req->fd_flt[1])); + dpaa2_fd_set_flc(&fd, req->flc_dma); + -+ /* -+ * There is no guarantee that preemption is disabled here, -+ * thus take action. -+ */ -+ preempt_disable(); -+ id = smp_processor_id() % priv->dpseci_attr.num_tx_queues; ++ ppriv = this_cpu_ptr(priv->ppriv); + for (i = 0; i < (priv->dpseci_attr.num_tx_queues << 1); i++) { -+ err = dpaa2_io_service_enqueue_fq(NULL, -+ priv->tx_queue_attr[id].fqid, ++ err = dpaa2_io_service_enqueue_fq(ppriv->dpio, ppriv->req_fqid, + &fd); + if (err != -EBUSY) + break; ++ ++ cpu_relax(); + } -+ preempt_enable(); + -+ if (unlikely(err < 0)) { -+ dev_err(dev, "Error enqueuing frame: %d\n", err); ++ if (unlikely(err)) { ++ dev_err_ratelimited(dev, "Error enqueuing frame: %d\n", err); + goto err_out; + } + @@ -9845,7 +11577,7 @@ Signed-off-by: Biwen Li +module_fsl_mc_driver(dpaa2_caam_driver); --- /dev/null +++ b/drivers/crypto/caam/caamalg_qi2.h -@@ -0,0 +1,274 @@ +@@ -0,0 +1,276 @@ +/* + * Copyright 2015-2016 Freescale Semiconductor Inc. + * Copyright 2017 NXP @@ -9953,6 +11685,7 @@ Signed-off-by: Biwen Li + * @nctx: notification context of response FQ + * @store: where dequeued frames are stored + * @priv: backpointer to dpaa2_caam_priv ++ * @dpio: portal used for data path operations + */ +struct dpaa2_caam_priv_per_cpu { + struct napi_struct napi; @@ -9963,6 +11696,7 @@ Signed-off-by: Biwen Li + struct dpaa2_io_notification_ctx nctx; + struct dpaa2_io_store *store; + struct dpaa2_caam_priv *priv; ++ struct dpaa2_io *dpio; +}; + +/* @@ -10122,7 +11856,15 @@ Signed-off-by: Biwen Li +#endif /* _CAAMALG_QI2_H_ */ --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c -@@ -62,6 +62,7 @@ +@@ -2,6 +2,7 @@ + * caam - Freescale FSL CAAM support for ahash functions of crypto API + * + * Copyright 2011 Freescale Semiconductor, Inc. ++ * Copyright 2018 NXP + * + * Based on caamalg.c crypto API driver. + * +@@ -62,6 +63,7 @@ #include "error.h" #include "sg_sw_sec4.h" #include "key_gen.h" @@ -10130,7 +11872,7 @@ Signed-off-by: Biwen Li #define CAAM_CRA_PRIORITY 3000 -@@ -71,14 +72,6 @@ +@@ -71,14 +73,6 @@ #define CAAM_MAX_HASH_BLOCK_SIZE SHA512_BLOCK_SIZE #define CAAM_MAX_HASH_DIGEST_SIZE SHA512_DIGEST_SIZE @@ -10145,7 +11887,7 @@ Signed-off-by: Biwen Li #define DESC_HASH_MAX_USED_BYTES (DESC_AHASH_FINAL_LEN + \ CAAM_MAX_HASH_KEY_SIZE) #define DESC_HASH_MAX_USED_LEN (DESC_HASH_MAX_USED_BYTES / CAAM_CMD_SZ) -@@ -107,6 +100,7 @@ struct caam_hash_ctx { +@@ -107,6 +101,7 @@ struct caam_hash_ctx { dma_addr_t sh_desc_update_first_dma; dma_addr_t sh_desc_fin_dma; dma_addr_t sh_desc_digest_dma; @@ -10153,7 +11895,7 @@ Signed-off-by: Biwen Li struct device *jrdev; u8 key[CAAM_MAX_HASH_KEY_SIZE]; int ctx_len; -@@ -218,7 +212,7 @@ static inline int buf_map_to_sec4_sg(str +@@ -218,7 +213,7 @@ static inline int buf_map_to_sec4_sg(str } /* Map state->caam_ctx, and add it to link table */ @@ -10162,7 +11904,7 @@ Signed-off-by: Biwen Li struct caam_hash_state *state, int ctx_len, struct sec4_sg_entry *sec4_sg, u32 flag) { -@@ -234,68 +228,22 @@ static inline int ctx_map_to_sec4_sg(u32 +@@ -234,68 +229,22 @@ static inline int ctx_map_to_sec4_sg(u32 return 0; } @@ -10237,7 +11979,7 @@ Signed-off-by: Biwen Li #ifdef DEBUG print_hex_dump(KERN_ERR, "ahash update shdesc@"__stringify(__LINE__)": ", -@@ -304,9 +252,10 @@ static int ahash_set_sh_desc(struct cryp +@@ -304,9 +253,10 @@ static int ahash_set_sh_desc(struct cryp /* ahash_update_first shared descriptor */ desc = ctx->sh_desc_update_first; @@ -10250,7 +11992,7 @@ Signed-off-by: Biwen Li #ifdef DEBUG print_hex_dump(KERN_ERR, "ahash update first shdesc@"__stringify(__LINE__)": ", -@@ -315,9 +264,10 @@ static int ahash_set_sh_desc(struct cryp +@@ -315,9 +265,10 @@ static int ahash_set_sh_desc(struct cryp /* ahash_final shared descriptor */ desc = ctx->sh_desc_fin; @@ -10263,7 +12005,7 @@ Signed-off-by: Biwen Li #ifdef DEBUG print_hex_dump(KERN_ERR, "ahash final shdesc@"__stringify(__LINE__)": ", DUMP_PREFIX_ADDRESS, 16, 4, desc, -@@ -326,9 +276,10 @@ static int ahash_set_sh_desc(struct cryp +@@ -326,9 +277,10 @@ static int ahash_set_sh_desc(struct cryp /* ahash_digest shared descriptor */ desc = ctx->sh_desc_digest; @@ -10276,7 +12018,7 @@ Signed-off-by: Biwen Li #ifdef DEBUG print_hex_dump(KERN_ERR, "ahash digest shdesc@"__stringify(__LINE__)": ", -@@ -421,6 +372,7 @@ static int ahash_setkey(struct crypto_ah +@@ -421,6 +373,7 @@ static int ahash_setkey(struct crypto_ah struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); int blocksize = crypto_tfm_alg_blocksize(&ahash->base); int digestsize = crypto_ahash_digestsize(ahash); @@ -10284,7 +12026,7 @@ Signed-off-by: Biwen Li int ret; u8 *hashed_key = NULL; -@@ -441,16 +393,26 @@ static int ahash_setkey(struct crypto_ah +@@ -441,16 +394,26 @@ static int ahash_setkey(struct crypto_ah key = hashed_key; } @@ -10320,7 +12062,7 @@ Signed-off-by: Biwen Li kfree(hashed_key); return ahash_set_sh_desc(ahash); -@@ -773,7 +735,7 @@ static int ahash_update_ctx(struct ahash +@@ -773,7 +736,7 @@ static int ahash_update_ctx(struct ahash edesc->src_nents = src_nents; edesc->sec4_sg_bytes = sec4_sg_bytes; @@ -10329,7 +12071,7 @@ Signed-off-by: Biwen Li edesc->sec4_sg, DMA_BIDIRECTIONAL); if (ret) goto unmap_ctx; -@@ -871,9 +833,8 @@ static int ahash_final_ctx(struct ahash_ +@@ -871,9 +834,8 @@ static int ahash_final_ctx(struct ahash_ desc = edesc->hw_desc; edesc->sec4_sg_bytes = sec4_sg_bytes; @@ -10340,7 +12082,7 @@ Signed-off-by: Biwen Li edesc->sec4_sg, DMA_TO_DEVICE); if (ret) goto unmap_ctx; -@@ -967,7 +928,7 @@ static int ahash_finup_ctx(struct ahash_ +@@ -967,7 +929,7 @@ static int ahash_finup_ctx(struct ahash_ edesc->src_nents = src_nents; @@ -10349,7 +12091,7 @@ Signed-off-by: Biwen Li edesc->sec4_sg, DMA_TO_DEVICE); if (ret) goto unmap_ctx; -@@ -1126,7 +1087,6 @@ static int ahash_final_no_ctx(struct aha +@@ -1126,7 +1088,6 @@ static int ahash_final_no_ctx(struct aha dev_err(jrdev, "unable to map dst\n"); goto unmap; } @@ -10357,7 +12099,7 @@ Signed-off-by: Biwen Li #ifdef DEBUG print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ", -@@ -1208,7 +1168,6 @@ static int ahash_update_no_ctx(struct ah +@@ -1208,7 +1169,6 @@ static int ahash_update_no_ctx(struct ah edesc->src_nents = src_nents; edesc->sec4_sg_bytes = sec4_sg_bytes; @@ -10365,7 +12107,7 @@ Signed-off-by: Biwen Li ret = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg, state); if (ret) -@@ -1420,7 +1379,6 @@ static int ahash_update_first(struct aha +@@ -1420,7 +1380,6 @@ static int ahash_update_first(struct aha } edesc->src_nents = src_nents; @@ -10373,7 +12115,7 @@ Signed-off-by: Biwen Li ret = ahash_edesc_add_src(ctx, edesc, req, mapped_nents, 0, 0, to_hash); -@@ -1722,6 +1680,7 @@ static int caam_hash_cra_init(struct cry +@@ -1722,6 +1681,7 @@ static int caam_hash_cra_init(struct cry HASH_MSG_LEN + 64, HASH_MSG_LEN + SHA512_DIGEST_SIZE }; dma_addr_t dma_addr; @@ -10381,7 +12123,7 @@ Signed-off-by: Biwen Li /* * Get a Job ring from Job Ring driver to ensure in-order -@@ -1733,10 +1692,13 @@ static int caam_hash_cra_init(struct cry +@@ -1733,10 +1693,13 @@ static int caam_hash_cra_init(struct cry return PTR_ERR(ctx->jrdev); } @@ -10396,7 +12138,7 @@ Signed-off-by: Biwen Li if (dma_mapping_error(ctx->jrdev, dma_addr)) { dev_err(ctx->jrdev, "unable to map shared descriptors\n"); caam_jr_free(ctx->jrdev); -@@ -1771,7 +1733,7 @@ static void caam_hash_cra_exit(struct cr +@@ -1771,11 +1734,11 @@ static void caam_hash_cra_exit(struct cr dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_update_dma, offsetof(struct caam_hash_ctx, sh_desc_update_dma), @@ -10405,6 +12147,95 @@ Signed-off-by: Biwen Li caam_jr_free(ctx->jrdev); } +-static void __exit caam_algapi_hash_exit(void) ++void caam_algapi_hash_exit(void) + { + struct caam_hash_alg *t_alg, *n; + +@@ -1834,56 +1797,38 @@ caam_hash_alloc(struct caam_hash_templat + return t_alg; + } + +-static int __init caam_algapi_hash_init(void) ++int caam_algapi_hash_init(struct device *ctrldev) + { +- struct device_node *dev_node; +- struct platform_device *pdev; +- struct device *ctrldev; + int i = 0, err = 0; +- struct caam_drv_private *priv; ++ struct caam_drv_private *priv = dev_get_drvdata(ctrldev); + unsigned int md_limit = SHA512_DIGEST_SIZE; +- u32 cha_inst, cha_vid; +- +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); +- if (!dev_node) { +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); +- if (!dev_node) +- return -ENODEV; +- } +- +- pdev = of_find_device_by_node(dev_node); +- if (!pdev) { +- of_node_put(dev_node); +- return -ENODEV; +- } +- +- ctrldev = &pdev->dev; +- priv = dev_get_drvdata(ctrldev); +- of_node_put(dev_node); +- +- /* +- * If priv is NULL, it's probably because the caam driver wasn't +- * properly initialized (e.g. RNG4 init failed). Thus, bail out here. +- */ +- if (!priv) +- return -ENODEV; ++ u32 md_inst, md_vid; + + /* + * Register crypto algorithms the device supports. First, identify + * presence and attributes of MD block. + */ +- cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls); +- cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls); ++ if (priv->era < 10) { ++ md_vid = (rd_reg32(&priv->ctrl->perfmon.cha_id_ls) & ++ CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; ++ md_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & ++ CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT; ++ } else { ++ u32 mdha = rd_reg32(&priv->ctrl->vreg.mdha); ++ ++ md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT; ++ md_inst = mdha & CHA_VER_NUM_MASK; ++ } + + /* + * Skip registration of any hashing algorithms if MD block + * is not present. + */ +- if (!((cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT)) ++ if (!md_inst) + return -ENODEV; + + /* Limit digest size based on LP256 */ +- if ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256) ++ if (md_vid == CHA_VER_VID_MD_LP256) + md_limit = SHA256_DIGEST_SIZE; + + INIT_LIST_HEAD(&hash_list); +@@ -1934,10 +1879,3 @@ static int __init caam_algapi_hash_init( + + return err; + } +- +-module_init(caam_algapi_hash_init); +-module_exit(caam_algapi_hash_exit); +- +-MODULE_LICENSE("GPL"); +-MODULE_DESCRIPTION("FSL CAAM support for ahash functions of crypto API"); +-MODULE_AUTHOR("Freescale Semiconductor - NMG"); --- /dev/null +++ b/drivers/crypto/caam/caamhash_desc.c @@ -0,0 +1,108 @@ @@ -10567,7 +12398,172 @@ Signed-off-by: Biwen Li +void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state, + int digestsize, int ctx_len, bool import_ctx, int era); + -+#endif /* _CAAMHASH_DESC_H_ */ ++#endif /* _CAAMHASH_DESC_H_ */ +--- a/drivers/crypto/caam/caampkc.c ++++ b/drivers/crypto/caam/caampkc.c +@@ -2,6 +2,7 @@ + * caam - Freescale FSL CAAM support for Public Key Cryptography + * + * Copyright 2016 Freescale Semiconductor, Inc. ++ * Copyright 2018 NXP + * + * There is no Shared Descriptor for PKC so that the Job Descriptor must carry + * all the desired key parameters, input and output pointers. +@@ -1017,46 +1018,22 @@ static struct akcipher_alg caam_rsa = { + }; + + /* Public Key Cryptography module initialization handler */ +-static int __init caam_pkc_init(void) ++int caam_pkc_init(struct device *ctrldev) + { +- struct device_node *dev_node; +- struct platform_device *pdev; +- struct device *ctrldev; +- struct caam_drv_private *priv; +- u32 cha_inst, pk_inst; ++ struct caam_drv_private *priv = dev_get_drvdata(ctrldev); ++ u32 pk_inst; + int err; + +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); +- if (!dev_node) { +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); +- if (!dev_node) +- return -ENODEV; +- } +- +- pdev = of_find_device_by_node(dev_node); +- if (!pdev) { +- of_node_put(dev_node); +- return -ENODEV; +- } +- +- ctrldev = &pdev->dev; +- priv = dev_get_drvdata(ctrldev); +- of_node_put(dev_node); +- +- /* +- * If priv is NULL, it's probably because the caam driver wasn't +- * properly initialized (e.g. RNG4 init failed). Thus, bail out here. +- */ +- if (!priv) +- return -ENODEV; +- + /* Determine public key hardware accelerator presence. */ +- cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls); +- pk_inst = (cha_inst & CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT; ++ if (priv->era < 10) ++ pk_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & ++ CHA_ID_LS_PK_MASK) >> CHA_ID_LS_PK_SHIFT; ++ else ++ pk_inst = rd_reg32(&priv->ctrl->vreg.pkha) & CHA_VER_NUM_MASK; + + /* Do not register algorithms if PKHA is not present. */ + if (!pk_inst) +- return -ENODEV; ++ return 0; + + err = crypto_register_akcipher(&caam_rsa); + if (err) +@@ -1068,14 +1045,7 @@ static int __init caam_pkc_init(void) + return err; + } + +-static void __exit caam_pkc_exit(void) ++void caam_pkc_exit(void) + { + crypto_unregister_akcipher(&caam_rsa); + } +- +-module_init(caam_pkc_init); +-module_exit(caam_pkc_exit); +- +-MODULE_LICENSE("Dual BSD/GPL"); +-MODULE_DESCRIPTION("FSL CAAM support for PKC functions of crypto API"); +-MODULE_AUTHOR("Freescale Semiconductor"); +--- a/drivers/crypto/caam/caamrng.c ++++ b/drivers/crypto/caam/caamrng.c +@@ -2,6 +2,7 @@ + * caam - Freescale FSL CAAM support for hw_random + * + * Copyright 2011 Freescale Semiconductor, Inc. ++ * Copyright 2018 NXP + * + * Based on caamalg.c crypto API driver. + * +@@ -294,49 +295,29 @@ static struct hwrng caam_rng = { + .read = caam_read, + }; + +-static void __exit caam_rng_exit(void) ++void caam_rng_exit(void) + { + caam_jr_free(rng_ctx->jrdev); + hwrng_unregister(&caam_rng); + kfree(rng_ctx); + } + +-static int __init caam_rng_init(void) ++int caam_rng_init(struct device *ctrldev) + { + struct device *dev; +- struct device_node *dev_node; +- struct platform_device *pdev; +- struct device *ctrldev; +- struct caam_drv_private *priv; ++ u32 rng_inst; ++ struct caam_drv_private *priv = dev_get_drvdata(ctrldev); + int err; + +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0"); +- if (!dev_node) { +- dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0"); +- if (!dev_node) +- return -ENODEV; +- } +- +- pdev = of_find_device_by_node(dev_node); +- if (!pdev) { +- of_node_put(dev_node); +- return -ENODEV; +- } +- +- ctrldev = &pdev->dev; +- priv = dev_get_drvdata(ctrldev); +- of_node_put(dev_node); +- +- /* +- * If priv is NULL, it's probably because the caam driver wasn't +- * properly initialized (e.g. RNG4 init failed). Thus, bail out here. +- */ +- if (!priv) +- return -ENODEV; +- + /* Check for an instantiated RNG before registration */ +- if (!(rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & CHA_ID_LS_RNG_MASK)) +- return -ENODEV; ++ if (priv->era < 10) ++ rng_inst = (rd_reg32(&priv->ctrl->perfmon.cha_num_ls) & ++ CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT; ++ else ++ rng_inst = rd_reg32(&priv->ctrl->vreg.rng) & CHA_VER_NUM_MASK; ++ ++ if (!rng_inst) ++ return 0; + + dev = caam_jr_alloc(); + if (IS_ERR(dev)) { +@@ -361,10 +342,3 @@ free_caam_alloc: + caam_jr_free(dev); + return err; + } +- +-module_init(caam_rng_init); +-module_exit(caam_rng_exit); +- +-MODULE_LICENSE("GPL"); +-MODULE_DESCRIPTION("FSL CAAM support for hw_random API"); +-MODULE_AUTHOR("Freescale Semiconductor - NMG"); --- a/drivers/crypto/caam/compat.h +++ b/drivers/crypto/caam/compat.h @@ -17,6 +17,7 @@ @@ -10578,7 +12574,13 @@ Signed-off-by: Biwen Li #include #include #include -@@ -38,6 +39,7 @@ +@@ -34,10 +35,13 @@ + #include + #include + #include ++#include ++#include + #include #include #include #include @@ -10588,7 +12590,26 @@ Signed-off-by: Biwen Li #include --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c -@@ -27,6 +27,8 @@ EXPORT_SYMBOL(caam_imx); +@@ -2,6 +2,7 @@ + * Controller-level driver, kernel property detection, initialization + * + * Copyright 2008-2012 Freescale Semiconductor, Inc. ++ * Copyright 2018 NXP + */ + + #include +@@ -16,17 +17,15 @@ + #include "desc_constr.h" + #include "ctrl.h" + +-bool caam_little_end; +-EXPORT_SYMBOL(caam_little_end); + bool caam_dpaa2; + EXPORT_SYMBOL(caam_dpaa2); +-bool caam_imx; +-EXPORT_SYMBOL(caam_imx); + + #ifdef CONFIG_CAAM_QI #include "qi.h" #endif @@ -10597,7 +12618,61 @@ Signed-off-by: Biwen Li /* * i.MX targets tend to have clock control subsystems that can * enable/disable clocking to our device. -@@ -332,6 +334,9 @@ static int caam_remove(struct platform_d +@@ -105,7 +104,7 @@ static inline int run_descriptor_deco0(s + struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl; + struct caam_deco __iomem *deco = ctrlpriv->deco; + unsigned int timeout = 100000; +- u32 deco_dbg_reg, flags; ++ u32 deco_dbg_reg, deco_state, flags; + int i; + + +@@ -148,13 +147,22 @@ static inline int run_descriptor_deco0(s + timeout = 10000000; + do { + deco_dbg_reg = rd_reg32(&deco->desc_dbg); ++ ++ if (ctrlpriv->era < 10) ++ deco_state = (deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) >> ++ DESC_DBG_DECO_STAT_SHIFT; ++ else ++ deco_state = (rd_reg32(&deco->dbg_exec) & ++ DESC_DER_DECO_STAT_MASK) >> ++ DESC_DER_DECO_STAT_SHIFT; ++ + /* + * If an error occured in the descriptor, then + * the DECO status field will be set to 0x0D + */ +- if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) == +- DESC_DBG_DECO_STAT_HOST_ERR) ++ if (deco_state == DECO_STAT_HOST_ERR) + break; ++ + cpu_relax(); + } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout); + +@@ -316,15 +324,15 @@ static int caam_remove(struct platform_d + of_platform_depopulate(ctrldev); + + #ifdef CONFIG_CAAM_QI +- if (ctrlpriv->qidev) +- caam_qi_shutdown(ctrlpriv->qidev); ++ if (ctrlpriv->qi_init) ++ caam_qi_shutdown(ctrldev); + #endif + + /* + * De-initialize RNG state handles initialized by this driver. +- * In case of DPAA 2.x, RNG is managed by MC firmware. ++ * In case of SoCs with Management Complex, RNG is managed by MC f/w. + */ +- if (!caam_dpaa2 && ctrlpriv->rng4_sh_init) ++ if (!ctrlpriv->mc_en && ctrlpriv->rng4_sh_init) + deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init); + + /* Shut down debug views */ +@@ -332,6 +340,9 @@ static int caam_remove(struct platform_d debugfs_remove_recursive(ctrlpriv->dfs_root); #endif @@ -10607,7 +12682,7 @@ Signed-off-by: Biwen Li /* Unmap controller region */ iounmap(ctrl); -@@ -433,6 +438,10 @@ static int caam_probe(struct platform_de +@@ -433,6 +444,10 @@ static int caam_probe(struct platform_de {.family = "Freescale i.MX"}, {}, }; @@ -10618,19 +12693,223 @@ Signed-off-by: Biwen Li struct device *dev; struct device_node *nprop, *np; struct caam_ctrl __iomem *ctrl; -@@ -615,6 +624,8 @@ static int caam_probe(struct platform_de - goto iounmap_ctrl; +@@ -442,7 +457,7 @@ static int caam_probe(struct platform_de + struct caam_perfmon *perfmon; + #endif + u32 scfgr, comp_params; +- u32 cha_vid_ls; ++ u8 rng_vid; + int pg_size; + int BLOCK_OFFSET = 0; + +@@ -454,15 +469,54 @@ static int caam_probe(struct platform_de + dev_set_drvdata(dev, ctrlpriv); + nprop = pdev->dev.of_node; + ++ /* Get configuration properties from device tree */ ++ /* First, get register page */ ++ ctrl = of_iomap(nprop, 0); ++ if (!ctrl) { ++ dev_err(dev, "caam: of_iomap() failed\n"); ++ return -ENOMEM; ++ } ++ ++ caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) & ++ (CSTA_PLEND | CSTA_ALT_PLEND)); + caam_imx = (bool)soc_device_match(imx_soc); + ++ comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms); ++ caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2); ++ ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK); ++ ++#ifdef CONFIG_CAAM_QI ++ /* If (DPAA 1.x) QI present, check whether dependencies are available */ ++ if (ctrlpriv->qi_present && !caam_dpaa2) { ++ ret = qman_is_probed(); ++ if (!ret) { ++ ret = -EPROBE_DEFER; ++ goto iounmap_ctrl; ++ } else if (ret < 0) { ++ dev_err(dev, "failing probe due to qman probe error\n"); ++ ret = -ENODEV; ++ goto iounmap_ctrl; ++ } ++ ++ ret = qman_portals_probed(); ++ if (!ret) { ++ ret = -EPROBE_DEFER; ++ goto iounmap_ctrl; ++ } else if (ret < 0) { ++ dev_err(dev, "failing probe due to qman portals probe error\n"); ++ ret = -ENODEV; ++ goto iounmap_ctrl; ++ } ++ } ++#endif ++ + /* Enable clocking */ + clk = caam_drv_identify_clk(&pdev->dev, "ipg"); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(&pdev->dev, + "can't identify CAAM ipg clk: %d\n", ret); +- return ret; ++ goto iounmap_ctrl; + } + ctrlpriv->caam_ipg = clk; + +@@ -471,7 +525,7 @@ static int caam_probe(struct platform_de + ret = PTR_ERR(clk); + dev_err(&pdev->dev, + "can't identify CAAM mem clk: %d\n", ret); +- return ret; ++ goto iounmap_ctrl; + } + ctrlpriv->caam_mem = clk; + +@@ -480,7 +534,7 @@ static int caam_probe(struct platform_de + ret = PTR_ERR(clk); + dev_err(&pdev->dev, + "can't identify CAAM aclk clk: %d\n", ret); +- return ret; ++ goto iounmap_ctrl; + } + ctrlpriv->caam_aclk = clk; + +@@ -490,7 +544,7 @@ static int caam_probe(struct platform_de + ret = PTR_ERR(clk); + dev_err(&pdev->dev, + "can't identify CAAM emi_slow clk: %d\n", ret); +- return ret; ++ goto iounmap_ctrl; + } + ctrlpriv->caam_emi_slow = clk; + } +@@ -498,7 +552,7 @@ static int caam_probe(struct platform_de + ret = clk_prepare_enable(ctrlpriv->caam_ipg); + if (ret < 0) { + dev_err(&pdev->dev, "can't enable CAAM ipg clock: %d\n", ret); +- return ret; ++ goto iounmap_ctrl; + } + + ret = clk_prepare_enable(ctrlpriv->caam_mem); +@@ -523,25 +577,10 @@ static int caam_probe(struct platform_de + } + } + +- /* Get configuration properties from device tree */ +- /* First, get register page */ +- ctrl = of_iomap(nprop, 0); +- if (ctrl == NULL) { +- dev_err(dev, "caam: of_iomap() failed\n"); +- ret = -ENOMEM; +- goto disable_caam_emi_slow; +- } +- +- caam_little_end = !(bool)(rd_reg32(&ctrl->perfmon.status) & +- (CSTA_PLEND | CSTA_ALT_PLEND)); +- +- /* Finding the page size for using the CTPR_MS register */ +- comp_params = rd_reg32(&ctrl->perfmon.comp_parms_ms); +- pg_size = (comp_params & CTPR_MS_PG_SZ_MASK) >> CTPR_MS_PG_SZ_SHIFT; +- + /* Allocating the BLOCK_OFFSET based on the supported page size on + * the platform + */ ++ pg_size = (comp_params & CTPR_MS_PG_SZ_MASK) >> CTPR_MS_PG_SZ_SHIFT; + if (pg_size == 0) + BLOCK_OFFSET = PG_SIZE_4K; + else +@@ -563,11 +602,14 @@ static int caam_probe(struct platform_de + /* + * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel, + * long pointers in master configuration register. +- * In case of DPAA 2.x, Management Complex firmware performs ++ * In case of SoCs with Management Complex, MC f/w performs + * the configuration. + */ +- caam_dpaa2 = !!(comp_params & CTPR_MS_DPAA2); +- if (!caam_dpaa2) ++ np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-mc"); ++ ctrlpriv->mc_en = !!np; ++ of_node_put(np); ++ ++ if (!ctrlpriv->mc_en) + clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR, + MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF | + MCFGR_WDENABLE | MCFGR_LARGE_BURST | +@@ -612,14 +654,11 @@ static int caam_probe(struct platform_de + } + if (ret) { + dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret); +- goto iounmap_ctrl; ++ goto disable_caam_emi_slow; } +- ret = of_platform_populate(nprop, caam_match, NULL, dev); +- if (ret) { +- dev_err(dev, "JR platform devices creation error\n"); +- goto iounmap_ctrl; +- } + ctrlpriv->era = caam_get_era(); ++ ctrlpriv->domain = iommu_get_domain_for_dev(dev); + + #ifdef CONFIG_DEBUG_FS + /* +@@ -633,21 +672,7 @@ static int caam_probe(struct platform_de + ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root); + #endif + +- ring = 0; +- for_each_available_child_of_node(nprop, np) +- if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || +- of_device_is_compatible(np, "fsl,sec4.0-job-ring")) { +- ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *) +- ((__force uint8_t *)ctrl + +- (ring + JR_BLOCK_NUMBER) * +- BLOCK_OFFSET +- ); +- ctrlpriv->total_jobrs++; +- ring++; +- } +- + /* Check to see if (DPAA 1.x) QI present. If so, enable */ +- ctrlpriv->qi_present = !!(comp_params & CTPR_MS_QI_MASK); + if (ctrlpriv->qi_present && !caam_dpaa2) { + ctrlpriv->qi = (struct caam_queue_if __iomem __force *) + ((__force uint8_t *)ctrl + +@@ -664,6 +689,25 @@ static int caam_probe(struct platform_de + #endif + } + ++ ret = of_platform_populate(nprop, caam_match, NULL, dev); ++ if (ret) { ++ dev_err(dev, "JR platform devices creation error\n"); ++ goto shutdown_qi; ++ } ++ ++ ring = 0; ++ for_each_available_child_of_node(nprop, np) ++ if (of_device_is_compatible(np, "fsl,sec-v4.0-job-ring") || ++ of_device_is_compatible(np, "fsl,sec4.0-job-ring")) { ++ ctrlpriv->jr[ring] = (struct caam_job_ring __iomem __force *) ++ ((__force uint8_t *)ctrl + ++ (ring + JR_BLOCK_NUMBER) * ++ BLOCK_OFFSET ++ ); ++ ctrlpriv->total_jobrs++; ++ ring++; ++ } + - ret = of_platform_populate(nprop, caam_match, NULL, dev); - if (ret) { - dev_err(dev, "JR platform devices creation error\n"); -@@ -671,6 +682,16 @@ static int caam_probe(struct platform_de + /* If no QI and no rings specified, quit and go home */ + if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) { + dev_err(dev, "no queues configured, terminating\n"); +@@ -671,15 +715,29 @@ static int caam_probe(struct platform_de goto caam_remove; } +- cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls); + caam_dma_pdev_info.parent = dev; + caam_dma_pdev_info.dma_mask = dma_get_mask(dev); + caam_dma_dev = platform_device_register_full(&caam_dma_pdev_info); @@ -10641,21 +12920,73 @@ Signed-off-by: Biwen Li + set_dma_ops(&caam_dma_dev->dev, get_dma_ops(dev)); + } + - cha_vid_ls = rd_reg32(&ctrl->perfmon.cha_id_ls); ++ if (ctrlpriv->era < 10) ++ rng_vid = (rd_reg32(&ctrl->perfmon.cha_id_ls) & ++ CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT; ++ else ++ rng_vid = (rd_reg32(&ctrl->vreg.rng) & CHA_VER_VID_MASK) >> ++ CHA_VER_VID_SHIFT; /* -@@ -746,7 +767,7 @@ static int caam_probe(struct platform_de + * If SEC has RNG version >= 4 and RNG state handle has not been + * already instantiated, do RNG instantiation +- * In case of DPAA 2.x, RNG is managed by MC firmware. ++ * In case of SoCs with Management Complex, RNG is managed by MC f/w. + */ +- if (!caam_dpaa2 && +- (cha_vid_ls & CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT >= 4) { ++ if (!ctrlpriv->mc_en && rng_vid >= 4) { + ctrlpriv->rng4_sh_init = + rd_reg32(&ctrl->r4tst[0].rdsta); + /* +@@ -746,10 +804,9 @@ static int caam_probe(struct platform_de /* Report "alive" for developer to see */ dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id, - caam_get_era()); +- dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n", +- ctrlpriv->total_jobrs, ctrlpriv->qi_present, +- caam_dpaa2 ? "yes" : "no"); + ctrlpriv->era); - dev_info(dev, "job rings = %d, qi = %d, dpaa2 = %s\n", - ctrlpriv->total_jobrs, ctrlpriv->qi_present, - caam_dpaa2 ? "yes" : "no"); ++ dev_info(dev, "job rings = %d, qi = %d\n", ++ ctrlpriv->total_jobrs, ctrlpriv->qi_present); + + #ifdef CONFIG_DEBUG_FS + debugfs_create_file("rq_dequeued", S_IRUSR | S_IRGRP | S_IROTH, +@@ -816,8 +873,11 @@ caam_remove: + caam_remove(pdev); + return ret; + +-iounmap_ctrl: +- iounmap(ctrl); ++shutdown_qi: ++#ifdef CONFIG_CAAM_QI ++ if (ctrlpriv->qi_init) ++ caam_qi_shutdown(dev); ++#endif + disable_caam_emi_slow: + if (ctrlpriv->caam_emi_slow) + clk_disable_unprepare(ctrlpriv->caam_emi_slow); +@@ -827,6 +887,8 @@ disable_caam_mem: + clk_disable_unprepare(ctrlpriv->caam_mem); + disable_caam_ipg: + clk_disable_unprepare(ctrlpriv->caam_ipg); ++iounmap_ctrl: ++ iounmap(ctrl); + return ret; + } + --- a/drivers/crypto/caam/desc.h +++ b/drivers/crypto/caam/desc.h -@@ -42,6 +42,7 @@ +@@ -4,6 +4,7 @@ + * Definitions to support CAAM descriptor instruction generation + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. ++ * Copyright 2018 NXP + */ + + #ifndef DESC_H +@@ -42,6 +43,7 @@ #define CMD_SEQ_LOAD (0x03 << CMD_SHIFT) #define CMD_FIFO_LOAD (0x04 << CMD_SHIFT) #define CMD_SEQ_FIFO_LOAD (0x05 << CMD_SHIFT) @@ -10663,7 +12994,28 @@ Signed-off-by: Biwen Li #define CMD_STORE (0x0a << CMD_SHIFT) #define CMD_SEQ_STORE (0x0b << CMD_SHIFT) #define CMD_FIFO_STORE (0x0c << CMD_SHIFT) -@@ -355,6 +356,7 @@ +@@ -242,6 +244,7 @@ + #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_SM (0x71 << LDST_SRCDST_SHIFT) + #define LDST_SRCDST_WORD_INFO_FIFO (0x7a << LDST_SRCDST_SHIFT) + + /* Offset in source/destination */ +@@ -284,6 +287,12 @@ + #define LDLEN_SET_OFIFO_OFFSET_SHIFT 0 + #define LDLEN_SET_OFIFO_OFFSET_MASK (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT) + ++/* Special Length definitions when dst=sm, nfifo-{sm,m} */ ++#define LDLEN_MATH0 0 ++#define LDLEN_MATH1 1 ++#define LDLEN_MATH2 2 ++#define LDLEN_MATH3 3 ++ + /* + * FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE + * Command Constructs +@@ -355,6 +364,7 @@ #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) @@ -10671,7 +13023,7 @@ Signed-off-by: Biwen Li /* Other types. Need to OR in last/flush bits as desired */ #define FIFOLD_TYPE_MSG_MASK (0x38 << FIFOLD_TYPE_SHIFT) -@@ -408,6 +410,7 @@ +@@ -408,6 +418,7 @@ #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) @@ -10679,7 +13031,7 @@ Signed-off-by: Biwen Li #define FIFOST_TYPE_SKIP (0x3f << FIFOST_TYPE_SHIFT) /* -@@ -444,6 +447,18 @@ +@@ -444,6 +455,18 @@ #define OP_PCLID_DSAVERIFY (0x16 << OP_PCLID_SHIFT) #define OP_PCLID_RSAENC_PUBKEY (0x18 << OP_PCLID_SHIFT) #define OP_PCLID_RSADEC_PRVKEY (0x19 << OP_PCLID_SHIFT) @@ -10698,7 +13050,7 @@ Signed-off-by: Biwen Li /* Assuming OP_TYPE = OP_TYPE_DECAP_PROTOCOL/ENCAP_PROTOCOL */ #define OP_PCLID_IPSEC (0x01 << OP_PCLID_SHIFT) -@@ -1093,6 +1108,22 @@ +@@ -1093,6 +1116,22 @@ /* MacSec protinfos */ #define OP_PCL_MACSEC 0x0001 @@ -10721,7 +13073,60 @@ Signed-off-by: Biwen Li /* PKI unidirectional protocol protinfo bits */ #define OP_PCL_PKPROT_TEST 0x0008 #define OP_PCL_PKPROT_DECRYPT 0x0004 -@@ -1440,10 +1471,11 @@ +@@ -1105,6 +1144,12 @@ + #define OP_ALG_TYPE_CLASS1 (2 << OP_ALG_TYPE_SHIFT) + #define OP_ALG_TYPE_CLASS2 (4 << OP_ALG_TYPE_SHIFT) + ++/* version register fields */ ++#define OP_VER_CCHA_NUM 0x000000ff /* Number CCHAs instantiated */ ++#define OP_VER_CCHA_MISC 0x0000ff00 /* CCHA Miscellaneous Information */ ++#define OP_VER_CCHA_REV 0x00ff0000 /* CCHA Revision Number */ ++#define OP_VER_CCHA_VID 0xff000000 /* CCHA Version ID */ ++ + #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) +@@ -1124,6 +1169,8 @@ + #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_ALGSEL_CHACHA20 (0xD0 << OP_ALG_ALGSEL_SHIFT) ++#define OP_ALG_ALGSEL_POLY1305 (0xE0 << OP_ALG_ALGSEL_SHIFT) + + #define OP_ALG_AAI_SHIFT 4 + #define OP_ALG_AAI_MASK (0x1ff << OP_ALG_AAI_SHIFT) +@@ -1171,6 +1218,11 @@ + #define OP_ALG_AAI_RNG4_AI (0x80 << OP_ALG_AAI_SHIFT) + #define OP_ALG_AAI_RNG4_SK (0x100 << OP_ALG_AAI_SHIFT) + ++/* Chacha20 AAI set */ ++#define OP_ALG_AAI_AEAD (0x002 << OP_ALG_AAI_SHIFT) ++#define OP_ALG_AAI_KEYSTREAM (0x001 << OP_ALG_AAI_SHIFT) ++#define OP_ALG_AAI_BC8 (0x008 << 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) +@@ -1359,6 +1411,7 @@ + #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_SRC_AUX_ABLK (0x0a << MOVE_SRC_SHIFT) + + #define MOVE_DEST_SHIFT 16 + #define MOVE_DEST_MASK (0x0f << MOVE_DEST_SHIFT) +@@ -1385,6 +1438,10 @@ + + #define MOVELEN_MRSEL_SHIFT 0 + #define MOVELEN_MRSEL_MASK (0x3 << MOVE_LEN_SHIFT) ++#define MOVELEN_MRSEL_MATH0 (0 << MOVELEN_MRSEL_SHIFT) ++#define MOVELEN_MRSEL_MATH1 (1 << MOVELEN_MRSEL_SHIFT) ++#define MOVELEN_MRSEL_MATH2 (2 << MOVELEN_MRSEL_SHIFT) ++#define MOVELEN_MRSEL_MATH3 (3 << MOVELEN_MRSEL_SHIFT) + + /* + * MATH Command Constructs +@@ -1440,10 +1497,11 @@ #define MATH_SRC1_REG2 (0x02 << MATH_SRC1_SHIFT) #define MATH_SRC1_REG3 (0x03 << MATH_SRC1_SHIFT) #define MATH_SRC1_IMM (0x04 << MATH_SRC1_SHIFT) @@ -10734,7 +13139,7 @@ Signed-off-by: Biwen Li /* Destination selectors */ #define MATH_DEST_SHIFT 8 -@@ -1452,6 +1484,7 @@ +@@ -1452,6 +1510,7 @@ #define MATH_DEST_REG1 (0x01 << MATH_DEST_SHIFT) #define MATH_DEST_REG2 (0x02 << MATH_DEST_SHIFT) #define MATH_DEST_REG3 (0x03 << MATH_DEST_SHIFT) @@ -10742,7 +13147,15 @@ Signed-off-by: Biwen Li #define MATH_DEST_SEQINLEN (0x08 << MATH_DEST_SHIFT) #define MATH_DEST_SEQOUTLEN (0x09 << MATH_DEST_SHIFT) #define MATH_DEST_VARSEQINLEN (0x0a << MATH_DEST_SHIFT) -@@ -1624,4 +1657,31 @@ +@@ -1560,6 +1619,7 @@ + #define NFIFOENTRY_DTYPE_IV (0x2 << NFIFOENTRY_DTYPE_SHIFT) + #define NFIFOENTRY_DTYPE_SAD (0x3 << NFIFOENTRY_DTYPE_SHIFT) + #define NFIFOENTRY_DTYPE_ICV (0xA << NFIFOENTRY_DTYPE_SHIFT) ++#define NFIFOENTRY_DTYPE_POLY (0xB << NFIFOENTRY_DTYPE_SHIFT) + #define NFIFOENTRY_DTYPE_SKIP (0xE << NFIFOENTRY_DTYPE_SHIFT) + #define NFIFOENTRY_DTYPE_MSG (0xF << NFIFOENTRY_DTYPE_SHIFT) + +@@ -1624,4 +1684,31 @@ /* Frame Descriptor Command for Replacement Job Descriptor */ #define FD_CMD_REPLACE_JOB_DESC 0x20000000 @@ -10794,15 +13207,16 @@ Signed-off-by: Biwen Li u32 command) { append_cmd(desc, command | IMMEDIATE | len); -@@ -189,6 +189,7 @@ static inline u32 *append_##cmd(u32 * co +@@ -189,6 +189,8 @@ static inline u32 *append_##cmd(u32 * co } APPEND_CMD_RET(jump, JUMP) APPEND_CMD_RET(move, MOVE) +APPEND_CMD_RET(moveb, MOVEB) ++APPEND_CMD_RET(move_len, MOVE_LEN) static inline void set_jump_tgt_here(u32 * const desc, u32 *jump_cmd) { -@@ -271,7 +272,7 @@ APPEND_SEQ_PTR_INTLEN(in, IN) +@@ -271,7 +273,7 @@ APPEND_SEQ_PTR_INTLEN(in, IN) APPEND_SEQ_PTR_INTLEN(out, OUT) #define APPEND_CMD_PTR_TO_IMM(cmd, op) \ @@ -10811,7 +13225,7 @@ Signed-off-by: Biwen Li unsigned int len, u32 options) \ { \ PRINT_POS; \ -@@ -312,7 +313,7 @@ APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_ +@@ -312,7 +314,7 @@ APPEND_CMD_PTR_LEN(seq_out_ptr, SEQ_OUT_ * from length of immediate data provided, e.g., split keys */ #define APPEND_CMD_PTR_TO_IMM2(cmd, op) \ @@ -10820,7 +13234,20 @@ Signed-off-by: Biwen Li unsigned int data_len, \ unsigned int len, u32 options) \ { \ -@@ -452,7 +453,7 @@ struct alginfo { +@@ -327,7 +329,11 @@ static inline void append_##cmd##_imm_## + u32 options) \ + { \ + PRINT_POS; \ +- append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \ ++ if (options & LDST_LEN_MASK) \ ++ append_cmd(desc, CMD_##op | IMMEDIATE | options); \ ++ else \ ++ append_cmd(desc, CMD_##op | IMMEDIATE | options | \ ++ sizeof(type)); \ + append_cmd(desc, immediate); \ + } + APPEND_CMD_RAW_IMM(load, LOAD, u32); +@@ -452,7 +458,7 @@ struct alginfo { unsigned int keylen_pad; union { dma_addr_t key_dma; @@ -10829,7 +13256,7 @@ Signed-off-by: Biwen Li }; bool key_inline; }; -@@ -496,4 +497,45 @@ static inline int desc_inline_query(unsi +@@ -496,4 +502,45 @@ static inline int desc_inline_query(unsi return (rem_bytes >= 0) ? 0 : -1; } @@ -12471,7 +14898,20 @@ Signed-off-by: Biwen Li +#endif /* _DPSECI_CMD_H_ */ --- a/drivers/crypto/caam/error.c +++ b/drivers/crypto/caam/error.c -@@ -108,6 +108,54 @@ static const struct { +@@ -50,6 +50,12 @@ void caam_dump_sg(const char *level, con + #endif /* DEBUG */ + EXPORT_SYMBOL(caam_dump_sg); + ++bool caam_little_end; ++EXPORT_SYMBOL(caam_little_end); ++ ++bool caam_imx; ++EXPORT_SYMBOL(caam_imx); ++ + static const struct { + u8 value; + const char *error_text; +@@ -108,6 +114,54 @@ static const struct { { 0xF1, "3GPP HFN matches or exceeds the Threshold" }, }; @@ -12526,7 +14966,7 @@ Signed-off-by: Biwen Li static const char * const cha_id_list[] = { "", "AES", -@@ -236,6 +284,27 @@ static void report_deco_status(struct de +@@ -236,6 +290,27 @@ static void report_deco_status(struct de status, error, idx_str, idx, err_str, err_err_code); } @@ -12554,7 +14994,7 @@ Signed-off-by: Biwen Li static void report_jr_status(struct device *jrdev, const u32 status, const char *error) { -@@ -250,7 +319,7 @@ static void report_cond_code_status(stru +@@ -250,7 +325,7 @@ static void report_cond_code_status(stru status, error, __func__); } @@ -12563,7 +15003,7 @@ Signed-off-by: Biwen Li { static const struct stat_src { void (*report_ssed)(struct device *jrdev, const u32 status, -@@ -262,7 +331,7 @@ void caam_jr_strstatus(struct device *jr +@@ -262,7 +337,7 @@ void caam_jr_strstatus(struct device *jr { report_ccb_status, "CCB" }, { report_jump_status, "Jump" }, { report_deco_status, "DECO" }, @@ -12572,7 +15012,7 @@ Signed-off-by: Biwen Li { report_jr_status, "Job Ring" }, { report_cond_code_status, "Condition Code" }, { NULL, NULL }, -@@ -288,4 +357,4 @@ void caam_jr_strstatus(struct device *jr +@@ -288,4 +363,4 @@ void caam_jr_strstatus(struct device *jr else dev_err(jrdev, "%d: unknown error source\n", ssrc); } @@ -12595,17 +15035,140 @@ Signed-off-by: Biwen Li int rowsize, int groupsize, struct scatterlist *sg, --- a/drivers/crypto/caam/intern.h +++ b/drivers/crypto/caam/intern.h -@@ -84,6 +84,7 @@ struct caam_drv_private { +@@ -65,10 +65,6 @@ struct caam_drv_private_jr { + * Driver-private storage for a single CAAM block instance + */ + struct caam_drv_private { +-#ifdef CONFIG_CAAM_QI +- struct device *qidev; +-#endif +- + /* Physical-presence section */ + struct caam_ctrl __iomem *ctrl; /* controller region */ + struct caam_deco __iomem *deco; /* DECO/CCB views */ +@@ -76,14 +72,21 @@ struct caam_drv_private { + struct caam_queue_if __iomem *qi; /* QI control region */ + struct caam_job_ring __iomem *jr[4]; /* JobR's register space */ + ++ struct iommu_domain *domain; ++ + /* + * Detected geometry block. Filled in from device tree if powerpc, + * or from register-based version detection code + */ + u8 total_jobrs; /* Total Job Rings in device */ u8 qi_present; /* Nonzero if QI present in device */ ++#ifdef CONFIG_CAAM_QI ++ u8 qi_init; /* Nonzero if QI has been initialized */ ++#endif ++ u8 mc_en; /* Nonzero if MC f/w is active */ int secvio_irq; /* Security violation interrupt number */ int virt_en; /* Virtualization enabled in CAAM */ + int era; /* CAAM Era (internal HW revision) */ #define RNG4_MAX_HANDLES 2 /* RNG4 block */ +@@ -108,8 +111,95 @@ struct caam_drv_private { + #endif + }; + +-void caam_jr_algapi_init(struct device *dev); +-void caam_jr_algapi_remove(struct device *dev); ++#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API ++ ++int caam_algapi_init(struct device *dev); ++void caam_algapi_exit(void); ++ ++#else ++ ++static inline int caam_algapi_init(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline void caam_algapi_exit(void) ++{ ++} ++ ++#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API */ ++ ++#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API ++ ++int caam_algapi_hash_init(struct device *dev); ++void caam_algapi_hash_exit(void); ++ ++#else ++ ++static inline int caam_algapi_hash_init(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline void caam_algapi_hash_exit(void) ++{ ++} ++ ++#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API */ ++ ++#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API ++ ++int caam_pkc_init(struct device *dev); ++void caam_pkc_exit(void); ++ ++#else ++ ++static inline int caam_pkc_init(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline void caam_pkc_exit(void) ++{ ++} ++ ++#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API */ ++ ++#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API ++ ++int caam_rng_init(struct device *dev); ++void caam_rng_exit(void); ++ ++#else ++ ++static inline int caam_rng_init(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline void caam_rng_exit(void) ++{ ++} ++ ++#endif /* CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API */ ++ ++#ifdef CONFIG_CAAM_QI ++ ++int caam_qi_algapi_init(struct device *dev); ++void caam_qi_algapi_exit(void); ++ ++#else ++ ++static inline int caam_qi_algapi_init(struct device *dev) ++{ ++ return 0; ++} ++ ++static inline void caam_qi_algapi_exit(void) ++{ ++} ++ ++#endif /* CONFIG_CAAM_QI */ + + #ifdef CONFIG_DEBUG_FS + static int caam_debugfs_u64_get(void *data, u64 *val) --- a/drivers/crypto/caam/jr.c +++ b/drivers/crypto/caam/jr.c -@@ -23,6 +23,14 @@ struct jr_driver_data { +@@ -23,6 +23,52 @@ struct jr_driver_data { static struct jr_driver_data driver_data; @@ -12616,11 +15179,59 @@ Signed-off-by: Biwen Li + return jr_driver_probed; +} +EXPORT_SYMBOL(caam_jr_driver_probed); ++ ++static DEFINE_MUTEX(algs_lock); ++static unsigned int active_devs; ++ ++static void register_algs(struct device *dev) ++{ ++ mutex_lock(&algs_lock); ++ ++ if (++active_devs != 1) ++ goto algs_unlock; ++ ++ caam_algapi_init(dev); ++ caam_algapi_hash_init(dev); ++ caam_pkc_init(dev); ++ caam_rng_init(dev); ++ caam_qi_algapi_init(dev); ++ ++algs_unlock: ++ mutex_unlock(&algs_lock); ++} ++ ++static void unregister_algs(void) ++{ ++ mutex_lock(&algs_lock); ++ ++ if (--active_devs != 0) ++ goto algs_unlock; ++ ++ caam_qi_algapi_exit(); ++ ++ caam_rng_exit(); ++ caam_pkc_exit(); ++ caam_algapi_hash_exit(); ++ caam_algapi_exit(); ++ ++algs_unlock: ++ mutex_unlock(&algs_lock); ++} + static int caam_reset_hw_jr(struct device *dev) { struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); -@@ -119,6 +127,8 @@ static int caam_jr_remove(struct platfor +@@ -108,6 +154,9 @@ static int caam_jr_remove(struct platfor + return -EBUSY; + } + ++ /* Unregister JR-based RNG & crypto algorithms */ ++ unregister_algs(); ++ + /* Remove the node from Physical JobR list maintained by driver */ + spin_lock(&driver_data.jr_alloc_lock); + list_del(&jrpriv->list_node); +@@ -119,6 +168,8 @@ static int caam_jr_remove(struct platfor dev_err(jrdev, "Failed to shut down job ring\n"); irq_dispose_mapping(jrpriv->irq); @@ -12629,7 +15240,7 @@ Signed-off-by: Biwen Li return ret; } -@@ -282,6 +292,36 @@ struct device *caam_jr_alloc(void) +@@ -282,6 +333,36 @@ struct device *caam_jr_alloc(void) EXPORT_SYMBOL(caam_jr_alloc); /** @@ -12666,10 +15277,11 @@ Signed-off-by: Biwen Li * caam_jr_free() - Free the Job Ring * @rdev - points to the dev that identifies the Job ring to * be released. -@@ -539,6 +579,8 @@ static int caam_jr_probe(struct platform +@@ -539,6 +620,9 @@ static int caam_jr_probe(struct platform atomic_set(&jrpriv->tfm_count, 0); ++ register_algs(jrdev->parent); + jr_driver_probed++; + return 0; @@ -12776,7 +15388,32 @@ Signed-off-by: Biwen Li #include "regs.h" #include "qi.h" -@@ -105,23 +105,21 @@ static struct kmem_cache *qi_cache; +@@ -58,11 +58,9 @@ static DEFINE_PER_CPU(int, last_cpu); + /* + * caam_qi_priv - CAAM QI backend private params + * @cgr: QMan congestion group +- * @qi_pdev: platform device for QI backend + */ + struct caam_qi_priv { + struct qman_cgr cgr; +- struct platform_device *qi_pdev; + }; + + static struct caam_qi_priv qipriv ____cacheline_aligned; +@@ -102,26 +100,34 @@ static int mod_init_cpu; + */ + static struct kmem_cache *qi_cache; + ++static void *caam_iova_to_virt(struct iommu_domain *domain, ++ dma_addr_t iova_addr) ++{ ++ phys_addr_t phys_addr; ++ ++ phys_addr = domain ? iommu_iova_to_phys(domain, iova_addr) : iova_addr; ++ ++ return phys_to_virt(phys_addr); ++} ++ int caam_qi_enqueue(struct device *qidev, struct caam_drv_req *req) { struct qm_fd fd; @@ -12806,7 +15443,7 @@ Signed-off-by: Biwen Li if (likely(!ret)) return 0; -@@ -137,7 +135,7 @@ int caam_qi_enqueue(struct device *qidev +@@ -137,20 +143,21 @@ int caam_qi_enqueue(struct device *qidev EXPORT_SYMBOL(caam_qi_enqueue); static void caam_fq_ern_cb(struct qman_portal *qm, struct qman_fq *fq, @@ -12815,7 +15452,8 @@ Signed-off-by: Biwen Li { const struct qm_fd *fd; struct caam_drv_req *drv_req; -@@ -145,7 +143,7 @@ static void caam_fq_ern_cb(struct qman_p + struct device *qidev = &(raw_cpu_ptr(&pcpu_qipriv)->net_dev.dev); ++ struct caam_drv_private *priv = dev_get_drvdata(qidev); fd = &msg->ern.fd; @@ -12824,7 +15462,13 @@ Signed-off-by: Biwen Li dev_err(qidev, "Non-compound FD from CAAM\n"); return; } -@@ -180,20 +178,22 @@ static struct qman_fq *create_caam_req_f + +- drv_req = (struct caam_drv_req *)phys_to_virt(qm_fd_addr_get64(fd)); ++ drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd)); + if (!drv_req) { + dev_err(qidev, + "Can't find original request for CAAM response\n"); +@@ -180,20 +187,22 @@ static struct qman_fq *create_caam_req_f req_fq->cb.fqs = NULL; ret = qman_create_fq(0, QMAN_FQ_FLAG_DYNAMIC_FQID | @@ -12856,7 +15500,7 @@ Signed-off-by: Biwen Li opts.fqd.cgid = qipriv.cgr.cgrid; ret = qman_init_fq(req_fq, fq_sched_flag, &opts); -@@ -207,7 +207,7 @@ static struct qman_fq *create_caam_req_f +@@ -207,7 +216,7 @@ static struct qman_fq *create_caam_req_f return req_fq; init_req_fq_fail: @@ -12865,7 +15509,7 @@ Signed-off-by: Biwen Li create_req_fq_fail: kfree(req_fq); return ERR_PTR(ret); -@@ -275,7 +275,7 @@ empty_fq: +@@ -275,7 +284,7 @@ empty_fq: if (ret) dev_err(qidev, "OOS of FQID: %u failed\n", fq->fqid); @@ -12874,7 +15518,7 @@ Signed-off-by: Biwen Li kfree(fq); return ret; -@@ -292,7 +292,7 @@ static int empty_caam_fq(struct qman_fq +@@ -292,7 +301,7 @@ static int empty_caam_fq(struct qman_fq if (ret) return ret; @@ -12883,11 +15527,29 @@ Signed-off-by: Biwen Li break; msleep(20); -@@ -572,22 +572,27 @@ static enum qman_cb_dqrr_result caam_rsp +@@ -495,7 +504,7 @@ EXPORT_SYMBOL(caam_drv_ctx_rel); + int caam_qi_shutdown(struct device *qidev) + { + int i, ret; +- struct caam_qi_priv *priv = dev_get_drvdata(qidev); ++ struct caam_qi_priv *priv = &qipriv; + const cpumask_t *cpus = qman_affine_cpus(); + struct cpumask old_cpumask = current->cpus_allowed; + +@@ -528,7 +537,6 @@ int caam_qi_shutdown(struct device *qide + /* Now that we're done with the CGRs, restore the cpus allowed mask */ + set_cpus_allowed_ptr(current, &old_cpumask); + +- platform_device_unregister(priv->qi_pdev); + return ret; + } + +@@ -572,22 +580,28 @@ static enum qman_cb_dqrr_result caam_rsp struct caam_drv_req *drv_req; const struct qm_fd *fd; struct device *qidev = &(raw_cpu_ptr(&pcpu_qipriv)->net_dev.dev); - u32 status; ++ struct caam_drv_private *priv = dev_get_drvdata(qidev); if (caam_qi_napi_schedule(p, caam_napi)) return qman_cb_dqrr_stop; @@ -12899,25 +15561,25 @@ Signed-off-by: Biwen Li + if (unlikely(fd->status)) { + u32 ssrc = fd->status & JRSTA_SSRC_MASK; + u8 err_id = fd->status & JRSTA_CCBERR_ERRID_MASK; -+ + +- if (unlikely(qm_fd_get_format(fd) != qm_fd_compound)) { + if (ssrc != JRSTA_SSRC_CCB_ERROR || + err_id != JRSTA_CCBERR_ERRID_ICVCHK) + dev_err(qidev, "Error: %#x in CAAM response FD\n", + fd->status); + } - -- if (unlikely(qm_fd_get_format(fd) != qm_fd_compound)) { ++ + if (unlikely(fd->format != qm_fd_compound)) { dev_err(qidev, "Non-compound FD from CAAM\n"); return qman_cb_dqrr_consume; } - drv_req = (struct caam_drv_req *)phys_to_virt(qm_fd_addr_get64(fd)); -+ drv_req = (struct caam_drv_req *)phys_to_virt(fd->addr); ++ drv_req = caam_iova_to_virt(priv->domain, qm_fd_addr_get64(fd)); if (unlikely(!drv_req)) { dev_err(qidev, "Can't find original request for caam response\n"); -@@ -597,7 +602,7 @@ static enum qman_cb_dqrr_result caam_rsp +@@ -597,7 +611,7 @@ static enum qman_cb_dqrr_result caam_rsp dma_unmap_single(drv_req->drv_ctx->qidev, qm_fd_addr(fd), sizeof(drv_req->fd_sgt), DMA_BIDIRECTIONAL); @@ -12926,7 +15588,7 @@ Signed-off-by: Biwen Li return qman_cb_dqrr_consume; } -@@ -621,17 +626,18 @@ static int alloc_rsp_fq_cpu(struct devic +@@ -621,17 +635,18 @@ static int alloc_rsp_fq_cpu(struct devic return -ENODEV; } @@ -12953,7 +15615,19 @@ Signed-off-by: Biwen Li ret = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &opts); if (ret) { -@@ -662,8 +668,7 @@ static int init_cgr(struct device *qidev +@@ -650,9 +665,8 @@ static int init_cgr(struct device *qidev + { + int ret; + struct qm_mcc_initcgr opts; +- const u64 cpus = *(u64 *)qman_affine_cpus(); +- const int num_cpus = hweight64(cpus); +- const u64 val = num_cpus * MAX_RSP_FQ_BACKLOG_PER_CPU; ++ const u64 val = (u64)cpumask_weight(qman_affine_cpus()) * ++ MAX_RSP_FQ_BACKLOG_PER_CPU; + + ret = qman_alloc_cgrid(&qipriv.cgr.cgrid); + if (ret) { +@@ -662,8 +676,7 @@ static int init_cgr(struct device *qidev qipriv.cgr.cb = cgr_cb; memset(&opts, 0, sizeof(opts)); @@ -12963,6 +15637,81 @@ Signed-off-by: Biwen Li opts.cgr.cscn_en = QM_CGR_EN; opts.cgr.mode = QMAN_CGR_MODE_FRAME; qm_cgr_cs_thres_set64(&opts.cgr.cs_thres, val, 1); +@@ -708,15 +721,10 @@ static void free_rsp_fqs(void) + int caam_qi_init(struct platform_device *caam_pdev) + { + int err, i; +- struct platform_device *qi_pdev; + struct device *ctrldev = &caam_pdev->dev, *qidev; + struct caam_drv_private *ctrlpriv; + const cpumask_t *cpus = qman_affine_cpus(); + struct cpumask old_cpumask = current->cpus_allowed; +- static struct platform_device_info qi_pdev_info = { +- .name = "caam_qi", +- .id = PLATFORM_DEVID_NONE +- }; + + /* + * QMAN requires CGRs to be removed from same CPU+portal from where it +@@ -728,24 +736,13 @@ int caam_qi_init(struct platform_device + mod_init_cpu = cpumask_first(cpus); + set_cpus_allowed_ptr(current, get_cpu_mask(mod_init_cpu)); + +- qi_pdev_info.parent = ctrldev; +- qi_pdev_info.dma_mask = dma_get_mask(ctrldev); +- qi_pdev = platform_device_register_full(&qi_pdev_info); +- if (IS_ERR(qi_pdev)) +- return PTR_ERR(qi_pdev); +- set_dma_ops(&qi_pdev->dev, get_dma_ops(ctrldev)); +- + ctrlpriv = dev_get_drvdata(ctrldev); +- qidev = &qi_pdev->dev; +- +- qipriv.qi_pdev = qi_pdev; +- dev_set_drvdata(qidev, &qipriv); ++ qidev = ctrldev; + + /* Initialize the congestion detection */ + err = init_cgr(qidev); + if (err) { + dev_err(qidev, "CGR initialization failed: %d\n", err); +- platform_device_unregister(qi_pdev); + return err; + } + +@@ -754,7 +751,6 @@ int caam_qi_init(struct platform_device + if (err) { + dev_err(qidev, "Can't allocate CAAM response FQs: %d\n", err); + free_rsp_fqs(); +- platform_device_unregister(qi_pdev); + return err; + } + +@@ -777,15 +773,11 @@ int caam_qi_init(struct platform_device + napi_enable(irqtask); + } + +- /* Hook up QI device to parent controlling caam device */ +- ctrlpriv->qidev = qidev; +- + qi_cache = kmem_cache_create("caamqicache", CAAM_QI_MEMCACHE_SIZE, 0, + SLAB_CACHE_DMA, NULL); + if (!qi_cache) { + dev_err(qidev, "Can't allocate CAAM cache\n"); + free_rsp_fqs(); +- platform_device_unregister(qi_pdev); + return -ENOMEM; + } + +@@ -795,6 +787,8 @@ int caam_qi_init(struct platform_device + debugfs_create_file("qi_congested", 0444, ctrlpriv->ctl, + ×_congested, &caam_fops_u64_ro); + #endif ++ ++ ctrlpriv->qi_init = 1; + dev_info(qidev, "Linux CAAM Queue I/F driver initialised\n"); + return 0; + } --- a/drivers/crypto/caam/qi.h +++ b/drivers/crypto/caam/qi.h @@ -9,7 +9,7 @@ @@ -12976,7 +15725,128 @@ Signed-off-by: Biwen Li #include "desc_constr.h" --- a/drivers/crypto/caam/regs.h +++ b/drivers/crypto/caam/regs.h -@@ -627,6 +627,8 @@ struct caam_job_ring { +@@ -3,6 +3,7 @@ + * CAAM hardware register-level view + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. ++ * Copyright 2018 NXP + */ + + #ifndef REGS_H +@@ -211,6 +212,47 @@ struct jr_outentry { + u32 jrstatus; /* Status for completed descriptor */ + } __packed; + ++/* Version registers (Era 10+) e80-eff */ ++struct version_regs { ++ u32 crca; /* CRCA_VERSION */ ++ u32 afha; /* AFHA_VERSION */ ++ u32 kfha; /* KFHA_VERSION */ ++ u32 pkha; /* PKHA_VERSION */ ++ u32 aesa; /* AESA_VERSION */ ++ u32 mdha; /* MDHA_VERSION */ ++ u32 desa; /* DESA_VERSION */ ++ u32 snw8a; /* SNW8A_VERSION */ ++ u32 snw9a; /* SNW9A_VERSION */ ++ u32 zuce; /* ZUCE_VERSION */ ++ u32 zuca; /* ZUCA_VERSION */ ++ u32 ccha; /* CCHA_VERSION */ ++ u32 ptha; /* PTHA_VERSION */ ++ u32 rng; /* RNG_VERSION */ ++ u32 trng; /* TRNG_VERSION */ ++ u32 aaha; /* AAHA_VERSION */ ++ u32 rsvd[10]; ++ u32 sr; /* SR_VERSION */ ++ u32 dma; /* DMA_VERSION */ ++ u32 ai; /* AI_VERSION */ ++ u32 qi; /* QI_VERSION */ ++ u32 jr; /* JR_VERSION */ ++ u32 deco; /* DECO_VERSION */ ++}; ++ ++/* Version registers bitfields */ ++ ++/* Number of CHAs instantiated */ ++#define CHA_VER_NUM_MASK 0xffull ++/* CHA Miscellaneous Information */ ++#define CHA_VER_MISC_SHIFT 8 ++#define CHA_VER_MISC_MASK (0xffull << CHA_VER_MISC_SHIFT) ++/* CHA Revision Number */ ++#define CHA_VER_REV_SHIFT 16 ++#define CHA_VER_REV_MASK (0xffull << CHA_VER_REV_SHIFT) ++/* CHA Version ID */ ++#define CHA_VER_VID_SHIFT 24 ++#define CHA_VER_VID_MASK (0xffull << CHA_VER_VID_SHIFT) ++ + /* + * caam_perfmon - Performance Monitor/Secure Memory Status/ + * CAAM Global Status/Component Version IDs +@@ -223,15 +265,13 @@ struct jr_outentry { + #define CHA_NUM_MS_DECONUM_MASK (0xfull << CHA_NUM_MS_DECONUM_SHIFT) + + /* +- * CHA version IDs / instantiation bitfields ++ * CHA version IDs / instantiation bitfields (< Era 10) + * Defined for use with the cha_id fields in perfmon, but the same shift/mask + * selectors can be used to pull out the number of instantiated blocks within + * cha_num fields in perfmon because the locations are the same. + */ + #define CHA_ID_LS_AES_SHIFT 0 + #define CHA_ID_LS_AES_MASK (0xfull << CHA_ID_LS_AES_SHIFT) +-#define CHA_ID_LS_AES_LP (0x3ull << CHA_ID_LS_AES_SHIFT) +-#define CHA_ID_LS_AES_HP (0x4ull << CHA_ID_LS_AES_SHIFT) + + #define CHA_ID_LS_DES_SHIFT 4 + #define CHA_ID_LS_DES_MASK (0xfull << CHA_ID_LS_DES_SHIFT) +@@ -241,9 +281,6 @@ struct jr_outentry { + + #define CHA_ID_LS_MD_SHIFT 12 + #define CHA_ID_LS_MD_MASK (0xfull << CHA_ID_LS_MD_SHIFT) +-#define CHA_ID_LS_MD_LP256 (0x0ull << CHA_ID_LS_MD_SHIFT) +-#define CHA_ID_LS_MD_LP512 (0x1ull << CHA_ID_LS_MD_SHIFT) +-#define CHA_ID_LS_MD_HP (0x2ull << CHA_ID_LS_MD_SHIFT) + + #define CHA_ID_LS_RNG_SHIFT 16 + #define CHA_ID_LS_RNG_MASK (0xfull << CHA_ID_LS_RNG_SHIFT) +@@ -269,6 +306,13 @@ struct jr_outentry { + #define CHA_ID_MS_JR_SHIFT 28 + #define CHA_ID_MS_JR_MASK (0xfull << CHA_ID_MS_JR_SHIFT) + ++/* Specific CHA version IDs */ ++#define CHA_VER_VID_AES_LP 0x3ull ++#define CHA_VER_VID_AES_HP 0x4ull ++#define CHA_VER_VID_MD_LP256 0x0ull ++#define CHA_VER_VID_MD_LP512 0x1ull ++#define CHA_VER_VID_MD_HP 0x2ull ++ + struct sec_vid { + u16 ip_id; + u8 maj_rev; +@@ -473,8 +517,10 @@ struct caam_ctrl { + struct rng4tst r4tst[2]; + }; + +- u32 rsvd9[448]; ++ u32 rsvd9[416]; + ++ /* Version registers - introduced with era 10 e80-eff */ ++ struct version_regs vreg; + /* Performance Monitor f00-fff */ + struct caam_perfmon perfmon; + }; +@@ -564,8 +610,10 @@ struct caam_job_ring { + u32 rsvd11; + u32 jrcommand; /* JRCRx - JobR command */ + +- u32 rsvd12[932]; ++ u32 rsvd12[900]; + ++ /* Version registers - introduced with era 10 e80-eff */ ++ struct version_regs vreg; + /* Performance Monitor f00-fff */ + struct caam_perfmon perfmon; + }; +@@ -627,6 +675,8 @@ struct caam_job_ring { #define JRSTA_DECOERR_INVSIGN 0x86 #define JRSTA_DECOERR_DSASIGN 0x87 @@ -12985,6 +15855,28 @@ Signed-off-by: Biwen Li #define JRSTA_CCBERR_JUMP 0x08000000 #define JRSTA_CCBERR_INDEX_MASK 0xff00 #define JRSTA_CCBERR_INDEX_SHIFT 8 +@@ -870,13 +920,19 @@ struct caam_deco { + u32 rsvd29[48]; + u32 descbuf[64]; /* DxDESB - Descriptor buffer */ + u32 rscvd30[193]; +-#define DESC_DBG_DECO_STAT_HOST_ERR 0x00D00000 + #define DESC_DBG_DECO_STAT_VALID 0x80000000 + #define DESC_DBG_DECO_STAT_MASK 0x00F00000 ++#define DESC_DBG_DECO_STAT_SHIFT 20 + u32 desc_dbg; /* DxDDR - DECO Debug Register */ +- u32 rsvd31[126]; ++ u32 rsvd31[13]; ++#define DESC_DER_DECO_STAT_MASK 0x000F0000 ++#define DESC_DER_DECO_STAT_SHIFT 16 ++ u32 dbg_exec; /* DxDER - DECO Debug Exec Register */ ++ u32 rsvd32[112]; + }; + ++#define DECO_STAT_HOST_ERR 0xD ++ + #define DECO_JQCR_WHL 0x20000000 + #define DECO_JQCR_FOUR 0x10000000 + --- a/drivers/crypto/caam/sg_sw_qm.h +++ b/drivers/crypto/caam/sg_sw_qm.h @@ -34,46 +34,61 @@ @@ -13091,3 +15983,13 @@ Signed-off-by: Biwen Li if (ret > 1) { tbl_off += ret; sync_needed = true; +--- a/include/crypto/chacha20.h ++++ b/include/crypto/chacha20.h +@@ -13,6 +13,7 @@ + #define CHACHA20_IV_SIZE 16 + #define CHACHA20_KEY_SIZE 32 + #define CHACHA20_BLOCK_SIZE 64 ++#define CHACHAPOLY_IV_SIZE 12 + + struct chacha20_ctx { + u32 key[8]; -- cgit v1.2.3