[OpenWrt-Devel] [PATCH] mvebu: Add SafeXcel crypto engine (Armada 37xx)
Marek Behún
marek.behun at nic.cz
Sun Aug 12 20:53:32 EDT 2018
These are backported patches from mainline kernel needed to support
Inside Secure's SafeXcel EIP97 crypto engine on Armada 37xx
(EspressoBin).
We also define a kernel package for crypto_safexcel in
target/mvebu/modules.mk.
Signed-off-by: Marek Behun <marek.behun at nic.cz>
---
target/linux/mvebu/modules.mk | 25 +
...ide-secure-remove-null-check-before-kfree.patch | 33 +
...de-secure-do-not-use-areq-result-for-part.patch | 63 ++
...pto-inside-secure-remove-extra-empty-line.patch | 28 +
...rypto-inside-secure-fix-typo-in-a-comment.patch | 29 +
...rypto-inside-secure-remove-useless-memset.patch | 30 +
...de-secure-refrain-from-unneeded-invalidat.patch | 91 +++
...de-secure-EBUSY-is-not-an-error-on-async-.patch | 35 +
...de-secure-move-cipher-crypto-mode-to-requ.patch | 76 ++
...de-secure-remove-unused-parameter-in-inva.patch | 74 ++
...de-secure-move-request-dequeueing-into-a-.patch | 204 +++++
...de-secure-use-threaded-IRQs-for-result-ha.patch | 136 ++++
...nside-secure-dequeue-all-requests-at-once.patch | 179 +++++
...ypto-inside-secure-increase-the-ring-size.patch | 37 +
...de-secure-acknowledge-the-result-requests.patch | 62 ++
...de-secure-handle-more-result-requests-whe.patch | 70 ++
...de-secure-retry-to-proceed-the-request-la.patch | 103 +++
.../616-crypto-inside-secure-EIP97-support.patch | 841 +++++++++++++++++++++
...de-secure-make-function-safexcel_try_push.patch | 38 +
...de-secure-do-not-overwrite-the-threshold-.patch | 40 +
...de-secure-keep-the-requests-push-pop-sync.patch | 136 ++++
...de-secure-unmap-the-result-in-the-hash-se.patch | 42 +
...de-secure-move-hash-result-dma-mapping-to.patch | 115 +++
...de-secure-move-cache-result-dma-mapping-t.patch | 152 ++++
...de-secure-fix-missing-unlock-on-error-in-.patch | 36 +
...nside-secure-improve-clock-initialization.patch | 48 ++
...de-secure-fix-clock-resource-by-adding-a-.patch | 146 ++++
...de-secure-move-the-digest-to-the-request-.patch | 161 ++++
...de-secure-fix-typo-s-allways-always-in-a-.patch | 45 ++
...side-secure-fix-a-typo-in-a-register-name.patch | 45 ++
...inside-secure-improve-the-send-error-path.patch | 50 ++
...de-secure-do-not-access-buffers-mapped-to.patch | 46 ++
...-inside-secure-improve-the-skcipher-token.patch | 36 +
...de-secure-the-context-ipad-opad-should-us.patch | 42 +
...-crypto-inside-secure-hmac-sha256-support.patch | 174 +++++
...-crypto-inside-secure-hmac-sha224-support.patch | 110 +++
...dts-marvell-armada-37xx-add-a-crypto-node.patch | 42 +
37 files changed, 3620 insertions(+)
create mode 100644 target/linux/mvebu/modules.mk
create mode 100644 target/linux/mvebu/patches-4.14/600-crypto-inside-secure-remove-null-check-before-kfree.patch
create mode 100644 target/linux/mvebu/patches-4.14/601-crypto-inside-secure-do-not-use-areq-result-for-part.patch
create mode 100644 target/linux/mvebu/patches-4.14/602-crypto-inside-secure-remove-extra-empty-line.patch
create mode 100644 target/linux/mvebu/patches-4.14/603-crypto-inside-secure-fix-typo-in-a-comment.patch
create mode 100644 target/linux/mvebu/patches-4.14/604-crypto-inside-secure-remove-useless-memset.patch
create mode 100644 target/linux/mvebu/patches-4.14/605-crypto-inside-secure-refrain-from-unneeded-invalidat.patch
create mode 100644 target/linux/mvebu/patches-4.14/606-crypto-inside-secure-EBUSY-is-not-an-error-on-async-.patch
create mode 100644 target/linux/mvebu/patches-4.14/607-crypto-inside-secure-move-cipher-crypto-mode-to-requ.patch
create mode 100644 target/linux/mvebu/patches-4.14/608-crypto-inside-secure-remove-unused-parameter-in-inva.patch
create mode 100644 target/linux/mvebu/patches-4.14/609-crypto-inside-secure-move-request-dequeueing-into-a-.patch
create mode 100644 target/linux/mvebu/patches-4.14/610-crypto-inside-secure-use-threaded-IRQs-for-result-ha.patch
create mode 100644 target/linux/mvebu/patches-4.14/611-crypto-inside-secure-dequeue-all-requests-at-once.patch
create mode 100644 target/linux/mvebu/patches-4.14/612-crypto-inside-secure-increase-the-ring-size.patch
create mode 100644 target/linux/mvebu/patches-4.14/613-crypto-inside-secure-acknowledge-the-result-requests.patch
create mode 100644 target/linux/mvebu/patches-4.14/614-crypto-inside-secure-handle-more-result-requests-whe.patch
create mode 100644 target/linux/mvebu/patches-4.14/615-crypto-inside-secure-retry-to-proceed-the-request-la.patch
create mode 100644 target/linux/mvebu/patches-4.14/616-crypto-inside-secure-EIP97-support.patch
create mode 100644 target/linux/mvebu/patches-4.14/617-crypto-inside-secure-make-function-safexcel_try_push.patch
create mode 100644 target/linux/mvebu/patches-4.14/618-crypto-inside-secure-do-not-overwrite-the-threshold-.patch
create mode 100644 target/linux/mvebu/patches-4.14/619-crypto-inside-secure-keep-the-requests-push-pop-sync.patch
create mode 100644 target/linux/mvebu/patches-4.14/620-crypto-inside-secure-unmap-the-result-in-the-hash-se.patch
create mode 100644 target/linux/mvebu/patches-4.14/621-crypto-inside-secure-move-hash-result-dma-mapping-to.patch
create mode 100644 target/linux/mvebu/patches-4.14/622-crypto-inside-secure-move-cache-result-dma-mapping-t.patch
create mode 100644 target/linux/mvebu/patches-4.14/623-crypto-inside-secure-fix-missing-unlock-on-error-in-.patch
create mode 100644 target/linux/mvebu/patches-4.14/624-crypto-inside-secure-improve-clock-initialization.patch
create mode 100644 target/linux/mvebu/patches-4.14/625-crypto-inside-secure-fix-clock-resource-by-adding-a-.patch
create mode 100644 target/linux/mvebu/patches-4.14/626-crypto-inside-secure-move-the-digest-to-the-request-.patch
create mode 100644 target/linux/mvebu/patches-4.14/627-crypto-inside-secure-fix-typo-s-allways-always-in-a-.patch
create mode 100644 target/linux/mvebu/patches-4.14/628-crypto-inside-secure-fix-a-typo-in-a-register-name.patch
create mode 100644 target/linux/mvebu/patches-4.14/629-crypto-inside-secure-improve-the-send-error-path.patch
create mode 100644 target/linux/mvebu/patches-4.14/630-crypto-inside-secure-do-not-access-buffers-mapped-to.patch
create mode 100644 target/linux/mvebu/patches-4.14/631-crypto-inside-secure-improve-the-skcipher-token.patch
create mode 100644 target/linux/mvebu/patches-4.14/632-crypto-inside-secure-the-context-ipad-opad-should-us.patch
create mode 100644 target/linux/mvebu/patches-4.14/633-crypto-inside-secure-hmac-sha256-support.patch
create mode 100644 target/linux/mvebu/patches-4.14/634-crypto-inside-secure-hmac-sha224-support.patch
create mode 100644 target/linux/mvebu/patches-4.14/635-arm64-dts-marvell-armada-37xx-add-a-crypto-node.patch
diff --git a/target/linux/mvebu/modules.mk b/target/linux/mvebu/modules.mk
new file mode 100644
index 0000000000..f0be14fcdb
--- /dev/null
+++ b/target/linux/mvebu/modules.mk
@@ -0,0 +1,25 @@
+define KernelPackage/crypto-hw-safexcel
+ TITLE:= MVEBU SafeXcel Crypto Engine module
+ DEPENDS:=@TARGET_mvebu
+ KCONFIG:= \
+ CONFIG_CRYPTO_HW=y \
+ CONFIG_CRYPTO_AES=y \
+ CONFIG_CRYPTO_BLKCIPHER=y \
+ CONFIG_CRYPTO_HASH=y \
+ CONFIG_CRYPTO_HMAC=y \
+ CONFIG_CRYPTO_SHA1=y \
+ CONFIG_CRYPTO_SHA256=y \
+ CONFIG_CRYPTO_SHA512=y \
+ CONFIG_CRYPTO_DEV_SAFEXCEL
+ FILES:=$(LINUX_DIR)/drivers/crypto/inside-secure/crypto_safexcel.ko
+ AUTOLOAD:=$(call AutoLoad,90,crypto_safexcel)
+ $(call AddDepends/crypto)
+endef
+
+define KernelPackage/crypto-hw-safexcel/description
+ MVEBU's EIP97 Cryptographic Engine driver designed by Inside Secure.
+ This is found on Marvell Armada 37xx/7k/8k SoCs, for example on
+ EspressoBin.
+endef
+
+$(eval $(call KernelPackage,crypto-hw-safexcel))
diff --git a/target/linux/mvebu/patches-4.14/600-crypto-inside-secure-remove-null-check-before-kfree.patch b/target/linux/mvebu/patches-4.14/600-crypto-inside-secure-remove-null-check-before-kfree.patch
new file mode 100644
index 0000000000..4abad3f62e
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/600-crypto-inside-secure-remove-null-check-before-kfree.patch
@@ -0,0 +1,33 @@
+From f546f46310528adb05b9fbbd51b7a17d2e59784f Mon Sep 17 00:00:00 2001
+From: Himanshu Jha <himanshujha199640 at gmail.com>
+Date: Sun, 27 Aug 2017 02:45:30 +0530
+Subject: [PATCH 01/36] crypto: inside-secure - remove null check before kfree
+
+Kfree on NULL pointer is a no-op and therefore checking is redundant.
+
+Signed-off-by: Himanshu Jha <himanshujha199640 at gmail.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 69f29776591a..46c2e15c0931 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -326,10 +326,8 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ ctx->base.cache_sz = 0;
+ }
+ free_cache:
+- if (ctx->base.cache) {
+- kfree(ctx->base.cache);
+- ctx->base.cache = NULL;
+- }
++ kfree(ctx->base.cache);
++ ctx->base.cache = NULL;
+
+ unlock:
+ spin_unlock_bh(&priv->ring[ring].egress_lock);
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/601-crypto-inside-secure-do-not-use-areq-result-for-part.patch b/target/linux/mvebu/patches-4.14/601-crypto-inside-secure-do-not-use-areq-result-for-part.patch
new file mode 100644
index 0000000000..8333740931
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/601-crypto-inside-secure-do-not-use-areq-result-for-part.patch
@@ -0,0 +1,63 @@
+From 9623afc293461e83ecfab48df6334f23ba0eb90e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Mon, 11 Dec 2017 12:10:58 +0100
+Subject: [PATCH 02/36] crypto: inside-secure - do not use areq->result for
+ partial results
+
+This patches update the SafeXcel driver to stop using the crypto
+ahash_request result field for partial results (i.e. on updates).
+Instead the driver local safexcel_ahash_req state field is used, and
+only on final operations the ahash_request result buffer is updated.
+
+Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 46c2e15c0931..c20c4db12190 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -37,7 +37,7 @@ struct safexcel_ahash_req {
+ int nents;
+
+ u8 state_sz; /* expected sate size, only set once */
+- u32 state[SHA256_DIGEST_SIZE / sizeof(u32)];
++ u32 state[SHA256_DIGEST_SIZE / sizeof(u32)] __aligned(sizeof(u32));
+
+ u64 len;
+ u64 processed;
+@@ -130,7 +130,7 @@ static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int rin
+ struct ahash_request *areq = ahash_request_cast(async);
+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
+ struct safexcel_ahash_req *sreq = ahash_request_ctx(areq);
+- int cache_len, result_sz = sreq->state_sz;
++ int cache_len;
+
+ *ret = 0;
+
+@@ -151,8 +151,8 @@ static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int rin
+ spin_unlock_bh(&priv->ring[ring].egress_lock);
+
+ if (sreq->finish)
+- result_sz = crypto_ahash_digestsize(ahash);
+- memcpy(sreq->state, areq->result, result_sz);
++ memcpy(areq->result, sreq->state,
++ crypto_ahash_digestsize(ahash));
+
+ if (sreq->nents) {
+ dma_unmap_sg(priv->dev, areq->src, sreq->nents, DMA_TO_DEVICE);
+@@ -292,7 +292,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ /* Add the token */
+ safexcel_hash_token(first_cdesc, len, req->state_sz);
+
+- ctx->base.result_dma = dma_map_single(priv->dev, areq->result,
++ ctx->base.result_dma = dma_map_single(priv->dev, req->state,
+ req->state_sz, DMA_FROM_DEVICE);
+ if (dma_mapping_error(priv->dev, ctx->base.result_dma)) {
+ ret = -EINVAL;
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/602-crypto-inside-secure-remove-extra-empty-line.patch b/target/linux/mvebu/patches-4.14/602-crypto-inside-secure-remove-extra-empty-line.patch
new file mode 100644
index 0000000000..2a20bbc98e
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/602-crypto-inside-secure-remove-extra-empty-line.patch
@@ -0,0 +1,28 @@
+From 505e74ab4b15db7c9ff13843b1ac3030f905e967 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:43 +0100
+Subject: [PATCH 03/36] crypto: inside-secure - remove extra empty line
+
+Cosmetic patch removing an extra empty line between header inclusions.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index c20c4db12190..37e7fcd2f54b 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -14,7 +14,6 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/dmapool.h>
+
+-
+ #include "safexcel.h"
+
+ struct safexcel_ahash_ctx {
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/603-crypto-inside-secure-fix-typo-in-a-comment.patch b/target/linux/mvebu/patches-4.14/603-crypto-inside-secure-fix-typo-in-a-comment.patch
new file mode 100644
index 0000000000..cbb2a40eee
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/603-crypto-inside-secure-fix-typo-in-a-comment.patch
@@ -0,0 +1,29 @@
+From d6f5a9a4252bc5a2fae8cadf1b772ae0b1957f33 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:44 +0100
+Subject: [PATCH 04/36] crypto: inside-secure - fix typo in a comment
+
+Cosmetic patch fixing one typo in one of the driver's comments.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 37e7fcd2f54b..50c28da35b0d 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -522,7 +522,7 @@ static int safexcel_ahash_cache(struct ahash_request *areq)
+ return areq->nbytes;
+ }
+
+- /* We could'nt cache all the data */
++ /* We couldn't cache all the data */
+ return -E2BIG;
+ }
+
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/604-crypto-inside-secure-remove-useless-memset.patch b/target/linux/mvebu/patches-4.14/604-crypto-inside-secure-remove-useless-memset.patch
new file mode 100644
index 0000000000..025936aa8f
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/604-crypto-inside-secure-remove-useless-memset.patch
@@ -0,0 +1,30 @@
+From 0bfd4e3e21e24ad77b32186d894bd57d08386e20 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:45 +0100
+Subject: [PATCH 05/36] crypto: inside-secure - remove useless memset
+
+This patch removes an useless memset in the ahash_export function, as
+the zeroed buffer will be entirely overridden the next line.
+
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 50c28da35b0d..8ed46ff4cbf9 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -642,7 +642,6 @@ static int safexcel_ahash_export(struct ahash_request *areq, void *out)
+ export->processed = req->processed;
+
+ memcpy(export->state, req->state, req->state_sz);
+- memset(export->cache, 0, crypto_ahash_blocksize(ahash));
+ memcpy(export->cache, req->cache, crypto_ahash_blocksize(ahash));
+
+ return 0;
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/605-crypto-inside-secure-refrain-from-unneeded-invalidat.patch b/target/linux/mvebu/patches-4.14/605-crypto-inside-secure-refrain-from-unneeded-invalidat.patch
new file mode 100644
index 0000000000..9a43a24965
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/605-crypto-inside-secure-refrain-from-unneeded-invalidat.patch
@@ -0,0 +1,91 @@
+From a05f52e7856dd8f3ca40960ee45807ef6c4b87cf Mon Sep 17 00:00:00 2001
+From: Ofer Heifetz <oferh at marvell.com>
+Date: Thu, 14 Dec 2017 15:26:47 +0100
+Subject: [PATCH 06/36] crypto: inside-secure - refrain from unneeded
+ invalidations
+
+The check to know if an invalidation is needed (i.e. when the context
+changes) is done even if the context does not exist yet. This happens
+when first setting a key for ciphers and/or hmac operations.
+
+This commits adds a check in the _setkey functions to only check if an
+invalidation is needed when a context exists, as there is no need to
+perform this check otherwise.
+
+Signed-off-by: Ofer Heifetz <oferh at marvell.com>
+[Antoine: commit message and added a comment and reworked one of the
+checks]
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_cipher.c | 10 ++++++----
+ drivers/crypto/inside-secure/safexcel_hash.c | 24 ++++++++++++++++--------
+ 2 files changed, 22 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c
+index 29cf7e00b574..6d8bc6a3fe5b 100644
+--- a/drivers/crypto/inside-secure/safexcel_cipher.c
++++ b/drivers/crypto/inside-secure/safexcel_cipher.c
+@@ -78,10 +78,12 @@ static int safexcel_aes_setkey(struct crypto_skcipher *ctfm, const u8 *key,
+ return ret;
+ }
+
+- for (i = 0; i < len / sizeof(u32); i++) {
+- if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
+- ctx->base.needs_inv = true;
+- break;
++ if (ctx->base.ctxr_dma) {
++ for (i = 0; i < len / sizeof(u32); i++) {
++ if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
++ ctx->base.needs_inv = true;
++ break;
++ }
+ }
+ }
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 8ed46ff4cbf9..955c242da244 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -535,10 +535,16 @@ static int safexcel_ahash_enqueue(struct ahash_request *areq)
+
+ req->needs_inv = false;
+
+- if (req->processed && ctx->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED)
+- ctx->base.needs_inv = safexcel_ahash_needs_inv_get(areq);
+-
+ if (ctx->base.ctxr) {
++ if (!ctx->base.needs_inv && req->processed &&
++ ctx->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED)
++ /* We're still setting needs_inv here, even though it is
++ * cleared right away, because the needs_inv flag can be
++ * set in other functions and we want to keep the same
++ * logic.
++ */
++ ctx->base.needs_inv = safexcel_ahash_needs_inv_get(areq);
++
+ if (ctx->base.needs_inv) {
+ ctx->base.needs_inv = false;
+ req->needs_inv = true;
+@@ -936,11 +942,13 @@ static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
+ if (ret)
+ return ret;
+
+- for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) {
+- if (ctx->ipad[i] != le32_to_cpu(istate.state[i]) ||
+- ctx->opad[i] != le32_to_cpu(ostate.state[i])) {
+- ctx->base.needs_inv = true;
+- break;
++ if (ctx->base.ctxr) {
++ for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) {
++ if (ctx->ipad[i] != le32_to_cpu(istate.state[i]) ||
++ ctx->opad[i] != le32_to_cpu(ostate.state[i])) {
++ ctx->base.needs_inv = true;
++ break;
++ }
+ }
+ }
+
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/606-crypto-inside-secure-EBUSY-is-not-an-error-on-async-.patch b/target/linux/mvebu/patches-4.14/606-crypto-inside-secure-EBUSY-is-not-an-error-on-async-.patch
new file mode 100644
index 0000000000..a901c4b7e1
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/606-crypto-inside-secure-EBUSY-is-not-an-error-on-async-.patch
@@ -0,0 +1,35 @@
+From ab8541f44b5856339f6ccd3c49b443b25091ff90 Mon Sep 17 00:00:00 2001
+From: Ofer Heifetz <oferh at marvell.com>
+Date: Thu, 14 Dec 2017 15:26:48 +0100
+Subject: [PATCH 07/36] crypto: inside-secure - EBUSY is not an error on async
+ request
+
+When initializing the IVs crypto_ahash_update() is called, which at some
+point will call crypto_enqueue_request(). This function can return
+-EBUSY when no resource is available and the request is queued. Since
+this is a valid case, -EBUSY shouldn't be treated as an error.
+
+Signed-off-by: Ofer Heifetz <oferh at marvell.com>
+[Antoine: commit message]
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 955c242da244..f32985e56668 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -870,7 +870,7 @@ static int safexcel_hmac_init_iv(struct ahash_request *areq,
+ req->last_req = true;
+
+ ret = crypto_ahash_update(areq);
+- if (ret && ret != -EINPROGRESS)
++ if (ret && ret != -EINPROGRESS && ret != -EBUSY)
+ return ret;
+
+ wait_for_completion_interruptible(&result.completion);
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/607-crypto-inside-secure-move-cipher-crypto-mode-to-requ.patch b/target/linux/mvebu/patches-4.14/607-crypto-inside-secure-move-cipher-crypto-mode-to-requ.patch
new file mode 100644
index 0000000000..73b6599422
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/607-crypto-inside-secure-move-cipher-crypto-mode-to-requ.patch
@@ -0,0 +1,76 @@
+From 27e6b38e3b123978a1eee928e5b7e5aea9349e31 Mon Sep 17 00:00:00 2001
+From: Ofer Heifetz <oferh at marvell.com>
+Date: Thu, 14 Dec 2017 15:26:49 +0100
+Subject: [PATCH 08/36] crypto: inside-secure - move cipher crypto mode to
+ request context
+
+The cipher direction can be different for requests within the same
+transformation context. This patch moves the direction flag from the
+context to the request scope.
+
+Signed-off-by: Ofer Heifetz <oferh at marvell.com>
+[Antoine: commit message]
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_cipher.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c
+index 6d8bc6a3fe5b..5af0c890646d 100644
+--- a/drivers/crypto/inside-secure/safexcel_cipher.c
++++ b/drivers/crypto/inside-secure/safexcel_cipher.c
+@@ -27,7 +27,6 @@ struct safexcel_cipher_ctx {
+ struct safexcel_context base;
+ struct safexcel_crypto_priv *priv;
+
+- enum safexcel_cipher_direction direction;
+ u32 mode;
+
+ __le32 key[8];
+@@ -35,6 +34,7 @@ struct safexcel_cipher_ctx {
+ };
+
+ struct safexcel_cipher_req {
++ enum safexcel_cipher_direction direction;
+ bool needs_inv;
+ };
+
+@@ -97,12 +97,15 @@ static int safexcel_aes_setkey(struct crypto_skcipher *ctfm, const u8 *key,
+ }
+
+ static int safexcel_context_control(struct safexcel_cipher_ctx *ctx,
++ struct crypto_async_request *async,
+ struct safexcel_command_desc *cdesc)
+ {
+ struct safexcel_crypto_priv *priv = ctx->priv;
++ struct skcipher_request *req = skcipher_request_cast(async);
++ struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);
+ int ctrl_size;
+
+- if (ctx->direction == SAFEXCEL_ENCRYPT)
++ if (sreq->direction == SAFEXCEL_ENCRYPT)
+ cdesc->control_data.control0 |= CONTEXT_CONTROL_TYPE_CRYPTO_OUT;
+ else
+ cdesc->control_data.control0 |= CONTEXT_CONTROL_TYPE_CRYPTO_IN;
+@@ -245,7 +248,7 @@ static int safexcel_aes_send(struct crypto_async_request *async,
+ n_cdesc++;
+
+ if (n_cdesc == 1) {
+- safexcel_context_control(ctx, cdesc);
++ safexcel_context_control(ctx, async, cdesc);
+ safexcel_cipher_token(ctx, async, cdesc, req->cryptlen);
+ }
+
+@@ -469,7 +472,7 @@ static int safexcel_aes(struct skcipher_request *req,
+ int ret, ring;
+
+ sreq->needs_inv = false;
+- ctx->direction = dir;
++ sreq->direction = dir;
+ ctx->mode = mode;
+
+ if (ctx->base.ctxr) {
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/608-crypto-inside-secure-remove-unused-parameter-in-inva.patch b/target/linux/mvebu/patches-4.14/608-crypto-inside-secure-remove-unused-parameter-in-inva.patch
new file mode 100644
index 0000000000..1f18e5d446
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/608-crypto-inside-secure-remove-unused-parameter-in-inva.patch
@@ -0,0 +1,74 @@
+From 66dbe290b05b716faefb8b13064501e4b503bea3 Mon Sep 17 00:00:00 2001
+From: Ofer Heifetz <oferh at marvell.com>
+Date: Thu, 14 Dec 2017 15:26:50 +0100
+Subject: [PATCH 09/36] crypto: inside-secure - remove unused parameter in
+ invalidate_cache
+
+The SafeXcel context isn't used in the cache invalidation function. This
+cosmetic patch removes it (as well as from the function prototype in the
+header file and when the function is called).
+
+Signed-off-by: Ofer Heifetz <oferh at marvell.com>
+[Antoine: commit message]
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 1 -
+ drivers/crypto/inside-secure/safexcel.h | 1 -
+ drivers/crypto/inside-secure/safexcel_cipher.c | 2 +-
+ drivers/crypto/inside-secure/safexcel_hash.c | 2 +-
+ 4 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 3ee68ecde9ec..daeefef76f11 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -549,7 +549,6 @@ void safexcel_inv_complete(struct crypto_async_request *req, int error)
+ }
+
+ int safexcel_invalidate_cache(struct crypto_async_request *async,
+- struct safexcel_context *ctx,
+ struct safexcel_crypto_priv *priv,
+ dma_addr_t ctxr_dma, int ring,
+ struct safexcel_request *request)
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 304c5838c11a..d12c2b479a5e 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -539,7 +539,6 @@ void safexcel_free_context(struct safexcel_crypto_priv *priv,
+ struct crypto_async_request *req,
+ int result_sz);
+ int safexcel_invalidate_cache(struct crypto_async_request *async,
+- struct safexcel_context *ctx,
+ struct safexcel_crypto_priv *priv,
+ dma_addr_t ctxr_dma, int ring,
+ struct safexcel_request *request);
+diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c
+index 5af0c890646d..f5ffae2808a8 100644
+--- a/drivers/crypto/inside-secure/safexcel_cipher.c
++++ b/drivers/crypto/inside-secure/safexcel_cipher.c
+@@ -395,7 +395,7 @@ static int safexcel_cipher_send_inv(struct crypto_async_request *async,
+ struct safexcel_crypto_priv *priv = ctx->priv;
+ int ret;
+
+- ret = safexcel_invalidate_cache(async, &ctx->base, priv,
++ ret = safexcel_invalidate_cache(async, priv,
+ ctx->base.ctxr_dma, ring, request);
+ if (unlikely(ret))
+ return ret;
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index f32985e56668..328ce02ac050 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -435,7 +435,7 @@ static int safexcel_ahash_send_inv(struct crypto_async_request *async,
+ struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
+ int ret;
+
+- ret = safexcel_invalidate_cache(async, &ctx->base, ctx->priv,
++ ret = safexcel_invalidate_cache(async, ctx->priv,
+ ctx->base.ctxr_dma, ring, request);
+ if (unlikely(ret))
+ return ret;
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/609-crypto-inside-secure-move-request-dequeueing-into-a-.patch b/target/linux/mvebu/patches-4.14/609-crypto-inside-secure-move-request-dequeueing-into-a-.patch
new file mode 100644
index 0000000000..a6f015abf2
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/609-crypto-inside-secure-move-request-dequeueing-into-a-.patch
@@ -0,0 +1,204 @@
+From fb445c38843fa3651d01966c62a443a9435a1449 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:51 +0100
+Subject: [PATCH 10/36] crypto: inside-secure - move request dequeueing into a
+ workqueue
+
+This patch moves the request dequeueing into a workqueue to improve the
+coalescing of interrupts when sending requests to the engine; as the
+engine is capable of having one single interrupt for n requests sent.
+Using a workqueue allows to send more request at once.
+
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 29 ++++++++++++++------------
+ drivers/crypto/inside-secure/safexcel.h | 2 +-
+ drivers/crypto/inside-secure/safexcel_cipher.c | 12 +++++------
+ drivers/crypto/inside-secure/safexcel_hash.c | 12 +++++------
+ 4 files changed, 29 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index daeefef76f11..9043ab8c98cb 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -429,8 +429,6 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ struct safexcel_request *request;
+ int ret, nreq = 0, cdesc = 0, rdesc = 0, commands, results;
+
+- priv->ring[ring].need_dequeue = false;
+-
+ do {
+ spin_lock_bh(&priv->ring[ring].queue_lock);
+ backlog = crypto_get_backlog(&priv->ring[ring].queue);
+@@ -445,8 +443,6 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ spin_lock_bh(&priv->ring[ring].queue_lock);
+ crypto_enqueue_request(&priv->ring[ring].queue, req);
+ spin_unlock_bh(&priv->ring[ring].queue_lock);
+-
+- priv->ring[ring].need_dequeue = true;
+ goto finalize;
+ }
+
+@@ -455,7 +451,6 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ if (ret) {
+ kfree(request);
+ req->complete(req, ret);
+- priv->ring[ring].need_dequeue = true;
+ goto finalize;
+ }
+
+@@ -480,9 +475,7 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ } while (nreq++ < EIP197_MAX_BATCH_SZ);
+
+ finalize:
+- if (nreq == EIP197_MAX_BATCH_SZ)
+- priv->ring[ring].need_dequeue = true;
+- else if (!nreq)
++ if (!nreq)
+ return;
+
+ spin_lock_bh(&priv->ring[ring].lock);
+@@ -637,13 +630,18 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ static void safexcel_handle_result_work(struct work_struct *work)
+ {
+ struct safexcel_work_data *data =
+- container_of(work, struct safexcel_work_data, work);
++ container_of(work, struct safexcel_work_data, result_work);
+ struct safexcel_crypto_priv *priv = data->priv;
+
+ safexcel_handle_result_descriptor(priv, data->ring);
++}
++
++static void safexcel_dequeue_work(struct work_struct *work)
++{
++ struct safexcel_work_data *data =
++ container_of(work, struct safexcel_work_data, work);
+
+- if (priv->ring[data->ring].need_dequeue)
+- safexcel_dequeue(data->priv, data->ring);
++ safexcel_dequeue(data->priv, data->ring);
+ }
+
+ struct safexcel_ring_irq_data {
+@@ -674,7 +672,10 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
+ */
+ dev_err(priv->dev, "RDR: fatal error.");
+ } else if (likely(stat & EIP197_xDR_THRESH)) {
+- queue_work(priv->ring[ring].workqueue, &priv->ring[ring].work_data.work);
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.result_work);
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.work);
+ }
+
+ /* ACK the interrupts */
+@@ -855,7 +856,9 @@ static int safexcel_probe(struct platform_device *pdev)
+
+ priv->ring[i].work_data.priv = priv;
+ priv->ring[i].work_data.ring = i;
+- INIT_WORK(&priv->ring[i].work_data.work, safexcel_handle_result_work);
++ INIT_WORK(&priv->ring[i].work_data.result_work,
++ safexcel_handle_result_work);
++ INIT_WORK(&priv->ring[i].work_data.work, safexcel_dequeue_work);
+
+ snprintf(wq_name, 9, "wq_ring%d", i);
+ priv->ring[i].workqueue = create_singlethread_workqueue(wq_name);
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index d12c2b479a5e..8e9c65183439 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -459,6 +459,7 @@ struct safexcel_config {
+
+ struct safexcel_work_data {
+ struct work_struct work;
++ struct work_struct result_work;
+ struct safexcel_crypto_priv *priv;
+ int ring;
+ };
+@@ -489,7 +490,6 @@ struct safexcel_crypto_priv {
+ /* queue */
+ struct crypto_queue queue;
+ spinlock_t queue_lock;
+- bool need_dequeue;
+ } ring[EIP197_MAX_RINGS];
+ };
+
+diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c
+index f5ffae2808a8..7c9a2d87135b 100644
+--- a/drivers/crypto/inside-secure/safexcel_cipher.c
++++ b/drivers/crypto/inside-secure/safexcel_cipher.c
+@@ -358,8 +358,8 @@ static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv,
+ if (enq_ret != -EINPROGRESS)
+ *ret = enq_ret;
+
+- if (!priv->ring[ring].need_dequeue)
+- safexcel_dequeue(priv, ring);
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.work);
+
+ *should_complete = false;
+
+@@ -448,8 +448,8 @@ static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm)
+ crypto_enqueue_request(&priv->ring[ring].queue, &req->base);
+ spin_unlock_bh(&priv->ring[ring].queue_lock);
+
+- if (!priv->ring[ring].need_dequeue)
+- safexcel_dequeue(priv, ring);
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.work);
+
+ wait_for_completion(&result.completion);
+
+@@ -495,8 +495,8 @@ static int safexcel_aes(struct skcipher_request *req,
+ ret = crypto_enqueue_request(&priv->ring[ring].queue, &req->base);
+ spin_unlock_bh(&priv->ring[ring].queue_lock);
+
+- if (!priv->ring[ring].need_dequeue)
+- safexcel_dequeue(priv, ring);
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.work);
+
+ return ret;
+ }
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 328ce02ac050..6912c032200b 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -399,8 +399,8 @@ static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv,
+ if (enq_ret != -EINPROGRESS)
+ *ret = enq_ret;
+
+- if (!priv->ring[ring].need_dequeue)
+- safexcel_dequeue(priv, ring);
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.work);
+
+ *should_complete = false;
+
+@@ -488,8 +488,8 @@ static int safexcel_ahash_exit_inv(struct crypto_tfm *tfm)
+ crypto_enqueue_request(&priv->ring[ring].queue, &req->base);
+ spin_unlock_bh(&priv->ring[ring].queue_lock);
+
+- if (!priv->ring[ring].need_dequeue)
+- safexcel_dequeue(priv, ring);
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.work);
+
+ wait_for_completion(&result.completion);
+
+@@ -564,8 +564,8 @@ static int safexcel_ahash_enqueue(struct ahash_request *areq)
+ ret = crypto_enqueue_request(&priv->ring[ring].queue, &areq->base);
+ spin_unlock_bh(&priv->ring[ring].queue_lock);
+
+- if (!priv->ring[ring].need_dequeue)
+- safexcel_dequeue(priv, ring);
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.work);
+
+ return ret;
+ }
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/610-crypto-inside-secure-use-threaded-IRQs-for-result-ha.patch b/target/linux/mvebu/patches-4.14/610-crypto-inside-secure-use-threaded-IRQs-for-result-ha.patch
new file mode 100644
index 0000000000..968c9107c8
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/610-crypto-inside-secure-use-threaded-IRQs-for-result-ha.patch
@@ -0,0 +1,136 @@
+From d9ed66ebd6731cde146ae4ff47965c91e05e9267 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:52 +0100
+Subject: [PATCH 11/36] crypto: inside-secure - use threaded IRQs for result
+ handling
+
+This patch moves the result handling from an IRQ handler to a threaded
+IRQ handler, to improve the number of complete requests being handled at
+once.
+
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 41 ++++++++++++++++++---------------
+ drivers/crypto/inside-secure/safexcel.h | 1 -
+ 2 files changed, 22 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 9043ab8c98cb..4931d21f63f7 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -627,15 +627,6 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ }
+ }
+
+-static void safexcel_handle_result_work(struct work_struct *work)
+-{
+- struct safexcel_work_data *data =
+- container_of(work, struct safexcel_work_data, result_work);
+- struct safexcel_crypto_priv *priv = data->priv;
+-
+- safexcel_handle_result_descriptor(priv, data->ring);
+-}
+-
+ static void safexcel_dequeue_work(struct work_struct *work)
+ {
+ struct safexcel_work_data *data =
+@@ -653,12 +644,12 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
+ {
+ struct safexcel_ring_irq_data *irq_data = data;
+ struct safexcel_crypto_priv *priv = irq_data->priv;
+- int ring = irq_data->ring;
++ int ring = irq_data->ring, rc = IRQ_NONE;
+ u32 status, stat;
+
+ status = readl(priv->base + EIP197_HIA_AIC_R_ENABLED_STAT(ring));
+ if (!status)
+- return IRQ_NONE;
++ return rc;
+
+ /* RDR interrupts */
+ if (status & EIP197_RDR_IRQ(ring)) {
+@@ -672,10 +663,7 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
+ */
+ dev_err(priv->dev, "RDR: fatal error.");
+ } else if (likely(stat & EIP197_xDR_THRESH)) {
+- queue_work(priv->ring[ring].workqueue,
+- &priv->ring[ring].work_data.result_work);
+- queue_work(priv->ring[ring].workqueue,
+- &priv->ring[ring].work_data.work);
++ rc = IRQ_WAKE_THREAD;
+ }
+
+ /* ACK the interrupts */
+@@ -686,11 +674,26 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
+ /* ACK the interrupts */
+ writel(status, priv->base + EIP197_HIA_AIC_R_ACK(ring));
+
++ return rc;
++}
++
++static irqreturn_t safexcel_irq_ring_thread(int irq, void *data)
++{
++ struct safexcel_ring_irq_data *irq_data = data;
++ struct safexcel_crypto_priv *priv = irq_data->priv;
++ int ring = irq_data->ring;
++
++ safexcel_handle_result_descriptor(priv, ring);
++
++ queue_work(priv->ring[ring].workqueue,
++ &priv->ring[ring].work_data.work);
++
+ return IRQ_HANDLED;
+ }
+
+ static int safexcel_request_ring_irq(struct platform_device *pdev, const char *name,
+ irq_handler_t handler,
++ irq_handler_t threaded_handler,
+ struct safexcel_ring_irq_data *ring_irq_priv)
+ {
+ int ret, irq = platform_get_irq_byname(pdev, name);
+@@ -700,8 +703,9 @@ static int safexcel_request_ring_irq(struct platform_device *pdev, const char *n
+ return irq;
+ }
+
+- ret = devm_request_irq(&pdev->dev, irq, handler, 0,
+- dev_name(&pdev->dev), ring_irq_priv);
++ ret = devm_request_threaded_irq(&pdev->dev, irq, handler,
++ threaded_handler, IRQF_ONESHOT,
++ dev_name(&pdev->dev), ring_irq_priv);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to request IRQ %d\n", irq);
+ return ret;
+@@ -848,6 +852,7 @@ static int safexcel_probe(struct platform_device *pdev)
+
+ snprintf(irq_name, 6, "ring%d", i);
+ irq = safexcel_request_ring_irq(pdev, irq_name, safexcel_irq_ring,
++ safexcel_irq_ring_thread,
+ ring_irq);
+ if (irq < 0) {
+ ret = irq;
+@@ -856,8 +861,6 @@ static int safexcel_probe(struct platform_device *pdev)
+
+ priv->ring[i].work_data.priv = priv;
+ priv->ring[i].work_data.ring = i;
+- INIT_WORK(&priv->ring[i].work_data.result_work,
+- safexcel_handle_result_work);
+ INIT_WORK(&priv->ring[i].work_data.work, safexcel_dequeue_work);
+
+ snprintf(wq_name, 9, "wq_ring%d", i);
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 8e9c65183439..fffddefb0d9b 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -459,7 +459,6 @@ struct safexcel_config {
+
+ struct safexcel_work_data {
+ struct work_struct work;
+- struct work_struct result_work;
+ struct safexcel_crypto_priv *priv;
+ int ring;
+ };
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/611-crypto-inside-secure-dequeue-all-requests-at-once.patch b/target/linux/mvebu/patches-4.14/611-crypto-inside-secure-dequeue-all-requests-at-once.patch
new file mode 100644
index 0000000000..4926c22323
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/611-crypto-inside-secure-dequeue-all-requests-at-once.patch
@@ -0,0 +1,179 @@
+From 475983c763e5d2090a16abf326dc895dd184d3f0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:53 +0100
+Subject: [PATCH 12/36] crypto: inside-secure - dequeue all requests at once
+
+This patch updates the dequeueing logic to dequeue all requests at once.
+Since we can have many requests in the queue, the interrupt coalescing
+is kept so that the ring interrupt fires every EIP197_MAX_BATCH_SZ at
+most.
+
+To allow dequeueing all requests at once while still using reasonable
+settings for the interrupt coalescing, the result handling function was
+updated to setup the threshold interrupt when needed (i.e. when more
+requests than EIP197_MAX_BATCH_SZ are in the queue). When using this
+capability the ring is marked as busy so that the dequeue function
+enqueue new requests without setting the threshold interrupt.
+
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 60 ++++++++++++++++++++++++++-------
+ drivers/crypto/inside-secure/safexcel.h | 8 +++++
+ 2 files changed, 56 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 4931d21f63f7..2b32ca5eafbd 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -422,6 +422,23 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ return 0;
+ }
+
++/* Called with ring's lock taken */
++int safexcel_try_push_requests(struct safexcel_crypto_priv *priv, int ring,
++ int reqs)
++{
++ int coal = min_t(int, reqs, EIP197_MAX_BATCH_SZ);
++
++ if (!coal)
++ return 0;
++
++ /* Configure when we want an interrupt */
++ writel(EIP197_HIA_RDR_THRESH_PKT_MODE |
++ EIP197_HIA_RDR_THRESH_PROC_PKT(coal),
++ priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_THRESH);
++
++ return coal;
++}
++
+ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ {
+ struct crypto_async_request *req, *backlog;
+@@ -429,7 +446,7 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ struct safexcel_request *request;
+ int ret, nreq = 0, cdesc = 0, rdesc = 0, commands, results;
+
+- do {
++ while (true) {
+ spin_lock_bh(&priv->ring[ring].queue_lock);
+ backlog = crypto_get_backlog(&priv->ring[ring].queue);
+ req = crypto_dequeue_request(&priv->ring[ring].queue);
+@@ -472,18 +489,24 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+
+ cdesc += commands;
+ rdesc += results;
+- } while (nreq++ < EIP197_MAX_BATCH_SZ);
++ nreq++;
++ }
+
+ finalize:
+ if (!nreq)
+ return;
+
+- spin_lock_bh(&priv->ring[ring].lock);
++ spin_lock_bh(&priv->ring[ring].egress_lock);
+
+- /* Configure when we want an interrupt */
+- writel(EIP197_HIA_RDR_THRESH_PKT_MODE |
+- EIP197_HIA_RDR_THRESH_PROC_PKT(nreq),
+- priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_THRESH);
++ if (!priv->ring[ring].busy) {
++ nreq -= safexcel_try_push_requests(priv, ring, nreq);
++ if (nreq)
++ priv->ring[ring].busy = true;
++ }
++
++ priv->ring[ring].requests_left += nreq;
++
++ spin_unlock_bh(&priv->ring[ring].egress_lock);
+
+ /* let the RDR know we have pending descriptors */
+ writel((rdesc * priv->config.rd_offset) << 2,
+@@ -492,8 +515,6 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ /* let the CDR know we have pending descriptors */
+ writel((cdesc * priv->config.cd_offset) << 2,
+ priv->base + EIP197_HIA_CDR(ring) + EIP197_HIA_xDR_PREP_COUNT);
+-
+- spin_unlock_bh(&priv->ring[ring].lock);
+ }
+
+ void safexcel_free_context(struct safexcel_crypto_priv *priv,
+@@ -588,14 +609,14 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ {
+ struct safexcel_request *sreq;
+ struct safexcel_context *ctx;
+- int ret, i, nreq, ndesc = 0;
++ int ret, i, nreq, ndesc = 0, done;
+ bool should_complete;
+
+ nreq = readl(priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PROC_COUNT);
+ nreq >>= 24;
+ nreq &= GENMASK(6, 0);
+ if (!nreq)
+- return;
++ goto requests_left;
+
+ for (i = 0; i < nreq; i++) {
+ spin_lock_bh(&priv->ring[ring].egress_lock);
+@@ -610,7 +631,7 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ if (ndesc < 0) {
+ kfree(sreq);
+ dev_err(priv->dev, "failed to handle result (%d)", ndesc);
+- return;
++ goto requests_left;
+ }
+
+ writel(EIP197_xDR_PROC_xD_PKT(1) |
+@@ -625,6 +646,18 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+
+ kfree(sreq);
+ }
++
++requests_left:
++ spin_lock_bh(&priv->ring[ring].egress_lock);
++
++ done = safexcel_try_push_requests(priv, ring,
++ priv->ring[ring].requests_left);
++
++ priv->ring[ring].requests_left -= done;
++ if (!done && !priv->ring[ring].requests_left)
++ priv->ring[ring].busy = false;
++
++ spin_unlock_bh(&priv->ring[ring].egress_lock);
+ }
+
+ static void safexcel_dequeue_work(struct work_struct *work)
+@@ -870,6 +903,9 @@ static int safexcel_probe(struct platform_device *pdev)
+ goto err_clk;
+ }
+
++ priv->ring[i].requests_left = 0;
++ priv->ring[i].busy = false;
++
+ crypto_init_queue(&priv->ring[i].queue,
+ EIP197_DEFAULT_RING_SIZE);
+
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index fffddefb0d9b..531e3e9d8384 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -489,6 +489,14 @@ struct safexcel_crypto_priv {
+ /* queue */
+ struct crypto_queue queue;
+ spinlock_t queue_lock;
++
++ /* Number of requests in the engine that needs the threshold
++ * interrupt to be set up.
++ */
++ int requests_left;
++
++ /* The ring is currently handling at least one request */
++ bool busy;
+ } ring[EIP197_MAX_RINGS];
+ };
+
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/612-crypto-inside-secure-increase-the-ring-size.patch b/target/linux/mvebu/patches-4.14/612-crypto-inside-secure-increase-the-ring-size.patch
new file mode 100644
index 0000000000..7b5704fa6b
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/612-crypto-inside-secure-increase-the-ring-size.patch
@@ -0,0 +1,37 @@
+From 0960fa4f79857635412051c61c9fb451a91e79b8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:54 +0100
+Subject: [PATCH 13/36] crypto: inside-secure - increase the ring size
+
+Increase the ring size to handle more requests in parallel, while
+keeping the batch size (for interrupt coalescing) to its previous value.
+The ring size and batch size are now unlinked.
+
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 531e3e9d8384..2a0ab6ce716a 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -19,11 +19,11 @@
+ #define EIP197_HIA_VERSION_BE 0x35ca
+
+ /* Static configuration */
+-#define EIP197_DEFAULT_RING_SIZE 64
++#define EIP197_DEFAULT_RING_SIZE 400
+ #define EIP197_MAX_TOKENS 5
+ #define EIP197_MAX_RINGS 4
+ #define EIP197_FETCH_COUNT 1
+-#define EIP197_MAX_BATCH_SZ EIP197_DEFAULT_RING_SIZE
++#define EIP197_MAX_BATCH_SZ 64
+
+ #define EIP197_GFP_FLAGS(base) ((base).flags & CRYPTO_TFM_REQ_MAY_SLEEP ? \
+ GFP_KERNEL : GFP_ATOMIC)
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/613-crypto-inside-secure-acknowledge-the-result-requests.patch b/target/linux/mvebu/patches-4.14/613-crypto-inside-secure-acknowledge-the-result-requests.patch
new file mode 100644
index 0000000000..ace53613ee
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/613-crypto-inside-secure-acknowledge-the-result-requests.patch
@@ -0,0 +1,62 @@
+From 28251290d2f7f45e9fc8c9a45d6e60bd5954c78f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:55 +0100
+Subject: [PATCH 14/36] crypto: inside-secure - acknowledge the result requests
+ all at once
+
+This patches moves the result request acknowledgment from a per request
+process to acknowledging all the result requests handled at once.
+
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 2b32ca5eafbd..af79bc751ad1 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -609,7 +609,7 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ {
+ struct safexcel_request *sreq;
+ struct safexcel_context *ctx;
+- int ret, i, nreq, ndesc = 0, done;
++ int ret, i, nreq, ndesc = 0, tot_descs = 0, done;
+ bool should_complete;
+
+ nreq = readl(priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PROC_COUNT);
+@@ -631,13 +631,9 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ if (ndesc < 0) {
+ kfree(sreq);
+ dev_err(priv->dev, "failed to handle result (%d)", ndesc);
+- goto requests_left;
++ goto acknowledge;
+ }
+
+- writel(EIP197_xDR_PROC_xD_PKT(1) |
+- EIP197_xDR_PROC_xD_COUNT(ndesc * priv->config.rd_offset),
+- priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PROC_COUNT);
+-
+ if (should_complete) {
+ local_bh_disable();
+ sreq->req->complete(sreq->req, ret);
+@@ -645,6 +641,14 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ }
+
+ kfree(sreq);
++ tot_descs += ndesc;
++ }
++
++acknowledge:
++ if (i) {
++ writel(EIP197_xDR_PROC_xD_PKT(i) |
++ EIP197_xDR_PROC_xD_COUNT(tot_descs * priv->config.rd_offset),
++ priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PROC_COUNT);
+ }
+
+ requests_left:
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/614-crypto-inside-secure-handle-more-result-requests-whe.patch b/target/linux/mvebu/patches-4.14/614-crypto-inside-secure-handle-more-result-requests-whe.patch
new file mode 100644
index 0000000000..c90e1401f5
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/614-crypto-inside-secure-handle-more-result-requests-whe.patch
@@ -0,0 +1,70 @@
+From c63ff238eca83cae2e1f69c2ca350d2c1879bcdb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:56 +0100
+Subject: [PATCH 15/36] crypto: inside-secure - handle more result requests
+ when counter is full
+
+This patch modifies the result handling logic to continue handling
+results when the completed requests counter is full and not showing the
+actual number of requests to handle.
+
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 15 ++++++++++++---
+ drivers/crypto/inside-secure/safexcel.h | 2 ++
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index af79bc751ad1..dec1925cf0ad 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -609,12 +609,15 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ {
+ struct safexcel_request *sreq;
+ struct safexcel_context *ctx;
+- int ret, i, nreq, ndesc = 0, tot_descs = 0, done;
++ int ret, i, nreq, ndesc, tot_descs, done;
+ bool should_complete;
+
++handle_results:
++ tot_descs = 0;
++
+ nreq = readl(priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PROC_COUNT);
+- nreq >>= 24;
+- nreq &= GENMASK(6, 0);
++ nreq >>= EIP197_xDR_PROC_xD_PKT_OFFSET;
++ nreq &= EIP197_xDR_PROC_xD_PKT_MASK;
+ if (!nreq)
+ goto requests_left;
+
+@@ -651,6 +654,12 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PROC_COUNT);
+ }
+
++ /* If the number of requests overflowed the counter, try to proceed more
++ * requests.
++ */
++ if (nreq == EIP197_xDR_PROC_xD_PKT_MASK)
++ goto handle_results;
++
+ requests_left:
+ spin_lock_bh(&priv->ring[ring].egress_lock);
+
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 2a0ab6ce716a..0c47e792192d 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -117,6 +117,8 @@
+ #define EIP197_xDR_PREP_CLR_COUNT BIT(31)
+
+ /* EIP197_HIA_xDR_PROC_COUNT */
++#define EIP197_xDR_PROC_xD_PKT_OFFSET 24
++#define EIP197_xDR_PROC_xD_PKT_MASK GENMASK(6, 0)
+ #define EIP197_xDR_PROC_xD_COUNT(n) ((n) << 2)
+ #define EIP197_xDR_PROC_xD_PKT(n) ((n) << 24)
+ #define EIP197_xDR_PROC_CLR_COUNT BIT(31)
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/615-crypto-inside-secure-retry-to-proceed-the-request-la.patch b/target/linux/mvebu/patches-4.14/615-crypto-inside-secure-retry-to-proceed-the-request-la.patch
new file mode 100644
index 0000000000..cfe901e83e
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/615-crypto-inside-secure-retry-to-proceed-the-request-la.patch
@@ -0,0 +1,103 @@
+From 929a581f8afd82685be4433cf39bcaa70606adce Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:57 +0100
+Subject: [PATCH 16/36] crypto: inside-secure - retry to proceed the request
+ later on fail
+
+The dequeueing function was putting back a request in the crypto queue
+on failure (when not enough resources are available) which is not
+perfect as the request will be handled much later. This patch updates
+this logic by keeping a reference on the failed request to try
+proceeding it later when enough resources are available.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 32 +++++++++++++++++++++++---------
+ drivers/crypto/inside-secure/safexcel.h | 6 ++++++
+ 2 files changed, 29 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index dec1925cf0ad..0c0199a65337 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -446,29 +446,36 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ struct safexcel_request *request;
+ int ret, nreq = 0, cdesc = 0, rdesc = 0, commands, results;
+
++ /* If a request wasn't properly dequeued because of a lack of resources,
++ * proceeded it first,
++ */
++ req = priv->ring[ring].req;
++ backlog = priv->ring[ring].backlog;
++ if (req)
++ goto handle_req;
++
+ while (true) {
+ spin_lock_bh(&priv->ring[ring].queue_lock);
+ backlog = crypto_get_backlog(&priv->ring[ring].queue);
+ req = crypto_dequeue_request(&priv->ring[ring].queue);
+ spin_unlock_bh(&priv->ring[ring].queue_lock);
+
+- if (!req)
++ if (!req) {
++ priv->ring[ring].req = NULL;
++ priv->ring[ring].backlog = NULL;
+ goto finalize;
++ }
+
++handle_req:
+ request = kzalloc(sizeof(*request), EIP197_GFP_FLAGS(*req));
+- if (!request) {
+- spin_lock_bh(&priv->ring[ring].queue_lock);
+- crypto_enqueue_request(&priv->ring[ring].queue, req);
+- spin_unlock_bh(&priv->ring[ring].queue_lock);
+- goto finalize;
+- }
++ if (!request)
++ goto request_failed;
+
+ ctx = crypto_tfm_ctx(req->tfm);
+ ret = ctx->send(req, ring, request, &commands, &results);
+ if (ret) {
+ kfree(request);
+- req->complete(req, ret);
+- goto finalize;
++ goto request_failed;
+ }
+
+ if (backlog)
+@@ -492,6 +499,13 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ nreq++;
+ }
+
++request_failed:
++ /* Not enough resources to handle all the requests. Bail out and save
++ * the request and the backlog for the next dequeue call (per-ring).
++ */
++ priv->ring[ring].req = req;
++ priv->ring[ring].backlog = backlog;
++
+ finalize:
+ if (!nreq)
+ return;
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 0c47e792192d..d4955abf873b 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -499,6 +499,12 @@ struct safexcel_crypto_priv {
+
+ /* The ring is currently handling at least one request */
+ bool busy;
++
++ /* Store for current requests when bailing out of the dequeueing
++ * function when no enough resources are available.
++ */
++ struct crypto_async_request *req;
++ struct crypto_async_request *backlog;
+ } ring[EIP197_MAX_RINGS];
+ };
+
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/616-crypto-inside-secure-EIP97-support.patch b/target/linux/mvebu/patches-4.14/616-crypto-inside-secure-EIP97-support.patch
new file mode 100644
index 0000000000..e9e36099e9
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/616-crypto-inside-secure-EIP97-support.patch
@@ -0,0 +1,841 @@
+From 90f63fbb6616deae34fc588b4227a03578c5852a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Antoine=20T=C3=A9nart?= <antoine.tenart at free-electrons.com>
+Date: Thu, 14 Dec 2017 15:26:58 +0100
+Subject: [PATCH 17/36] crypto: inside-secure - EIP97 support
+
+The Inside Secure SafeXcel driver was firstly designed to support the
+EIP197 cryptographic engine which is an evolution (with much more
+feature, better performances) of the EIP97 cryptographic engine. This
+patch convert the Inside Secure SafeXcel driver to support both engines
+(EIP97 + EIP197).
+
+The main differences are the register offsets and the context
+invalidation process which is EIP197 specific. This patch adds an
+indirection on the register offsets and adds checks not to send any
+invalidation request when driving the EIP97. A new compatible is added
+as well to bind the driver from device trees.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 212 +++++++++++++++----------
+ drivers/crypto/inside-secure/safexcel.h | 151 ++++++++++++------
+ drivers/crypto/inside-secure/safexcel_cipher.c | 20 ++-
+ drivers/crypto/inside-secure/safexcel_hash.c | 19 ++-
+ 4 files changed, 264 insertions(+), 138 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 0c0199a65337..b0787f5f62ad 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -108,10 +108,10 @@ static void eip197_write_firmware(struct safexcel_crypto_priv *priv,
+ writel(EIP197_PE_ICE_x_CTRL_SW_RESET |
+ EIP197_PE_ICE_x_CTRL_CLR_ECC_CORR |
+ EIP197_PE_ICE_x_CTRL_CLR_ECC_NON_CORR,
+- priv->base + ctrl);
++ EIP197_PE(priv) + ctrl);
+
+ /* Enable access to the program memory */
+- writel(prog_en, priv->base + EIP197_PE_ICE_RAM_CTRL);
++ writel(prog_en, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL);
+
+ /* Write the firmware */
+ for (i = 0; i < fw->size / sizeof(u32); i++)
+@@ -119,12 +119,12 @@ static void eip197_write_firmware(struct safexcel_crypto_priv *priv,
+ priv->base + EIP197_CLASSIFICATION_RAMS + i * sizeof(u32));
+
+ /* Disable access to the program memory */
+- writel(0, priv->base + EIP197_PE_ICE_RAM_CTRL);
++ writel(0, EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL);
+
+ /* Release engine from reset */
+- val = readl(priv->base + ctrl);
++ val = readl(EIP197_PE(priv) + ctrl);
+ val &= ~EIP197_PE_ICE_x_CTRL_SW_RESET;
+- writel(val, priv->base + ctrl);
++ writel(val, EIP197_PE(priv) + ctrl);
+ }
+
+ static int eip197_load_firmwares(struct safexcel_crypto_priv *priv)
+@@ -145,14 +145,14 @@ static int eip197_load_firmwares(struct safexcel_crypto_priv *priv)
+ }
+
+ /* Clear the scratchpad memory */
+- val = readl(priv->base + EIP197_PE_ICE_SCRATCH_CTRL);
++ val = readl(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL);
+ val |= EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_TIMER |
+ EIP197_PE_ICE_SCRATCH_CTRL_TIMER_EN |
+ EIP197_PE_ICE_SCRATCH_CTRL_SCRATCH_ACCESS |
+ EIP197_PE_ICE_SCRATCH_CTRL_CHANGE_ACCESS;
+- writel(val, priv->base + EIP197_PE_ICE_SCRATCH_CTRL);
++ writel(val, EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_CTRL);
+
+- memset(priv->base + EIP197_PE_ICE_SCRATCH_RAM, 0,
++ memset(EIP197_PE(priv) + EIP197_PE_ICE_SCRATCH_RAM, 0,
+ EIP197_NUM_OF_SCRATCH_BLOCKS * sizeof(u32));
+
+ eip197_write_firmware(priv, fw[FW_IFPP], EIP197_PE_ICE_FPP_CTRL,
+@@ -173,7 +173,7 @@ static int safexcel_hw_setup_cdesc_rings(struct safexcel_crypto_priv *priv)
+ u32 hdw, cd_size_rnd, val;
+ int i;
+
+- hdw = readl(priv->base + EIP197_HIA_OPTIONS);
++ hdw = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS);
+ hdw &= GENMASK(27, 25);
+ hdw >>= 25;
+
+@@ -182,26 +182,25 @@ static int safexcel_hw_setup_cdesc_rings(struct safexcel_crypto_priv *priv)
+ for (i = 0; i < priv->config.rings; i++) {
+ /* ring base address */
+ writel(lower_32_bits(priv->ring[i].cdr.base_dma),
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_RING_BASE_ADDR_LO);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_LO);
+ writel(upper_32_bits(priv->ring[i].cdr.base_dma),
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI);
+
+ writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.cd_offset << 16) |
+ priv->config.cd_size,
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_DESC_SIZE);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_DESC_SIZE);
+ writel(((EIP197_FETCH_COUNT * (cd_size_rnd << hdw)) << 16) |
+ (EIP197_FETCH_COUNT * priv->config.cd_offset),
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_CFG);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_CFG);
+
+ /* Configure DMA tx control */
+ val = EIP197_HIA_xDR_CFG_WR_CACHE(WR_CACHE_3BITS);
+ val |= EIP197_HIA_xDR_CFG_RD_CACHE(RD_CACHE_3BITS);
+- writel(val,
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_DMA_CFG);
++ writel(val, EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_DMA_CFG);
+
+ /* clear any pending interrupt */
+ writel(GENMASK(5, 0),
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_STAT);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_STAT);
+ }
+
+ return 0;
+@@ -212,7 +211,7 @@ static int safexcel_hw_setup_rdesc_rings(struct safexcel_crypto_priv *priv)
+ u32 hdw, rd_size_rnd, val;
+ int i;
+
+- hdw = readl(priv->base + EIP197_HIA_OPTIONS);
++ hdw = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS);
+ hdw &= GENMASK(27, 25);
+ hdw >>= 25;
+
+@@ -221,33 +220,33 @@ static int safexcel_hw_setup_rdesc_rings(struct safexcel_crypto_priv *priv)
+ for (i = 0; i < priv->config.rings; i++) {
+ /* ring base address */
+ writel(lower_32_bits(priv->ring[i].rdr.base_dma),
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_RING_BASE_ADDR_LO);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_LO);
+ writel(upper_32_bits(priv->ring[i].rdr.base_dma),
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_BASE_ADDR_HI);
+
+ writel(EIP197_xDR_DESC_MODE_64BIT | (priv->config.rd_offset << 16) |
+ priv->config.rd_size,
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_DESC_SIZE);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_DESC_SIZE);
+
+ writel(((EIP197_FETCH_COUNT * (rd_size_rnd << hdw)) << 16) |
+ (EIP197_FETCH_COUNT * priv->config.rd_offset),
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_CFG);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_CFG);
+
+ /* Configure DMA tx control */
+ val = EIP197_HIA_xDR_CFG_WR_CACHE(WR_CACHE_3BITS);
+ val |= EIP197_HIA_xDR_CFG_RD_CACHE(RD_CACHE_3BITS);
+ val |= EIP197_HIA_xDR_WR_RES_BUF | EIP197_HIA_xDR_WR_CTRL_BUG;
+ writel(val,
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_DMA_CFG);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_DMA_CFG);
+
+ /* clear any pending interrupt */
+ writel(GENMASK(7, 0),
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_STAT);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_STAT);
+
+ /* enable ring interrupt */
+- val = readl(priv->base + EIP197_HIA_AIC_R_ENABLE_CTRL(i));
++ val = readl(EIP197_HIA_AIC_R(priv) + EIP197_HIA_AIC_R_ENABLE_CTRL(i));
+ val |= EIP197_RDR_IRQ(i);
+- writel(val, priv->base + EIP197_HIA_AIC_R_ENABLE_CTRL(i));
++ writel(val, EIP197_HIA_AIC_R(priv) + EIP197_HIA_AIC_R_ENABLE_CTRL(i));
+ }
+
+ return 0;
+@@ -259,39 +258,40 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ int i, ret;
+
+ /* Determine endianess and configure byte swap */
+- version = readl(priv->base + EIP197_HIA_VERSION);
+- val = readl(priv->base + EIP197_HIA_MST_CTRL);
++ version = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_VERSION);
++ val = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
+
+ if ((version & 0xffff) == EIP197_HIA_VERSION_BE)
+ val |= EIP197_MST_CTRL_BYTE_SWAP;
+ else if (((version >> 16) & 0xffff) == EIP197_HIA_VERSION_LE)
+ val |= (EIP197_MST_CTRL_NO_BYTE_SWAP >> 24);
+
+- writel(val, priv->base + EIP197_HIA_MST_CTRL);
+-
++ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
+
+ /* Configure wr/rd cache values */
+ writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) |
+ EIP197_MST_CTRL_WD_CACHE(WR_CACHE_4BITS),
+- priv->base + EIP197_MST_CTRL);
++ EIP197_HIA_GEN_CFG(priv) + EIP197_MST_CTRL);
+
+ /* Interrupts reset */
+
+ /* Disable all global interrupts */
+- writel(0, priv->base + EIP197_HIA_AIC_G_ENABLE_CTRL);
++ writel(0, EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ENABLE_CTRL);
+
+ /* Clear any pending interrupt */
+- writel(GENMASK(31, 0), priv->base + EIP197_HIA_AIC_G_ACK);
++ writel(GENMASK(31, 0), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK);
+
+ /* Data Fetch Engine configuration */
+
+ /* Reset all DFE threads */
+ writel(EIP197_DxE_THR_CTRL_RESET_PE,
+- priv->base + EIP197_HIA_DFE_THR_CTRL);
++ EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL);
+
+- /* Reset HIA input interface arbiter */
+- writel(EIP197_HIA_RA_PE_CTRL_RESET,
+- priv->base + EIP197_HIA_RA_PE_CTRL);
++ if (priv->version == EIP197) {
++ /* Reset HIA input interface arbiter */
++ writel(EIP197_HIA_RA_PE_CTRL_RESET,
++ EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL);
++ }
+
+ /* DMA transfer size to use */
+ val = EIP197_HIA_DFE_CFG_DIS_DEBUG;
+@@ -299,29 +299,32 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ val |= EIP197_HIA_DxE_CFG_MIN_CTRL_SIZE(5) | EIP197_HIA_DxE_CFG_MAX_CTRL_SIZE(7);
+ val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(RD_CACHE_3BITS);
+ val |= EIP197_HIA_DxE_CFG_CTRL_CACHE_CTRL(RD_CACHE_3BITS);
+- writel(val, priv->base + EIP197_HIA_DFE_CFG);
++ writel(val, EIP197_HIA_DFE(priv) + EIP197_HIA_DFE_CFG);
+
+ /* Leave the DFE threads reset state */
+- writel(0, priv->base + EIP197_HIA_DFE_THR_CTRL);
++ writel(0, EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL);
+
+ /* Configure the procesing engine thresholds */
+ writel(EIP197_PE_IN_xBUF_THRES_MIN(5) | EIP197_PE_IN_xBUF_THRES_MAX(9),
+- priv->base + EIP197_PE_IN_DBUF_THRES);
++ EIP197_PE(priv) + EIP197_PE_IN_DBUF_THRES);
+ writel(EIP197_PE_IN_xBUF_THRES_MIN(5) | EIP197_PE_IN_xBUF_THRES_MAX(7),
+- priv->base + EIP197_PE_IN_TBUF_THRES);
++ EIP197_PE(priv) + EIP197_PE_IN_TBUF_THRES);
+
+- /* enable HIA input interface arbiter and rings */
+- writel(EIP197_HIA_RA_PE_CTRL_EN | GENMASK(priv->config.rings - 1, 0),
+- priv->base + EIP197_HIA_RA_PE_CTRL);
++ if (priv->version == EIP197) {
++ /* enable HIA input interface arbiter and rings */
++ writel(EIP197_HIA_RA_PE_CTRL_EN |
++ GENMASK(priv->config.rings - 1, 0),
++ EIP197_HIA_AIC(priv) + EIP197_HIA_RA_PE_CTRL);
++ }
+
+ /* Data Store Engine configuration */
+
+ /* Reset all DSE threads */
+ writel(EIP197_DxE_THR_CTRL_RESET_PE,
+- priv->base + EIP197_HIA_DSE_THR_CTRL);
++ EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL);
+
+ /* Wait for all DSE threads to complete */
+- while ((readl(priv->base + EIP197_HIA_DSE_THR_STAT) &
++ while ((readl(EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_STAT) &
+ GENMASK(15, 12)) != GENMASK(15, 12))
+ ;
+
+@@ -330,15 +333,19 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(7) | EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(8);
+ val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS);
+ val |= EIP197_HIA_DSE_CFG_ALLWAYS_BUFFERABLE;
+- val |= EIP197_HIA_DSE_CFG_EN_SINGLE_WR;
+- writel(val, priv->base + EIP197_HIA_DSE_CFG);
++ /* FIXME: instability issues can occur for EIP97 but disabling it impact
++ * performances.
++ */
++ if (priv->version == EIP197)
++ val |= EIP197_HIA_DSE_CFG_EN_SINGLE_WR;
++ writel(val, EIP197_HIA_DSE(priv) + EIP197_HIA_DSE_CFG);
+
+ /* Leave the DSE threads reset state */
+- writel(0, priv->base + EIP197_HIA_DSE_THR_CTRL);
++ writel(0, EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL);
+
+ /* Configure the procesing engine thresholds */
+ writel(EIP197_PE_OUT_DBUF_THRES_MIN(7) | EIP197_PE_OUT_DBUF_THRES_MAX(8),
+- priv->base + EIP197_PE_OUT_DBUF_THRES);
++ EIP197_PE(priv) + EIP197_PE_OUT_DBUF_THRES);
+
+ /* Processing Engine configuration */
+
+@@ -348,73 +355,75 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ val |= EIP197_ALG_AES_ECB | EIP197_ALG_AES_CBC;
+ val |= EIP197_ALG_SHA1 | EIP197_ALG_HMAC_SHA1;
+ val |= EIP197_ALG_SHA2;
+- writel(val, priv->base + EIP197_PE_EIP96_FUNCTION_EN);
++ writel(val, EIP197_PE(priv) + EIP197_PE_EIP96_FUNCTION_EN);
+
+ /* Command Descriptor Rings prepare */
+ for (i = 0; i < priv->config.rings; i++) {
+ /* Clear interrupts for this ring */
+ writel(GENMASK(31, 0),
+- priv->base + EIP197_HIA_AIC_R_ENABLE_CLR(i));
++ EIP197_HIA_AIC_R(priv) + EIP197_HIA_AIC_R_ENABLE_CLR(i));
+
+ /* Disable external triggering */
+- writel(0, priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_CFG);
++ writel(0, EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_CFG);
+
+ /* Clear the pending prepared counter */
+ writel(EIP197_xDR_PREP_CLR_COUNT,
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_PREP_COUNT);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_PREP_COUNT);
+
+ /* Clear the pending processed counter */
+ writel(EIP197_xDR_PROC_CLR_COUNT,
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_PROC_COUNT);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_PROC_COUNT);
+
+ writel(0,
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_PREP_PNTR);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_PREP_PNTR);
+ writel(0,
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_PROC_PNTR);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_PROC_PNTR);
+
+ writel((EIP197_DEFAULT_RING_SIZE * priv->config.cd_offset) << 2,
+- priv->base + EIP197_HIA_CDR(i) + EIP197_HIA_xDR_RING_SIZE);
++ EIP197_HIA_CDR(priv, i) + EIP197_HIA_xDR_RING_SIZE);
+ }
+
+ /* Result Descriptor Ring prepare */
+ for (i = 0; i < priv->config.rings; i++) {
+ /* Disable external triggering*/
+- writel(0, priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_CFG);
++ writel(0, EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_CFG);
+
+ /* Clear the pending prepared counter */
+ writel(EIP197_xDR_PREP_CLR_COUNT,
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_PREP_COUNT);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_PREP_COUNT);
+
+ /* Clear the pending processed counter */
+ writel(EIP197_xDR_PROC_CLR_COUNT,
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_PROC_COUNT);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_PROC_COUNT);
+
+ writel(0,
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_PREP_PNTR);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_PREP_PNTR);
+ writel(0,
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_PROC_PNTR);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_PROC_PNTR);
+
+ /* Ring size */
+ writel((EIP197_DEFAULT_RING_SIZE * priv->config.rd_offset) << 2,
+- priv->base + EIP197_HIA_RDR(i) + EIP197_HIA_xDR_RING_SIZE);
++ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_RING_SIZE);
+ }
+
+ /* Enable command descriptor rings */
+ writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0),
+- priv->base + EIP197_HIA_DFE_THR_CTRL);
++ EIP197_HIA_DFE_THR(priv) + EIP197_HIA_DFE_THR_CTRL);
+
+ /* Enable result descriptor rings */
+ writel(EIP197_DxE_THR_CTRL_EN | GENMASK(priv->config.rings - 1, 0),
+- priv->base + EIP197_HIA_DSE_THR_CTRL);
++ EIP197_HIA_DSE_THR(priv) + EIP197_HIA_DSE_THR_CTRL);
+
+ /* Clear any HIA interrupt */
+- writel(GENMASK(30, 20), priv->base + EIP197_HIA_AIC_G_ACK);
++ writel(GENMASK(30, 20), EIP197_HIA_AIC_G(priv) + EIP197_HIA_AIC_G_ACK);
+
+- eip197_trc_cache_init(priv);
++ if (priv->version == EIP197) {
++ eip197_trc_cache_init(priv);
+
+- ret = eip197_load_firmwares(priv);
+- if (ret)
+- return ret;
++ ret = eip197_load_firmwares(priv);
++ if (ret)
++ return ret;
++ }
+
+ safexcel_hw_setup_cdesc_rings(priv);
+ safexcel_hw_setup_rdesc_rings(priv);
+@@ -434,7 +443,7 @@ int safexcel_try_push_requests(struct safexcel_crypto_priv *priv, int ring,
+ /* Configure when we want an interrupt */
+ writel(EIP197_HIA_RDR_THRESH_PKT_MODE |
+ EIP197_HIA_RDR_THRESH_PROC_PKT(coal),
+- priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_THRESH);
++ EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_THRESH);
+
+ return coal;
+ }
+@@ -524,11 +533,11 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+
+ /* let the RDR know we have pending descriptors */
+ writel((rdesc * priv->config.rd_offset) << 2,
+- priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PREP_COUNT);
++ EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_PREP_COUNT);
+
+ /* let the CDR know we have pending descriptors */
+ writel((cdesc * priv->config.cd_offset) << 2,
+- priv->base + EIP197_HIA_CDR(ring) + EIP197_HIA_xDR_PREP_COUNT);
++ EIP197_HIA_CDR(priv, ring) + EIP197_HIA_xDR_PREP_COUNT);
+ }
+
+ void safexcel_free_context(struct safexcel_crypto_priv *priv,
+@@ -629,7 +638,7 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ handle_results:
+ tot_descs = 0;
+
+- nreq = readl(priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PROC_COUNT);
++ nreq = readl(EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_PROC_COUNT);
+ nreq >>= EIP197_xDR_PROC_xD_PKT_OFFSET;
+ nreq &= EIP197_xDR_PROC_xD_PKT_MASK;
+ if (!nreq)
+@@ -665,7 +674,7 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ if (i) {
+ writel(EIP197_xDR_PROC_xD_PKT(i) |
+ EIP197_xDR_PROC_xD_COUNT(tot_descs * priv->config.rd_offset),
+- priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_PROC_COUNT);
++ EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_PROC_COUNT);
+ }
+
+ /* If the number of requests overflowed the counter, try to proceed more
+@@ -707,13 +716,13 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
+ int ring = irq_data->ring, rc = IRQ_NONE;
+ u32 status, stat;
+
+- status = readl(priv->base + EIP197_HIA_AIC_R_ENABLED_STAT(ring));
++ status = readl(EIP197_HIA_AIC_R(priv) + EIP197_HIA_AIC_R_ENABLED_STAT(ring));
+ if (!status)
+ return rc;
+
+ /* RDR interrupts */
+ if (status & EIP197_RDR_IRQ(ring)) {
+- stat = readl(priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_STAT);
++ stat = readl(EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_STAT);
+
+ if (unlikely(stat & EIP197_xDR_ERR)) {
+ /*
+@@ -728,11 +737,11 @@ static irqreturn_t safexcel_irq_ring(int irq, void *data)
+
+ /* ACK the interrupts */
+ writel(stat & 0xff,
+- priv->base + EIP197_HIA_RDR(ring) + EIP197_HIA_xDR_STAT);
++ EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_STAT);
+ }
+
+ /* ACK the interrupts */
+- writel(status, priv->base + EIP197_HIA_AIC_R_ACK(ring));
++ writel(status, EIP197_HIA_AIC_R(priv) + EIP197_HIA_AIC_R_ACK(ring));
+
+ return rc;
+ }
+@@ -828,11 +837,11 @@ static void safexcel_configure(struct safexcel_crypto_priv *priv)
+ {
+ u32 val, mask;
+
+- val = readl(priv->base + EIP197_HIA_OPTIONS);
++ val = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS);
+ val = (val & GENMASK(27, 25)) >> 25;
+ mask = BIT(val) - 1;
+
+- val = readl(priv->base + EIP197_HIA_OPTIONS);
++ val = readl(EIP197_HIA_AIC_G(priv) + EIP197_HIA_OPTIONS);
+ priv->config.rings = min_t(u32, val & GENMASK(3, 0), max_rings);
+
+ priv->config.cd_size = (sizeof(struct safexcel_command_desc) / sizeof(u32));
+@@ -842,6 +851,35 @@ static void safexcel_configure(struct safexcel_crypto_priv *priv)
+ priv->config.rd_offset = (priv->config.rd_size + mask) & ~mask;
+ }
+
++static void safexcel_init_register_offsets(struct safexcel_crypto_priv *priv)
++{
++ struct safexcel_register_offsets *offsets = &priv->offsets;
++
++ if (priv->version == EIP197) {
++ offsets->hia_aic = EIP197_HIA_AIC_BASE;
++ offsets->hia_aic_g = EIP197_HIA_AIC_G_BASE;
++ offsets->hia_aic_r = EIP197_HIA_AIC_R_BASE;
++ offsets->hia_aic_xdr = EIP197_HIA_AIC_xDR_BASE;
++ offsets->hia_dfe = EIP197_HIA_DFE_BASE;
++ offsets->hia_dfe_thr = EIP197_HIA_DFE_THR_BASE;
++ offsets->hia_dse = EIP197_HIA_DSE_BASE;
++ offsets->hia_dse_thr = EIP197_HIA_DSE_THR_BASE;
++ offsets->hia_gen_cfg = EIP197_HIA_GEN_CFG_BASE;
++ offsets->pe = EIP197_PE_BASE;
++ } else {
++ offsets->hia_aic = EIP97_HIA_AIC_BASE;
++ offsets->hia_aic_g = EIP97_HIA_AIC_G_BASE;
++ offsets->hia_aic_r = EIP97_HIA_AIC_R_BASE;
++ offsets->hia_aic_xdr = EIP97_HIA_AIC_xDR_BASE;
++ offsets->hia_dfe = EIP97_HIA_DFE_BASE;
++ offsets->hia_dfe_thr = EIP97_HIA_DFE_THR_BASE;
++ offsets->hia_dse = EIP97_HIA_DSE_BASE;
++ offsets->hia_dse_thr = EIP97_HIA_DSE_THR_BASE;
++ offsets->hia_gen_cfg = EIP97_HIA_GEN_CFG_BASE;
++ offsets->pe = EIP97_PE_BASE;
++ }
++}
++
+ static int safexcel_probe(struct platform_device *pdev)
+ {
+ struct device *dev = &pdev->dev;
+@@ -854,6 +892,9 @@ static int safexcel_probe(struct platform_device *pdev)
+ return -ENOMEM;
+
+ priv->dev = dev;
++ priv->version = (enum safexcel_eip_version)of_device_get_match_data(dev);
++
++ safexcel_init_register_offsets(priv);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->base = devm_ioremap_resource(dev, res);
+@@ -980,7 +1021,14 @@ static int safexcel_remove(struct platform_device *pdev)
+ }
+
+ static const struct of_device_id safexcel_of_match_table[] = {
+- { .compatible = "inside-secure,safexcel-eip197" },
++ {
++ .compatible = "inside-secure,safexcel-eip97",
++ .data = (void *)EIP97,
++ },
++ {
++ .compatible = "inside-secure,safexcel-eip197",
++ .data = (void *)EIP197,
++ },
+ {},
+ };
+
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index d4955abf873b..4e219c21608b 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -28,55 +28,94 @@
+ #define EIP197_GFP_FLAGS(base) ((base).flags & CRYPTO_TFM_REQ_MAY_SLEEP ? \
+ GFP_KERNEL : GFP_ATOMIC)
+
++/* Register base offsets */
++#define EIP197_HIA_AIC(priv) ((priv)->base + (priv)->offsets.hia_aic)
++#define EIP197_HIA_AIC_G(priv) ((priv)->base + (priv)->offsets.hia_aic_g)
++#define EIP197_HIA_AIC_R(priv) ((priv)->base + (priv)->offsets.hia_aic_r)
++#define EIP197_HIA_AIC_xDR(priv) ((priv)->base + (priv)->offsets.hia_aic_xdr)
++#define EIP197_HIA_DFE(priv) ((priv)->base + (priv)->offsets.hia_dfe)
++#define EIP197_HIA_DFE_THR(priv) ((priv)->base + (priv)->offsets.hia_dfe_thr)
++#define EIP197_HIA_DSE(priv) ((priv)->base + (priv)->offsets.hia_dse)
++#define EIP197_HIA_DSE_THR(priv) ((priv)->base + (priv)->offsets.hia_dse_thr)
++#define EIP197_HIA_GEN_CFG(priv) ((priv)->base + (priv)->offsets.hia_gen_cfg)
++#define EIP197_PE(priv) ((priv)->base + (priv)->offsets.pe)
++
++/* EIP197 base offsets */
++#define EIP197_HIA_AIC_BASE 0x90000
++#define EIP197_HIA_AIC_G_BASE 0x90000
++#define EIP197_HIA_AIC_R_BASE 0x90800
++#define EIP197_HIA_AIC_xDR_BASE 0x80000
++#define EIP197_HIA_DFE_BASE 0x8c000
++#define EIP197_HIA_DFE_THR_BASE 0x8c040
++#define EIP197_HIA_DSE_BASE 0x8d000
++#define EIP197_HIA_DSE_THR_BASE 0x8d040
++#define EIP197_HIA_GEN_CFG_BASE 0xf0000
++#define EIP197_PE_BASE 0xa0000
++
++/* EIP97 base offsets */
++#define EIP97_HIA_AIC_BASE 0x0
++#define EIP97_HIA_AIC_G_BASE 0x0
++#define EIP97_HIA_AIC_R_BASE 0x0
++#define EIP97_HIA_AIC_xDR_BASE 0x0
++#define EIP97_HIA_DFE_BASE 0xf000
++#define EIP97_HIA_DFE_THR_BASE 0xf200
++#define EIP97_HIA_DSE_BASE 0xf400
++#define EIP97_HIA_DSE_THR_BASE 0xf600
++#define EIP97_HIA_GEN_CFG_BASE 0x10000
++#define EIP97_PE_BASE 0x10000
++
+ /* CDR/RDR register offsets */
+-#define EIP197_HIA_xDR_OFF(r) (0x80000 + (r) * 0x1000)
+-#define EIP197_HIA_CDR(r) (EIP197_HIA_xDR_OFF(r))
+-#define EIP197_HIA_RDR(r) (EIP197_HIA_xDR_OFF(r) + 0x800)
+-#define EIP197_HIA_xDR_RING_BASE_ADDR_LO 0x0
+-#define EIP197_HIA_xDR_RING_BASE_ADDR_HI 0x4
+-#define EIP197_HIA_xDR_RING_SIZE 0x18
+-#define EIP197_HIA_xDR_DESC_SIZE 0x1c
+-#define EIP197_HIA_xDR_CFG 0x20
+-#define EIP197_HIA_xDR_DMA_CFG 0x24
+-#define EIP197_HIA_xDR_THRESH 0x28
+-#define EIP197_HIA_xDR_PREP_COUNT 0x2c
+-#define EIP197_HIA_xDR_PROC_COUNT 0x30
+-#define EIP197_HIA_xDR_PREP_PNTR 0x34
+-#define EIP197_HIA_xDR_PROC_PNTR 0x38
+-#define EIP197_HIA_xDR_STAT 0x3c
++#define EIP197_HIA_xDR_OFF(priv, r) (EIP197_HIA_AIC_xDR(priv) + (r) * 0x1000)
++#define EIP197_HIA_CDR(priv, r) (EIP197_HIA_xDR_OFF(priv, r))
++#define EIP197_HIA_RDR(priv, r) (EIP197_HIA_xDR_OFF(priv, r) + 0x800)
++#define EIP197_HIA_xDR_RING_BASE_ADDR_LO 0x0000
++#define EIP197_HIA_xDR_RING_BASE_ADDR_HI 0x0004
++#define EIP197_HIA_xDR_RING_SIZE 0x0018
++#define EIP197_HIA_xDR_DESC_SIZE 0x001c
++#define EIP197_HIA_xDR_CFG 0x0020
++#define EIP197_HIA_xDR_DMA_CFG 0x0024
++#define EIP197_HIA_xDR_THRESH 0x0028
++#define EIP197_HIA_xDR_PREP_COUNT 0x002c
++#define EIP197_HIA_xDR_PROC_COUNT 0x0030
++#define EIP197_HIA_xDR_PREP_PNTR 0x0034
++#define EIP197_HIA_xDR_PROC_PNTR 0x0038
++#define EIP197_HIA_xDR_STAT 0x003c
+
+ /* register offsets */
+-#define EIP197_HIA_DFE_CFG 0x8c000
+-#define EIP197_HIA_DFE_THR_CTRL 0x8c040
+-#define EIP197_HIA_DFE_THR_STAT 0x8c044
+-#define EIP197_HIA_DSE_CFG 0x8d000
+-#define EIP197_HIA_DSE_THR_CTRL 0x8d040
+-#define EIP197_HIA_DSE_THR_STAT 0x8d044
+-#define EIP197_HIA_RA_PE_CTRL 0x90010
+-#define EIP197_HIA_RA_PE_STAT 0x90014
++#define EIP197_HIA_DFE_CFG 0x0000
++#define EIP197_HIA_DFE_THR_CTRL 0x0000
++#define EIP197_HIA_DFE_THR_STAT 0x0004
++#define EIP197_HIA_DSE_CFG 0x0000
++#define EIP197_HIA_DSE_THR_CTRL 0x0000
++#define EIP197_HIA_DSE_THR_STAT 0x0004
++#define EIP197_HIA_RA_PE_CTRL 0x0010
++#define EIP197_HIA_RA_PE_STAT 0x0014
+ #define EIP197_HIA_AIC_R_OFF(r) ((r) * 0x1000)
+-#define EIP197_HIA_AIC_R_ENABLE_CTRL(r) (0x9e808 - EIP197_HIA_AIC_R_OFF(r))
+-#define EIP197_HIA_AIC_R_ENABLED_STAT(r) (0x9e810 - EIP197_HIA_AIC_R_OFF(r))
+-#define EIP197_HIA_AIC_R_ACK(r) (0x9e810 - EIP197_HIA_AIC_R_OFF(r))
+-#define EIP197_HIA_AIC_R_ENABLE_CLR(r) (0x9e814 - EIP197_HIA_AIC_R_OFF(r))
+-#define EIP197_HIA_AIC_G_ENABLE_CTRL 0x9f808
+-#define EIP197_HIA_AIC_G_ENABLED_STAT 0x9f810
+-#define EIP197_HIA_AIC_G_ACK 0x9f810
+-#define EIP197_HIA_MST_CTRL 0x9fff4
+-#define EIP197_HIA_OPTIONS 0x9fff8
+-#define EIP197_HIA_VERSION 0x9fffc
+-#define EIP197_PE_IN_DBUF_THRES 0xa0000
+-#define EIP197_PE_IN_TBUF_THRES 0xa0100
+-#define EIP197_PE_ICE_SCRATCH_RAM 0xa0800
+-#define EIP197_PE_ICE_PUE_CTRL 0xa0c80
+-#define EIP197_PE_ICE_SCRATCH_CTRL 0xa0d04
+-#define EIP197_PE_ICE_FPP_CTRL 0xa0d80
+-#define EIP197_PE_ICE_RAM_CTRL 0xa0ff0
+-#define EIP197_PE_EIP96_FUNCTION_EN 0xa1004
+-#define EIP197_PE_EIP96_CONTEXT_CTRL 0xa1008
+-#define EIP197_PE_EIP96_CONTEXT_STAT 0xa100c
+-#define EIP197_PE_OUT_DBUF_THRES 0xa1c00
+-#define EIP197_PE_OUT_TBUF_THRES 0xa1d00
++#define EIP197_HIA_AIC_R_ENABLE_CTRL(r) (0xe008 - EIP197_HIA_AIC_R_OFF(r))
++#define EIP197_HIA_AIC_R_ENABLED_STAT(r) (0xe010 - EIP197_HIA_AIC_R_OFF(r))
++#define EIP197_HIA_AIC_R_ACK(r) (0xe010 - EIP197_HIA_AIC_R_OFF(r))
++#define EIP197_HIA_AIC_R_ENABLE_CLR(r) (0xe014 - EIP197_HIA_AIC_R_OFF(r))
++#define EIP197_HIA_AIC_G_ENABLE_CTRL 0xf808
++#define EIP197_HIA_AIC_G_ENABLED_STAT 0xf810
++#define EIP197_HIA_AIC_G_ACK 0xf810
++#define EIP197_HIA_MST_CTRL 0xfff4
++#define EIP197_HIA_OPTIONS 0xfff8
++#define EIP197_HIA_VERSION 0xfffc
++#define EIP197_PE_IN_DBUF_THRES 0x0000
++#define EIP197_PE_IN_TBUF_THRES 0x0100
++#define EIP197_PE_ICE_SCRATCH_RAM 0x0800
++#define EIP197_PE_ICE_PUE_CTRL 0x0c80
++#define EIP197_PE_ICE_SCRATCH_CTRL 0x0d04
++#define EIP197_PE_ICE_FPP_CTRL 0x0d80
++#define EIP197_PE_ICE_RAM_CTRL 0x0ff0
++#define EIP197_PE_EIP96_FUNCTION_EN 0x1004
++#define EIP197_PE_EIP96_CONTEXT_CTRL 0x1008
++#define EIP197_PE_EIP96_CONTEXT_STAT 0x100c
++#define EIP197_PE_OUT_DBUF_THRES 0x1c00
++#define EIP197_PE_OUT_TBUF_THRES 0x1d00
++#define EIP197_MST_CTRL 0xfff4
++
++/* EIP197-specific registers, no indirection */
+ #define EIP197_CLASSIFICATION_RAMS 0xe0000
+ #define EIP197_TRC_CTRL 0xf0800
+ #define EIP197_TRC_LASTRES 0xf0804
+@@ -90,7 +129,6 @@
+ #define EIP197_TRC_ECCDATASTAT 0xf083c
+ #define EIP197_TRC_ECCDATA 0xf0840
+ #define EIP197_CS_RAM_CTRL 0xf7ff0
+-#define EIP197_MST_CTRL 0xffff4
+
+ /* EIP197_HIA_xDR_DESC_SIZE */
+ #define EIP197_xDR_DESC_MODE_64BIT BIT(31)
+@@ -465,12 +503,33 @@ struct safexcel_work_data {
+ int ring;
+ };
+
++enum safexcel_eip_version {
++ EIP97,
++ EIP197,
++};
++
++struct safexcel_register_offsets {
++ u32 hia_aic;
++ u32 hia_aic_g;
++ u32 hia_aic_r;
++ u32 hia_aic_xdr;
++ u32 hia_dfe;
++ u32 hia_dfe_thr;
++ u32 hia_dse;
++ u32 hia_dse_thr;
++ u32 hia_gen_cfg;
++ u32 pe;
++};
++
+ struct safexcel_crypto_priv {
+ void __iomem *base;
+ struct device *dev;
+ struct clk *clk;
+ struct safexcel_config config;
+
++ enum safexcel_eip_version version;
++ struct safexcel_register_offsets offsets;
++
+ /* context DMA pool */
+ struct dma_pool *context_pool;
+
+diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c
+index 7c9a2d87135b..17a7725a6f6d 100644
+--- a/drivers/crypto/inside-secure/safexcel_cipher.c
++++ b/drivers/crypto/inside-secure/safexcel_cipher.c
+@@ -69,6 +69,7 @@ static int safexcel_aes_setkey(struct crypto_skcipher *ctfm, const u8 *key,
+ {
+ struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
+ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
++ struct safexcel_crypto_priv *priv = ctx->priv;
+ struct crypto_aes_ctx aes;
+ int ret, i;
+
+@@ -78,7 +79,7 @@ static int safexcel_aes_setkey(struct crypto_skcipher *ctfm, const u8 *key,
+ return ret;
+ }
+
+- if (ctx->base.ctxr_dma) {
++ if (priv->version == EIP197 && ctx->base.ctxr_dma) {
+ for (i = 0; i < len / sizeof(u32); i++) {
+ if (ctx->key[i] != cpu_to_le32(aes.key_enc[i])) {
+ ctx->base.needs_inv = true;
+@@ -411,9 +412,13 @@ static int safexcel_send(struct crypto_async_request *async,
+ int *commands, int *results)
+ {
+ struct skcipher_request *req = skcipher_request_cast(async);
++ struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+ struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);
++ struct safexcel_crypto_priv *priv = ctx->priv;
+ int ret;
+
++ BUG_ON(priv->version == EIP97 && sreq->needs_inv);
++
+ if (sreq->needs_inv)
+ ret = safexcel_cipher_send_inv(async, ring, request,
+ commands, results);
+@@ -476,7 +481,7 @@ static int safexcel_aes(struct skcipher_request *req,
+ ctx->mode = mode;
+
+ if (ctx->base.ctxr) {
+- if (ctx->base.needs_inv) {
++ if (priv->version == EIP197 && ctx->base.needs_inv) {
+ sreq->needs_inv = true;
+ ctx->base.needs_inv = false;
+ }
+@@ -544,9 +549,14 @@ static void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm)
+
+ memzero_explicit(ctx->base.ctxr->data, 8 * sizeof(u32));
+
+- ret = safexcel_cipher_exit_inv(tfm);
+- if (ret)
+- dev_warn(priv->dev, "cipher: invalidation error %d\n", ret);
++ if (priv->version == EIP197) {
++ ret = safexcel_cipher_exit_inv(tfm);
++ if (ret)
++ dev_warn(priv->dev, "cipher: invalidation error %d\n", ret);
++ } else {
++ dma_pool_free(priv->context_pool, ctx->base.ctxr,
++ ctx->base.ctxr_dma);
++ }
+ }
+
+ struct safexcel_alg_template safexcel_alg_ecb_aes = {
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 6912c032200b..b9a2bfd91c20 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -415,6 +415,8 @@ static int safexcel_handle_result(struct safexcel_crypto_priv *priv, int ring,
+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
+ int err;
+
++ BUG_ON(priv->version == EIP97 && req->needs_inv);
++
+ if (req->needs_inv) {
+ req->needs_inv = false;
+ err = safexcel_handle_inv_result(priv, ring, async,
+@@ -536,7 +538,8 @@ static int safexcel_ahash_enqueue(struct ahash_request *areq)
+ req->needs_inv = false;
+
+ if (ctx->base.ctxr) {
+- if (!ctx->base.needs_inv && req->processed &&
++ if (priv->version == EIP197 &&
++ !ctx->base.needs_inv && req->processed &&
+ ctx->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED)
+ /* We're still setting needs_inv here, even though it is
+ * cleared right away, because the needs_inv flag can be
+@@ -729,9 +732,14 @@ static void safexcel_ahash_cra_exit(struct crypto_tfm *tfm)
+ if (!ctx->base.ctxr)
+ return;
+
+- ret = safexcel_ahash_exit_inv(tfm);
+- if (ret)
+- dev_warn(priv->dev, "hash: invalidation error %d\n", ret);
++ if (priv->version == EIP197) {
++ ret = safexcel_ahash_exit_inv(tfm);
++ if (ret)
++ dev_warn(priv->dev, "hash: invalidation error %d\n", ret);
++ } else {
++ dma_pool_free(priv->context_pool, ctx->base.ctxr,
++ ctx->base.ctxr_dma);
++ }
+ }
+
+ struct safexcel_alg_template safexcel_alg_sha1 = {
+@@ -935,6 +943,7 @@ static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
+ unsigned int keylen)
+ {
+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
++ struct safexcel_crypto_priv *priv = ctx->priv;
+ struct safexcel_ahash_export_state istate, ostate;
+ int ret, i;
+
+@@ -942,7 +951,7 @@ static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
+ if (ret)
+ return ret;
+
+- if (ctx->base.ctxr) {
++ if (priv->version == EIP197 && ctx->base.ctxr) {
+ for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) {
+ if (ctx->ipad[i] != le32_to_cpu(istate.state[i]) ||
+ ctx->opad[i] != le32_to_cpu(ostate.state[i])) {
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/617-crypto-inside-secure-make-function-safexcel_try_push.patch b/target/linux/mvebu/patches-4.14/617-crypto-inside-secure-make-function-safexcel_try_push.patch
new file mode 100644
index 0000000000..e05e0484c8
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/617-crypto-inside-secure-make-function-safexcel_try_push.patch
@@ -0,0 +1,38 @@
+From a7586ad9713b6eafecb6e6724c75a4c4071c9a23 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king at canonical.com>
+Date: Tue, 16 Jan 2018 08:41:58 +0100
+Subject: [PATCH 18/36] crypto: inside-secure - make function
+ safexcel_try_push_requests static
+
+The function safexcel_try_push_requests is local to the source and does
+not need to be in global scope, so make it static.
+
+Cleans up sparse warning:
+symbol 'safexcel_try_push_requests' was not declared. Should it be static?
+
+Signed-off-by: Colin Ian King <colin.king at canonical.com>
+[Antoine: fixed alignment]
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index b0787f5f62ad..46b691aae475 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -432,8 +432,8 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ }
+
+ /* Called with ring's lock taken */
+-int safexcel_try_push_requests(struct safexcel_crypto_priv *priv, int ring,
+- int reqs)
++static int safexcel_try_push_requests(struct safexcel_crypto_priv *priv,
++ int ring, int reqs)
+ {
+ int coal = min_t(int, reqs, EIP197_MAX_BATCH_SZ);
+
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/618-crypto-inside-secure-do-not-overwrite-the-threshold-.patch b/target/linux/mvebu/patches-4.14/618-crypto-inside-secure-do-not-overwrite-the-threshold-.patch
new file mode 100644
index 0000000000..f2c62b02eb
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/618-crypto-inside-secure-do-not-overwrite-the-threshold-.patch
@@ -0,0 +1,40 @@
+From e0080b4984f85b8cb0b824528b562d3b126e7607 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Tue, 13 Feb 2018 09:26:51 +0100
+Subject: [PATCH 19/36] crypto: inside-secure - do not overwrite the threshold
+ value
+
+This patch fixes the Inside Secure SafeXcel driver not to overwrite the
+interrupt threshold value. In certain cases the value of this register,
+which controls when to fire an interrupt, was overwritten. This lead to
+packet not being processed or acked as the driver never was aware of
+their completion.
+
+This patch fixes this behaviour by not setting the threshold when
+requests are being processed by the engine.
+
+Fixes: dc7e28a3286e ("crypto: inside-secure - dequeue all requests at once")
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 46b691aae475..f4a76971b4ac 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -523,8 +523,7 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+
+ if (!priv->ring[ring].busy) {
+ nreq -= safexcel_try_push_requests(priv, ring, nreq);
+- if (nreq)
+- priv->ring[ring].busy = true;
++ priv->ring[ring].busy = true;
+ }
+
+ priv->ring[ring].requests_left += nreq;
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/619-crypto-inside-secure-keep-the-requests-push-pop-sync.patch b/target/linux/mvebu/patches-4.14/619-crypto-inside-secure-keep-the-requests-push-pop-sync.patch
new file mode 100644
index 0000000000..414b005810
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/619-crypto-inside-secure-keep-the-requests-push-pop-sync.patch
@@ -0,0 +1,136 @@
+From c5caee0a5c026f0c3a9605a113e16cd691d3428f Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Tue, 13 Feb 2018 09:26:56 +0100
+Subject: [PATCH 20/36] crypto: inside-secure - keep the requests push/pop
+ synced
+
+This patch updates the Inside Secure SafeXcel driver to avoid being
+out-of-sync between the number of requests sent and the one being
+completed.
+
+The number of requests acknowledged by the driver can be different than
+the threshold that was configured if new requests were being pushed to
+the h/w in the meantime. The driver wasn't taking those into account,
+and the number of remaining requests to handled (to reconfigure the
+interrupt threshold) could be out-of sync.
+
+This patch fixes it by not taking in account the number of requests
+left, but by taking in account the total number of requests being sent
+to the hardware, so that new requests are being taken into account.
+
+Fixes: dc7e28a3286e ("crypto: inside-secure - dequeue all requests at once")
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 28 +++++++++++++---------------
+ drivers/crypto/inside-secure/safexcel.h | 6 ++----
+ 2 files changed, 15 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index f4a76971b4ac..fe1f55c3e501 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -432,20 +432,18 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ }
+
+ /* Called with ring's lock taken */
+-static int safexcel_try_push_requests(struct safexcel_crypto_priv *priv,
+- int ring, int reqs)
++static void safexcel_try_push_requests(struct safexcel_crypto_priv *priv,
++ int ring)
+ {
+- int coal = min_t(int, reqs, EIP197_MAX_BATCH_SZ);
++ int coal = min_t(int, priv->ring[ring].requests, EIP197_MAX_BATCH_SZ);
+
+ if (!coal)
+- return 0;
++ return;
+
+ /* Configure when we want an interrupt */
+ writel(EIP197_HIA_RDR_THRESH_PKT_MODE |
+ EIP197_HIA_RDR_THRESH_PROC_PKT(coal),
+ EIP197_HIA_RDR(priv, ring) + EIP197_HIA_xDR_THRESH);
+-
+- return coal;
+ }
+
+ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+@@ -521,13 +519,13 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+
+ spin_lock_bh(&priv->ring[ring].egress_lock);
+
++ priv->ring[ring].requests += nreq;
++
+ if (!priv->ring[ring].busy) {
+- nreq -= safexcel_try_push_requests(priv, ring, nreq);
++ safexcel_try_push_requests(priv, ring);
+ priv->ring[ring].busy = true;
+ }
+
+- priv->ring[ring].requests_left += nreq;
+-
+ spin_unlock_bh(&priv->ring[ring].egress_lock);
+
+ /* let the RDR know we have pending descriptors */
+@@ -631,7 +629,7 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ {
+ struct safexcel_request *sreq;
+ struct safexcel_context *ctx;
+- int ret, i, nreq, ndesc, tot_descs, done;
++ int ret, i, nreq, ndesc, tot_descs, handled = 0;
+ bool should_complete;
+
+ handle_results:
+@@ -667,6 +665,7 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+
+ kfree(sreq);
+ tot_descs += ndesc;
++ handled++;
+ }
+
+ acknowledge:
+@@ -685,11 +684,10 @@ static inline void safexcel_handle_result_descriptor(struct safexcel_crypto_priv
+ requests_left:
+ spin_lock_bh(&priv->ring[ring].egress_lock);
+
+- done = safexcel_try_push_requests(priv, ring,
+- priv->ring[ring].requests_left);
++ priv->ring[ring].requests -= handled;
++ safexcel_try_push_requests(priv, ring);
+
+- priv->ring[ring].requests_left -= done;
+- if (!done && !priv->ring[ring].requests_left)
++ if (!priv->ring[ring].requests)
+ priv->ring[ring].busy = false;
+
+ spin_unlock_bh(&priv->ring[ring].egress_lock);
+@@ -970,7 +968,7 @@ static int safexcel_probe(struct platform_device *pdev)
+ goto err_clk;
+ }
+
+- priv->ring[i].requests_left = 0;
++ priv->ring[i].requests = 0;
+ priv->ring[i].busy = false;
+
+ crypto_init_queue(&priv->ring[i].queue,
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 4e219c21608b..caaf6a81b162 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -551,10 +551,8 @@ struct safexcel_crypto_priv {
+ struct crypto_queue queue;
+ spinlock_t queue_lock;
+
+- /* Number of requests in the engine that needs the threshold
+- * interrupt to be set up.
+- */
+- int requests_left;
++ /* Number of requests in the engine. */
++ int requests;
+
+ /* The ring is currently handling at least one request */
+ bool busy;
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/620-crypto-inside-secure-unmap-the-result-in-the-hash-se.patch b/target/linux/mvebu/patches-4.14/620-crypto-inside-secure-unmap-the-result-in-the-hash-se.patch
new file mode 100644
index 0000000000..1404188e1b
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/620-crypto-inside-secure-unmap-the-result-in-the-hash-se.patch
@@ -0,0 +1,42 @@
+From 832e97cc80a5bf9992edbc6178de62d63ef9ad77 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Tue, 13 Feb 2018 09:26:57 +0100
+Subject: [PATCH 21/36] crypto: inside-secure - unmap the result in the hash
+ send error path
+
+This patch adds a label to unmap the result buffer in the hash send
+function error path.
+
+Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index b9a2bfd91c20..7b181bd6959f 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -303,7 +303,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ req->state_sz);
+ if (IS_ERR(rdesc)) {
+ ret = PTR_ERR(rdesc);
+- goto cdesc_rollback;
++ goto unmap_result;
+ }
+
+ spin_unlock_bh(&priv->ring[ring].egress_lock);
+@@ -315,6 +315,8 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ *results = 1;
+ return 0;
+
++unmap_result:
++ dma_unmap_sg(priv->dev, areq->src, req->nents, DMA_TO_DEVICE);
+ cdesc_rollback:
+ for (i = 0; i < n_cdesc; i++)
+ safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr);
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/621-crypto-inside-secure-move-hash-result-dma-mapping-to.patch b/target/linux/mvebu/patches-4.14/621-crypto-inside-secure-move-hash-result-dma-mapping-to.patch
new file mode 100644
index 0000000000..2254286906
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/621-crypto-inside-secure-move-hash-result-dma-mapping-to.patch
@@ -0,0 +1,115 @@
+From a7476abde5ff9f8b7c6eaa2df0e2b8aadba4a705 Mon Sep 17 00:00:00 2001
+From: Ofer Heifetz <oferh at marvell.com>
+Date: Mon, 26 Feb 2018 14:45:10 +0100
+Subject: [PATCH 22/36] crypto: inside-secure - move hash result dma mapping to
+ request
+
+In heavy traffic the DMA mapping is overwritten by multiple requests as
+the DMA address is stored in a global context. This patch moves this
+information to the per-hash request context so that it can't be
+overwritten.
+
+Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
+Signed-off-by: Ofer Heifetz <oferh at marvell.com>
+[Antoine: rebased the patch, small fixes, commit message.]
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 7 +------
+ drivers/crypto/inside-secure/safexcel.h | 4 +---
+ drivers/crypto/inside-secure/safexcel_hash.c | 17 ++++++++++++-----
+ 3 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index fe1f55c3e501..97cd64041189 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -538,15 +538,10 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ }
+
+ void safexcel_free_context(struct safexcel_crypto_priv *priv,
+- struct crypto_async_request *req,
+- int result_sz)
++ struct crypto_async_request *req)
+ {
+ struct safexcel_context *ctx = crypto_tfm_ctx(req->tfm);
+
+- if (ctx->result_dma)
+- dma_unmap_single(priv->dev, ctx->result_dma, result_sz,
+- DMA_FROM_DEVICE);
+-
+ if (ctx->cache) {
+ dma_unmap_single(priv->dev, ctx->cache_dma, ctx->cache_sz,
+ DMA_TO_DEVICE);
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index caaf6a81b162..4e14c7e730c4 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -580,7 +580,6 @@ struct safexcel_context {
+ bool exit_inv;
+
+ /* Used for ahash requests */
+- dma_addr_t result_dma;
+ void *cache;
+ dma_addr_t cache_dma;
+ unsigned int cache_sz;
+@@ -608,8 +607,7 @@ struct safexcel_inv_result {
+ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring);
+ void safexcel_complete(struct safexcel_crypto_priv *priv, int ring);
+ void safexcel_free_context(struct safexcel_crypto_priv *priv,
+- struct crypto_async_request *req,
+- int result_sz);
++ struct crypto_async_request *req);
+ int safexcel_invalidate_cache(struct crypto_async_request *async,
+ struct safexcel_crypto_priv *priv,
+ dma_addr_t ctxr_dma, int ring,
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 7b181bd6959f..a31837f3b506 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -34,6 +34,7 @@ struct safexcel_ahash_req {
+ bool needs_inv;
+
+ int nents;
++ dma_addr_t result_dma;
+
+ u8 state_sz; /* expected sate size, only set once */
+ u32 state[SHA256_DIGEST_SIZE / sizeof(u32)] __aligned(sizeof(u32));
+@@ -158,7 +159,13 @@ static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int rin
+ sreq->nents = 0;
+ }
+
+- safexcel_free_context(priv, async, sreq->state_sz);
++ if (sreq->result_dma) {
++ dma_unmap_single(priv->dev, sreq->result_dma, sreq->state_sz,
++ DMA_FROM_DEVICE);
++ sreq->result_dma = 0;
++ }
++
++ safexcel_free_context(priv, async);
+
+ cache_len = sreq->len - sreq->processed;
+ if (cache_len)
+@@ -291,15 +298,15 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ /* Add the token */
+ safexcel_hash_token(first_cdesc, len, req->state_sz);
+
+- ctx->base.result_dma = dma_map_single(priv->dev, req->state,
+- req->state_sz, DMA_FROM_DEVICE);
+- if (dma_mapping_error(priv->dev, ctx->base.result_dma)) {
++ req->result_dma = dma_map_single(priv->dev, req->state, req->state_sz,
++ DMA_FROM_DEVICE);
++ if (dma_mapping_error(priv->dev, req->result_dma)) {
+ ret = -EINVAL;
+ goto cdesc_rollback;
+ }
+
+ /* Add a result descriptor */
+- rdesc = safexcel_add_rdesc(priv, ring, 1, 1, ctx->base.result_dma,
++ rdesc = safexcel_add_rdesc(priv, ring, 1, 1, req->result_dma,
+ req->state_sz);
+ if (IS_ERR(rdesc)) {
+ ret = PTR_ERR(rdesc);
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/622-crypto-inside-secure-move-cache-result-dma-mapping-t.patch b/target/linux/mvebu/patches-4.14/622-crypto-inside-secure-move-cache-result-dma-mapping-t.patch
new file mode 100644
index 0000000000..c3b18af150
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/622-crypto-inside-secure-move-cache-result-dma-mapping-t.patch
@@ -0,0 +1,152 @@
+From 4ec1e0702a31576a91eb6cd9ace703ae7acd99c1 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 26 Feb 2018 14:45:11 +0100
+Subject: [PATCH 23/36] crypto: inside-secure - move cache result dma mapping
+ to request
+
+In heavy traffic the DMA mapping is overwritten by multiple requests as
+the DMA address is stored in a global context. This patch moves this
+information to the per-hash request context so that it can't be
+overwritten.
+
+Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 14 ----------
+ drivers/crypto/inside-secure/safexcel.h | 7 -----
+ drivers/crypto/inside-secure/safexcel_hash.c | 42 ++++++++++++----------------
+ 3 files changed, 18 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 97cd64041189..09adeaa0da6b 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -537,20 +537,6 @@ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring)
+ EIP197_HIA_CDR(priv, ring) + EIP197_HIA_xDR_PREP_COUNT);
+ }
+
+-void safexcel_free_context(struct safexcel_crypto_priv *priv,
+- struct crypto_async_request *req)
+-{
+- struct safexcel_context *ctx = crypto_tfm_ctx(req->tfm);
+-
+- if (ctx->cache) {
+- dma_unmap_single(priv->dev, ctx->cache_dma, ctx->cache_sz,
+- DMA_TO_DEVICE);
+- kfree(ctx->cache);
+- ctx->cache = NULL;
+- ctx->cache_sz = 0;
+- }
+-}
+-
+ void safexcel_complete(struct safexcel_crypto_priv *priv, int ring)
+ {
+ struct safexcel_command_desc *cdesc;
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 4e14c7e730c4..d8dff65fc311 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -578,11 +578,6 @@ struct safexcel_context {
+ int ring;
+ bool needs_inv;
+ bool exit_inv;
+-
+- /* Used for ahash requests */
+- void *cache;
+- dma_addr_t cache_dma;
+- unsigned int cache_sz;
+ };
+
+ /*
+@@ -606,8 +601,6 @@ struct safexcel_inv_result {
+
+ void safexcel_dequeue(struct safexcel_crypto_priv *priv, int ring);
+ void safexcel_complete(struct safexcel_crypto_priv *priv, int ring);
+-void safexcel_free_context(struct safexcel_crypto_priv *priv,
+- struct crypto_async_request *req);
+ int safexcel_invalidate_cache(struct crypto_async_request *async,
+ struct safexcel_crypto_priv *priv,
+ dma_addr_t ctxr_dma, int ring,
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index a31837f3b506..9703a4063cfc 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -43,6 +43,9 @@ struct safexcel_ahash_req {
+ u64 processed;
+
+ u8 cache[SHA256_BLOCK_SIZE] __aligned(sizeof(u32));
++ dma_addr_t cache_dma;
++ unsigned int cache_sz;
++
+ u8 cache_next[SHA256_BLOCK_SIZE] __aligned(sizeof(u32));
+ };
+
+@@ -165,7 +168,11 @@ static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int rin
+ sreq->result_dma = 0;
+ }
+
+- safexcel_free_context(priv, async);
++ if (sreq->cache_dma) {
++ dma_unmap_single(priv->dev, sreq->cache_dma, sreq->cache_sz,
++ DMA_TO_DEVICE);
++ sreq->cache_dma = 0;
++ }
+
+ cache_len = sreq->len - sreq->processed;
+ if (cache_len)
+@@ -227,24 +234,15 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+
+ /* Add a command descriptor for the cached data, if any */
+ if (cache_len) {
+- ctx->base.cache = kzalloc(cache_len, EIP197_GFP_FLAGS(*async));
+- if (!ctx->base.cache) {
+- ret = -ENOMEM;
+- goto unlock;
+- }
+- memcpy(ctx->base.cache, req->cache, cache_len);
+- ctx->base.cache_dma = dma_map_single(priv->dev, ctx->base.cache,
+- cache_len, DMA_TO_DEVICE);
+- if (dma_mapping_error(priv->dev, ctx->base.cache_dma)) {
+- ret = -EINVAL;
+- goto free_cache;
+- }
++ req->cache_dma = dma_map_single(priv->dev, req->cache,
++ cache_len, DMA_TO_DEVICE);
++ if (dma_mapping_error(priv->dev, req->cache_dma))
++ return -EINVAL;
+
+- ctx->base.cache_sz = cache_len;
++ req->cache_sz = cache_len;
+ first_cdesc = safexcel_add_cdesc(priv, ring, 1,
+ (cache_len == len),
+- ctx->base.cache_dma,
+- cache_len, len,
++ req->cache_dma, cache_len, len,
+ ctx->base.ctxr_dma);
+ if (IS_ERR(first_cdesc)) {
+ ret = PTR_ERR(first_cdesc);
+@@ -328,16 +326,12 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ for (i = 0; i < n_cdesc; i++)
+ safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr);
+ unmap_cache:
+- if (ctx->base.cache_dma) {
+- dma_unmap_single(priv->dev, ctx->base.cache_dma,
+- ctx->base.cache_sz, DMA_TO_DEVICE);
+- ctx->base.cache_sz = 0;
++ if (req->cache_dma) {
++ dma_unmap_single(priv->dev, req->cache_dma, req->cache_sz,
++ DMA_TO_DEVICE);
++ req->cache_sz = 0;
+ }
+-free_cache:
+- kfree(ctx->base.cache);
+- ctx->base.cache = NULL;
+
+-unlock:
+ spin_unlock_bh(&priv->ring[ring].egress_lock);
+ return ret;
+ }
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/623-crypto-inside-secure-fix-missing-unlock-on-error-in-.patch b/target/linux/mvebu/patches-4.14/623-crypto-inside-secure-fix-missing-unlock-on-error-in-.patch
new file mode 100644
index 0000000000..8852f9b698
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/623-crypto-inside-secure-fix-missing-unlock-on-error-in-.patch
@@ -0,0 +1,36 @@
+From d26b54baf430da2d33288d62e0e3bff07e02c28d Mon Sep 17 00:00:00 2001
+From: "weiyongjun \\(A\\)" <weiyongjun1 at huawei.com>
+Date: Tue, 13 Mar 2018 14:54:03 +0000
+Subject: [PATCH 24/36] crypto: inside-secure - fix missing unlock on error in
+ safexcel_ahash_send_req()
+
+Add the missing unlock before return from function
+safexcel_ahash_send_req() in the error handling case.
+
+Fixes: cff9a17545a3 ("crypto: inside-secure - move cache result dma mapping to request")
+Signed-off-by: Wei Yongjun <weiyongjun1 at huawei.com>
+Acked-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 9703a4063cfc..a7702da92b02 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -236,8 +236,10 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ if (cache_len) {
+ req->cache_dma = dma_map_single(priv->dev, req->cache,
+ cache_len, DMA_TO_DEVICE);
+- if (dma_mapping_error(priv->dev, req->cache_dma))
++ if (dma_mapping_error(priv->dev, req->cache_dma)) {
++ spin_unlock_bh(&priv->ring[ring].egress_lock);
+ return -EINVAL;
++ }
+
+ req->cache_sz = cache_len;
+ first_cdesc = safexcel_add_cdesc(priv, ring, 1,
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/624-crypto-inside-secure-improve-clock-initialization.patch b/target/linux/mvebu/patches-4.14/624-crypto-inside-secure-improve-clock-initialization.patch
new file mode 100644
index 0000000000..3ce5bc11dd
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/624-crypto-inside-secure-improve-clock-initialization.patch
@@ -0,0 +1,48 @@
+From b2da8a42670c569d084fbfb92ffde36cc7524f53 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement at bootlin.com>
+Date: Tue, 13 Mar 2018 17:48:41 +0100
+Subject: [PATCH 25/36] crypto: inside-secure - improve clock initialization
+
+The clock is optional, but if it is present we should managed it. If
+there is an error while trying getting it, we should exit and report this
+error.
+
+So instead of returning an error only in the -EPROBE case, turn it in an
+other way and ignore the clock only if it is not present (-ENOENT case).
+
+Signed-off-by: Gregory CLEMENT <gregory.clement at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 09adeaa0da6b..cbcb5d9f17bd 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -882,16 +882,17 @@ static int safexcel_probe(struct platform_device *pdev)
+ }
+
+ priv->clk = devm_clk_get(&pdev->dev, NULL);
+- if (!IS_ERR(priv->clk)) {
++ ret = PTR_ERR_OR_ZERO(priv->clk);
++ /* The clock isn't mandatory */
++ if (ret != -ENOENT) {
++ if (ret)
++ return ret;
++
+ ret = clk_prepare_enable(priv->clk);
+ if (ret) {
+ dev_err(dev, "unable to enable clk (%d)\n", ret);
+ return ret;
+ }
+- } else {
+- /* The clock isn't mandatory */
+- if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
+- return -EPROBE_DEFER;
+ }
+
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/625-crypto-inside-secure-fix-clock-resource-by-adding-a-.patch b/target/linux/mvebu/patches-4.14/625-crypto-inside-secure-fix-clock-resource-by-adding-a-.patch
new file mode 100644
index 0000000000..3366950758
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/625-crypto-inside-secure-fix-clock-resource-by-adding-a-.patch
@@ -0,0 +1,146 @@
+From 9f9f1c49dcce9bef968bcef522f78048255a7416 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement at bootlin.com>
+Date: Tue, 13 Mar 2018 17:48:42 +0100
+Subject: [PATCH 26/36] crypto: inside-secure - fix clock resource by adding a
+ register clock
+
+On Armada 7K/8K we need to explicitly enable the register clock. This
+clock is optional because not all the SoCs using this IP need it but at
+least for Armada 7K/8K it is actually mandatory.
+
+The binding documentation is updated accordingly.
+
+Signed-off-by: Gregory CLEMENT <gregory.clement at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ .../bindings/crypto/inside-secure-safexcel.txt | 6 +++-
+ drivers/crypto/inside-secure/safexcel.c | 34 ++++++++++++++++------
+ drivers/crypto/inside-secure/safexcel.h | 1 +
+ 3 files changed, 31 insertions(+), 10 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt b/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt
+index fbc07d12322f..5a3d0829ddf2 100644
+--- a/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt
++++ b/Documentation/devicetree/bindings/crypto/inside-secure-safexcel.txt
+@@ -7,7 +7,11 @@ Required properties:
+ - interrupt-names: Should be "ring0", "ring1", "ring2", "ring3", "eip", "mem".
+
+ Optional properties:
+-- clocks: Reference to the crypto engine clock.
++- clocks: Reference to the crypto engine clocks, the second clock is
++ needed for the Armada 7K/8K SoCs.
++- clock-names: mandatory if there is a second clock, in this case the
++ name must be "core" for the first clock and "reg" for
++ the second one.
+
+ Example:
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index cbcb5d9f17bd..2f68b4ed5500 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -895,16 +895,30 @@ static int safexcel_probe(struct platform_device *pdev)
+ }
+ }
+
++ priv->reg_clk = devm_clk_get(&pdev->dev, "reg");
++ ret = PTR_ERR_OR_ZERO(priv->reg_clk);
++ /* The clock isn't mandatory */
++ if (ret != -ENOENT) {
++ if (ret)
++ goto err_core_clk;
++
++ ret = clk_prepare_enable(priv->reg_clk);
++ if (ret) {
++ dev_err(dev, "unable to enable reg clk (%d)\n", ret);
++ goto err_core_clk;
++ }
++ }
++
+ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+ if (ret)
+- goto err_clk;
++ goto err_reg_clk;
+
+ priv->context_pool = dmam_pool_create("safexcel-context", dev,
+ sizeof(struct safexcel_context_record),
+ 1, 0);
+ if (!priv->context_pool) {
+ ret = -ENOMEM;
+- goto err_clk;
++ goto err_reg_clk;
+ }
+
+ safexcel_configure(priv);
+@@ -919,12 +933,12 @@ static int safexcel_probe(struct platform_device *pdev)
+ &priv->ring[i].cdr,
+ &priv->ring[i].rdr);
+ if (ret)
+- goto err_clk;
++ goto err_reg_clk;
+
+ ring_irq = devm_kzalloc(dev, sizeof(*ring_irq), GFP_KERNEL);
+ if (!ring_irq) {
+ ret = -ENOMEM;
+- goto err_clk;
++ goto err_reg_clk;
+ }
+
+ ring_irq->priv = priv;
+@@ -936,7 +950,7 @@ static int safexcel_probe(struct platform_device *pdev)
+ ring_irq);
+ if (irq < 0) {
+ ret = irq;
+- goto err_clk;
++ goto err_reg_clk;
+ }
+
+ priv->ring[i].work_data.priv = priv;
+@@ -947,7 +961,7 @@ static int safexcel_probe(struct platform_device *pdev)
+ priv->ring[i].workqueue = create_singlethread_workqueue(wq_name);
+ if (!priv->ring[i].workqueue) {
+ ret = -ENOMEM;
+- goto err_clk;
++ goto err_reg_clk;
+ }
+
+ priv->ring[i].requests = 0;
+@@ -968,18 +982,20 @@ static int safexcel_probe(struct platform_device *pdev)
+ ret = safexcel_hw_init(priv);
+ if (ret) {
+ dev_err(dev, "EIP h/w init failed (%d)\n", ret);
+- goto err_clk;
++ goto err_reg_clk;
+ }
+
+ ret = safexcel_register_algorithms(priv);
+ if (ret) {
+ dev_err(dev, "Failed to register algorithms (%d)\n", ret);
+- goto err_clk;
++ goto err_reg_clk;
+ }
+
+ return 0;
+
+-err_clk:
++err_reg_clk:
++ clk_disable_unprepare(priv->reg_clk);
++err_core_clk:
+ clk_disable_unprepare(priv->clk);
+ return ret;
+ }
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index d8dff65fc311..4efeb0251daf 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -525,6 +525,7 @@ struct safexcel_crypto_priv {
+ void __iomem *base;
+ struct device *dev;
+ struct clk *clk;
++ struct clk *reg_clk;
+ struct safexcel_config config;
+
+ enum safexcel_eip_version version;
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/626-crypto-inside-secure-move-the-digest-to-the-request-.patch b/target/linux/mvebu/patches-4.14/626-crypto-inside-secure-move-the-digest-to-the-request-.patch
new file mode 100644
index 0000000000..535e51f5f7
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/626-crypto-inside-secure-move-the-digest-to-the-request-.patch
@@ -0,0 +1,161 @@
+From ba9692358a5cba4770b5230d31e71944f517a06c Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:13 +0100
+Subject: [PATCH 27/36] crypto: inside-secure - move the digest to the request
+ context
+
+This patches moves the digest information from the transformation
+context to the request context. This fixes cases where HMAC init
+functions were called and override the digest value for a short period
+of time, as the HMAC init functions call the SHA init one which reset
+the value. This lead to a small percentage of HMAC being incorrectly
+computed under heavy load.
+
+Fixes: 1b44c5a60c13 ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
+Suggested-by: Ofer Heifetz <oferh at marvell.com>
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+[Ofer here did all the work, from seeing the issue to understanding the
+root cause. I only made the patch.]
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 30 +++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index a7702da92b02..cfcae5e51b9d 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -21,7 +21,6 @@ struct safexcel_ahash_ctx {
+ struct safexcel_crypto_priv *priv;
+
+ u32 alg;
+- u32 digest;
+
+ u32 ipad[SHA1_DIGEST_SIZE / sizeof(u32)];
+ u32 opad[SHA1_DIGEST_SIZE / sizeof(u32)];
+@@ -36,6 +35,8 @@ struct safexcel_ahash_req {
+ int nents;
+ dma_addr_t result_dma;
+
++ u32 digest;
++
+ u8 state_sz; /* expected sate size, only set once */
+ u32 state[SHA256_DIGEST_SIZE / sizeof(u32)] __aligned(sizeof(u32));
+
+@@ -53,6 +54,8 @@ struct safexcel_ahash_export_state {
+ u64 len;
+ u64 processed;
+
++ u32 digest;
++
+ u32 state[SHA256_DIGEST_SIZE / sizeof(u32)];
+ u8 cache[SHA256_BLOCK_SIZE];
+ };
+@@ -86,9 +89,9 @@ static void safexcel_context_control(struct safexcel_ahash_ctx *ctx,
+
+ cdesc->control_data.control0 |= CONTEXT_CONTROL_TYPE_HASH_OUT;
+ cdesc->control_data.control0 |= ctx->alg;
+- cdesc->control_data.control0 |= ctx->digest;
++ cdesc->control_data.control0 |= req->digest;
+
+- if (ctx->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED) {
++ if (req->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED) {
+ if (req->processed) {
+ if (ctx->alg == CONTEXT_CONTROL_CRYPTO_ALG_SHA1)
+ cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(6);
+@@ -116,7 +119,7 @@ static void safexcel_context_control(struct safexcel_ahash_ctx *ctx,
+ if (req->finish)
+ ctx->base.ctxr->data[i] = cpu_to_le32(req->processed / blocksize);
+ }
+- } else if (ctx->digest == CONTEXT_CONTROL_DIGEST_HMAC) {
++ } else if (req->digest == CONTEXT_CONTROL_DIGEST_HMAC) {
+ cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(10);
+
+ memcpy(ctx->base.ctxr->data, ctx->ipad, digestsize);
+@@ -545,7 +548,7 @@ static int safexcel_ahash_enqueue(struct ahash_request *areq)
+ if (ctx->base.ctxr) {
+ if (priv->version == EIP197 &&
+ !ctx->base.needs_inv && req->processed &&
+- ctx->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED)
++ req->digest == CONTEXT_CONTROL_DIGEST_PRECOMPUTED)
+ /* We're still setting needs_inv here, even though it is
+ * cleared right away, because the needs_inv flag can be
+ * set in other functions and we want to keep the same
+@@ -580,7 +583,6 @@ static int safexcel_ahash_enqueue(struct ahash_request *areq)
+
+ static int safexcel_ahash_update(struct ahash_request *areq)
+ {
+- struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
+ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
+ struct crypto_ahash *ahash = crypto_ahash_reqtfm(areq);
+
+@@ -596,7 +598,7 @@ static int safexcel_ahash_update(struct ahash_request *areq)
+ * We're not doing partial updates when performing an hmac request.
+ * Everything will be handled by the final() call.
+ */
+- if (ctx->digest == CONTEXT_CONTROL_DIGEST_HMAC)
++ if (req->digest == CONTEXT_CONTROL_DIGEST_HMAC)
+ return 0;
+
+ if (req->hmac)
+@@ -655,6 +657,8 @@ static int safexcel_ahash_export(struct ahash_request *areq, void *out)
+ export->len = req->len;
+ export->processed = req->processed;
+
++ export->digest = req->digest;
++
+ memcpy(export->state, req->state, req->state_sz);
+ memcpy(export->cache, req->cache, crypto_ahash_blocksize(ahash));
+
+@@ -675,6 +679,8 @@ static int safexcel_ahash_import(struct ahash_request *areq, const void *in)
+ req->len = export->len;
+ req->processed = export->processed;
+
++ req->digest = export->digest;
++
+ memcpy(req->cache, export->cache, crypto_ahash_blocksize(ahash));
+ memcpy(req->state, export->state, req->state_sz);
+
+@@ -711,7 +717,7 @@ static int safexcel_sha1_init(struct ahash_request *areq)
+ req->state[4] = SHA1_H4;
+
+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
+- ctx->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
++ req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
+ req->state_sz = SHA1_DIGEST_SIZE;
+
+ return 0;
+@@ -778,10 +784,10 @@ struct safexcel_alg_template safexcel_alg_sha1 = {
+
+ static int safexcel_hmac_sha1_init(struct ahash_request *areq)
+ {
+- struct safexcel_ahash_ctx *ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(areq));
++ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
+
+ safexcel_sha1_init(areq);
+- ctx->digest = CONTEXT_CONTROL_DIGEST_HMAC;
++ req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
+ return 0;
+ }
+
+@@ -1019,7 +1025,7 @@ static int safexcel_sha256_init(struct ahash_request *areq)
+ req->state[7] = SHA256_H7;
+
+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256;
+- ctx->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
++ req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
+ req->state_sz = SHA256_DIGEST_SIZE;
+
+ return 0;
+@@ -1081,7 +1087,7 @@ static int safexcel_sha224_init(struct ahash_request *areq)
+ req->state[7] = SHA224_H7;
+
+ ctx->alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224;
+- ctx->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
++ req->digest = CONTEXT_CONTROL_DIGEST_PRECOMPUTED;
+ req->state_sz = SHA256_DIGEST_SIZE;
+
+ return 0;
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/627-crypto-inside-secure-fix-typo-s-allways-always-in-a-.patch b/target/linux/mvebu/patches-4.14/627-crypto-inside-secure-fix-typo-s-allways-always-in-a-.patch
new file mode 100644
index 0000000000..578f5045f6
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/627-crypto-inside-secure-fix-typo-s-allways-always-in-a-.patch
@@ -0,0 +1,45 @@
+From 3648bce52f9a3f432a12c2bd0453019a90341660 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:14 +0100
+Subject: [PATCH 28/36] crypto: inside-secure - fix typo s/allways/always/ in a
+ define
+
+Small cosmetic patch fixing one typo in the
+EIP197_HIA_DSE_CFG_ALLWAYS_BUFFERABLE macro, it should be _ALWAYS_.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 2 +-
+ drivers/crypto/inside-secure/safexcel.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 2f68b4ed5500..cc9d2e9126b4 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -332,7 +332,7 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ val = EIP197_HIA_DSE_CFG_DIS_DEBUG;
+ val |= EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(7) | EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(8);
+ val |= EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(WR_CACHE_3BITS);
+- val |= EIP197_HIA_DSE_CFG_ALLWAYS_BUFFERABLE;
++ val |= EIP197_HIA_DSE_CFG_ALWAYS_BUFFERABLE;
+ /* FIXME: instability issues can occur for EIP97 but disabling it impact
+ * performances.
+ */
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 4efeb0251daf..9ca1654136e0 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -179,7 +179,7 @@
+ #define EIP197_HIA_DxE_CFG_MIN_DATA_SIZE(n) ((n) << 0)
+ #define EIP197_HIA_DxE_CFG_DATA_CACHE_CTRL(n) (((n) & 0x7) << 4)
+ #define EIP197_HIA_DxE_CFG_MAX_DATA_SIZE(n) ((n) << 8)
+-#define EIP197_HIA_DSE_CFG_ALLWAYS_BUFFERABLE GENMASK(15, 14)
++#define EIP197_HIA_DSE_CFG_ALWAYS_BUFFERABLE GENMASK(15, 14)
+ #define EIP197_HIA_DxE_CFG_MIN_CTRL_SIZE(n) ((n) << 16)
+ #define EIP197_HIA_DxE_CFG_CTRL_CACHE_CTRL(n) (((n) & 0x7) << 20)
+ #define EIP197_HIA_DxE_CFG_MAX_CTRL_SIZE(n) ((n) << 24)
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/628-crypto-inside-secure-fix-a-typo-in-a-register-name.patch b/target/linux/mvebu/patches-4.14/628-crypto-inside-secure-fix-a-typo-in-a-register-name.patch
new file mode 100644
index 0000000000..ae2b51d052
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/628-crypto-inside-secure-fix-a-typo-in-a-register-name.patch
@@ -0,0 +1,45 @@
+From 5883f9a3c4d207518860ee05ec3c8ba6ffb2454c Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:15 +0100
+Subject: [PATCH 29/36] crypto: inside-secure - fix a typo in a register name
+
+This patch fixes a typo in the EIP197_HIA_xDR_WR_CTRL_BUG register name,
+as it should be EIP197_HIA_xDR_WR_CTRL_BUF. This is a cosmetic only
+change.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 2 +-
+ drivers/crypto/inside-secure/safexcel.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index cc9d2e9126b4..f7d7293de699 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -235,7 +235,7 @@ static int safexcel_hw_setup_rdesc_rings(struct safexcel_crypto_priv *priv)
+ /* Configure DMA tx control */
+ val = EIP197_HIA_xDR_CFG_WR_CACHE(WR_CACHE_3BITS);
+ val |= EIP197_HIA_xDR_CFG_RD_CACHE(RD_CACHE_3BITS);
+- val |= EIP197_HIA_xDR_WR_RES_BUF | EIP197_HIA_xDR_WR_CTRL_BUG;
++ val |= EIP197_HIA_xDR_WR_RES_BUF | EIP197_HIA_xDR_WR_CTRL_BUF;
+ writel(val,
+ EIP197_HIA_RDR(priv, i) + EIP197_HIA_xDR_DMA_CFG);
+
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 9ca1654136e0..295813920618 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -135,7 +135,7 @@
+
+ /* EIP197_HIA_xDR_DMA_CFG */
+ #define EIP197_HIA_xDR_WR_RES_BUF BIT(22)
+-#define EIP197_HIA_xDR_WR_CTRL_BUG BIT(23)
++#define EIP197_HIA_xDR_WR_CTRL_BUF BIT(23)
+ #define EIP197_HIA_xDR_WR_OWN_BUF BIT(24)
+ #define EIP197_HIA_xDR_CFG_WR_CACHE(n) (((n) & 0x7) << 25)
+ #define EIP197_HIA_xDR_CFG_RD_CACHE(n) (((n) & 0x7) << 29)
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/629-crypto-inside-secure-improve-the-send-error-path.patch b/target/linux/mvebu/patches-4.14/629-crypto-inside-secure-improve-the-send-error-path.patch
new file mode 100644
index 0000000000..a5d8fae1c4
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/629-crypto-inside-secure-improve-the-send-error-path.patch
@@ -0,0 +1,50 @@
+From 7a3daac97ede7897225c206389230bbcc265e834 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:16 +0100
+Subject: [PATCH 30/36] crypto: inside-secure - improve the send error path
+
+This patch improves the send error path as it wasn't handling all error
+cases. A new label is added, and some of the goto are updated to point
+to the right labels, so that the code is more robust to errors.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index cfcae5e51b9d..4ff3f7615b3d 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -281,7 +281,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ sglen, len, ctx->base.ctxr_dma);
+ if (IS_ERR(cdesc)) {
+ ret = PTR_ERR(cdesc);
+- goto cdesc_rollback;
++ goto unmap_sg;
+ }
+ n_cdesc++;
+
+@@ -305,7 +305,7 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(priv->dev, req->result_dma)) {
+ ret = -EINVAL;
+- goto cdesc_rollback;
++ goto unmap_sg;
+ }
+
+ /* Add a result descriptor */
+@@ -326,6 +326,9 @@ static int safexcel_ahash_send_req(struct crypto_async_request *async, int ring,
+ return 0;
+
+ unmap_result:
++ dma_unmap_single(priv->dev, req->result_dma, req->state_sz,
++ DMA_FROM_DEVICE);
++unmap_sg:
+ dma_unmap_sg(priv->dev, areq->src, req->nents, DMA_TO_DEVICE);
+ cdesc_rollback:
+ for (i = 0; i < n_cdesc; i++)
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/630-crypto-inside-secure-do-not-access-buffers-mapped-to.patch b/target/linux/mvebu/patches-4.14/630-crypto-inside-secure-do-not-access-buffers-mapped-to.patch
new file mode 100644
index 0000000000..1f04c8a0dc
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/630-crypto-inside-secure-do-not-access-buffers-mapped-to.patch
@@ -0,0 +1,46 @@
+From 89099c389a04fb6d049cdad85cbcd5d5447fb1d1 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:17 +0100
+Subject: [PATCH 31/36] crypto: inside-secure - do not access buffers mapped to
+ the device
+
+This patches update the way the digest is copied from the state buffer
+to the result buffer, so that the copy only happen after the state
+buffer was DMA unmapped, as otherwise the buffer would be owned by the
+device.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 4ff3f7615b3d..573b12e4d9dd 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -156,10 +156,6 @@ static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int rin
+ safexcel_complete(priv, ring);
+ spin_unlock_bh(&priv->ring[ring].egress_lock);
+
+- if (sreq->finish)
+- memcpy(areq->result, sreq->state,
+- crypto_ahash_digestsize(ahash));
+-
+ if (sreq->nents) {
+ dma_unmap_sg(priv->dev, areq->src, sreq->nents, DMA_TO_DEVICE);
+ sreq->nents = 0;
+@@ -177,6 +173,10 @@ static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int rin
+ sreq->cache_dma = 0;
+ }
+
++ if (sreq->finish)
++ memcpy(areq->result, sreq->state,
++ crypto_ahash_digestsize(ahash));
++
+ cache_len = sreq->len - sreq->processed;
+ if (cache_len)
+ memcpy(sreq->cache, sreq->cache_next, cache_len);
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/631-crypto-inside-secure-improve-the-skcipher-token.patch b/target/linux/mvebu/patches-4.14/631-crypto-inside-secure-improve-the-skcipher-token.patch
new file mode 100644
index 0000000000..7d25a6255e
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/631-crypto-inside-secure-improve-the-skcipher-token.patch
@@ -0,0 +1,36 @@
+From 65c1ad099b6fab06cf04e1a0d797f490aa02719b Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:18 +0100
+Subject: [PATCH 32/36] crypto: inside-secure - improve the skcipher token
+
+The token used for encryption and decryption of skcipher algorithms sets
+its stat field to "last packet". As it's a cipher only algorithm, there
+is not hash operation and thus the "last hash" bit should be set to tell
+the internal engine no hash operation should be performed.
+
+This does not fix a bug, but improves the token definition to follow
+exactly what's advised by the datasheet.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_cipher.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c
+index 17a7725a6f6d..bafb60505fab 100644
+--- a/drivers/crypto/inside-secure/safexcel_cipher.c
++++ b/drivers/crypto/inside-secure/safexcel_cipher.c
+@@ -58,7 +58,8 @@ static void safexcel_cipher_token(struct safexcel_cipher_ctx *ctx,
+
+ token[0].opcode = EIP197_TOKEN_OPCODE_DIRECTION;
+ token[0].packet_length = length;
+- token[0].stat = EIP197_TOKEN_STAT_LAST_PACKET;
++ token[0].stat = EIP197_TOKEN_STAT_LAST_PACKET |
++ EIP197_TOKEN_STAT_LAST_HASH;
+ token[0].instructions = EIP197_TOKEN_INS_LAST |
+ EIP197_TOKEN_INS_TYPE_CRYTO |
+ EIP197_TOKEN_INS_TYPE_OUTPUT;
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/632-crypto-inside-secure-the-context-ipad-opad-should-us.patch b/target/linux/mvebu/patches-4.14/632-crypto-inside-secure-the-context-ipad-opad-should-us.patch
new file mode 100644
index 0000000000..00ca242006
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/632-crypto-inside-secure-the-context-ipad-opad-should-us.patch
@@ -0,0 +1,42 @@
+From f8fcb222ce5f865703d89bdc9ebc4b30e6e32110 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:19 +0100
+Subject: [PATCH 33/36] crypto: inside-secure - the context ipad/opad should
+ use the state sz
+
+This patches uses the state size of the algorithms instead of their
+digest size to copy the ipad and opad in the context. This doesn't fix
+anything as the state and digest size are the same for many algorithms,
+and for all the hmac currently supported by this driver. However
+hmac(sha224) use the sha224 hash function which has a different digest
+and state size. This commit prepares the addition of such algorithms.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel_hash.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 573b12e4d9dd..d152f2eb0271 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -120,11 +120,11 @@ static void safexcel_context_control(struct safexcel_ahash_ctx *ctx,
+ ctx->base.ctxr->data[i] = cpu_to_le32(req->processed / blocksize);
+ }
+ } else if (req->digest == CONTEXT_CONTROL_DIGEST_HMAC) {
+- cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(10);
++ cdesc->control_data.control0 |= CONTEXT_CONTROL_SIZE(2 * req->state_sz / sizeof(u32));
+
+- memcpy(ctx->base.ctxr->data, ctx->ipad, digestsize);
+- memcpy(ctx->base.ctxr->data + digestsize / sizeof(u32),
+- ctx->opad, digestsize);
++ memcpy(ctx->base.ctxr->data, ctx->ipad, req->state_sz);
++ memcpy(ctx->base.ctxr->data + req->state_sz / sizeof(u32),
++ ctx->opad, req->state_sz);
+ }
+ }
+
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/633-crypto-inside-secure-hmac-sha256-support.patch b/target/linux/mvebu/patches-4.14/633-crypto-inside-secure-hmac-sha256-support.patch
new file mode 100644
index 0000000000..a95b19532c
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/633-crypto-inside-secure-hmac-sha256-support.patch
@@ -0,0 +1,174 @@
+From 97eb1ecf57d126f52e1974fb0f9e2c17dc3ea0a0 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:20 +0100
+Subject: [PATCH 34/36] crypto: inside-secure - hmac(sha256) support
+
+This patch adds the hmac(sha256) support to the Inside Secure
+cryptographic engine driver.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 3 +-
+ drivers/crypto/inside-secure/safexcel.h | 1 +
+ drivers/crypto/inside-secure/safexcel_hash.c | 80 +++++++++++++++++++++++++---
+ 3 files changed, 75 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index f7d7293de699..33595f41586f 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -354,7 +354,7 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
+ val |= EIP197_PROTOCOL_ENCRYPT_ONLY | EIP197_PROTOCOL_HASH_ONLY;
+ val |= EIP197_ALG_AES_ECB | EIP197_ALG_AES_CBC;
+ val |= EIP197_ALG_SHA1 | EIP197_ALG_HMAC_SHA1;
+- val |= EIP197_ALG_SHA2;
++ val |= EIP197_ALG_SHA2 | EIP197_ALG_HMAC_SHA2;
+ writel(val, EIP197_PE(priv) + EIP197_PE_EIP96_FUNCTION_EN);
+
+ /* Command Descriptor Rings prepare */
+@@ -768,6 +768,7 @@ static struct safexcel_alg_template *safexcel_algs[] = {
+ &safexcel_alg_sha224,
+ &safexcel_alg_sha256,
+ &safexcel_alg_hmac_sha1,
++ &safexcel_alg_hmac_sha256,
+ };
+
+ static int safexcel_register_algorithms(struct safexcel_crypto_priv *priv)
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 295813920618..99e0f32452ff 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -633,5 +633,6 @@ extern struct safexcel_alg_template safexcel_alg_sha1;
+ extern struct safexcel_alg_template safexcel_alg_sha224;
+ extern struct safexcel_alg_template safexcel_alg_sha256;
+ extern struct safexcel_alg_template safexcel_alg_hmac_sha1;
++extern struct safexcel_alg_template safexcel_alg_hmac_sha256;
+
+ #endif
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index d152f2eb0271..2917a902596d 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -22,8 +22,8 @@ struct safexcel_ahash_ctx {
+
+ u32 alg;
+
+- u32 ipad[SHA1_DIGEST_SIZE / sizeof(u32)];
+- u32 opad[SHA1_DIGEST_SIZE / sizeof(u32)];
++ u32 ipad[SHA256_DIGEST_SIZE / sizeof(u32)];
++ u32 opad[SHA256_DIGEST_SIZE / sizeof(u32)];
+ };
+
+ struct safexcel_ahash_req {
+@@ -953,20 +953,21 @@ static int safexcel_hmac_setkey(const char *alg, const u8 *key,
+ return ret;
+ }
+
+-static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
+- unsigned int keylen)
++static int safexcel_hmac_alg_setkey(struct crypto_ahash *tfm, const u8 *key,
++ unsigned int keylen, const char *alg,
++ unsigned int state_sz)
+ {
+ struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm));
+ struct safexcel_crypto_priv *priv = ctx->priv;
+ struct safexcel_ahash_export_state istate, ostate;
+ int ret, i;
+
+- ret = safexcel_hmac_setkey("safexcel-sha1", key, keylen, &istate, &ostate);
++ ret = safexcel_hmac_setkey(alg, key, keylen, &istate, &ostate);
+ if (ret)
+ return ret;
+
+ if (priv->version == EIP197 && ctx->base.ctxr) {
+- for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) {
++ for (i = 0; i < state_sz / sizeof(u32); i++) {
+ if (ctx->ipad[i] != le32_to_cpu(istate.state[i]) ||
+ ctx->opad[i] != le32_to_cpu(ostate.state[i])) {
+ ctx->base.needs_inv = true;
+@@ -975,12 +976,19 @@ static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
+ }
+ }
+
+- memcpy(ctx->ipad, &istate.state, SHA1_DIGEST_SIZE);
+- memcpy(ctx->opad, &ostate.state, SHA1_DIGEST_SIZE);
++ memcpy(ctx->ipad, &istate.state, state_sz);
++ memcpy(ctx->opad, &ostate.state, state_sz);
+
+ return 0;
+ }
+
++static int safexcel_hmac_sha1_setkey(struct crypto_ahash *tfm, const u8 *key,
++ unsigned int keylen)
++{
++ return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sha1",
++ SHA1_DIGEST_SIZE);
++}
++
+ struct safexcel_alg_template safexcel_alg_hmac_sha1 = {
+ .type = SAFEXCEL_ALG_TYPE_AHASH,
+ .alg.ahash = {
+@@ -1134,3 +1142,59 @@ struct safexcel_alg_template safexcel_alg_sha224 = {
+ },
+ },
+ };
++
++static int safexcel_hmac_sha256_setkey(struct crypto_ahash *tfm, const u8 *key,
++ unsigned int keylen)
++{
++ return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sha256",
++ SHA256_DIGEST_SIZE);
++}
++
++static int safexcel_hmac_sha256_init(struct ahash_request *areq)
++{
++ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
++
++ safexcel_sha256_init(areq);
++ req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
++ return 0;
++}
++
++static int safexcel_hmac_sha256_digest(struct ahash_request *areq)
++{
++ int ret = safexcel_hmac_sha256_init(areq);
++
++ if (ret)
++ return ret;
++
++ return safexcel_ahash_finup(areq);
++}
++
++struct safexcel_alg_template safexcel_alg_hmac_sha256 = {
++ .type = SAFEXCEL_ALG_TYPE_AHASH,
++ .alg.ahash = {
++ .init = safexcel_hmac_sha256_init,
++ .update = safexcel_ahash_update,
++ .final = safexcel_ahash_final,
++ .finup = safexcel_ahash_finup,
++ .digest = safexcel_hmac_sha256_digest,
++ .setkey = safexcel_hmac_sha256_setkey,
++ .export = safexcel_ahash_export,
++ .import = safexcel_ahash_import,
++ .halg = {
++ .digestsize = SHA256_DIGEST_SIZE,
++ .statesize = sizeof(struct safexcel_ahash_export_state),
++ .base = {
++ .cra_name = "hmac(sha256)",
++ .cra_driver_name = "safexcel-hmac-sha256",
++ .cra_priority = 300,
++ .cra_flags = CRYPTO_ALG_ASYNC |
++ CRYPTO_ALG_KERN_DRIVER_ONLY,
++ .cra_blocksize = SHA256_BLOCK_SIZE,
++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
++ .cra_init = safexcel_ahash_cra_init,
++ .cra_exit = safexcel_ahash_cra_exit,
++ .cra_module = THIS_MODULE,
++ },
++ },
++ },
++};
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/634-crypto-inside-secure-hmac-sha224-support.patch b/target/linux/mvebu/patches-4.14/634-crypto-inside-secure-hmac-sha224-support.patch
new file mode 100644
index 0000000000..23ed568f9d
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/634-crypto-inside-secure-hmac-sha224-support.patch
@@ -0,0 +1,110 @@
+From 3fcdf8383e1154e89056636a57124401df552e29 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at bootlin.com>
+Date: Mon, 19 Mar 2018 09:21:21 +0100
+Subject: [PATCH 35/36] crypto: inside-secure - hmac(sha224) support
+
+This patch adds the hmac(sha224) support to the Inside Secure
+cryptographic engine driver.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at bootlin.com>
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+---
+ drivers/crypto/inside-secure/safexcel.c | 1 +
+ drivers/crypto/inside-secure/safexcel.h | 1 +
+ drivers/crypto/inside-secure/safexcel_hash.c | 56 ++++++++++++++++++++++++++++
+ 3 files changed, 58 insertions(+)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 33595f41586f..d4a81be0d7d2 100644
+--- a/drivers/crypto/inside-secure/safexcel.c
++++ b/drivers/crypto/inside-secure/safexcel.c
+@@ -768,6 +768,7 @@ static struct safexcel_alg_template *safexcel_algs[] = {
+ &safexcel_alg_sha224,
+ &safexcel_alg_sha256,
+ &safexcel_alg_hmac_sha1,
++ &safexcel_alg_hmac_sha224,
+ &safexcel_alg_hmac_sha256,
+ };
+
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index 99e0f32452ff..b470a849721f 100644
+--- a/drivers/crypto/inside-secure/safexcel.h
++++ b/drivers/crypto/inside-secure/safexcel.h
+@@ -633,6 +633,7 @@ extern struct safexcel_alg_template safexcel_alg_sha1;
+ extern struct safexcel_alg_template safexcel_alg_sha224;
+ extern struct safexcel_alg_template safexcel_alg_sha256;
+ extern struct safexcel_alg_template safexcel_alg_hmac_sha1;
++extern struct safexcel_alg_template safexcel_alg_hmac_sha224;
+ extern struct safexcel_alg_template safexcel_alg_hmac_sha256;
+
+ #endif
+diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c
+index 2917a902596d..d9ddf776c799 100644
+--- a/drivers/crypto/inside-secure/safexcel_hash.c
++++ b/drivers/crypto/inside-secure/safexcel_hash.c
+@@ -1143,6 +1143,62 @@ struct safexcel_alg_template safexcel_alg_sha224 = {
+ },
+ };
+
++static int safexcel_hmac_sha224_setkey(struct crypto_ahash *tfm, const u8 *key,
++ unsigned int keylen)
++{
++ return safexcel_hmac_alg_setkey(tfm, key, keylen, "safexcel-sha224",
++ SHA256_DIGEST_SIZE);
++}
++
++static int safexcel_hmac_sha224_init(struct ahash_request *areq)
++{
++ struct safexcel_ahash_req *req = ahash_request_ctx(areq);
++
++ safexcel_sha224_init(areq);
++ req->digest = CONTEXT_CONTROL_DIGEST_HMAC;
++ return 0;
++}
++
++static int safexcel_hmac_sha224_digest(struct ahash_request *areq)
++{
++ int ret = safexcel_hmac_sha224_init(areq);
++
++ if (ret)
++ return ret;
++
++ return safexcel_ahash_finup(areq);
++}
++
++struct safexcel_alg_template safexcel_alg_hmac_sha224 = {
++ .type = SAFEXCEL_ALG_TYPE_AHASH,
++ .alg.ahash = {
++ .init = safexcel_hmac_sha224_init,
++ .update = safexcel_ahash_update,
++ .final = safexcel_ahash_final,
++ .finup = safexcel_ahash_finup,
++ .digest = safexcel_hmac_sha224_digest,
++ .setkey = safexcel_hmac_sha224_setkey,
++ .export = safexcel_ahash_export,
++ .import = safexcel_ahash_import,
++ .halg = {
++ .digestsize = SHA224_DIGEST_SIZE,
++ .statesize = sizeof(struct safexcel_ahash_export_state),
++ .base = {
++ .cra_name = "hmac(sha224)",
++ .cra_driver_name = "safexcel-hmac-sha224",
++ .cra_priority = 300,
++ .cra_flags = CRYPTO_ALG_ASYNC |
++ CRYPTO_ALG_KERN_DRIVER_ONLY,
++ .cra_blocksize = SHA224_BLOCK_SIZE,
++ .cra_ctxsize = sizeof(struct safexcel_ahash_ctx),
++ .cra_init = safexcel_ahash_cra_init,
++ .cra_exit = safexcel_ahash_cra_exit,
++ .cra_module = THIS_MODULE,
++ },
++ },
++ },
++};
++
+ static int safexcel_hmac_sha256_setkey(struct crypto_ahash *tfm, const u8 *key,
+ unsigned int keylen)
+ {
+--
+2.16.4
+
diff --git a/target/linux/mvebu/patches-4.14/635-arm64-dts-marvell-armada-37xx-add-a-crypto-node.patch b/target/linux/mvebu/patches-4.14/635-arm64-dts-marvell-armada-37xx-add-a-crypto-node.patch
new file mode 100644
index 0000000000..da41aa2a02
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/635-arm64-dts-marvell-armada-37xx-add-a-crypto-node.patch
@@ -0,0 +1,42 @@
+From d2c023f2d1c7158ea315853a7b1e175c75641ca6 Mon Sep 17 00:00:00 2001
+From: Antoine Tenart <antoine.tenart at free-electrons.com>
+Date: Tue, 26 Dec 2017 17:16:53 +0100
+Subject: [PATCH 36/36] arm64: dts: marvell: armada-37xx: add a crypto node
+
+This patch adds a crypto node describing the EIP97 engine found in
+Armada 37xx SoCs. The cryptographic engine is enabled by default.
+
+Signed-off-by: Antoine Tenart <antoine.tenart at free-electrons.com>
+Signed-off-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
+---
+ arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+index a5fe6c60cd0a..8cd43ce38571 100644
+--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+@@ -302,6 +302,20 @@
+ };
+ };
+
++ crypto: crypto at 90000 {
++ compatible = "inside-secure,safexcel-eip97";
++ reg = <0x90000 0x20000>;
++ interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
++ <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
++ interrupt-names = "mem", "ring0", "ring1",
++ "ring2", "ring3", "eip";
++ clocks = <&nb_periph_clk 15>;
++ };
++
+ sdhci1: sdhci at d0000 {
+ compatible = "marvell,armada-3700-sdhci",
+ "marvell,sdhci-xenon";
+--
+2.16.4
+
--
2.16.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list