2022-07-06 09:06:50

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 00/33] crypto: rockchip: permit to pass self-tests

Hello

The rockchip crypto driver is broken and do not pass self-tests.
This serie's goal is to permit to become usable and pass self-tests.

This whole serie is tested on a rk3328-rock64, rk3288-miqi and
rk3399-khadas-edge-v with selftests (with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS=y)

Regards

Changes since v1:
- select CRYPTO_ENGINE
- forgot to free fallbacks TFMs
- fixed kernel test robots warning
- add the PM patch

Changes since v2:
- Added DMA clock back to 3288 since it dont work without it
- fallback needed to select CBC and ECB configs
- Added support for rk3399
- Added more patch (style, read_poll_timeout)

Changes since v3:
- full rewrite of support for RK3399
- splited dt-binding patch in two

Changes since v4:
- Another full rewrite of support for RK3399
- Fixed dt-binding from Krzysztof Kozlowski's comments
- Use readl_poll_timeout() instead of read_poll_timeout()
- Rewrite the fallback SG tests

Changes since v5:
- fixed errors in DT binding patch

Change since v6:
- remove quotes around const values in dt-bindings

Changes since v7:
- added lot of reviewed/tested by
- In patch 14: keep initial reset pulse.

Corentin Labbe (33):
crypto: rockchip: use dev_err for error message about interrupt
crypto: rockchip: do not use uninitialized variable
crypto: rockchip: do not do custom power management
crypto: rockchip: fix privete/private typo
crypto: rockchip: do not store mode globally
crypto: rockchip: add fallback for cipher
crypto: rockchip: add fallback for ahash
crypto: rockchip: better handle cipher key
crypto: rockchip: remove non-aligned handling
crypto: rockchip: rework by using crypto_engine
crypto: rockchip: rewrite type
crypto: rockchip: add debugfs
crypto: rockchip: introduce PM
crypto: rockchip: handle reset also in PM
crypto: rockchip: use clk_bulk to simplify clock management
crypto: rockchip: add myself as maintainer
crypto: rockchip: use read_poll_timeout
crypto: rockchip: fix style issue
crypto: rockchip: add support for rk3328
crypto: rockchip: rename ablk functions to cipher
crypto: rockchip: rework rk_handle_req function
crypto: rockchip: use a rk_crypto_info variable instead of lot of
indirection
crypto: rockchip: use the rk_crypto_info given as parameter
dt-bindings: crypto: convert rockchip-crypto to YAML
dt-bindings: crypto: rockchip: convert to new driver bindings
clk: rk3399: use proper crypto0 name
arm64: dts: rockchip: add rk3328 crypto node
arm64: dts: rockchip: rk3399: add crypto node
crypto: rockchip: store crypto_info in request context
crypto: rockchip: Check for clocks numbers and their frequencies
crypto: rockchip: rk_ahash_reg_init use crypto_info from parameter
crypto: rockchip: permit to have more than one reset
crypto: rockchip: Add support for RK3399

.../crypto/rockchip,rk3288-crypto.yaml | 133 +++++
.../bindings/crypto/rockchip-crypto.txt | 28 -
MAINTAINERS | 7 +
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 11 +
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 20 +
drivers/crypto/Kconfig | 15 +
drivers/crypto/rockchip/rk3288_crypto.c | 506 ++++++++--------
drivers/crypto/rockchip/rk3288_crypto.h | 107 ++--
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 267 +++++----
.../crypto/rockchip/rk3288_crypto_skcipher.c | 543 ++++++++++--------
include/dt-bindings/clock/rk3399-cru.h | 6 +-
11 files changed, 955 insertions(+), 688 deletions(-)
create mode 100644 Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
delete mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt

--
2.35.1


2022-07-06 09:06:53

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 03/33] crypto: rockchip: do not do custom power management

The clock enable/disable at tfm init/exit is fragile,
if 2 tfm are init in the same time and one is removed just after,
it will leave the hardware uncloked even if a user remains.

Instead simply enable clocks at probe time.
We will do PM later.

Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 4 ++--
drivers/crypto/rockchip/rk3288_crypto.h | 2 --
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 3 +--
drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 5 +++--
4 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 21d3f1458584..4cff49b82983 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -394,8 +394,7 @@ static int rk_crypto_probe(struct platform_device *pdev)
rk_crypto_done_task_cb, (unsigned long)crypto_info);
crypto_init_queue(&crypto_info->queue, 50);

- crypto_info->enable_clk = rk_crypto_enable_clk;
- crypto_info->disable_clk = rk_crypto_disable_clk;
+ rk_crypto_enable_clk(crypto_info);
crypto_info->load_data = rk_load_data;
crypto_info->unload_data = rk_unload_data;
crypto_info->enqueue = rk_crypto_enqueue;
@@ -422,6 +421,7 @@ static int rk_crypto_remove(struct platform_device *pdev)
struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);

rk_crypto_unregister();
+ rk_crypto_disable_clk(crypto_tmp);
tasklet_kill(&crypto_tmp->done_task);
tasklet_kill(&crypto_tmp->queue_task);
return 0;
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 97278c2574ff..2fa7131e4060 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -220,8 +220,6 @@ struct rk_crypto_info {
int (*start)(struct rk_crypto_info *dev);
int (*update)(struct rk_crypto_info *dev);
void (*complete)(struct crypto_async_request *base, int err);
- int (*enable_clk)(struct rk_crypto_info *dev);
- void (*disable_clk)(struct rk_crypto_info *dev);
int (*load_data)(struct rk_crypto_info *dev,
struct scatterlist *sg_src,
struct scatterlist *sg_dst);
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index ed03058497bc..49017d1fb510 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -301,7 +301,7 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
sizeof(struct rk_ahash_rctx) +
crypto_ahash_reqsize(tctx->fallback_tfm));

- return tctx->dev->enable_clk(tctx->dev);
+ return 0;
}

static void rk_cra_hash_exit(struct crypto_tfm *tfm)
@@ -309,7 +309,6 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);

free_page((unsigned long)tctx->dev->addr_vir);
- return tctx->dev->disable_clk(tctx->dev);
}

struct rk_crypto_tmp rk_ahash_sha1 = {
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 5bbf0d2722e1..8c44a19eab75 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -388,8 +388,10 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
ctx->dev->update = rk_ablk_rx;
ctx->dev->complete = rk_crypto_complete;
ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL);
+ if (!ctx->dev->addr_vir)
+ return -ENOMEM;

- return ctx->dev->addr_vir ? ctx->dev->enable_clk(ctx->dev) : -ENOMEM;
+ return 0;
}

static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
@@ -397,7 +399,6 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);

free_page((unsigned long)ctx->dev->addr_vir);
- ctx->dev->disable_clk(ctx->dev);
}

struct rk_crypto_tmp rk_ecb_aes_alg = {
--
2.35.1

2022-07-06 09:06:54

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 04/33] crypto: rockchip: fix privete/private typo

This fix a simple typo on private word.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 2fa7131e4060..656d6795d400 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -235,7 +235,7 @@ struct rk_ahash_ctx {
struct crypto_ahash *fallback_tfm;
};

-/* the privete variable of hash for fallback */
+/* the private variable of hash for fallback */
struct rk_ahash_rctx {
struct ahash_request fallback_req;
u32 mode;
--
2.35.1

2022-07-06 09:07:06

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 07/33] crypto: rockchip: add fallback for ahash

Adds a fallback for all case hardware cannot handle.

Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index 49017d1fb510..16009bb0bf16 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -16,6 +16,40 @@
* so we put the fixed hash out when met zero message.
*/

+static bool rk_ahash_need_fallback(struct ahash_request *req)
+{
+ struct scatterlist *sg;
+
+ sg = req->src;
+ while (sg) {
+ if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
+ return true;
+ }
+ if (sg->length % 4) {
+ return true;
+ }
+ sg = sg_next(sg);
+ }
+ return false;
+}
+
+static int rk_ahash_digest_fb(struct ahash_request *areq)
+{
+ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm);
+
+ ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
+ rctx->fallback_req.base.flags = areq->base.flags &
+ CRYPTO_TFM_REQ_MAY_SLEEP;
+
+ rctx->fallback_req.nbytes = areq->nbytes;
+ rctx->fallback_req.src = areq->src;
+ rctx->fallback_req.result = areq->result;
+
+ return crypto_ahash_digest(&rctx->fallback_req);
+}
+
static int zero_message_process(struct ahash_request *req)
{
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
@@ -167,6 +201,9 @@ static int rk_ahash_digest(struct ahash_request *req)
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
struct rk_crypto_info *dev = tctx->dev;

+ if (rk_ahash_need_fallback(req))
+ return rk_ahash_digest_fb(req);
+
if (!req->nbytes)
return zero_message_process(req);
else
@@ -309,6 +346,7 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);

free_page((unsigned long)tctx->dev->addr_vir);
+ crypto_free_ahash(tctx->fallback_tfm);
}

struct rk_crypto_tmp rk_ahash_sha1 = {
--
2.35.1

2022-07-06 09:07:10

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 08/33] crypto: rockchip: better handle cipher key

The key should not be set in hardware too much in advance, this will
fail it 2 TFM with different keys generate alternative requests.
The key should be stored and used just before doing cipher operations.

Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.h | 1 +
drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 10 +++++++---
2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 8b1e15d8ddc6..540b81a14b9b 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -245,6 +245,7 @@ struct rk_ahash_rctx {
struct rk_cipher_ctx {
struct rk_crypto_info *dev;
unsigned int keylen;
+ u8 key[AES_MAX_KEY_SIZE];
u8 iv[AES_BLOCK_SIZE];
struct crypto_skcipher *fallback_tfm;
};
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index eac5bba66e25..1ef94f8db2c5 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -95,7 +95,7 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher,
keylen != AES_KEYSIZE_256)
return -EINVAL;
ctx->keylen = keylen;
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen);
+ memcpy(ctx->key, key, keylen);

return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
}
@@ -111,7 +111,7 @@ static int rk_des_setkey(struct crypto_skcipher *cipher,
return err;

ctx->keylen = keylen;
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
+ memcpy(ctx->key, key, keylen);

return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
}
@@ -127,7 +127,8 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher,
return err;

ctx->keylen = keylen;
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
+ memcpy(ctx->key, key, keylen);
+
return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
}

@@ -283,6 +284,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
RK_CRYPTO_TDES_BYTESWAP_IV;
CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
+ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
conf_reg = RK_CRYPTO_DESSEL;
} else {
rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
@@ -295,6 +297,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
rctx->mode |= RK_CRYPTO_AES_256BIT_key;
CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
+ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
}
conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
RK_CRYPTO_BYTESWAP_BRFIFO;
@@ -484,6 +487,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
{
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);

+ memzero_explicit(ctx->key, ctx->keylen);
free_page((unsigned long)ctx->dev->addr_vir);
crypto_free_skcipher(ctx->fallback_tfm);
}
--
2.35.1

2022-07-06 09:07:10

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 05/33] crypto: rockchip: do not store mode globally

Storing the mode globally does not work if 2 requests are handled in the
same time.
We should store it in a request context.

Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.h | 5 +-
.../crypto/rockchip/rk3288_crypto_skcipher.c | 58 ++++++++++++-------
2 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 656d6795d400..c919d9a43a08 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -245,10 +245,13 @@ struct rk_ahash_rctx {
struct rk_cipher_ctx {
struct rk_crypto_info *dev;
unsigned int keylen;
- u32 mode;
u8 iv[AES_BLOCK_SIZE];
};

+struct rk_cipher_rctx {
+ u32 mode;
+};
+
enum alg_type {
ALG_TYPE_HASH,
ALG_TYPE_CIPHER,
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 8c44a19eab75..bbd0bf52bf07 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -76,9 +76,10 @@ static int rk_aes_ecb_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_AES_ECB_MODE;
+ rctx->mode = RK_CRYPTO_AES_ECB_MODE;
return rk_handle_req(dev, req);
}

@@ -86,9 +87,10 @@ static int rk_aes_ecb_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -96,9 +98,10 @@ static int rk_aes_cbc_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_AES_CBC_MODE;
+ rctx->mode = RK_CRYPTO_AES_CBC_MODE;
return rk_handle_req(dev, req);
}

@@ -106,9 +109,10 @@ static int rk_aes_cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -116,9 +120,10 @@ static int rk_des_ecb_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = 0;
+ rctx->mode = 0;
return rk_handle_req(dev, req);
}

@@ -126,9 +131,10 @@ static int rk_des_ecb_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -136,9 +142,10 @@ static int rk_des_cbc_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
+ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
return rk_handle_req(dev, req);
}

@@ -146,9 +153,10 @@ static int rk_des_cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -156,9 +164,10 @@ static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_SELECT;
+ rctx->mode = RK_CRYPTO_TDES_SELECT;
return rk_handle_req(dev, req);
}

@@ -166,9 +175,10 @@ static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
+ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}

@@ -176,9 +186,10 @@ static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
+ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
return rk_handle_req(dev, req);
}

@@ -186,9 +197,10 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *dev = ctx->dev;

- ctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
+ rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
RK_CRYPTO_DEC;
return rk_handle_req(dev, req);
}
@@ -199,6 +211,7 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
skcipher_request_cast(dev->async_req);
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
u32 ivsize, block, conf_reg = 0;

@@ -206,22 +219,22 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
ivsize = crypto_skcipher_ivsize(cipher);

if (block == DES_BLOCK_SIZE) {
- ctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
+ rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
RK_CRYPTO_TDES_BYTESWAP_KEY |
RK_CRYPTO_TDES_BYTESWAP_IV;
- CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, ctx->mode);
+ CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
conf_reg = RK_CRYPTO_DESSEL;
} else {
- ctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
+ rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
RK_CRYPTO_AES_KEY_CHANGE |
RK_CRYPTO_AES_BYTESWAP_KEY |
RK_CRYPTO_AES_BYTESWAP_IV;
if (ctx->keylen == AES_KEYSIZE_192)
- ctx->mode |= RK_CRYPTO_AES_192BIT_key;
+ rctx->mode |= RK_CRYPTO_AES_192BIT_key;
else if (ctx->keylen == AES_KEYSIZE_256)
- ctx->mode |= RK_CRYPTO_AES_256BIT_key;
- CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, ctx->mode);
+ rctx->mode |= RK_CRYPTO_AES_256BIT_key;
+ CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
}
conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
@@ -246,6 +259,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
struct skcipher_request *req =
skcipher_request_cast(dev->async_req);
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
u32 ivsize = crypto_skcipher_ivsize(tfm);
u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
@@ -254,7 +268,7 @@ static int rk_set_data_start(struct rk_crypto_info *dev)
/* Store the iv that need to be updated in chain mode.
* And update the IV buffer to contain the next IV for decryption mode.
*/
- if (ctx->mode & RK_CRYPTO_DEC) {
+ if (rctx->mode & RK_CRYPTO_DEC) {
memcpy(ctx->iv, src_last_blk, ivsize);
sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
ivsize, dev->total - ivsize);
@@ -294,11 +308,12 @@ static void rk_iv_copyback(struct rk_crypto_info *dev)
struct skcipher_request *req =
skcipher_request_cast(dev->async_req);
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
u32 ivsize = crypto_skcipher_ivsize(tfm);

/* Update the IV buffer to contain the next IV for encryption mode. */
- if (!(ctx->mode & RK_CRYPTO_DEC)) {
+ if (!(rctx->mode & RK_CRYPTO_DEC)) {
if (dev->aligned) {
memcpy(req->iv, sg_virt(dev->sg_dst) +
dev->sg_dst->length - ivsize, ivsize);
@@ -314,11 +329,12 @@ static void rk_update_iv(struct rk_crypto_info *dev)
struct skcipher_request *req =
skcipher_request_cast(dev->async_req);
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
u32 ivsize = crypto_skcipher_ivsize(tfm);
u8 *new_iv = NULL;

- if (ctx->mode & RK_CRYPTO_DEC) {
+ if (rctx->mode & RK_CRYPTO_DEC) {
new_iv = ctx->iv;
} else {
new_iv = page_address(sg_page(dev->sg_dst)) +
--
2.35.1

2022-07-06 09:07:13

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 09/33] crypto: rockchip: remove non-aligned handling

Now driver have fallback for un-aligned cases, remove all code handling
those cases.

Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 69 +++++--------------
drivers/crypto/rockchip/rk3288_crypto.h | 4 --
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 22 ++----
.../crypto/rockchip/rk3288_crypto_skcipher.c | 39 +++--------
4 files changed, 31 insertions(+), 103 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 4cff49b82983..b3db096e2ec2 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -88,63 +88,26 @@ static int rk_load_data(struct rk_crypto_info *dev,
{
unsigned int count;

- dev->aligned = dev->aligned ?
- check_alignment(sg_src, sg_dst, dev->align_size) :
- dev->aligned;
- if (dev->aligned) {
- count = min(dev->left_bytes, sg_src->length);
- dev->left_bytes -= count;
-
- if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) {
- dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n",
+ count = min(dev->left_bytes, sg_src->length);
+ dev->left_bytes -= count;
+
+ if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) {
+ dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n",
__func__, __LINE__);
- return -EINVAL;
- }
- dev->addr_in = sg_dma_address(sg_src);
+ return -EINVAL;
+ }
+ dev->addr_in = sg_dma_address(sg_src);

- if (sg_dst) {
- if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) {
- dev_err(dev->dev,
+ if (sg_dst) {
+ if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) {
+ dev_err(dev->dev,
"[%s:%d] dma_map_sg(dst) error\n",
__func__, __LINE__);
- dma_unmap_sg(dev->dev, sg_src, 1,
- DMA_TO_DEVICE);
- return -EINVAL;
- }
- dev->addr_out = sg_dma_address(sg_dst);
- }
- } else {
- count = (dev->left_bytes > PAGE_SIZE) ?
- PAGE_SIZE : dev->left_bytes;
-
- if (!sg_pcopy_to_buffer(dev->first, dev->src_nents,
- dev->addr_vir, count,
- dev->total - dev->left_bytes)) {
- dev_err(dev->dev, "[%s:%d] pcopy err\n",
- __func__, __LINE__);
+ dma_unmap_sg(dev->dev, sg_src, 1,
+ DMA_TO_DEVICE);
return -EINVAL;
}
- dev->left_bytes -= count;
- sg_init_one(&dev->sg_tmp, dev->addr_vir, count);
- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1, DMA_TO_DEVICE)) {
- dev_err(dev->dev, "[%s:%d] dma_map_sg(sg_tmp) error\n",
- __func__, __LINE__);
- return -ENOMEM;
- }
- dev->addr_in = sg_dma_address(&dev->sg_tmp);
-
- if (sg_dst) {
- if (!dma_map_sg(dev->dev, &dev->sg_tmp, 1,
- DMA_FROM_DEVICE)) {
- dev_err(dev->dev,
- "[%s:%d] dma_map_sg(sg_tmp) error\n",
- __func__, __LINE__);
- dma_unmap_sg(dev->dev, &dev->sg_tmp, 1,
- DMA_TO_DEVICE);
- return -ENOMEM;
- }
- dev->addr_out = sg_dma_address(&dev->sg_tmp);
- }
+ dev->addr_out = sg_dma_address(sg_dst);
}
dev->count = count;
return 0;
@@ -154,11 +117,11 @@ static void rk_unload_data(struct rk_crypto_info *dev)
{
struct scatterlist *sg_in, *sg_out;

- sg_in = dev->aligned ? dev->sg_src : &dev->sg_tmp;
+ sg_in = dev->sg_src;
dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE);

if (dev->sg_dst) {
- sg_out = dev->aligned ? dev->sg_dst : &dev->sg_tmp;
+ sg_out = dev->sg_dst;
dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE);
}
}
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 540b81a14b9b..a7de5738f6dc 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -204,12 +204,8 @@ struct rk_crypto_info {
/* the public variable */
struct scatterlist *sg_src;
struct scatterlist *sg_dst;
- struct scatterlist sg_tmp;
struct scatterlist *first;
unsigned int left_bytes;
- void *addr_vir;
- int aligned;
- int align_size;
size_t src_nents;
size_t dst_nents;
unsigned int total;
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index 16009bb0bf16..c762e462eb57 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -236,8 +236,6 @@ static int rk_ahash_start(struct rk_crypto_info *dev)

dev->total = req->nbytes;
dev->left_bytes = req->nbytes;
- dev->aligned = 0;
- dev->align_size = 4;
dev->sg_dst = NULL;
dev->sg_src = req->src;
dev->first = req->src;
@@ -272,15 +270,13 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)

dev->unload_data(dev);
if (dev->left_bytes) {
- if (dev->aligned) {
- if (sg_is_last(dev->sg_src)) {
- dev_warn(dev->dev, "[%s:%d], Lack of data\n",
- __func__, __LINE__);
- err = -ENOMEM;
- goto out_rx;
- }
- dev->sg_src = sg_next(dev->sg_src);
+ if (sg_is_last(dev->sg_src)) {
+ dev_warn(dev->dev, "[%s:%d], Lack of data\n",
+ __func__, __LINE__);
+ err = -ENOMEM;
+ goto out_rx;
}
+ dev->sg_src = sg_next(dev->sg_src);
err = rk_ahash_set_data_start(dev);
} else {
/*
@@ -318,11 +314,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
algt = container_of(alg, struct rk_crypto_tmp, alg.hash);

tctx->dev = algt->dev;
- tctx->dev->addr_vir = (void *)__get_free_page(GFP_KERNEL);
- if (!tctx->dev->addr_vir) {
- dev_err(tctx->dev->dev, "failed to kmalloc for addr_vir\n");
- return -ENOMEM;
- }
tctx->dev->start = rk_ahash_start;
tctx->dev->update = rk_ahash_crypto_rx;
tctx->dev->complete = rk_ahash_crypto_complete;
@@ -345,7 +336,6 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
{
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);

- free_page((unsigned long)tctx->dev->addr_vir);
crypto_free_ahash(tctx->fallback_tfm);
}

diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 1ef94f8db2c5..d067b7f09165 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -356,7 +356,6 @@ static int rk_ablk_start(struct rk_crypto_info *dev)
dev->src_nents = sg_nents(req->src);
dev->sg_dst = req->dst;
dev->dst_nents = sg_nents(req->dst);
- dev->aligned = 1;

spin_lock_irqsave(&dev->lock, flags);
rk_ablk_hw_init(dev);
@@ -376,13 +375,9 @@ static void rk_iv_copyback(struct rk_crypto_info *dev)

/* Update the IV buffer to contain the next IV for encryption mode. */
if (!(rctx->mode & RK_CRYPTO_DEC)) {
- if (dev->aligned) {
- memcpy(req->iv, sg_virt(dev->sg_dst) +
- dev->sg_dst->length - ivsize, ivsize);
- } else {
- memcpy(req->iv, dev->addr_vir +
- dev->count - ivsize, ivsize);
- }
+ memcpy(req->iv,
+ sg_virt(dev->sg_dst) + dev->sg_dst->length - ivsize,
+ ivsize);
}
}

@@ -420,27 +415,16 @@ static int rk_ablk_rx(struct rk_crypto_info *dev)
skcipher_request_cast(dev->async_req);

dev->unload_data(dev);
- if (!dev->aligned) {
- if (!sg_pcopy_from_buffer(req->dst, dev->dst_nents,
- dev->addr_vir, dev->count,
- dev->total - dev->left_bytes -
- dev->count)) {
- err = -EINVAL;
- goto out_rx;
- }
- }
if (dev->left_bytes) {
rk_update_iv(dev);
- if (dev->aligned) {
- if (sg_is_last(dev->sg_src)) {
- dev_err(dev->dev, "[%s:%d] Lack of data\n",
+ if (sg_is_last(dev->sg_src)) {
+ dev_err(dev->dev, "[%s:%d] Lack of data\n",
__func__, __LINE__);
- err = -ENOMEM;
- goto out_rx;
- }
- dev->sg_src = sg_next(dev->sg_src);
- dev->sg_dst = sg_next(dev->sg_dst);
+ err = -ENOMEM;
+ goto out_rx;
}
+ dev->sg_src = sg_next(dev->sg_src);
+ dev->sg_dst = sg_next(dev->sg_dst);
err = rk_set_data_start(dev);
} else {
rk_iv_copyback(dev);
@@ -462,13 +446,9 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);

ctx->dev = algt->dev;
- ctx->dev->align_size = crypto_tfm_alg_alignmask(crypto_skcipher_tfm(tfm)) + 1;
ctx->dev->start = rk_ablk_start;
ctx->dev->update = rk_ablk_rx;
ctx->dev->complete = rk_crypto_complete;
- ctx->dev->addr_vir = (char *)__get_free_page(GFP_KERNEL);
- if (!ctx->dev->addr_vir)
- return -ENOMEM;

ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(ctx->fallback_tfm)) {
@@ -488,7 +468,6 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);

memzero_explicit(ctx->key, ctx->keylen);
- free_page((unsigned long)ctx->dev->addr_vir);
crypto_free_skcipher(ctx->fallback_tfm);
}

--
2.35.1

2022-07-06 09:07:23

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 10/33] crypto: rockchip: rework by using crypto_engine

Instead of doing manual queue management, let's use the crypto/engine
for that.
In the same time, rework the requests handling to be easier to
understand (and fix all bugs related to them).

Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/Kconfig | 1 +
drivers/crypto/rockchip/rk3288_crypto.c | 152 +----------
drivers/crypto/rockchip/rk3288_crypto.h | 39 +--
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 144 +++++-----
.../crypto/rockchip/rk3288_crypto_skcipher.c | 250 +++++++++---------
5 files changed, 221 insertions(+), 365 deletions(-)

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index c293f801806c..df4f0a2de098 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -789,6 +789,7 @@ config CRYPTO_DEV_ROCKCHIP
select CRYPTO_CBC
select CRYPTO_DES
select CRYPTO_AES
+ select CRYPTO_ENGINE
select CRYPTO_LIB_DES
select CRYPTO_MD5
select CRYPTO_SHA1
diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index b3db096e2ec2..1afb65eee6c9 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -65,149 +65,24 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev)
clk_disable_unprepare(dev->sclk);
}

-static int check_alignment(struct scatterlist *sg_src,
- struct scatterlist *sg_dst,
- int align_mask)
-{
- int in, out, align;
-
- in = IS_ALIGNED((uint32_t)sg_src->offset, 4) &&
- IS_ALIGNED((uint32_t)sg_src->length, align_mask);
- if (!sg_dst)
- return in;
- out = IS_ALIGNED((uint32_t)sg_dst->offset, 4) &&
- IS_ALIGNED((uint32_t)sg_dst->length, align_mask);
- align = in && out;
-
- return (align && (sg_src->length == sg_dst->length));
-}
-
-static int rk_load_data(struct rk_crypto_info *dev,
- struct scatterlist *sg_src,
- struct scatterlist *sg_dst)
-{
- unsigned int count;
-
- count = min(dev->left_bytes, sg_src->length);
- dev->left_bytes -= count;
-
- if (!dma_map_sg(dev->dev, sg_src, 1, DMA_TO_DEVICE)) {
- dev_err(dev->dev, "[%s:%d] dma_map_sg(src) error\n",
- __func__, __LINE__);
- return -EINVAL;
- }
- dev->addr_in = sg_dma_address(sg_src);
-
- if (sg_dst) {
- if (!dma_map_sg(dev->dev, sg_dst, 1, DMA_FROM_DEVICE)) {
- dev_err(dev->dev,
- "[%s:%d] dma_map_sg(dst) error\n",
- __func__, __LINE__);
- dma_unmap_sg(dev->dev, sg_src, 1,
- DMA_TO_DEVICE);
- return -EINVAL;
- }
- dev->addr_out = sg_dma_address(sg_dst);
- }
- dev->count = count;
- return 0;
-}
-
-static void rk_unload_data(struct rk_crypto_info *dev)
-{
- struct scatterlist *sg_in, *sg_out;
-
- sg_in = dev->sg_src;
- dma_unmap_sg(dev->dev, sg_in, 1, DMA_TO_DEVICE);
-
- if (dev->sg_dst) {
- sg_out = dev->sg_dst;
- dma_unmap_sg(dev->dev, sg_out, 1, DMA_FROM_DEVICE);
- }
-}
-
static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id)
{
struct rk_crypto_info *dev = platform_get_drvdata(dev_id);
u32 interrupt_status;

- spin_lock(&dev->lock);
interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS);
CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status);

+ dev->status = 1;
if (interrupt_status & 0x0a) {
dev_warn(dev->dev, "DMA Error\n");
- dev->err = -EFAULT;
+ dev->status = 0;
}
- tasklet_schedule(&dev->done_task);
+ complete(&dev->complete);

- spin_unlock(&dev->lock);
return IRQ_HANDLED;
}

-static int rk_crypto_enqueue(struct rk_crypto_info *dev,
- struct crypto_async_request *async_req)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&dev->lock, flags);
- ret = crypto_enqueue_request(&dev->queue, async_req);
- if (dev->busy) {
- spin_unlock_irqrestore(&dev->lock, flags);
- return ret;
- }
- dev->busy = true;
- spin_unlock_irqrestore(&dev->lock, flags);
- tasklet_schedule(&dev->queue_task);
-
- return ret;
-}
-
-static void rk_crypto_queue_task_cb(unsigned long data)
-{
- struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
- struct crypto_async_request *async_req, *backlog;
- unsigned long flags;
- int err = 0;
-
- dev->err = 0;
- spin_lock_irqsave(&dev->lock, flags);
- backlog = crypto_get_backlog(&dev->queue);
- async_req = crypto_dequeue_request(&dev->queue);
-
- if (!async_req) {
- dev->busy = false;
- spin_unlock_irqrestore(&dev->lock, flags);
- return;
- }
- spin_unlock_irqrestore(&dev->lock, flags);
-
- if (backlog) {
- backlog->complete(backlog, -EINPROGRESS);
- backlog = NULL;
- }
-
- dev->async_req = async_req;
- err = dev->start(dev);
- if (err)
- dev->complete(dev->async_req, err);
-}
-
-static void rk_crypto_done_task_cb(unsigned long data)
-{
- struct rk_crypto_info *dev = (struct rk_crypto_info *)data;
-
- if (dev->err) {
- dev->complete(dev->async_req, dev->err);
- return;
- }
-
- dev->err = dev->update(dev);
- if (dev->err)
- dev->complete(dev->async_req, dev->err);
-}
-
static struct rk_crypto_tmp *rk_cipher_algs[] = {
&rk_ecb_aes_alg,
&rk_cbc_aes_alg,
@@ -300,8 +175,6 @@ static int rk_crypto_probe(struct platform_device *pdev)
if (err)
goto err_crypto;

- spin_lock_init(&crypto_info->lock);
-
crypto_info->reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(crypto_info->reg)) {
err = PTR_ERR(crypto_info->reg);
@@ -351,17 +224,11 @@ static int rk_crypto_probe(struct platform_device *pdev)
crypto_info->dev = &pdev->dev;
platform_set_drvdata(pdev, crypto_info);

- tasklet_init(&crypto_info->queue_task,
- rk_crypto_queue_task_cb, (unsigned long)crypto_info);
- tasklet_init(&crypto_info->done_task,
- rk_crypto_done_task_cb, (unsigned long)crypto_info);
- crypto_init_queue(&crypto_info->queue, 50);
+ crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true);
+ crypto_engine_start(crypto_info->engine);
+ init_completion(&crypto_info->complete);

rk_crypto_enable_clk(crypto_info);
- crypto_info->load_data = rk_load_data;
- crypto_info->unload_data = rk_unload_data;
- crypto_info->enqueue = rk_crypto_enqueue;
- crypto_info->busy = false;

err = rk_crypto_register(crypto_info);
if (err) {
@@ -373,9 +240,9 @@ static int rk_crypto_probe(struct platform_device *pdev)
return 0;

err_register_alg:
- tasklet_kill(&crypto_info->queue_task);
- tasklet_kill(&crypto_info->done_task);
+ crypto_engine_exit(crypto_info->engine);
err_crypto:
+ dev_err(dev, "Crypto Accelerator not successfully registered\n");
return err;
}

@@ -385,8 +252,7 @@ static int rk_crypto_remove(struct platform_device *pdev)

rk_crypto_unregister();
rk_crypto_disable_clk(crypto_tmp);
- tasklet_kill(&crypto_tmp->done_task);
- tasklet_kill(&crypto_tmp->queue_task);
+ crypto_engine_exit(crypto_tmp->engine);
return 0;
}

diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index a7de5738f6dc..65ed645e0168 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -5,9 +5,11 @@
#include <crypto/aes.h>
#include <crypto/internal/des.h>
#include <crypto/algapi.h>
+#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/scatterlist.h>
+#include <crypto/engine.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>

@@ -193,39 +195,15 @@ struct rk_crypto_info {
struct reset_control *rst;
void __iomem *reg;
int irq;
- struct crypto_queue queue;
- struct tasklet_struct queue_task;
- struct tasklet_struct done_task;
- struct crypto_async_request *async_req;
- int err;
- /* device lock */
- spinlock_t lock;
-
- /* the public variable */
- struct scatterlist *sg_src;
- struct scatterlist *sg_dst;
- struct scatterlist *first;
- unsigned int left_bytes;
- size_t src_nents;
- size_t dst_nents;
- unsigned int total;
- unsigned int count;
- dma_addr_t addr_in;
- dma_addr_t addr_out;
- bool busy;
- int (*start)(struct rk_crypto_info *dev);
- int (*update)(struct rk_crypto_info *dev);
- void (*complete)(struct crypto_async_request *base, int err);
- int (*load_data)(struct rk_crypto_info *dev,
- struct scatterlist *sg_src,
- struct scatterlist *sg_dst);
- void (*unload_data)(struct rk_crypto_info *dev);
- int (*enqueue)(struct rk_crypto_info *dev,
- struct crypto_async_request *async_req);
+
+ struct crypto_engine *engine;
+ struct completion complete;
+ int status;
};

/* the private variable of hash */
struct rk_ahash_ctx {
+ struct crypto_engine_ctx enginectx;
struct rk_crypto_info *dev;
/* for fallback */
struct crypto_ahash *fallback_tfm;
@@ -235,10 +213,12 @@ struct rk_ahash_ctx {
struct rk_ahash_rctx {
struct ahash_request fallback_req;
u32 mode;
+ int nrsg;
};

/* the private variable of cipher */
struct rk_cipher_ctx {
+ struct crypto_engine_ctx enginectx;
struct rk_crypto_info *dev;
unsigned int keylen;
u8 key[AES_MAX_KEY_SIZE];
@@ -247,6 +227,7 @@ struct rk_cipher_ctx {
};

struct rk_cipher_rctx {
+ u8 backup_iv[AES_BLOCK_SIZE];
u32 mode;
struct skcipher_request fallback_req; // keep at the end
};
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index c762e462eb57..edd40e16a3f0 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -9,6 +9,7 @@
* Some ideas are from marvell/cesa.c and s5p-sss.c driver.
*/
#include <linux/device.h>
+#include <asm/unaligned.h>
#include "rk3288_crypto.h"

/*
@@ -72,16 +73,12 @@ static int zero_message_process(struct ahash_request *req)
return 0;
}

-static void rk_ahash_crypto_complete(struct crypto_async_request *base, int err)
+static void rk_ahash_reg_init(struct ahash_request *req)
{
- if (base->complete)
- base->complete(base, err);
-}
-
-static void rk_ahash_reg_init(struct rk_crypto_info *dev)
-{
- struct ahash_request *req = ahash_request_cast(dev->async_req);
struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct rk_crypto_info *dev = tctx->dev;
int reg_status;

reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) |
@@ -108,7 +105,7 @@ static void rk_ahash_reg_init(struct rk_crypto_info *dev)
RK_CRYPTO_BYTESWAP_BRFIFO |
RK_CRYPTO_BYTESWAP_BTFIFO);

- CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, dev->total);
+ CRYPTO_WRITE(dev, RK_CRYPTO_HASH_MSG_LEN, req->nbytes);
}

static int rk_ahash_init(struct ahash_request *req)
@@ -206,44 +203,59 @@ static int rk_ahash_digest(struct ahash_request *req)

if (!req->nbytes)
return zero_message_process(req);
- else
- return dev->enqueue(dev, &req->base);
+
+ return crypto_transfer_hash_request_to_engine(dev->engine, req);
}

-static void crypto_ahash_dma_start(struct rk_crypto_info *dev)
+static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg)
{
- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, dev->addr_in);
- CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, (dev->count + 3) / 4);
+ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAS, sg_dma_address(sg));
+ CRYPTO_WRITE(dev, RK_CRYPTO_HRDMAL, sg_dma_len(sg) / 4);
CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_HASH_START |
(RK_CRYPTO_HASH_START << 16));
}

-static int rk_ahash_set_data_start(struct rk_crypto_info *dev)
+static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
+{
+ struct ahash_request *areq = container_of(breq, struct ahash_request, base);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
+ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ int ret;
+
+ ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
+ if (ret <= 0)
+ return -EINVAL;
+
+ rctx->nrsg = ret;
+
+ return 0;
+}
+
+static int rk_hash_unprepare(struct crypto_engine *engine, void *breq)
{
- int err;
+ struct ahash_request *areq = container_of(breq, struct ahash_request, base);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
+ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);

- err = dev->load_data(dev, dev->sg_src, NULL);
- if (!err)
- crypto_ahash_dma_start(dev);
- return err;
+ dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
+ return 0;
}

-static int rk_ahash_start(struct rk_crypto_info *dev)
+static int rk_hash_run(struct crypto_engine *engine, void *breq)
{
- struct ahash_request *req = ahash_request_cast(dev->async_req);
- struct crypto_ahash *tfm;
- struct rk_ahash_rctx *rctx;
-
- dev->total = req->nbytes;
- dev->left_bytes = req->nbytes;
- dev->sg_dst = NULL;
- dev->sg_src = req->src;
- dev->first = req->src;
- dev->src_nents = sg_nents(req->src);
- rctx = ahash_request_ctx(req);
+ struct ahash_request *areq = container_of(breq, struct ahash_request, base);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+ struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
+ struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct scatterlist *sg = areq->src;
+ int err = 0;
+ int i;
+ u32 v;
+
rctx->mode = 0;

- tfm = crypto_ahash_reqtfm(req);
switch (crypto_ahash_digestsize(tfm)) {
case SHA1_DIGEST_SIZE:
rctx->mode = RK_CRYPTO_HASH_SHA1;
@@ -255,30 +267,26 @@ static int rk_ahash_start(struct rk_crypto_info *dev)
rctx->mode = RK_CRYPTO_HASH_MD5;
break;
default:
- return -EINVAL;
+ err = -EINVAL;
+ goto theend;
}

- rk_ahash_reg_init(dev);
- return rk_ahash_set_data_start(dev);
-}
+ rk_ahash_reg_init(areq);

-static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
-{
- int err = 0;
- struct ahash_request *req = ahash_request_cast(dev->async_req);
- struct crypto_ahash *tfm;
-
- dev->unload_data(dev);
- if (dev->left_bytes) {
- if (sg_is_last(dev->sg_src)) {
- dev_warn(dev->dev, "[%s:%d], Lack of data\n",
- __func__, __LINE__);
- err = -ENOMEM;
- goto out_rx;
+ while (sg) {
+ reinit_completion(&tctx->dev->complete);
+ tctx->dev->status = 0;
+ crypto_ahash_dma_start(tctx->dev, sg);
+ wait_for_completion_interruptible_timeout(&tctx->dev->complete,
+ msecs_to_jiffies(2000));
+ if (!tctx->dev->status) {
+ dev_err(tctx->dev->dev, "DMA timeout\n");
+ err = -EFAULT;
+ goto theend;
}
- dev->sg_src = sg_next(dev->sg_src);
- err = rk_ahash_set_data_start(dev);
- } else {
+ sg = sg_next(sg);
+ }
+
/*
* it will take some time to process date after last dma
* transmission.
@@ -289,18 +297,20 @@ static int rk_ahash_crypto_rx(struct rk_crypto_info *dev)
* efficiency, and make it response quickly when dma
* complete.
*/
- while (!CRYPTO_READ(dev, RK_CRYPTO_HASH_STS))
- udelay(10);
-
- tfm = crypto_ahash_reqtfm(req);
- memcpy_fromio(req->result, dev->reg + RK_CRYPTO_HASH_DOUT_0,
- crypto_ahash_digestsize(tfm));
- dev->complete(dev->async_req, 0);
- tasklet_schedule(&dev->queue_task);
+ while (!CRYPTO_READ(tctx->dev, RK_CRYPTO_HASH_STS))
+ udelay(10);
+
+ for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) {
+ v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
+ put_unaligned_le32(v, areq->result + i * 4);
}

-out_rx:
- return err;
+theend:
+ local_bh_disable();
+ crypto_finalize_hash_request(engine, breq, err);
+ local_bh_enable();
+
+ return 0;
}

static int rk_cra_hash_init(struct crypto_tfm *tfm)
@@ -314,9 +324,6 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
algt = container_of(alg, struct rk_crypto_tmp, alg.hash);

tctx->dev = algt->dev;
- tctx->dev->start = rk_ahash_start;
- tctx->dev->update = rk_ahash_crypto_rx;
- tctx->dev->complete = rk_ahash_crypto_complete;

/* for fallback */
tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
@@ -325,10 +332,15 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
dev_err(tctx->dev->dev, "Could not load fallback driver.\n");
return PTR_ERR(tctx->fallback_tfm);
}
+
crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm),
sizeof(struct rk_ahash_rctx) +
crypto_ahash_reqsize(tctx->fallback_tfm));

+ tctx->enginectx.op.do_one_request = rk_hash_run;
+ tctx->enginectx.op.prepare_request = rk_hash_prepare;
+ tctx->enginectx.op.unprepare_request = rk_hash_unprepare;
+
return 0;
}

diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index d067b7f09165..67a7e05d5ae3 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -9,6 +9,7 @@
* Some ideas are from marvell-cesa.c and s5p-sss.c driver.
*/
#include <linux/device.h>
+#include <crypto/scatterwalk.h>
#include "rk3288_crypto.h"

#define RK_CRYPTO_DEC BIT(0)
@@ -70,19 +71,15 @@ static int rk_cipher_fallback(struct skcipher_request *areq)
return err;
}

-static void rk_crypto_complete(struct crypto_async_request *base, int err)
-{
- if (base->complete)
- base->complete(base, err);
-}
-
static int rk_handle_req(struct rk_crypto_info *dev,
struct skcipher_request *req)
{
+ struct crypto_engine *engine = dev->engine;
+
if (rk_cipher_need_fallback(req))
return rk_cipher_fallback(req);

- return dev->enqueue(dev, &req->base);
+ return crypto_transfer_skcipher_request_to_engine(engine, req);
}

static int rk_aes_setkey(struct crypto_skcipher *cipher,
@@ -265,25 +262,21 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
return rk_handle_req(dev, req);
}

-static void rk_ablk_hw_init(struct rk_crypto_info *dev)
+static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req)
{
- struct skcipher_request *req =
- skcipher_request_cast(dev->async_req);
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(cipher);
- u32 ivsize, block, conf_reg = 0;
+ u32 block, conf_reg = 0;

block = crypto_tfm_alg_blocksize(tfm);
- ivsize = crypto_skcipher_ivsize(cipher);

if (block == DES_BLOCK_SIZE) {
rctx->mode |= RK_CRYPTO_TDES_FIFO_MODE |
RK_CRYPTO_TDES_BYTESWAP_KEY |
RK_CRYPTO_TDES_BYTESWAP_IV;
CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, req->iv, ivsize);
memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
conf_reg = RK_CRYPTO_DESSEL;
} else {
@@ -296,7 +289,6 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
else if (ctx->keylen == AES_KEYSIZE_256)
rctx->mode |= RK_CRYPTO_AES_256BIT_key;
CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, req->iv, ivsize);
memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
}
conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
@@ -306,133 +298,138 @@ static void rk_ablk_hw_init(struct rk_crypto_info *dev)
RK_CRYPTO_BCDMA_ERR_ENA | RK_CRYPTO_BCDMA_DONE_ENA);
}

-static void crypto_dma_start(struct rk_crypto_info *dev)
+static void crypto_dma_start(struct rk_crypto_info *dev,
+ struct scatterlist *sgs,
+ struct scatterlist *sgd, unsigned int todo)
{
- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, dev->addr_in);
- CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, dev->count / 4);
- CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, dev->addr_out);
+ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAS, sg_dma_address(sgs));
+ CRYPTO_WRITE(dev, RK_CRYPTO_BRDMAL, todo);
+ CRYPTO_WRITE(dev, RK_CRYPTO_BTDMAS, sg_dma_address(sgd));
CRYPTO_WRITE(dev, RK_CRYPTO_CTRL, RK_CRYPTO_BLOCK_START |
_SBF(RK_CRYPTO_BLOCK_START, 16));
}

-static int rk_set_data_start(struct rk_crypto_info *dev)
+static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
{
- int err;
- struct skcipher_request *req =
- skcipher_request_cast(dev->async_req);
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
+ struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base);
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
- u32 ivsize = crypto_skcipher_ivsize(tfm);
- u8 *src_last_blk = page_address(sg_page(dev->sg_src)) +
- dev->sg_src->offset + dev->sg_src->length - ivsize;
-
- /* Store the iv that need to be updated in chain mode.
- * And update the IV buffer to contain the next IV for decryption mode.
- */
- if (rctx->mode & RK_CRYPTO_DEC) {
- memcpy(ctx->iv, src_last_blk, ivsize);
- sg_pcopy_to_buffer(dev->first, dev->src_nents, req->iv,
- ivsize, dev->total - ivsize);
- }
-
- err = dev->load_data(dev, dev->sg_src, dev->sg_dst);
- if (!err)
- crypto_dma_start(dev);
- return err;
-}
-
-static int rk_ablk_start(struct rk_crypto_info *dev)
-{
- struct skcipher_request *req =
- skcipher_request_cast(dev->async_req);
- unsigned long flags;
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
+ struct scatterlist *sgs, *sgd;
int err = 0;
+ int ivsize = crypto_skcipher_ivsize(tfm);
+ int offset;
+ u8 iv[AES_BLOCK_SIZE];
+ u8 biv[AES_BLOCK_SIZE];
+ u8 *ivtouse = areq->iv;
+ unsigned int len = areq->cryptlen;
+ unsigned int todo;
+
+ ivsize = crypto_skcipher_ivsize(tfm);
+ if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
+ if (rctx->mode & RK_CRYPTO_DEC) {
+ offset = areq->cryptlen - ivsize;
+ scatterwalk_map_and_copy(rctx->backup_iv, areq->src,
+ offset, ivsize, 0);
+ }
+ }

- dev->left_bytes = req->cryptlen;
- dev->total = req->cryptlen;
- dev->sg_src = req->src;
- dev->first = req->src;
- dev->src_nents = sg_nents(req->src);
- dev->sg_dst = req->dst;
- dev->dst_nents = sg_nents(req->dst);
-
- spin_lock_irqsave(&dev->lock, flags);
- rk_ablk_hw_init(dev);
- err = rk_set_data_start(dev);
- spin_unlock_irqrestore(&dev->lock, flags);
- return err;
-}
-
-static void rk_iv_copyback(struct rk_crypto_info *dev)
-{
- struct skcipher_request *req =
- skcipher_request_cast(dev->async_req);
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
- u32 ivsize = crypto_skcipher_ivsize(tfm);
+ sgs = areq->src;
+ sgd = areq->dst;

- /* Update the IV buffer to contain the next IV for encryption mode. */
- if (!(rctx->mode & RK_CRYPTO_DEC)) {
- memcpy(req->iv,
- sg_virt(dev->sg_dst) + dev->sg_dst->length - ivsize,
- ivsize);
+ while (sgs && sgd && len) {
+ if (!sgs->length) {
+ sgs = sg_next(sgs);
+ sgd = sg_next(sgd);
+ continue;
+ }
+ if (rctx->mode & RK_CRYPTO_DEC) {
+ /* we backup last block of source to be used as IV at next step */
+ offset = sgs->length - ivsize;
+ scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0);
+ }
+ if (sgs == sgd) {
+ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ if (err <= 0) {
+ err = -EINVAL;
+ goto theend_iv;
+ }
+ } else {
+ err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
+ if (err <= 0) {
+ err = -EINVAL;
+ goto theend_iv;
+ }
+ err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ if (err <= 0) {
+ err = -EINVAL;
+ goto theend_sgs;
+ }
+ }
+ err = 0;
+ rk_ablk_hw_init(ctx->dev, areq);
+ if (ivsize) {
+ if (ivsize == DES_BLOCK_SIZE)
+ memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
+ else
+ memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize);
+ }
+ reinit_completion(&ctx->dev->complete);
+ ctx->dev->status = 0;
+
+ todo = min(sg_dma_len(sgs), len);
+ len -= todo;
+ crypto_dma_start(ctx->dev, sgs, sgd, todo / 4);
+ wait_for_completion_interruptible_timeout(&ctx->dev->complete,
+ msecs_to_jiffies(2000));
+ if (!ctx->dev->status) {
+ dev_err(ctx->dev->dev, "DMA timeout\n");
+ err = -EFAULT;
+ goto theend;
+ }
+ if (sgs == sgd) {
+ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ } else {
+ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ }
+ if (rctx->mode & RK_CRYPTO_DEC) {
+ memcpy(iv, biv, ivsize);
+ ivtouse = iv;
+ } else {
+ offset = sgd->length - ivsize;
+ scatterwalk_map_and_copy(iv, sgd, offset, ivsize, 0);
+ ivtouse = iv;
+ }
+ sgs = sg_next(sgs);
+ sgd = sg_next(sgd);
}
-}
-
-static void rk_update_iv(struct rk_crypto_info *dev)
-{
- struct skcipher_request *req =
- skcipher_request_cast(dev->async_req);
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
- u32 ivsize = crypto_skcipher_ivsize(tfm);
- u8 *new_iv = NULL;

- if (rctx->mode & RK_CRYPTO_DEC) {
- new_iv = ctx->iv;
- } else {
- new_iv = page_address(sg_page(dev->sg_dst)) +
- dev->sg_dst->offset + dev->sg_dst->length - ivsize;
+ if (areq->iv && ivsize > 0) {
+ offset = areq->cryptlen - ivsize;
+ if (rctx->mode & RK_CRYPTO_DEC) {
+ memcpy(areq->iv, rctx->backup_iv, ivsize);
+ memzero_explicit(rctx->backup_iv, ivsize);
+ } else {
+ scatterwalk_map_and_copy(areq->iv, areq->dst, offset,
+ ivsize, 0);
+ }
}

- if (ivsize == DES_BLOCK_SIZE)
- memcpy_toio(dev->reg + RK_CRYPTO_TDES_IV_0, new_iv, ivsize);
- else if (ivsize == AES_BLOCK_SIZE)
- memcpy_toio(dev->reg + RK_CRYPTO_AES_IV_0, new_iv, ivsize);
-}
+theend:
+ local_bh_disable();
+ crypto_finalize_skcipher_request(engine, areq, err);
+ local_bh_enable();
+ return 0;

-/* return:
- * true some err was occurred
- * fault no err, continue
- */
-static int rk_ablk_rx(struct rk_crypto_info *dev)
-{
- int err = 0;
- struct skcipher_request *req =
- skcipher_request_cast(dev->async_req);
-
- dev->unload_data(dev);
- if (dev->left_bytes) {
- rk_update_iv(dev);
- if (sg_is_last(dev->sg_src)) {
- dev_err(dev->dev, "[%s:%d] Lack of data\n",
- __func__, __LINE__);
- err = -ENOMEM;
- goto out_rx;
- }
- dev->sg_src = sg_next(dev->sg_src);
- dev->sg_dst = sg_next(dev->sg_dst);
- err = rk_set_data_start(dev);
+theend_sgs:
+ if (sgs == sgd) {
+ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
} else {
- rk_iv_copyback(dev);
- /* here show the calculation is over without any err */
- dev->complete(dev->async_req, 0);
- tasklet_schedule(&dev->queue_task);
+ dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
}
-out_rx:
+theend_iv:
return err;
}

@@ -446,9 +443,6 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);

ctx->dev = algt->dev;
- ctx->dev->start = rk_ablk_start;
- ctx->dev->update = rk_ablk_rx;
- ctx->dev->complete = rk_crypto_complete;

ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(ctx->fallback_tfm)) {
@@ -460,6 +454,8 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
tfm->reqsize = sizeof(struct rk_cipher_rctx) +
crypto_skcipher_reqsize(ctx->fallback_tfm);

+ ctx->enginectx.op.do_one_request = rk_cipher_run;
+
return 0;
}

--
2.35.1

2022-07-06 09:07:24

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 16/33] crypto: rockchip: add myself as maintainer

Nobody is set as maintainer of rockchip crypto, I propose to do it as I
have already reworked lot of this code.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
MAINTAINERS | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 392e59e9a03e..f8af07fa96fe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17449,6 +17449,13 @@ F: Documentation/ABI/*/sysfs-driver-hid-roccat*
F: drivers/hid/hid-roccat*
F: include/linux/hid-roccat*

+ROCKCHIP CRYPTO DRIVERS
+M: Corentin Labbe <[email protected]>
+L: [email protected]
+S: Maintained
+F: Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
+F: drivers/crypto/rockchip/
+
ROCKCHIP I2S TDM DRIVER
M: Nicolas Frattaroli <[email protected]>
L: [email protected]
--
2.35.1

2022-07-06 09:07:24

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 13/33] crypto: rockchip: introduce PM

Add runtime PM support for rockchip crypto.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 51 ++++++++++++++++++-
drivers/crypto/rockchip/rk3288_crypto.h | 1 +
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 10 ++++
.../crypto/rockchip/rk3288_crypto_skcipher.c | 9 ++++
4 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 3e1b4f3b2422..d9258b9e71b3 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -65,6 +65,48 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev)
clk_disable_unprepare(dev->sclk);
}

+/*
+ * Power management strategy: The device is suspended unless a TFM exists for
+ * one of the algorithms proposed by this driver.
+ */
+static int rk_crypto_pm_suspend(struct device *dev)
+{
+ struct rk_crypto_info *rkdev = dev_get_drvdata(dev);
+
+ rk_crypto_disable_clk(rkdev);
+ return 0;
+}
+
+static int rk_crypto_pm_resume(struct device *dev)
+{
+ struct rk_crypto_info *rkdev = dev_get_drvdata(dev);
+
+ return rk_crypto_enable_clk(rkdev);
+}
+
+static const struct dev_pm_ops rk_crypto_pm_ops = {
+ SET_RUNTIME_PM_OPS(rk_crypto_pm_suspend, rk_crypto_pm_resume, NULL)
+};
+
+static int rk_crypto_pm_init(struct rk_crypto_info *rkdev)
+{
+ int err;
+
+ pm_runtime_use_autosuspend(rkdev->dev);
+ pm_runtime_set_autosuspend_delay(rkdev->dev, 2000);
+
+ err = pm_runtime_set_suspended(rkdev->dev);
+ if (err)
+ return err;
+ pm_runtime_enable(rkdev->dev);
+ return err;
+}
+
+static void rk_crypto_pm_exit(struct rk_crypto_info *rkdev)
+{
+ pm_runtime_disable(rkdev->dev);
+}
+
static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id)
{
struct rk_crypto_info *dev = platform_get_drvdata(dev_id);
@@ -273,7 +315,9 @@ static int rk_crypto_probe(struct platform_device *pdev)
crypto_engine_start(crypto_info->engine);
init_completion(&crypto_info->complete);

- rk_crypto_enable_clk(crypto_info);
+ err = rk_crypto_pm_init(crypto_info);
+ if (err)
+ goto err_pm;

err = rk_crypto_register(crypto_info);
if (err) {
@@ -294,6 +338,8 @@ static int rk_crypto_probe(struct platform_device *pdev)
return 0;

err_register_alg:
+ rk_crypto_pm_exit(crypto_info);
+err_pm:
crypto_engine_exit(crypto_info->engine);
err_crypto:
dev_err(dev, "Crypto Accelerator not successfully registered\n");
@@ -308,7 +354,7 @@ static int rk_crypto_remove(struct platform_device *pdev)
debugfs_remove_recursive(crypto_tmp->dbgfs_dir);
#endif
rk_crypto_unregister();
- rk_crypto_disable_clk(crypto_tmp);
+ rk_crypto_pm_exit(crypto_tmp);
crypto_engine_exit(crypto_tmp->engine);
return 0;
}
@@ -318,6 +364,7 @@ static struct platform_driver crypto_driver = {
.remove = rk_crypto_remove,
.driver = {
.name = "rk3288-crypto",
+ .pm = &rk_crypto_pm_ops,
.of_match_table = crypto_of_id_table,
},
};
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 945a8184bbad..ddbb9246ce16 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -9,6 +9,7 @@
#include <linux/interrupt.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
+#include <linux/pm_runtime.h>
#include <linux/scatterlist.h>
#include <crypto/engine.h>
#include <crypto/internal/hash.h>
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index 8856c6226be6..137013bd4410 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -328,6 +328,7 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);

const char *alg_name = crypto_tfm_alg_name(tfm);
+ int err;

algt = container_of(alg, struct rk_crypto_tmp, alg.hash);

@@ -349,7 +350,15 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
tctx->enginectx.op.prepare_request = rk_hash_prepare;
tctx->enginectx.op.unprepare_request = rk_hash_unprepare;

+ err = pm_runtime_resume_and_get(tctx->dev->dev);
+ if (err < 0)
+ goto error_pm;
+
return 0;
+error_pm:
+ crypto_free_ahash(tctx->fallback_tfm);
+
+ return err;
}

static void rk_cra_hash_exit(struct crypto_tfm *tfm)
@@ -357,6 +366,7 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);

crypto_free_ahash(tctx->fallback_tfm);
+ pm_runtime_put_autosuspend(tctx->dev->dev);
}

struct rk_crypto_tmp rk_ahash_sha1 = {
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 91b8a4c574da..3bdb304aa794 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -454,6 +454,7 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
const char *name = crypto_tfm_alg_name(&tfm->base);
struct rk_crypto_tmp *algt;
+ int err;

algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);

@@ -471,7 +472,14 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)

ctx->enginectx.op.do_one_request = rk_cipher_run;

+ err = pm_runtime_resume_and_get(ctx->dev->dev);
+ if (err < 0)
+ goto error_pm;
+
return 0;
+error_pm:
+ crypto_free_skcipher(ctx->fallback_tfm);
+ return err;
}

static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
@@ -480,6 +488,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)

memzero_explicit(ctx->key, ctx->keylen);
crypto_free_skcipher(ctx->fallback_tfm);
+ pm_runtime_put_autosuspend(ctx->dev->dev);
}

struct rk_crypto_tmp rk_ecb_aes_alg = {
--
2.35.1

2022-07-06 09:07:35

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 12/33] crypto: rockchip: add debugfs

This patch enable to access usage stats for each algorithm.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/Kconfig | 10 ++++
drivers/crypto/rockchip/rk3288_crypto.c | 47 +++++++++++++++++++
drivers/crypto/rockchip/rk3288_crypto.h | 11 +++++
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 8 ++++
.../crypto/rockchip/rk3288_crypto_skcipher.c | 15 ++++++
5 files changed, 91 insertions(+)

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index df4f0a2de098..2286df229c81 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -801,6 +801,16 @@ config CRYPTO_DEV_ROCKCHIP
This driver interfaces with the hardware crypto accelerator.
Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode.

+config CRYPTO_DEV_ROCKCHIP_DEBUG
+ bool "Enable Rockchip crypto stats"
+ depends on CRYPTO_DEV_ROCKCHIP
+ depends on DEBUG_FS
+ help
+ Say y to enable Rockchip crypto debug stats.
+ This will create /sys/kernel/debug/rk3288_crypto/stats for displaying
+ the number of requests per algorithm and other internal stats.
+
+
config CRYPTO_DEV_ZYNQMP_AES
tristate "Support for Xilinx ZynqMP AES hw accelerator"
depends on ZYNQMP_FIRMWARE || COMPILE_TEST
diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 8f9664acc78d..3e1b4f3b2422 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -95,6 +95,41 @@ static struct rk_crypto_tmp *rk_cipher_algs[] = {
&rk_ahash_md5,
};

+#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
+static int rk_crypto_debugfs_show(struct seq_file *seq, void *v)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
+ if (!rk_cipher_algs[i]->dev)
+ continue;
+ switch (rk_cipher_algs[i]->type) {
+ case CRYPTO_ALG_TYPE_SKCIPHER:
+ seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n",
+ rk_cipher_algs[i]->alg.skcipher.base.cra_driver_name,
+ rk_cipher_algs[i]->alg.skcipher.base.cra_name,
+ rk_cipher_algs[i]->stat_req, rk_cipher_algs[i]->stat_fb);
+ seq_printf(seq, "\tfallback due to length: %lu\n",
+ rk_cipher_algs[i]->stat_fb_len);
+ seq_printf(seq, "\tfallback due to alignment: %lu\n",
+ rk_cipher_algs[i]->stat_fb_align);
+ seq_printf(seq, "\tfallback due to SGs: %lu\n",
+ rk_cipher_algs[i]->stat_fb_sgdiff);
+ break;
+ case CRYPTO_ALG_TYPE_AHASH:
+ seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n",
+ rk_cipher_algs[i]->alg.hash.halg.base.cra_driver_name,
+ rk_cipher_algs[i]->alg.hash.halg.base.cra_name,
+ rk_cipher_algs[i]->stat_req, rk_cipher_algs[i]->stat_fb);
+ break;
+ }
+ }
+ return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(rk_crypto_debugfs);
+#endif
+
static int rk_crypto_register(struct rk_crypto_info *crypto_info)
{
unsigned int i, k;
@@ -246,6 +281,15 @@ static int rk_crypto_probe(struct platform_device *pdev)
goto err_register_alg;
}

+#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
+ /* Ignore error of debugfs */
+ crypto_info->dbgfs_dir = debugfs_create_dir("rk3288_crypto", NULL);
+ crypto_info->dbgfs_stats = debugfs_create_file("stats", 0444,
+ crypto_info->dbgfs_dir,
+ crypto_info,
+ &rk_crypto_debugfs_fops);
+#endif
+
dev_info(dev, "Crypto Accelerator successfully registered\n");
return 0;

@@ -260,6 +304,9 @@ static int rk_crypto_remove(struct platform_device *pdev)
{
struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);

+#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
+ debugfs_remove_recursive(crypto_tmp->dbgfs_dir);
+#endif
rk_crypto_unregister();
rk_crypto_disable_clk(crypto_tmp);
crypto_engine_exit(crypto_tmp->engine);
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index d924ea17402a..945a8184bbad 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -7,6 +7,7 @@
#include <crypto/algapi.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/scatterlist.h>
#include <crypto/engine.h>
@@ -199,6 +200,10 @@ struct rk_crypto_info {
struct crypto_engine *engine;
struct completion complete;
int status;
+#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
+ struct dentry *dbgfs_dir;
+ struct dentry *dbgfs_stats;
+#endif
};

/* the private variable of hash */
@@ -239,6 +244,12 @@ struct rk_crypto_tmp {
struct skcipher_alg skcipher;
struct ahash_alg hash;
} alg;
+ unsigned long stat_req;
+ unsigned long stat_fb;
+ unsigned long stat_fb_len;
+ unsigned long stat_fb_sglen;
+ unsigned long stat_fb_align;
+ unsigned long stat_fb_sgdiff;
};

extern struct rk_crypto_tmp rk_ecb_aes_alg;
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index d08e2438d356..8856c6226be6 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -39,6 +39,10 @@ static int rk_ahash_digest_fb(struct ahash_request *areq)
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_ctx *tfmctx = crypto_ahash_ctx(tfm);
+ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
+
+ algt->stat_fb++;

ahash_request_set_tfm(&rctx->fallback_req, tfmctx->fallback_tfm);
rctx->fallback_req.base.flags = areq->base.flags &
@@ -249,6 +253,8 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
struct scatterlist *sg = areq->src;
int err = 0;
int i;
@@ -256,6 +262,8 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)

rctx->mode = 0;

+ algt->stat_req++;
+
switch (crypto_ahash_digestsize(tfm)) {
case SHA1_DIGEST_SIZE:
rctx->mode = RK_CRYPTO_HASH_SHA1;
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 1ed297f5d809..91b8a4c574da 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -18,6 +18,8 @@ static int rk_cipher_need_fallback(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
unsigned int bs = crypto_skcipher_blocksize(tfm);
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
struct scatterlist *sgs, *sgd;
unsigned int stodo, dtodo, len;

@@ -29,20 +31,25 @@ static int rk_cipher_need_fallback(struct skcipher_request *req)
sgd = req->dst;
while (sgs && sgd) {
if (!IS_ALIGNED(sgs->offset, sizeof(u32))) {
+ algt->stat_fb_align++;
return true;
}
if (!IS_ALIGNED(sgd->offset, sizeof(u32))) {
+ algt->stat_fb_align++;
return true;
}
stodo = min(len, sgs->length);
if (stodo % bs) {
+ algt->stat_fb_len++;
return true;
}
dtodo = min(len, sgd->length);
if (dtodo % bs) {
+ algt->stat_fb_len++;
return true;
}
if (stodo != dtodo) {
+ algt->stat_fb_sgdiff++;
return true;
}
len -= stodo;
@@ -57,8 +64,12 @@ static int rk_cipher_fallback(struct skcipher_request *areq)
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
int err;

+ algt->stat_fb++;
+
skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm);
skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags,
areq->base.complete, areq->base.data);
@@ -324,6 +335,10 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
u8 *ivtouse = areq->iv;
unsigned int len = areq->cryptlen;
unsigned int todo;
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
+
+ algt->stat_req++;

ivsize = crypto_skcipher_ivsize(tfm);
if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
--
2.35.1

2022-07-06 09:07:42

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 11/33] crypto: rockchip: rewrite type

Instead of using a custom type for classify algorithms, let's just use
already defined ones.
And let's made a bit more verbose about what is registered.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 26 +++++++++++++------
drivers/crypto/rockchip/rk3288_crypto.h | 7 +----
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 6 ++---
.../crypto/rockchip/rk3288_crypto_skcipher.c | 12 ++++-----
4 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 1afb65eee6c9..8f9664acc78d 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -102,12 +102,22 @@ static int rk_crypto_register(struct rk_crypto_info *crypto_info)

for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
rk_cipher_algs[i]->dev = crypto_info;
- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
- err = crypto_register_skcipher(
- &rk_cipher_algs[i]->alg.skcipher);
- else
- err = crypto_register_ahash(
- &rk_cipher_algs[i]->alg.hash);
+ switch (rk_cipher_algs[i]->type) {
+ case CRYPTO_ALG_TYPE_SKCIPHER:
+ dev_info(crypto_info->dev, "Register %s as %s\n",
+ rk_cipher_algs[i]->alg.skcipher.base.cra_name,
+ rk_cipher_algs[i]->alg.skcipher.base.cra_driver_name);
+ err = crypto_register_skcipher(&rk_cipher_algs[i]->alg.skcipher);
+ break;
+ case CRYPTO_ALG_TYPE_AHASH:
+ dev_info(crypto_info->dev, "Register %s as %s\n",
+ rk_cipher_algs[i]->alg.hash.halg.base.cra_name,
+ rk_cipher_algs[i]->alg.hash.halg.base.cra_driver_name);
+ err = crypto_register_ahash(&rk_cipher_algs[i]->alg.hash);
+ break;
+ default:
+ dev_err(crypto_info->dev, "unknown algorithm\n");
+ }
if (err)
goto err_cipher_algs;
}
@@ -115,7 +125,7 @@ static int rk_crypto_register(struct rk_crypto_info *crypto_info)

err_cipher_algs:
for (k = 0; k < i; k++) {
- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
+ if (rk_cipher_algs[i]->type == CRYPTO_ALG_TYPE_SKCIPHER)
crypto_unregister_skcipher(&rk_cipher_algs[k]->alg.skcipher);
else
crypto_unregister_ahash(&rk_cipher_algs[i]->alg.hash);
@@ -128,7 +138,7 @@ static void rk_crypto_unregister(void)
unsigned int i;

for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
- if (rk_cipher_algs[i]->type == ALG_TYPE_CIPHER)
+ if (rk_cipher_algs[i]->type == CRYPTO_ALG_TYPE_SKCIPHER)
crypto_unregister_skcipher(&rk_cipher_algs[i]->alg.skcipher);
else
crypto_unregister_ahash(&rk_cipher_algs[i]->alg.hash);
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 65ed645e0168..d924ea17402a 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -232,18 +232,13 @@ struct rk_cipher_rctx {
struct skcipher_request fallback_req; // keep at the end
};

-enum alg_type {
- ALG_TYPE_HASH,
- ALG_TYPE_CIPHER,
-};
-
struct rk_crypto_tmp {
+ u32 type;
struct rk_crypto_info *dev;
union {
struct skcipher_alg skcipher;
struct ahash_alg hash;
} alg;
- enum alg_type type;
};

extern struct rk_crypto_tmp rk_ecb_aes_alg;
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index edd40e16a3f0..d08e2438d356 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -352,7 +352,7 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
}

struct rk_crypto_tmp rk_ahash_sha1 = {
- .type = ALG_TYPE_HASH,
+ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
.init = rk_ahash_init,
.update = rk_ahash_update,
@@ -382,7 +382,7 @@ struct rk_crypto_tmp rk_ahash_sha1 = {
};

struct rk_crypto_tmp rk_ahash_sha256 = {
- .type = ALG_TYPE_HASH,
+ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
.init = rk_ahash_init,
.update = rk_ahash_update,
@@ -412,7 +412,7 @@ struct rk_crypto_tmp rk_ahash_sha256 = {
};

struct rk_crypto_tmp rk_ahash_md5 = {
- .type = ALG_TYPE_HASH,
+ .type = CRYPTO_ALG_TYPE_AHASH,
.alg.hash = {
.init = rk_ahash_init,
.update = rk_ahash_update,
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 67a7e05d5ae3..1ed297f5d809 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -468,7 +468,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
}

struct rk_crypto_tmp rk_ecb_aes_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "ecb(aes)",
.base.cra_driver_name = "ecb-aes-rk",
@@ -490,7 +490,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = {
};

struct rk_crypto_tmp rk_cbc_aes_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "cbc(aes)",
.base.cra_driver_name = "cbc-aes-rk",
@@ -513,7 +513,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = {
};

struct rk_crypto_tmp rk_ecb_des_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "ecb(des)",
.base.cra_driver_name = "ecb-des-rk",
@@ -535,7 +535,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = {
};

struct rk_crypto_tmp rk_cbc_des_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "cbc(des)",
.base.cra_driver_name = "cbc-des-rk",
@@ -558,7 +558,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = {
};

struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "ecb(des3_ede)",
.base.cra_driver_name = "ecb-des3-ede-rk",
@@ -580,7 +580,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
};

struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
- .type = ALG_TYPE_CIPHER,
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
.alg.skcipher = {
.base.cra_name = "cbc(des3_ede)",
.base.cra_driver_name = "cbc-des3-ede-rk",
--
2.35.1

2022-07-06 09:07:50

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 14/33] crypto: rockchip: handle reset also in PM

reset could be handled by PM functions.
We keep the initial reset pulse to be sure the hw is a know device state
after probe.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index d9258b9e71b3..399829ef92e0 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -74,14 +74,23 @@ static int rk_crypto_pm_suspend(struct device *dev)
struct rk_crypto_info *rkdev = dev_get_drvdata(dev);

rk_crypto_disable_clk(rkdev);
+ reset_control_assert(rkdev->rst);
+
return 0;
}

static int rk_crypto_pm_resume(struct device *dev)
{
struct rk_crypto_info *rkdev = dev_get_drvdata(dev);
+ int ret;
+
+ ret = rk_crypto_enable_clk(rkdev);
+ if (ret)
+ return ret;
+
+ reset_control_deassert(rkdev->rst);
+ return 0;

- return rk_crypto_enable_clk(rkdev);
}

static const struct dev_pm_ops rk_crypto_pm_ops = {
@@ -222,13 +231,6 @@ static void rk_crypto_unregister(void)
}
}

-static void rk_crypto_action(void *data)
-{
- struct rk_crypto_info *crypto_info = data;
-
- reset_control_assert(crypto_info->rst);
-}
-
static const struct of_device_id crypto_of_id_table[] = {
{ .compatible = "rockchip,rk3288-crypto" },
{}
@@ -258,10 +260,6 @@ static int rk_crypto_probe(struct platform_device *pdev)
usleep_range(10, 20);
reset_control_deassert(crypto_info->rst);

- err = devm_add_action_or_reset(dev, rk_crypto_action, crypto_info);
- if (err)
- goto err_crypto;
-
crypto_info->reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(crypto_info->reg)) {
err = PTR_ERR(crypto_info->reg);
--
2.35.1

2022-07-06 09:08:17

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 06/33] crypto: rockchip: add fallback for cipher

The hardware does not handle 0 size length request, let's add a
fallback.
Furthermore fallback will be used for all unaligned case the hardware
cannot handle.

Fixes: ce0183cb6464b ("crypto: rockchip - switch to skcipher API")
Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/Kconfig | 4 +
drivers/crypto/rockchip/rk3288_crypto.h | 2 +
.../crypto/rockchip/rk3288_crypto_skcipher.c | 97 ++++++++++++++++---
3 files changed, 90 insertions(+), 13 deletions(-)

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index ee99c02c84e8..c293f801806c 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -784,6 +784,10 @@ config CRYPTO_DEV_IMGTEC_HASH
config CRYPTO_DEV_ROCKCHIP
tristate "Rockchip's Cryptographic Engine driver"
depends on OF && ARCH_ROCKCHIP
+ depends on PM
+ select CRYPTO_ECB
+ select CRYPTO_CBC
+ select CRYPTO_DES
select CRYPTO_AES
select CRYPTO_LIB_DES
select CRYPTO_MD5
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index c919d9a43a08..8b1e15d8ddc6 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -246,10 +246,12 @@ struct rk_cipher_ctx {
struct rk_crypto_info *dev;
unsigned int keylen;
u8 iv[AES_BLOCK_SIZE];
+ struct crypto_skcipher *fallback_tfm;
};

struct rk_cipher_rctx {
u32 mode;
+ struct skcipher_request fallback_req; // keep at the end
};

enum alg_type {
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index bbd0bf52bf07..eac5bba66e25 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -13,6 +13,63 @@

#define RK_CRYPTO_DEC BIT(0)

+static int rk_cipher_need_fallback(struct skcipher_request *req)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ unsigned int bs = crypto_skcipher_blocksize(tfm);
+ struct scatterlist *sgs, *sgd;
+ unsigned int stodo, dtodo, len;
+
+ if (!req->cryptlen)
+ return true;
+
+ len = req->cryptlen;
+ sgs = req->src;
+ sgd = req->dst;
+ while (sgs && sgd) {
+ if (!IS_ALIGNED(sgs->offset, sizeof(u32))) {
+ return true;
+ }
+ if (!IS_ALIGNED(sgd->offset, sizeof(u32))) {
+ return true;
+ }
+ stodo = min(len, sgs->length);
+ if (stodo % bs) {
+ return true;
+ }
+ dtodo = min(len, sgd->length);
+ if (dtodo % bs) {
+ return true;
+ }
+ if (stodo != dtodo) {
+ return true;
+ }
+ len -= stodo;
+ sgs = sg_next(sgs);
+ sgd = sg_next(sgd);
+ }
+ return false;
+}
+
+static int rk_cipher_fallback(struct skcipher_request *areq)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+ struct rk_cipher_ctx *op = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
+ int err;
+
+ skcipher_request_set_tfm(&rctx->fallback_req, op->fallback_tfm);
+ skcipher_request_set_callback(&rctx->fallback_req, areq->base.flags,
+ areq->base.complete, areq->base.data);
+ skcipher_request_set_crypt(&rctx->fallback_req, areq->src, areq->dst,
+ areq->cryptlen, areq->iv);
+ if (rctx->mode & RK_CRYPTO_DEC)
+ err = crypto_skcipher_decrypt(&rctx->fallback_req);
+ else
+ err = crypto_skcipher_encrypt(&rctx->fallback_req);
+ return err;
+}
+
static void rk_crypto_complete(struct crypto_async_request *base, int err)
{
if (base->complete)
@@ -22,10 +79,10 @@ static void rk_crypto_complete(struct crypto_async_request *base, int err)
static int rk_handle_req(struct rk_crypto_info *dev,
struct skcipher_request *req)
{
- if (!IS_ALIGNED(req->cryptlen, dev->align_size))
- return -EINVAL;
- else
- return dev->enqueue(dev, &req->base);
+ if (rk_cipher_need_fallback(req))
+ return rk_cipher_fallback(req);
+
+ return dev->enqueue(dev, &req->base);
}

static int rk_aes_setkey(struct crypto_skcipher *cipher,
@@ -39,7 +96,8 @@ static int rk_aes_setkey(struct crypto_skcipher *cipher,
return -EINVAL;
ctx->keylen = keylen;
memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, key, keylen);
- return 0;
+
+ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
}

static int rk_des_setkey(struct crypto_skcipher *cipher,
@@ -54,7 +112,8 @@ static int rk_des_setkey(struct crypto_skcipher *cipher,

ctx->keylen = keylen;
memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
- return 0;
+
+ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
}

static int rk_tdes_setkey(struct crypto_skcipher *cipher,
@@ -69,7 +128,7 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher,

ctx->keylen = keylen;
memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, key, keylen);
- return 0;
+ return crypto_skcipher_setkey(ctx->fallback_tfm, key, keylen);
}

static int rk_aes_ecb_encrypt(struct skcipher_request *req)
@@ -394,6 +453,7 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
{
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ const char *name = crypto_tfm_alg_name(&tfm->base);
struct rk_crypto_tmp *algt;

algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
@@ -407,6 +467,16 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
if (!ctx->dev->addr_vir)
return -ENOMEM;

+ ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(ctx->fallback_tfm)) {
+ dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
+ name, PTR_ERR(ctx->fallback_tfm));
+ return PTR_ERR(ctx->fallback_tfm);
+ }
+
+ tfm->reqsize = sizeof(struct rk_cipher_rctx) +
+ crypto_skcipher_reqsize(ctx->fallback_tfm);
+
return 0;
}

@@ -415,6 +485,7 @@ static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);

free_page((unsigned long)ctx->dev->addr_vir);
+ crypto_free_skcipher(ctx->fallback_tfm);
}

struct rk_crypto_tmp rk_ecb_aes_alg = {
@@ -423,7 +494,7 @@ struct rk_crypto_tmp rk_ecb_aes_alg = {
.base.cra_name = "ecb(aes)",
.base.cra_driver_name = "ecb-aes-rk",
.base.cra_priority = 300,
- .base.cra_flags = CRYPTO_ALG_ASYNC,
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
.base.cra_blocksize = AES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
.base.cra_alignmask = 0x0f,
@@ -445,7 +516,7 @@ struct rk_crypto_tmp rk_cbc_aes_alg = {
.base.cra_name = "cbc(aes)",
.base.cra_driver_name = "cbc-aes-rk",
.base.cra_priority = 300,
- .base.cra_flags = CRYPTO_ALG_ASYNC,
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
.base.cra_blocksize = AES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
.base.cra_alignmask = 0x0f,
@@ -468,7 +539,7 @@ struct rk_crypto_tmp rk_ecb_des_alg = {
.base.cra_name = "ecb(des)",
.base.cra_driver_name = "ecb-des-rk",
.base.cra_priority = 300,
- .base.cra_flags = CRYPTO_ALG_ASYNC,
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
.base.cra_blocksize = DES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
.base.cra_alignmask = 0x07,
@@ -490,7 +561,7 @@ struct rk_crypto_tmp rk_cbc_des_alg = {
.base.cra_name = "cbc(des)",
.base.cra_driver_name = "cbc-des-rk",
.base.cra_priority = 300,
- .base.cra_flags = CRYPTO_ALG_ASYNC,
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
.base.cra_blocksize = DES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
.base.cra_alignmask = 0x07,
@@ -513,7 +584,7 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
.base.cra_name = "ecb(des3_ede)",
.base.cra_driver_name = "ecb-des3-ede-rk",
.base.cra_priority = 300,
- .base.cra_flags = CRYPTO_ALG_ASYNC,
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
.base.cra_blocksize = DES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
.base.cra_alignmask = 0x07,
@@ -535,7 +606,7 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
.base.cra_name = "cbc(des3_ede)",
.base.cra_driver_name = "cbc-des3-ede-rk",
.base.cra_priority = 300,
- .base.cra_flags = CRYPTO_ALG_ASYNC,
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
.base.cra_blocksize = DES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct rk_cipher_ctx),
.base.cra_alignmask = 0x07,
--
2.35.1

2022-07-06 09:08:17

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 20/33] crypto: rockchip: rename ablk functions to cipher

Some functions have still ablk in their name even if there are
not handling ablk_cipher anymore.
So let's rename them.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
.../crypto/rockchip/rk3288_crypto_skcipher.c | 32 +++++++++----------
1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 3bdb304aa794..d60c206e717d 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -273,7 +273,7 @@ static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
return rk_handle_req(dev, req);
}

-static void rk_ablk_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req)
+static void rk_cipher_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req)
{
struct crypto_skcipher *cipher = crypto_skcipher_reqtfm(req);
struct crypto_tfm *tfm = crypto_skcipher_tfm(cipher);
@@ -382,7 +382,7 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
}
}
err = 0;
- rk_ablk_hw_init(ctx->dev, areq);
+ rk_cipher_hw_init(ctx->dev, areq);
if (ivsize) {
if (ivsize == DES_BLOCK_SIZE)
memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
@@ -448,7 +448,7 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
return err;
}

-static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
+static int rk_cipher_tfm_init(struct crypto_skcipher *tfm)
{
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
@@ -482,7 +482,7 @@ static int rk_ablk_init_tfm(struct crypto_skcipher *tfm)
return err;
}

-static void rk_ablk_exit_tfm(struct crypto_skcipher *tfm)
+static void rk_cipher_tfm_exit(struct crypto_skcipher *tfm)
{
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);

@@ -503,8 +503,8 @@ struct rk_crypto_tmp rk_ecb_aes_alg = {
.base.cra_alignmask = 0x0f,
.base.cra_module = THIS_MODULE,

- .init = rk_ablk_init_tfm,
- .exit = rk_ablk_exit_tfm,
+ .init = rk_cipher_tfm_init,
+ .exit = rk_cipher_tfm_exit,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.setkey = rk_aes_setkey,
@@ -525,8 +525,8 @@ struct rk_crypto_tmp rk_cbc_aes_alg = {
.base.cra_alignmask = 0x0f,
.base.cra_module = THIS_MODULE,

- .init = rk_ablk_init_tfm,
- .exit = rk_ablk_exit_tfm,
+ .init = rk_cipher_tfm_init,
+ .exit = rk_cipher_tfm_exit,
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
@@ -548,8 +548,8 @@ struct rk_crypto_tmp rk_ecb_des_alg = {
.base.cra_alignmask = 0x07,
.base.cra_module = THIS_MODULE,

- .init = rk_ablk_init_tfm,
- .exit = rk_ablk_exit_tfm,
+ .init = rk_cipher_tfm_init,
+ .exit = rk_cipher_tfm_exit,
.min_keysize = DES_KEY_SIZE,
.max_keysize = DES_KEY_SIZE,
.setkey = rk_des_setkey,
@@ -570,8 +570,8 @@ struct rk_crypto_tmp rk_cbc_des_alg = {
.base.cra_alignmask = 0x07,
.base.cra_module = THIS_MODULE,

- .init = rk_ablk_init_tfm,
- .exit = rk_ablk_exit_tfm,
+ .init = rk_cipher_tfm_init,
+ .exit = rk_cipher_tfm_exit,
.min_keysize = DES_KEY_SIZE,
.max_keysize = DES_KEY_SIZE,
.ivsize = DES_BLOCK_SIZE,
@@ -593,8 +593,8 @@ struct rk_crypto_tmp rk_ecb_des3_ede_alg = {
.base.cra_alignmask = 0x07,
.base.cra_module = THIS_MODULE,

- .init = rk_ablk_init_tfm,
- .exit = rk_ablk_exit_tfm,
+ .init = rk_cipher_tfm_init,
+ .exit = rk_cipher_tfm_exit,
.min_keysize = DES3_EDE_KEY_SIZE,
.max_keysize = DES3_EDE_KEY_SIZE,
.setkey = rk_tdes_setkey,
@@ -615,8 +615,8 @@ struct rk_crypto_tmp rk_cbc_des3_ede_alg = {
.base.cra_alignmask = 0x07,
.base.cra_module = THIS_MODULE,

- .init = rk_ablk_init_tfm,
- .exit = rk_ablk_exit_tfm,
+ .init = rk_cipher_tfm_init,
+ .exit = rk_cipher_tfm_exit,
.min_keysize = DES3_EDE_KEY_SIZE,
.max_keysize = DES3_EDE_KEY_SIZE,
.ivsize = DES_BLOCK_SIZE,
--
2.35.1

2022-07-06 09:08:20

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 22/33] crypto: rockchip: use a rk_crypto_info variable instead of lot of indirection

Instead of using lot of ctx->dev->xx indirections, use an intermediate
variable for rk_crypto_info.
This will help later, when 2 different rk_crypto_info would be used.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 23 +++++++-----
.../crypto/rockchip/rk3288_crypto_skcipher.c | 37 ++++++++++---------
2 files changed, 32 insertions(+), 28 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index fae779d73c84..636dbcde0ca3 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -226,9 +226,10 @@ static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct rk_crypto_info *rkc = tctx->dev;
int ret;

- ret = dma_map_sg(tctx->dev->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
+ ret = dma_map_sg(rkc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
if (ret <= 0)
return -EINVAL;

@@ -243,8 +244,9 @@ static int rk_hash_unprepare(struct crypto_engine *engine, void *breq)
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct rk_crypto_info *rkc = tctx->dev;

- dma_unmap_sg(tctx->dev->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
+ dma_unmap_sg(rkc->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
return 0;
}

@@ -257,6 +259,7 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
struct scatterlist *sg = areq->src;
+ struct rk_crypto_info *rkc = tctx->dev;
int err = 0;
int i;
u32 v;
@@ -283,13 +286,13 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
rk_ahash_reg_init(areq);

while (sg) {
- reinit_completion(&tctx->dev->complete);
- tctx->dev->status = 0;
- crypto_ahash_dma_start(tctx->dev, sg);
- wait_for_completion_interruptible_timeout(&tctx->dev->complete,
+ reinit_completion(&rkc->complete);
+ rkc->status = 0;
+ crypto_ahash_dma_start(rkc, sg);
+ wait_for_completion_interruptible_timeout(&rkc->complete,
msecs_to_jiffies(2000));
- if (!tctx->dev->status) {
- dev_err(tctx->dev->dev, "DMA timeout\n");
+ if (!rkc->status) {
+ dev_err(rkc->dev, "DMA timeout\n");
err = -EFAULT;
goto theend;
}
@@ -306,10 +309,10 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
* efficiency, and make it response quickly when dma
* complete.
*/
- readl_poll_timeout(tctx->dev->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000);
+ readl_poll_timeout(rkc->reg + RK_CRYPTO_HASH_STS, v, v == 0, 10, 1000);

for (i = 0; i < crypto_ahash_digestsize(tfm) / 4; i++) {
- v = readl(tctx->dev->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
+ v = readl(rkc->reg + RK_CRYPTO_HASH_DOUT_0 + i * 4);
put_unaligned_le32(v, areq->result + i * 4);
}

diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 3187869c4c68..6a1bea98fded 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -303,6 +303,7 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
unsigned int todo;
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
+ struct rk_crypto_info *rkc = ctx->dev;

algt->stat_req++;

@@ -330,49 +331,49 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
scatterwalk_map_and_copy(biv, sgs, offset, ivsize, 0);
}
if (sgs == sgd) {
- err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ err = dma_map_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL);
if (err <= 0) {
err = -EINVAL;
goto theend_iv;
}
} else {
- err = dma_map_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
+ err = dma_map_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE);
if (err <= 0) {
err = -EINVAL;
goto theend_iv;
}
- err = dma_map_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ err = dma_map_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE);
if (err <= 0) {
err = -EINVAL;
goto theend_sgs;
}
}
err = 0;
- rk_cipher_hw_init(ctx->dev, areq);
+ rk_cipher_hw_init(rkc, areq);
if (ivsize) {
if (ivsize == DES_BLOCK_SIZE)
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
+ memcpy_toio(rkc->reg + RK_CRYPTO_TDES_IV_0, ivtouse, ivsize);
else
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize);
+ memcpy_toio(rkc->reg + RK_CRYPTO_AES_IV_0, ivtouse, ivsize);
}
- reinit_completion(&ctx->dev->complete);
- ctx->dev->status = 0;
+ reinit_completion(&rkc->complete);
+ rkc->status = 0;

todo = min(sg_dma_len(sgs), len);
len -= todo;
- crypto_dma_start(ctx->dev, sgs, sgd, todo / 4);
- wait_for_completion_interruptible_timeout(&ctx->dev->complete,
+ crypto_dma_start(rkc, sgs, sgd, todo / 4);
+ wait_for_completion_interruptible_timeout(&rkc->complete,
msecs_to_jiffies(2000));
- if (!ctx->dev->status) {
- dev_err(ctx->dev->dev, "DMA timeout\n");
+ if (!rkc->status) {
+ dev_err(rkc->dev, "DMA timeout\n");
err = -EFAULT;
goto theend;
}
if (sgs == sgd) {
- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ dma_unmap_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL);
} else {
- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
- dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ dma_unmap_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE);
}
if (rctx->mode & RK_CRYPTO_DEC) {
memcpy(iv, biv, ivsize);
@@ -405,10 +406,10 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)

theend_sgs:
if (sgs == sgd) {
- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_BIDIRECTIONAL);
+ dma_unmap_sg(rkc->dev, sgs, 1, DMA_BIDIRECTIONAL);
} else {
- dma_unmap_sg(ctx->dev->dev, sgs, 1, DMA_TO_DEVICE);
- dma_unmap_sg(ctx->dev->dev, sgd, 1, DMA_FROM_DEVICE);
+ dma_unmap_sg(rkc->dev, sgs, 1, DMA_TO_DEVICE);
+ dma_unmap_sg(rkc->dev, sgd, 1, DMA_FROM_DEVICE);
}
theend_iv:
return err;
--
2.35.1

2022-07-06 09:08:23

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 23/33] crypto: rockchip: use the rk_crypto_info given as parameter

Instead of using the crypto_info from TFM ctx, use the one given as parameter.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 6a1bea98fded..cf0dfb6029d8 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -254,7 +254,7 @@ static void rk_cipher_hw_init(struct rk_crypto_info *dev, struct skcipher_reques
RK_CRYPTO_TDES_BYTESWAP_KEY |
RK_CRYPTO_TDES_BYTESWAP_IV;
CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, rctx->mode);
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
+ memcpy_toio(dev->reg + RK_CRYPTO_TDES_KEY1_0, ctx->key, ctx->keylen);
conf_reg = RK_CRYPTO_DESSEL;
} else {
rctx->mode |= RK_CRYPTO_AES_FIFO_MODE |
@@ -266,7 +266,7 @@ static void rk_cipher_hw_init(struct rk_crypto_info *dev, struct skcipher_reques
else if (ctx->keylen == AES_KEYSIZE_256)
rctx->mode |= RK_CRYPTO_AES_256BIT_key;
CRYPTO_WRITE(dev, RK_CRYPTO_AES_CTRL, rctx->mode);
- memcpy_toio(ctx->dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
+ memcpy_toio(dev->reg + RK_CRYPTO_AES_KEY_0, ctx->key, ctx->keylen);
}
conf_reg |= RK_CRYPTO_BYTESWAP_BTFIFO |
RK_CRYPTO_BYTESWAP_BRFIFO;
--
2.35.1

2022-07-06 09:08:26

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 24/33] dt-bindings: crypto: convert rockchip-crypto to YAML

Convert rockchip-crypto to YAML.

Reviewed-by: John Keeping <[email protected]>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
.../crypto/rockchip,rk3288-crypto.yaml | 64 +++++++++++++++++++
.../bindings/crypto/rockchip-crypto.txt | 28 --------
2 files changed, 64 insertions(+), 28 deletions(-)
create mode 100644 Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
delete mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt

diff --git a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
new file mode 100644
index 000000000000..8a219d439d02
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/crypto/rockchip,rk3288-crypto.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip Electronics Security Accelerator
+
+maintainers:
+ - Heiko Stuebner <[email protected]>
+
+properties:
+ compatible:
+ enum:
+ - rockchip,rk3288-crypto
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 4
+
+ clock-names:
+ items:
+ - const: aclk
+ - const: hclk
+ - const: sclk
+ - const: apb_pclk
+
+ resets:
+ maxItems: 1
+
+ reset-names:
+ items:
+ - const: crypto-rst
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - resets
+ - reset-names
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/rk3288-cru.h>
+ crypto@ff8a0000 {
+ compatible = "rockchip,rk3288-crypto";
+ reg = <0xff8a0000 0x4000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>,
+ <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>;
+ clock-names = "aclk", "hclk", "sclk", "apb_pclk";
+ resets = <&cru SRST_CRYPTO>;
+ reset-names = "crypto-rst";
+ };
diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt
deleted file mode 100644
index 5e2ba385b8c9..000000000000
--- a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Rockchip Electronics And Security Accelerator
-
-Required properties:
-- compatible: Should be "rockchip,rk3288-crypto"
-- reg: Base physical address of the engine and length of memory mapped
- region
-- interrupts: Interrupt number
-- clocks: Reference to the clocks about crypto
-- clock-names: "aclk" used to clock data
- "hclk" used to clock data
- "sclk" used to clock crypto accelerator
- "apb_pclk" used to clock dma
-- resets: Must contain an entry for each entry in reset-names.
- See ../reset/reset.txt for details.
-- reset-names: Must include the name "crypto-rst".
-
-Examples:
-
- crypto: cypto-controller@ff8a0000 {
- compatible = "rockchip,rk3288-crypto";
- reg = <0xff8a0000 0x4000>;
- interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cru ACLK_CRYPTO>, <&cru HCLK_CRYPTO>,
- <&cru SCLK_CRYPTO>, <&cru ACLK_DMAC1>;
- clock-names = "aclk", "hclk", "sclk", "apb_pclk";
- resets = <&cru SRST_CRYPTO>;
- reset-names = "crypto-rst";
- };
--
2.35.1

2022-07-06 09:08:40

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 27/33] arm64: dts: rockchip: add rk3328 crypto node

rk3328 has a crypto IP handled by the rk3288 crypto driver so adds a
node for it.

Signed-off-by: Corentin Labbe <[email protected]>
---
arch/arm64/boot/dts/rockchip/rk3328.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 49ae15708a0b..96a7a777bae8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -1025,6 +1025,17 @@ gic: interrupt-controller@ff811000 {
(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};

+ crypto: crypto@ff060000 {
+ compatible = "rockchip,rk3328-crypto";
+ reg = <0x0 0xff060000 0x0 0x4000>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_CRYPTO_MST>, <&cru HCLK_CRYPTO_SLV>,
+ <&cru SCLK_CRYPTO>;
+ clock-names = "hclk_master", "hclk_slave", "sclk";
+ resets = <&cru SRST_CRYPTO>;
+ reset-names = "crypto-rst";
+ };
+
pinctrl: pinctrl {
compatible = "rockchip,rk3328-pinctrl";
rockchip,grf = <&grf>;
--
2.35.1

2022-07-06 09:08:42

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 29/33] crypto: rockchip: store crypto_info in request context

The crypto_info to use must be stored in the request context.
This will help when 2 crypto_info will be available on rk3399.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.h | 2 ++
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 14 ++++++--------
drivers/crypto/rockchip/rk3288_crypto_skcipher.c | 6 ++++--
3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index 28bf09fe1c1d..ff9fc25972eb 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -215,6 +215,7 @@ struct rk_ahash_ctx {

/* the private variable of hash for fallback */
struct rk_ahash_rctx {
+ struct rk_crypto_info *dev;
struct ahash_request fallback_req;
u32 mode;
int nrsg;
@@ -231,6 +232,7 @@ struct rk_cipher_ctx {
};

struct rk_cipher_rctx {
+ struct rk_crypto_info *dev;
u8 backup_iv[AES_BLOCK_SIZE];
u32 mode;
struct skcipher_request fallback_req; // keep at the end
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index 636dbcde0ca3..d1bf68cb390d 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -200,6 +200,7 @@ static int rk_ahash_export(struct ahash_request *req, void *out)

static int rk_ahash_digest(struct ahash_request *req)
{
+ struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
struct rk_crypto_info *dev = tctx->dev;

@@ -209,6 +210,8 @@ static int rk_ahash_digest(struct ahash_request *req)
if (!req->nbytes)
return zero_message_process(req);

+ rctx->dev = dev;
+
return crypto_transfer_hash_request_to_engine(dev->engine, req);
}

@@ -223,10 +226,8 @@ static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlis
static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
{
struct ahash_request *areq = container_of(breq, struct ahash_request, base);
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
- struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
- struct rk_crypto_info *rkc = tctx->dev;
+ struct rk_crypto_info *rkc = rctx->dev;
int ret;

ret = dma_map_sg(rkc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
@@ -241,10 +242,8 @@ static int rk_hash_prepare(struct crypto_engine *engine, void *breq)
static int rk_hash_unprepare(struct crypto_engine *engine, void *breq)
{
struct ahash_request *areq = container_of(breq, struct ahash_request, base);
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
- struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
- struct rk_crypto_info *rkc = tctx->dev;
+ struct rk_crypto_info *rkc = rctx->dev;

dma_unmap_sg(rkc->dev, areq->src, rctx->nrsg, DMA_TO_DEVICE);
return 0;
@@ -255,11 +254,10 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
struct ahash_request *areq = container_of(breq, struct ahash_request, base);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
struct rk_ahash_rctx *rctx = ahash_request_ctx(areq);
- struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
struct ahash_alg *alg = __crypto_ahash_alg(tfm->base.__crt_alg);
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
struct scatterlist *sg = areq->src;
- struct rk_crypto_info *rkc = tctx->dev;
+ struct rk_crypto_info *rkc = rctx->dev;
int err = 0;
int i;
u32 v;
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index cf0dfb6029d8..0b1c90ababb7 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -86,12 +86,15 @@ static int rk_cipher_handle_req(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct rk_cipher_ctx *tctx = crypto_skcipher_ctx(tfm);
+ struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
struct rk_crypto_info *rkc = tctx->dev;
struct crypto_engine *engine = rkc->engine;

if (rk_cipher_need_fallback(req))
return rk_cipher_fallback(req);

+ rctx->dev = rkc;
+
return crypto_transfer_skcipher_request_to_engine(engine, req);
}

@@ -290,7 +293,6 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
{
struct skcipher_request *areq = container_of(async_req, struct skcipher_request, base);
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(areq);
struct scatterlist *sgs, *sgd;
int err = 0;
@@ -303,7 +305,7 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
unsigned int todo;
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
- struct rk_crypto_info *rkc = ctx->dev;
+ struct rk_crypto_info *rkc = rctx->dev;

algt->stat_req++;

--
2.35.1

2022-07-06 09:08:42

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 21/33] crypto: rockchip: rework rk_handle_req function

This patch rework the rk_handle_req(), simply removing the
rk_crypto_info parameter.

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
.../crypto/rockchip/rk3288_crypto_skcipher.c | 68 +++++--------------
1 file changed, 17 insertions(+), 51 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index d60c206e717d..3187869c4c68 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -82,10 +82,12 @@ static int rk_cipher_fallback(struct skcipher_request *areq)
return err;
}

-static int rk_handle_req(struct rk_crypto_info *dev,
- struct skcipher_request *req)
+static int rk_cipher_handle_req(struct skcipher_request *req)
{
- struct crypto_engine *engine = dev->engine;
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct rk_cipher_ctx *tctx = crypto_skcipher_ctx(tfm);
+ struct rk_crypto_info *rkc = tctx->dev;
+ struct crypto_engine *engine = rkc->engine;

if (rk_cipher_need_fallback(req))
return rk_cipher_fallback(req);
@@ -142,135 +144,99 @@ static int rk_tdes_setkey(struct crypto_skcipher *cipher,

static int rk_aes_ecb_encrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_AES_ECB_MODE;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_aes_ecb_decrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_AES_ECB_MODE | RK_CRYPTO_DEC;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_aes_cbc_encrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_AES_CBC_MODE;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_aes_cbc_decrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_AES_CBC_MODE | RK_CRYPTO_DEC;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_des_ecb_encrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = 0;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_des_ecb_decrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_DEC;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_des_cbc_encrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_des_cbc_decrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_TDES_CHAINMODE_CBC | RK_CRYPTO_DEC;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_des3_ede_ecb_encrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_TDES_SELECT;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_des3_ede_ecb_decrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_DEC;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_des3_ede_cbc_encrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static int rk_des3_ede_cbc_decrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *dev = ctx->dev;

rctx->mode = RK_CRYPTO_TDES_SELECT | RK_CRYPTO_TDES_CHAINMODE_CBC |
RK_CRYPTO_DEC;
- return rk_handle_req(dev, req);
+ return rk_cipher_handle_req(req);
}

static void rk_cipher_hw_init(struct rk_crypto_info *dev, struct skcipher_request *req)
--
2.35.1

2022-07-06 09:08:55

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 30/33] crypto: rockchip: Check for clocks numbers and their frequencies

Add the number of clocks needed for each compatible.
Rockchip's datasheet give maximum frequencies for some clocks, so add
checks for verifying they are within limits. Let's start with rk3288 for
clock frequency check, other will came later.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 75 +++++++++++++++++++++----
drivers/crypto/rockchip/rk3288_crypto.h | 16 +++++-
2 files changed, 79 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index c92559b83f7d..232dc625d6e5 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -14,10 +14,58 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/crypto.h>
#include <linux/reset.h>

+static const struct rk_variant rk3288_variant = {
+ .num_clks = 4,
+ .rkclks = {
+ { "sclk", 150000000},
+ }
+};
+
+static const struct rk_variant rk3328_variant = {
+ .num_clks = 3,
+};
+
+static int rk_crypto_get_clks(struct rk_crypto_info *dev)
+{
+ int i, j, err;
+ unsigned long cr;
+
+ dev->num_clks = devm_clk_bulk_get_all(dev->dev, &dev->clks);
+ if (dev->num_clks < dev->variant->num_clks) {
+ dev_err(dev->dev, "Missing clocks, got %d instead of %d\n",
+ dev->num_clks, dev->variant->num_clks);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < dev->num_clks; i++) {
+ cr = clk_get_rate(dev->clks[i].clk);
+ for (j = 0; j < ARRAY_SIZE(dev->variant->rkclks); j++) {
+ if (dev->variant->rkclks[j].max == 0)
+ continue;
+ if (strcmp(dev->variant->rkclks[j].name, dev->clks[i].id))
+ continue;
+ if (cr > dev->variant->rkclks[j].max) {
+ err = clk_set_rate(dev->clks[i].clk,
+ dev->variant->rkclks[j].max);
+ if (err)
+ dev_err(dev->dev, "Fail downclocking %s from %lu to %lu\n",
+ dev->variant->rkclks[j].name, cr,
+ dev->variant->rkclks[j].max);
+ else
+ dev_info(dev->dev, "Downclocking %s from %lu to %lu\n",
+ dev->variant->rkclks[j].name, cr,
+ dev->variant->rkclks[j].max);
+ }
+ }
+ }
+ return 0;
+}
+
static int rk_crypto_enable_clk(struct rk_crypto_info *dev)
{
int err;
@@ -201,8 +249,12 @@ static void rk_crypto_unregister(void)
}

static const struct of_device_id crypto_of_id_table[] = {
- { .compatible = "rockchip,rk3288-crypto" },
- { .compatible = "rockchip,rk3328-crypto" },
+ { .compatible = "rockchip,rk3288-crypto",
+ .data = &rk3288_variant,
+ },
+ { .compatible = "rockchip,rk3328-crypto",
+ .data = &rk3328_variant,
+ },
{}
};
MODULE_DEVICE_TABLE(of, crypto_of_id_table);
@@ -220,6 +272,15 @@ static int rk_crypto_probe(struct platform_device *pdev)
goto err_crypto;
}

+ crypto_info->dev = &pdev->dev;
+ platform_set_drvdata(pdev, crypto_info);
+
+ crypto_info->variant = of_device_get_match_data(&pdev->dev);
+ if (!crypto_info->variant) {
+ dev_err(&pdev->dev, "Missing variant\n");
+ return -EINVAL;
+ }
+
crypto_info->rst = devm_reset_control_get(dev, "crypto-rst");
if (IS_ERR(crypto_info->rst)) {
err = PTR_ERR(crypto_info->rst);
@@ -236,12 +297,9 @@ static int rk_crypto_probe(struct platform_device *pdev)
goto err_crypto;
}

- crypto_info->num_clks = devm_clk_bulk_get_all(&pdev->dev,
- &crypto_info->clks);
- if (crypto_info->num_clks < 3) {
- err = -EINVAL;
+ err = rk_crypto_get_clks(crypto_info);
+ if (err)
goto err_crypto;
- }

crypto_info->irq = platform_get_irq(pdev, 0);
if (crypto_info->irq < 0) {
@@ -259,9 +317,6 @@ static int rk_crypto_probe(struct platform_device *pdev)
goto err_crypto;
}

- crypto_info->dev = &pdev->dev;
- platform_set_drvdata(pdev, crypto_info);
-
crypto_info->engine = crypto_engine_alloc_init(&pdev->dev, true);
crypto_engine_start(crypto_info->engine);
init_completion(&crypto_info->complete);
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index ff9fc25972eb..ac979d67ced9 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -188,14 +188,26 @@
#define CRYPTO_WRITE(dev, offset, val) \
writel_relaxed((val), ((dev)->reg + (offset)))

+#define RK_MAX_CLKS 4
+
+struct rk_clks {
+ const char *name;
+ unsigned long max;
+};
+
+struct rk_variant {
+ int num_clks;
+ struct rk_clks rkclks[RK_MAX_CLKS];
+};
+
struct rk_crypto_info {
struct device *dev;
struct clk_bulk_data *clks;
- int num_clks;
+ int num_clks;
struct reset_control *rst;
void __iomem *reg;
int irq;
-
+ const struct rk_variant *variant;
struct crypto_engine *engine;
struct completion complete;
int status;
--
2.35.1

2022-07-06 09:09:00

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

The latest addition to the rockchip crypto driver need to update the
driver bindings.

Reviewed-by: Krzysztof Kozlowski <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
.../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
1 file changed, 77 insertions(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
index 8a219d439d02..5bb6bf4699ff 100644
--- a/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml
@@ -13,6 +13,8 @@ properties:
compatible:
enum:
- rockchip,rk3288-crypto
+ - rockchip,rk3328-crypto
+ - rockchip,rk3399-crypto

reg:
maxItems: 1
@@ -21,21 +23,88 @@ properties:
maxItems: 1

clocks:
+ minItems: 3
maxItems: 4

clock-names:
- items:
- - const: aclk
- - const: hclk
- - const: sclk
- - const: apb_pclk
+ minItems: 3
+ maxItems: 4

resets:
- maxItems: 1
+ minItems: 1
+ maxItems: 3

reset-names:
- items:
- - const: crypto-rst
+ minItems: 1
+ maxItems: 3
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3288-crypto
+ then:
+ properties:
+ clocks:
+ minItems: 4
+ clock-names:
+ items:
+ - const: aclk
+ - const: hclk
+ - const: sclk
+ - const: apb_pclk
+ minItems: 4
+ resets:
+ maxItems: 1
+ reset-names:
+ items:
+ - const: crypto-rst
+ maxItems: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3328-crypto
+ then:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ items:
+ - const: hclk_master
+ - const: hclk_slave
+ - const: sclk
+ maxItems: 3
+ resets:
+ maxItems: 1
+ reset-names:
+ items:
+ - const: crypto-rst
+ maxItems: 1
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3399-crypto
+ then:
+ properties:
+ clocks:
+ maxItems: 3
+ clock-names:
+ items:
+ - const: hclk_master
+ - const: hclk_slave
+ - const: sclk
+ maxItems: 3
+ resets:
+ minItems: 3
+ reset-names:
+ items:
+ - const: rst_master
+ - const: rst_slave
+ - const: crypto-rst
+ minItems: 3

required:
- compatible
--
2.35.1

2022-07-06 09:09:05

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 33/33] crypto: rockchip: Add support for RK3399

The RK3399 has 2 rk3288 compatible crypto device named crypto0 and
crypto1. The only difference is lack of RSA in crypto1.

We need to add driver support for 2 parallel instance as only one need
to register crypto algorithms.
Then the driver will round robin each request on each device.

For avoiding complexity (device bringup after a TFM is created), PM is
modified to be handled per request.
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 92 +++++++++++++++----
drivers/crypto/rockchip/rk3288_crypto.h | 25 +++--
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 37 ++++----
.../crypto/rockchip/rk3288_crypto_skcipher.c | 37 ++++----
4 files changed, 123 insertions(+), 68 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index d96f375423d5..6217e73ba4c4 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -19,6 +19,23 @@
#include <linux/crypto.h>
#include <linux/reset.h>

+static struct rockchip_ip rocklist = {
+ .dev_list = LIST_HEAD_INIT(rocklist.dev_list),
+ .lock = __SPIN_LOCK_UNLOCKED(rocklist.lock),
+};
+
+struct rk_crypto_info *get_rk_crypto(void)
+{
+ struct rk_crypto_info *first;
+
+ spin_lock(&rocklist.lock);
+ first = list_first_entry_or_null(&rocklist.dev_list,
+ struct rk_crypto_info, list);
+ list_rotate_left(&rocklist.dev_list);
+ spin_unlock(&rocklist.lock);
+ return first;
+}
+
static const struct rk_variant rk3288_variant = {
.num_clks = 4,
.rkclks = {
@@ -30,6 +47,10 @@ static const struct rk_variant rk3328_variant = {
.num_clks = 3,
};

+static const struct rk_variant rk3399_variant = {
+ .num_clks = 3,
+};
+
static int rk_crypto_get_clks(struct rk_crypto_info *dev)
{
int i, j, err;
@@ -83,8 +104,8 @@ static void rk_crypto_disable_clk(struct rk_crypto_info *dev)
}

/*
- * Power management strategy: The device is suspended unless a TFM exists for
- * one of the algorithms proposed by this driver.
+ * Power management strategy: The device is suspended until a request
+ * is handled. For avoiding suspend/resume yoyo, the autosuspend is set to 2s.
*/
static int rk_crypto_pm_suspend(struct device *dev)
{
@@ -166,8 +187,17 @@ static struct rk_crypto_tmp *rk_cipher_algs[] = {
#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
static int rk_crypto_debugfs_show(struct seq_file *seq, void *v)
{
+ struct rk_crypto_info *dd;
unsigned int i;

+ spin_lock(&rocklist.lock);
+ list_for_each_entry(dd, &rocklist.dev_list, list) {
+ seq_printf(seq, "%s %s requests: %lu\n",
+ dev_driver_string(dd->dev), dev_name(dd->dev),
+ dd->nreq);
+ }
+ spin_unlock(&rocklist.lock);
+
for (i = 0; i < ARRAY_SIZE(rk_cipher_algs); i++) {
if (!rk_cipher_algs[i]->dev)
continue;
@@ -198,6 +228,18 @@ static int rk_crypto_debugfs_show(struct seq_file *seq, void *v)
DEFINE_SHOW_ATTRIBUTE(rk_crypto_debugfs);
#endif

+static void register_debugfs(struct rk_crypto_info *crypto_info)
+{
+#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
+ /* Ignore error of debugfs */
+ rocklist.dbgfs_dir = debugfs_create_dir("rk3288_crypto", NULL);
+ rocklist.dbgfs_stats = debugfs_create_file("stats", 0444,
+ rocklist.dbgfs_dir,
+ &rocklist,
+ &rk_crypto_debugfs_fops);
+#endif
+}
+
static int rk_crypto_register(struct rk_crypto_info *crypto_info)
{
unsigned int i, k;
@@ -255,6 +297,9 @@ static const struct of_device_id crypto_of_id_table[] = {
{ .compatible = "rockchip,rk3328-crypto",
.data = &rk3328_variant,
},
+ { .compatible = "rockchip,rk3399-crypto",
+ .data = &rk3399_variant,
+ },
{}
};
MODULE_DEVICE_TABLE(of, crypto_of_id_table);
@@ -262,7 +307,7 @@ MODULE_DEVICE_TABLE(of, crypto_of_id_table);
static int rk_crypto_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
- struct rk_crypto_info *crypto_info;
+ struct rk_crypto_info *crypto_info, *first;
int err = 0;

crypto_info = devm_kzalloc(&pdev->dev,
@@ -325,22 +370,22 @@ static int rk_crypto_probe(struct platform_device *pdev)
if (err)
goto err_pm;

- err = rk_crypto_register(crypto_info);
- if (err) {
- dev_err(dev, "err in register alg");
- goto err_register_alg;
- }
+ spin_lock(&rocklist.lock);
+ first = list_first_entry_or_null(&rocklist.dev_list,
+ struct rk_crypto_info, list);
+ list_add_tail(&crypto_info->list, &rocklist.dev_list);
+ spin_unlock(&rocklist.lock);
+
+ if (!first) {
+ err = rk_crypto_register(crypto_info);
+ if (err) {
+ dev_err(dev, "Fail to register crypto algorithms");
+ goto err_register_alg;
+ }

-#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
- /* Ignore error of debugfs */
- crypto_info->dbgfs_dir = debugfs_create_dir("rk3288_crypto", NULL);
- crypto_info->dbgfs_stats = debugfs_create_file("stats", 0444,
- crypto_info->dbgfs_dir,
- crypto_info,
- &rk_crypto_debugfs_fops);
-#endif
+ register_debugfs(crypto_info);
+ }

- dev_info(dev, "Crypto Accelerator successfully registered\n");
return 0;

err_register_alg:
@@ -355,11 +400,20 @@ static int rk_crypto_probe(struct platform_device *pdev)
static int rk_crypto_remove(struct platform_device *pdev)
{
struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev);
+ struct rk_crypto_info *first;
+
+ spin_lock_bh(&rocklist.lock);
+ list_del(&crypto_tmp->list);
+ first = list_first_entry_or_null(&rocklist.dev_list,
+ struct rk_crypto_info, list);
+ spin_unlock_bh(&rocklist.lock);

+ if (!first) {
#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
- debugfs_remove_recursive(crypto_tmp->dbgfs_dir);
+ debugfs_remove_recursive(rocklist.dbgfs_dir);
#endif
- rk_crypto_unregister();
+ rk_crypto_unregister();
+ }
rk_crypto_pm_exit(crypto_tmp);
crypto_engine_exit(crypto_tmp->engine);
return 0;
diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h
index ac979d67ced9..b2695258cade 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.h
+++ b/drivers/crypto/rockchip/rk3288_crypto.h
@@ -190,6 +190,20 @@

#define RK_MAX_CLKS 4

+/*
+ * struct rockchip_ip - struct for managing a list of RK crypto instance
+ * @dev_list: Used for doing a list of rk_crypto_info
+ * @lock: Control access to dev_list
+ * @dbgfs_dir: Debugfs dentry for statistic directory
+ * @dbgfs_stats: Debugfs dentry for statistic counters
+ */
+struct rockchip_ip {
+ struct list_head dev_list;
+ spinlock_t lock; /* Control access to dev_list */
+ struct dentry *dbgfs_dir;
+ struct dentry *dbgfs_stats;
+};
+
struct rk_clks {
const char *name;
unsigned long max;
@@ -201,6 +215,7 @@ struct rk_variant {
};

struct rk_crypto_info {
+ struct list_head list;
struct device *dev;
struct clk_bulk_data *clks;
int num_clks;
@@ -208,19 +223,15 @@ struct rk_crypto_info {
void __iomem *reg;
int irq;
const struct rk_variant *variant;
+ unsigned long nreq;
struct crypto_engine *engine;
struct completion complete;
int status;
-#ifdef CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG
- struct dentry *dbgfs_dir;
- struct dentry *dbgfs_stats;
-#endif
};

/* the private variable of hash */
struct rk_ahash_ctx {
struct crypto_engine_ctx enginectx;
- struct rk_crypto_info *dev;
/* for fallback */
struct crypto_ahash *fallback_tfm;
};
@@ -236,7 +247,6 @@ struct rk_ahash_rctx {
/* the private variable of cipher */
struct rk_cipher_ctx {
struct crypto_engine_ctx enginectx;
- struct rk_crypto_info *dev;
unsigned int keylen;
u8 key[AES_MAX_KEY_SIZE];
u8 iv[AES_BLOCK_SIZE];
@@ -252,7 +262,7 @@ struct rk_cipher_rctx {

struct rk_crypto_tmp {
u32 type;
- struct rk_crypto_info *dev;
+ struct rk_crypto_info *dev;
union {
struct skcipher_alg skcipher;
struct ahash_alg hash;
@@ -276,4 +286,5 @@ extern struct rk_crypto_tmp rk_ahash_sha1;
extern struct rk_crypto_tmp rk_ahash_sha256;
extern struct rk_crypto_tmp rk_ahash_md5;

+struct rk_crypto_info *get_rk_crypto(void);
#endif
diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index 30f78256c955..a78ff3dcd0b1 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -199,8 +199,8 @@ static int rk_ahash_export(struct ahash_request *req, void *out)
static int rk_ahash_digest(struct ahash_request *req)
{
struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
- struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
- struct rk_crypto_info *dev = tctx->dev;
+ struct rk_crypto_info *dev;
+ struct crypto_engine *engine;

if (rk_ahash_need_fallback(req))
return rk_ahash_digest_fb(req);
@@ -208,9 +208,12 @@ static int rk_ahash_digest(struct ahash_request *req)
if (!req->nbytes)
return zero_message_process(req);

+ dev = get_rk_crypto();
+
rctx->dev = dev;
+ engine = dev->engine;

- return crypto_transfer_hash_request_to_engine(dev->engine, req);
+ return crypto_transfer_hash_request_to_engine(engine, req);
}

static void crypto_ahash_dma_start(struct rk_crypto_info *dev, struct scatterlist *sg)
@@ -260,9 +263,14 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
int i;
u32 v;

+ err = pm_runtime_resume_and_get(rkc->dev);
+ if (err)
+ return err;
+
rctx->mode = 0;

algt->stat_req++;
+ rkc->nreq++;

switch (crypto_ahash_digestsize(tfm)) {
case SHA1_DIGEST_SIZE:
@@ -313,6 +321,8 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
}

theend:
+ pm_runtime_put_autosuspend(rkc->dev);
+
local_bh_disable();
crypto_finalize_hash_request(engine, breq, err);
local_bh_enable();
@@ -323,21 +333,15 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
static int rk_cra_hash_init(struct crypto_tfm *tfm)
{
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);
- struct rk_crypto_tmp *algt;
- struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
-
const char *alg_name = crypto_tfm_alg_name(tfm);
- int err;
-
- algt = container_of(alg, struct rk_crypto_tmp, alg.hash);
-
- tctx->dev = algt->dev;
+ struct ahash_alg *alg = __crypto_ahash_alg(tfm->__crt_alg);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.hash);

/* for fallback */
tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(tctx->fallback_tfm)) {
- dev_err(tctx->dev->dev, "Could not load fallback driver.\n");
+ dev_err(algt->dev->dev, "Could not load fallback driver.\n");
return PTR_ERR(tctx->fallback_tfm);
}

@@ -349,15 +353,7 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)
tctx->enginectx.op.prepare_request = rk_hash_prepare;
tctx->enginectx.op.unprepare_request = rk_hash_unprepare;

- err = pm_runtime_resume_and_get(tctx->dev->dev);
- if (err < 0)
- goto error_pm;
-
return 0;
-error_pm:
- crypto_free_ahash(tctx->fallback_tfm);
-
- return err;
}

static void rk_cra_hash_exit(struct crypto_tfm *tfm)
@@ -365,7 +361,6 @@ static void rk_cra_hash_exit(struct crypto_tfm *tfm)
struct rk_ahash_ctx *tctx = crypto_tfm_ctx(tfm);

crypto_free_ahash(tctx->fallback_tfm);
- pm_runtime_put_autosuspend(tctx->dev->dev);
}

struct rk_crypto_tmp rk_ahash_sha1 = {
diff --git a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
index 0b1c90ababb7..59069457582b 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_skcipher.c
@@ -17,11 +17,11 @@
static int rk_cipher_need_fallback(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- unsigned int bs = crypto_skcipher_blocksize(tfm);
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
struct scatterlist *sgs, *sgd;
unsigned int stodo, dtodo, len;
+ unsigned int bs = crypto_skcipher_blocksize(tfm);

if (!req->cryptlen)
return true;
@@ -84,15 +84,16 @@ static int rk_cipher_fallback(struct skcipher_request *areq)

static int rk_cipher_handle_req(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct rk_cipher_ctx *tctx = crypto_skcipher_ctx(tfm);
struct rk_cipher_rctx *rctx = skcipher_request_ctx(req);
- struct rk_crypto_info *rkc = tctx->dev;
- struct crypto_engine *engine = rkc->engine;
+ struct rk_crypto_info *rkc;
+ struct crypto_engine *engine;

if (rk_cipher_need_fallback(req))
return rk_cipher_fallback(req);

+ rkc = get_rk_crypto();
+
+ engine = rkc->engine;
rctx->dev = rkc;

return crypto_transfer_skcipher_request_to_engine(engine, req);
@@ -307,7 +308,12 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
struct rk_crypto_info *rkc = rctx->dev;

+ err = pm_runtime_resume_and_get(rkc->dev);
+ if (err)
+ return err;
+
algt->stat_req++;
+ rkc->nreq++;

ivsize = crypto_skcipher_ivsize(tfm);
if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
@@ -401,6 +407,8 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
}

theend:
+ pm_runtime_put_autosuspend(rkc->dev);
+
local_bh_disable();
crypto_finalize_skcipher_request(engine, areq, err);
local_bh_enable();
@@ -420,18 +428,13 @@ static int rk_cipher_run(struct crypto_engine *engine, void *async_req)
static int rk_cipher_tfm_init(struct crypto_skcipher *tfm)
{
struct rk_cipher_ctx *ctx = crypto_skcipher_ctx(tfm);
- struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
const char *name = crypto_tfm_alg_name(&tfm->base);
- struct rk_crypto_tmp *algt;
- int err;
-
- algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);
-
- ctx->dev = algt->dev;
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct rk_crypto_tmp *algt = container_of(alg, struct rk_crypto_tmp, alg.skcipher);

ctx->fallback_tfm = crypto_alloc_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(ctx->fallback_tfm)) {
- dev_err(ctx->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
+ dev_err(algt->dev->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
name, PTR_ERR(ctx->fallback_tfm));
return PTR_ERR(ctx->fallback_tfm);
}
@@ -441,14 +444,7 @@ static int rk_cipher_tfm_init(struct crypto_skcipher *tfm)

ctx->enginectx.op.do_one_request = rk_cipher_run;

- err = pm_runtime_resume_and_get(ctx->dev->dev);
- if (err < 0)
- goto error_pm;
-
return 0;
-error_pm:
- crypto_free_skcipher(ctx->fallback_tfm);
- return err;
}

static void rk_cipher_tfm_exit(struct crypto_skcipher *tfm)
@@ -457,7 +453,6 @@ static void rk_cipher_tfm_exit(struct crypto_skcipher *tfm)

memzero_explicit(ctx->key, ctx->keylen);
crypto_free_skcipher(ctx->fallback_tfm);
- pm_runtime_put_autosuspend(ctx->dev->dev);
}

struct rk_crypto_tmp rk_ecb_aes_alg = {
--
2.35.1

2022-07-06 09:09:11

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 28/33] arm64: dts: rockchip: rk3399: add crypto node

The rk3399 has a crypto IP handled by the rk3288 crypto driver so adds a
node for it.

Tested-by Diederik de Haas <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 9d5b0e8c9cca..8e5aa1ca62d1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -582,6 +582,26 @@ saradc: saradc@ff100000 {
status = "disabled";
};

+ crypto0: crypto@ff8b0000 {
+ compatible = "rockchip,rk3399-crypto";
+ reg = <0x0 0xff8b0000 0x0 0x4000>;
+ interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru HCLK_M_CRYPTO0>, <&cru HCLK_S_CRYPTO0>, <&cru SCLK_CRYPTO0>;
+ clock-names = "hclk_master", "hclk_slave", "sclk";
+ resets = <&cru SRST_CRYPTO0>, <&cru SRST_CRYPTO0_S>, <&cru SRST_CRYPTO0_M>;
+ reset-names = "rst_master", "rst_slave", "crypto-rst";
+ };
+
+ crypto1: crypto@ff8b8000 {
+ compatible = "rockchip,rk3399-crypto";
+ reg = <0x0 0xff8b8000 0x0 0x4000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru HCLK_M_CRYPTO1>, <&cru HCLK_S_CRYPTO1>, <&cru SCLK_CRYPTO1>;
+ clock-names = "hclk_master", "hclk_slave", "sclk";
+ resets = <&cru SRST_CRYPTO1>, <&cru SRST_CRYPTO1_S>, <&cru SRST_CRYPTO1_M>;
+ reset-names = "rst_master", "rst_slave", "crypto-rst";
+ };
+
i2c1: i2c@ff110000 {
compatible = "rockchip,rk3399-i2c";
reg = <0x0 0xff110000 0x0 0x1000>;
--
2.35.1

2022-07-06 09:09:19

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 31/33] crypto: rockchip: rk_ahash_reg_init use crypto_info from parameter

rk_ahash_reg_init() use crypto_info from TFM context, since we will
remove it, let's take if from parameters.

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index d1bf68cb390d..30f78256c955 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -78,12 +78,10 @@ static int zero_message_process(struct ahash_request *req)
return 0;
}

-static void rk_ahash_reg_init(struct ahash_request *req)
+static void rk_ahash_reg_init(struct ahash_request *req,
+ struct rk_crypto_info *dev)
{
struct rk_ahash_rctx *rctx = ahash_request_ctx(req);
- struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
- struct rk_ahash_ctx *tctx = crypto_ahash_ctx(tfm);
- struct rk_crypto_info *dev = tctx->dev;
int reg_status;

reg_status = CRYPTO_READ(dev, RK_CRYPTO_CTRL) |
@@ -281,7 +279,7 @@ static int rk_hash_run(struct crypto_engine *engine, void *breq)
goto theend;
}

- rk_ahash_reg_init(areq);
+ rk_ahash_reg_init(areq, rkc);

while (sg) {
reinit_completion(&rkc->complete);
--
2.35.1

2022-07-06 09:09:24

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 26/33] clk: rk3399: use proper crypto0 name

RK3399 has 2 crypto instance, named crypto0 and crypto1 in the TRM.
Only reset for crypto1 is correctly named, but crypto0 is not.
Since nobody use them , add a 0 to be consistent with the TRM and crypto1 entries.

Acked-by: Rob Herring <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
include/dt-bindings/clock/rk3399-cru.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/dt-bindings/clock/rk3399-cru.h b/include/dt-bindings/clock/rk3399-cru.h
index 44e0a319f077..39169d94a44e 100644
--- a/include/dt-bindings/clock/rk3399-cru.h
+++ b/include/dt-bindings/clock/rk3399-cru.h
@@ -547,8 +547,8 @@
#define SRST_H_PERILP0 171
#define SRST_H_PERILP0_NOC 172
#define SRST_ROM 173
-#define SRST_CRYPTO_S 174
-#define SRST_CRYPTO_M 175
+#define SRST_CRYPTO0_S 174
+#define SRST_CRYPTO0_M 175

/* cru_softrst_con11 */
#define SRST_P_DCF 176
@@ -556,7 +556,7 @@
#define SRST_CM0S 178
#define SRST_CM0S_DBG 179
#define SRST_CM0S_PO 180
-#define SRST_CRYPTO 181
+#define SRST_CRYPTO0 181
#define SRST_P_PERILP1_SGRF 182
#define SRST_P_PERILP1_GRF 183
#define SRST_CRYPTO1_S 184
--
2.35.1

2022-07-06 09:09:33

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 32/33] crypto: rockchip: permit to have more than one reset

The RK3399 has 3 resets, so the driver to handle multiple resets.
This is done by using devm_reset_control_array_get_exclusive().

Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c
index 232dc625d6e5..d96f375423d5 100644
--- a/drivers/crypto/rockchip/rk3288_crypto.c
+++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -281,7 +281,7 @@ static int rk_crypto_probe(struct platform_device *pdev)
return -EINVAL;
}

- crypto_info->rst = devm_reset_control_get(dev, "crypto-rst");
+ crypto_info->rst = devm_reset_control_array_get_exclusive(dev);
if (IS_ERR(crypto_info->rst)) {
err = PTR_ERR(crypto_info->rst);
goto err_crypto;
--
2.35.1

2022-07-06 09:09:33

by Corentin LABBE

[permalink] [raw]
Subject: [PATCH v8 18/33] crypto: rockchip: fix style issue

This patch fixes some warning reported by checkpatch

Reviewed-by: John Keeping <[email protected]>
Signed-off-by: Corentin Labbe <[email protected]>
---
drivers/crypto/rockchip/rk3288_crypto_ahash.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
index 1fbab86c9238..fae779d73c84 100644
--- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c
+++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c
@@ -336,7 +336,7 @@ static int rk_cra_hash_init(struct crypto_tfm *tfm)

/* for fallback */
tctx->fallback_tfm = crypto_alloc_ahash(alg_name, 0,
- CRYPTO_ALG_NEED_FALLBACK);
+ CRYPTO_ALG_NEED_FALLBACK);
if (IS_ERR(tctx->fallback_tfm)) {
dev_err(tctx->dev->dev, "Could not load fallback driver.\n");
return PTR_ERR(tctx->fallback_tfm);
@@ -394,8 +394,8 @@ struct rk_crypto_tmp rk_ahash_sha1 = {
.cra_init = rk_cra_hash_init,
.cra_exit = rk_cra_hash_exit,
.cra_module = THIS_MODULE,
- }
- }
+ }
+ }
}
};

@@ -424,8 +424,8 @@ struct rk_crypto_tmp rk_ahash_sha256 = {
.cra_init = rk_cra_hash_init,
.cra_exit = rk_cra_hash_exit,
.cra_module = THIS_MODULE,
- }
- }
+ }
+ }
}
};

@@ -454,7 +454,7 @@ struct rk_crypto_tmp rk_ahash_md5 = {
.cra_init = rk_cra_hash_init,
.cra_exit = rk_cra_hash_exit,
.cra_module = THIS_MODULE,
- }
}
+ }
}
};
--
2.35.1

2022-07-06 13:38:17

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v8 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

On Wed, 06 Jul 2022 09:04:04 +0000, Corentin Labbe wrote:
> The latest addition to the rockchip crypto driver need to update the
> driver bindings.
>
> Reviewed-by: Krzysztof Kozlowski <[email protected]>
> Signed-off-by: Corentin Labbe <[email protected]>
> ---
> .../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
> 1 file changed, 77 insertions(+), 8 deletions(-)
>

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:0:then:properties:clock-names: 'oneOf' conditional failed, one must be fixed:
[{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too long
[{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too short
False schema does not allow 4
1 was expected
4 is greater than the maximum of 2
4 is greater than the maximum of 3
hint: "minItems" is only needed if less than the "items" list length
from schema $id: http://devicetree.org/meta-schemas/items.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:0:then:properties:reset-names: {'items': [{'const': 'crypto-rst'}], 'maxItems': 1} should not be valid under {'required': ['maxItems']}
hint: "maxItems" is not needed with an "items" list
from schema $id: http://devicetree.org/meta-schemas/items.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:1:then:properties:clock-names: {'items': [{'const': 'hclk_master'}, {'const': 'hclk_slave'}, {'const': 'sclk'}], 'maxItems': 3} should not be valid under {'required': ['maxItems']}
hint: "maxItems" is not needed with an "items" list
from schema $id: http://devicetree.org/meta-schemas/items.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:1:then:properties:reset-names: {'items': [{'const': 'crypto-rst'}], 'maxItems': 1} should not be valid under {'required': ['maxItems']}
hint: "maxItems" is not needed with an "items" list
from schema $id: http://devicetree.org/meta-schemas/items.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:2:then:properties:clock-names: {'items': [{'const': 'hclk_master'}, {'const': 'hclk_slave'}, {'const': 'sclk'}], 'maxItems': 3} should not be valid under {'required': ['maxItems']}
hint: "maxItems" is not needed with an "items" list
from schema $id: http://devicetree.org/meta-schemas/items.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:2:then:properties:reset-names: 'oneOf' conditional failed, one must be fixed:
[{'const': 'rst_master'}, {'const': 'rst_slave'}, {'const': 'crypto-rst'}] is too long
[{'const': 'rst_master'}, {'const': 'rst_slave'}, {'const': 'crypto-rst'}] is too short
False schema does not allow 3
1 was expected
3 is greater than the maximum of 2
hint: "minItems" is only needed if less than the "items" list length
from schema $id: http://devicetree.org/meta-schemas/items.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: ignoring, error in schema: allOf: 0: then: properties: reset-names
Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.example.dtb:0:0: /example-0/crypto@ff8a0000: failed to match any schema with compatible: ['rockchip,rk3288-crypto']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.

2022-07-06 14:38:02

by Corentin LABBE

[permalink] [raw]
Subject: Re: [PATCH v8 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

Le Wed, Jul 06, 2022 at 07:29:04AM -0600, Rob Herring a ?crit :
> On Wed, 06 Jul 2022 09:04:04 +0000, Corentin Labbe wrote:
> > The latest addition to the rockchip crypto driver need to update the
> > driver bindings.
> >
> > Reviewed-by: Krzysztof Kozlowski <[email protected]>
> > Signed-off-by: Corentin Labbe <[email protected]>
> > ---
> > .../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
> > 1 file changed, 77 insertions(+), 8 deletions(-)
> >
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:0:then:properties:clock-names: 'oneOf' conditional failed, one must be fixed:
> [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too long
> [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too short
> False schema does not allow 4
> 1 was expected
> 4 is greater than the maximum of 2
> 4 is greater than the maximum of 3

Hello

I upgraded to dt-schema 2022.07 and fail to reproduce all errors.

Regards

2022-07-06 15:28:28

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v8 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

On 06/07/2022 16:28, LABBE Corentin wrote:
> Le Wed, Jul 06, 2022 at 07:29:04AM -0600, Rob Herring a écrit :
>> On Wed, 06 Jul 2022 09:04:04 +0000, Corentin Labbe wrote:
>>> The latest addition to the rockchip crypto driver need to update the
>>> driver bindings.
>>>
>>> Reviewed-by: Krzysztof Kozlowski <[email protected]>
>>> Signed-off-by: Corentin Labbe <[email protected]>
>>> ---
>>> .../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
>>> 1 file changed, 77 insertions(+), 8 deletions(-)
>>>
>>
>> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
>> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>>
>> yamllint warnings/errors:
>>
>> dtschema/dtc warnings/errors:
>> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:0:then:properties:clock-names: 'oneOf' conditional failed, one must be fixed:
>> [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too long
>> [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too short
>> False schema does not allow 4
>> 1 was expected
>> 4 is greater than the maximum of 2
>> 4 is greater than the maximum of 3
>
> Hello
>
> I upgraded to dt-schema 2022.07 and fail to reproduce all errors.

Visible on older dtschema (2022.6.dev10+gcd64f75fe091), visible on
newest (2022.7).

Exactly the same error.

Best regards,
Krzysztof

2022-07-07 08:46:50

by Corentin LABBE

[permalink] [raw]
Subject: Re: [PATCH v8 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

Le Wed, Jul 06, 2022 at 05:25:21PM +0200, Krzysztof Kozlowski a ?crit :
> On 06/07/2022 16:28, LABBE Corentin wrote:
> > Le Wed, Jul 06, 2022 at 07:29:04AM -0600, Rob Herring a ?crit :
> >> On Wed, 06 Jul 2022 09:04:04 +0000, Corentin Labbe wrote:
> >>> The latest addition to the rockchip crypto driver need to update the
> >>> driver bindings.
> >>>
> >>> Reviewed-by: Krzysztof Kozlowski <[email protected]>
> >>> Signed-off-by: Corentin Labbe <[email protected]>
> >>> ---
> >>> .../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
> >>> 1 file changed, 77 insertions(+), 8 deletions(-)
> >>>
> >>
> >> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> >> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> >>
> >> yamllint warnings/errors:
> >>
> >> dtschema/dtc warnings/errors:
> >> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:0:then:properties:clock-names: 'oneOf' conditional failed, one must be fixed:
> >> [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too long
> >> [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too short
> >> False schema does not allow 4
> >> 1 was expected
> >> 4 is greater than the maximum of 2
> >> 4 is greater than the maximum of 3
> >
> > Hello
> >
> > I upgraded to dt-schema 2022.07 and fail to reproduce all errors.
>
> Visible on older dtschema (2022.6.dev10+gcd64f75fe091), visible on
> newest (2022.7).
>
> Exactly the same error.
>

Hello

I am sorry, I finally succesfully reproduced it.
Just doing what the hints gives (removing max/min-items) from "static" list fix the issue.

Does I need to remove your Reviewed-by ?

Thanks

2022-07-10 15:13:57

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v8 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

On 07/07/2022 10:37, LABBE Corentin wrote:
> Le Wed, Jul 06, 2022 at 05:25:21PM +0200, Krzysztof Kozlowski a écrit :
>> On 06/07/2022 16:28, LABBE Corentin wrote:
>>> Le Wed, Jul 06, 2022 at 07:29:04AM -0600, Rob Herring a écrit :
>>>> On Wed, 06 Jul 2022 09:04:04 +0000, Corentin Labbe wrote:
>>>>> The latest addition to the rockchip crypto driver need to update the
>>>>> driver bindings.
>>>>>
>>>>> Reviewed-by: Krzysztof Kozlowski <[email protected]>
>>>>> Signed-off-by: Corentin Labbe <[email protected]>
>>>>> ---
>>>>> .../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
>>>>> 1 file changed, 77 insertions(+), 8 deletions(-)
>>>>>
>>>>
>>>> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
>>>> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>>>>
>>>> yamllint warnings/errors:
>>>>
>>>> dtschema/dtc warnings/errors:
>>>> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:0:then:properties:clock-names: 'oneOf' conditional failed, one must be fixed:
>>>> [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too long
>>>> [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too short
>>>> False schema does not allow 4
>>>> 1 was expected
>>>> 4 is greater than the maximum of 2
>>>> 4 is greater than the maximum of 3
>>>
>>> Hello
>>>
>>> I upgraded to dt-schema 2022.07 and fail to reproduce all errors.
>>
>> Visible on older dtschema (2022.6.dev10+gcd64f75fe091), visible on
>> newest (2022.7).
>>
>> Exactly the same error.
>>
>
> Hello
>
> I am sorry, I finally succesfully reproduced it.
> Just doing what the hints gives (removing max/min-items) from "static" list fix the issue.

Not sure what do you mean by "static list". I think you should drop
min/maxItems from clock-names/reset-names in allOf:if:then sections.

> Does I need to remove your Reviewed-by ?

Let's drop, so it will be back to my to-review queue.

Best regards,
Krzysztof

2022-07-12 21:58:30

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v8 25/33] dt-bindings: crypto: rockchip: convert to new driver bindings

On Wed, Jul 06, 2022 at 04:28:40PM +0200, LABBE Corentin wrote:
> Le Wed, Jul 06, 2022 at 07:29:04AM -0600, Rob Herring a ?crit :
> > On Wed, 06 Jul 2022 09:04:04 +0000, Corentin Labbe wrote:
> > > The latest addition to the rockchip crypto driver need to update the
> > > driver bindings.
> > >
> > > Reviewed-by: Krzysztof Kozlowski <[email protected]>
> > > Signed-off-by: Corentin Labbe <[email protected]>
> > > ---
> > > .../crypto/rockchip,rk3288-crypto.yaml | 85 +++++++++++++++++--
> > > 1 file changed, 77 insertions(+), 8 deletions(-)
> > >
> >
> > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> > on your patch (DT_CHECKER_FLAGS is new in v5.13):
> >
> > yamllint warnings/errors:
> >
> > dtschema/dtc warnings/errors:
> > /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/crypto/rockchip,rk3288-crypto.yaml: allOf:0:then:properties:clock-names: 'oneOf' conditional failed, one must be fixed:
> > [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too long
> > [{'const': 'aclk'}, {'const': 'hclk'}, {'const': 'sclk'}, {'const': 'apb_pclk'}] is too short
> > False schema does not allow 4
> > 1 was expected
> > 4 is greater than the maximum of 2
> > 4 is greater than the maximum of 3
>
> Hello
>
> I upgraded to dt-schema 2022.07 and fail to reproduce all errors.

Did you clean your tree or just touch this file after upgrading? I'm
guessing not. We don't detect dt-schema changes.

Rob