2024-02-12 13:57:13

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 00/20] Support more Amlogic SoC families in crypto driver

Hello!

This patchset expand the funcionality of the Amlogic
crypto driver by adding support for more SoC families:
AXG, G12A, G12B, SM1, A1, S4.

Also specify and enable crypto node in device tree
for reference Amlogic devices.

Tested on AXG, G12A/B, SM1, A1 and S4 devices via
custom tests [1] and tcrypt module.

---

Changes V1 -> V2 [2]:

- Rebased over linux-next.
- Adjusted device tree bindings description.
- A1 and S4 dts use their own compatible, which is a G12 fallback.

Changes V2 -> V3 [3]:

- Fix errors in dt-bindings and device tree.
- Add new field in platform data, which determines
whether clock controller should be used for crypto IP.
- Place back MODULE_DEVICE_TABLE.
- Correct commit messages.

Changes V3 -> V4 [4]:

- Update dt-bindings as per Krzysztof Kozlowski comments.
- Fix bisection: get rid of compiler errors in some patches.

Links:
- [1] https://gist.github.com/mRrvz/3fb8943a7487ab7b943ec140706995e7
- [2] https://lore.kernel.org/all/[email protected]/
- [3] https://lore.kernel.org/all/[email protected]/
- [4] https://lore.kernel.org/all/[email protected]/

Alexey Romanov (20):
drivers: crypto: meson: don't hardcode IRQ count
drviers: crypto: meson: add platform data
drivers: crypto: meson: make CLK controller optional
drivers: crypto: meson: add MMIO helpers
drivers: crypto: meson: move get_engine_number()
drivers: crypto: meson: drop status field from meson_flow
drivers: crypto: meson: move algs definition and cipher API to
cipher.c
drivers: crypto: meson: cleanup defines
drivers: crypto: meson: process more than MAXDESCS descriptors
drivers: crypto: meson: avoid kzalloc in engine thread
drivers: crypto: meson: introduce hasher
drivers: crypto: meson: add support for AES-CTR
drivers: crypto: meson: use fallback for 192-bit keys
drivers: crypto: meson: add support for G12-series
drivers: crypto: meson: add support for AXG-series
dt-bindings: crypto: meson: support new SoC's
arch: arm64: dts: meson: a1: add crypto node
arch: arm64: dts: meson: s4: add crypto node
arch: arm64: dts: meson: g12: add crypto node
arch: arm64: dts: meson: axg: add crypto node

.../bindings/crypto/amlogic,gxl-crypto.yaml | 43 +-
arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 7 +
arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 +
.../boot/dts/amlogic/meson-g12-common.dtsi | 6 +
arch/arm64/boot/dts/amlogic/meson-s4.dtsi | 6 +
drivers/crypto/amlogic/Makefile | 2 +-
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 602 ++++++++++++------
drivers/crypto/amlogic/amlogic-gxl-core.c | 290 +++++----
drivers/crypto/amlogic/amlogic-gxl-hasher.c | 452 +++++++++++++
drivers/crypto/amlogic/amlogic-gxl.h | 117 +++-
10 files changed, 1183 insertions(+), 348 deletions(-)
create mode 100644 drivers/crypto/amlogic/amlogic-gxl-hasher.c

--
2.34.1



2024-02-12 13:57:25

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 02/20] drviers: crypto: meson: add platform data

To support other Amlogic SoC's we have to
use platform data: descriptors and status registers
offsets are individual for each SoC series.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 2 +-
drivers/crypto/amlogic/amlogic-gxl-core.c | 32 +++++++++++++++------
drivers/crypto/amlogic/amlogic-gxl.h | 11 +++++++
3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index b19032f92415..7eff3ae7356f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)

reinit_completion(&mc->chanlist[flow].complete);
mc->chanlist[flow].status = 0;
- writel(mc->chanlist[flow].t_phy | 2, mc->base + (flow << 2));
+ writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
msecs_to_jiffies(500));
if (mc->chanlist[flow].status == 0) {
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 35ec64df5b3a..4d1b1d5b7a54 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>

#include "amlogic-gxl.h"
@@ -30,9 +31,10 @@ static irqreturn_t meson_irq_handler(int irq, void *data)

for (flow = 0; flow < mc->flow_cnt; flow++) {
if (mc->chanlist[flow].irq == irq) {
- p = readl(mc->base + ((0x04 + flow) << 2));
+ p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
if (p) {
- writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
+ writel_relaxed(0xF, mc->base +
+ ((mc->pdata->status_reg + flow) << 2));
mc->chanlist[flow].status = 1;
complete(&mc->chanlist[flow].complete);
return IRQ_HANDLED;
@@ -245,15 +247,35 @@ static void meson_unregister_algs(struct meson_dev *mc)
}
}

+static const struct meson_pdata meson_gxl_pdata = {
+ .descs_reg = 0x0,
+ .status_reg = 0x4,
+};
+
+static const struct of_device_id meson_crypto_of_match_table[] = {
+ {
+ .compatible = "amlogic,gxl-crypto",
+ .data = &meson_gxl_pdata,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
+
static int meson_crypto_probe(struct platform_device *pdev)
{
+ const struct of_device_id *match;
struct meson_dev *mc;
int err;

+ match = of_match_device(meson_crypto_of_match_table, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+
mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
if (!mc)
return -ENOMEM;

+ mc->pdata = match->data;
mc->dev = &pdev->dev;
platform_set_drvdata(pdev, mc);

@@ -319,12 +341,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
clk_disable_unprepare(mc->busclk);
}

-static const struct of_device_id meson_crypto_of_match_table[] = {
- { .compatible = "amlogic,gxl-crypto", },
- {}
-};
-MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
-
static struct platform_driver meson_crypto_driver = {
.probe = meson_crypto_probe,
.remove_new = meson_crypto_remove,
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 79177cfa8b88..9ad75da214ff 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -78,6 +78,16 @@ struct meson_flow {
#endif
};

+/*
+ * struct meson_pdata - SoC series dependent data.
+ * @reg_descs: offset to descriptors register
+ * @reg_status: offset to status register
+ */
+struct meson_pdata {
+ u32 descs_reg;
+ u32 status_reg;
+};
+
/*
* struct meson_dev - main container for all this driver information
* @base: base address of amlogic-crypto
@@ -93,6 +103,7 @@ struct meson_dev {
void __iomem *base;
struct clk *busclk;
struct device *dev;
+ const struct meson_pdata *pdata;
struct meson_flow *chanlist;
atomic_t flow;
int flow_cnt;
--
2.34.1


2024-02-12 13:57:42

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 04/20] drivers: crypto: meson: add MMIO helpers

Add MMIO access helpers: meson_dma_start() and meson_dma_ready().

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 2 +-
drivers/crypto/amlogic/amlogic-gxl-core.c | 24 ++++++++++++++++-----
drivers/crypto/amlogic/amlogic-gxl.h | 2 ++
3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 7eff3ae7356f..1fe916b0a138 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)

reinit_completion(&mc->chanlist[flow].complete);
mc->chanlist[flow].status = 0;
- writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
+ meson_dma_start(mc, flow);
wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
msecs_to_jiffies(500));
if (mc->chanlist[flow].status == 0) {
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 54113c524ec5..372c30f72072 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -23,18 +23,32 @@

#include "amlogic-gxl.h"

+void meson_dma_start(struct meson_dev *mc, int flow)
+{
+ u32 offset = (mc->pdata->descs_reg + flow) << 2;
+
+ writel(mc->chanlist[flow].t_phy | 2, mc->base + offset);
+}
+
+static bool meson_dma_ready(struct meson_dev *mc, int flow)
+{
+ u32 offset = (mc->pdata->status_reg + flow) << 2;
+ u32 data = readl(mc->base + offset);
+
+ if (data)
+ writel_relaxed(0xF, mc->base + offset);
+
+ return data;
+}
+
static irqreturn_t meson_irq_handler(int irq, void *data)
{
struct meson_dev *mc = (struct meson_dev *)data;
int flow;
- u32 p;

for (flow = 0; flow < mc->flow_cnt; flow++) {
if (mc->chanlist[flow].irq == irq) {
- p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
- if (p) {
- writel_relaxed(0xF, mc->base +
- ((mc->pdata->status_reg + flow) << 2));
+ if (meson_dma_ready(mc, flow)) {
mc->chanlist[flow].status = 1;
complete(&mc->chanlist[flow].complete);
return IRQ_HANDLED;
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index a36b9bac63a0..59fc6a67e0a9 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -163,6 +163,8 @@ struct meson_alg_template {
#endif
};

+void meson_dma_start(struct meson_dev *mc, int flow);
+
int meson_enqueue(struct crypto_async_request *areq, u32 type);

int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
--
2.34.1


2024-02-12 13:58:05

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 01/20] drivers: crypto: meson: don't hardcode IRQ count

IRQ count is no longer hardcoded, and make it part of
struct meson_flow. We need this for extend driver support for
other Amlogic SoC's.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 2 +-
drivers/crypto/amlogic/amlogic-gxl-core.c | 47 ++++++++++++---------
drivers/crypto/amlogic/amlogic-gxl.h | 8 ++--
3 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 29048da6f50a..b19032f92415 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -19,7 +19,7 @@

static int get_engine_number(struct meson_dev *mc)
{
- return atomic_inc_return(&mc->flow) % MAXFLOW;
+ return atomic_inc_return(&mc->flow) % mc->flow_cnt;
}

static bool meson_cipher_need_fallback(struct skcipher_request *areq)
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f54ab0d0b1e8..35ec64df5b3a 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -28,8 +28,8 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
int flow;
u32 p;

- for (flow = 0; flow < MAXFLOW; flow++) {
- if (mc->irqs[flow] == irq) {
+ for (flow = 0; flow < mc->flow_cnt; flow++) {
+ if (mc->chanlist[flow].irq == irq) {
p = readl(mc->base + ((0x04 + flow) << 2));
if (p) {
writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
@@ -110,7 +110,7 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
struct meson_dev *mc __maybe_unused = seq->private;
int i;

- for (i = 0; i < MAXFLOW; i++)
+ for (i = 0; i < mc->flow_cnt; i++)
seq_printf(seq, "Channel %d: nreq %lu\n", i,
#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
mc->chanlist[i].stat_req);
@@ -153,14 +153,32 @@ static void meson_free_chanlist(struct meson_dev *mc, int i)
*/
static int meson_allocate_chanlist(struct meson_dev *mc)
{
+ struct platform_device *pdev = to_platform_device(mc->dev);
int i, err;

- mc->chanlist = devm_kcalloc(mc->dev, MAXFLOW,
+ mc->flow_cnt = platform_irq_count(pdev);
+ if (mc->flow_cnt <= 0) {
+ dev_err(mc->dev, "No IRQs defined\n");
+ return -ENODEV;
+ }
+
+ mc->chanlist = devm_kcalloc(mc->dev, mc->flow_cnt,
sizeof(struct meson_flow), GFP_KERNEL);
if (!mc->chanlist)
return -ENOMEM;

- for (i = 0; i < MAXFLOW; i++) {
+ for (i = 0; i < mc->flow_cnt; i++) {
+ mc->chanlist[i].irq = platform_get_irq(pdev, i);
+ if (mc->chanlist[i].irq < 0)
+ return mc->chanlist[i].irq;
+
+ err = devm_request_irq(mc->dev, mc->chanlist[i].irq,
+ meson_irq_handler, 0, "aml-crypto", mc);
+ if (err < 0) {
+ dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
+ return err;
+ }
+
init_completion(&mc->chanlist[i].complete);

mc->chanlist[i].engine = crypto_engine_alloc_init(mc->dev, true);
@@ -230,7 +248,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
static int meson_crypto_probe(struct platform_device *pdev)
{
struct meson_dev *mc;
- int err, i;
+ int err;

mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
if (!mc)
@@ -252,19 +270,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
return err;
}

- for (i = 0; i < MAXFLOW; i++) {
- mc->irqs[i] = platform_get_irq(pdev, i);
- if (mc->irqs[i] < 0)
- return mc->irqs[i];
-
- err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0,
- "gxl-crypto", mc);
- if (err < 0) {
- dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
- return err;
- }
- }
-
err = clk_prepare_enable(mc->busclk);
if (err != 0) {
dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
@@ -294,7 +299,7 @@ static int meson_crypto_probe(struct platform_device *pdev)
error_alg:
meson_unregister_algs(mc);
error_flow:
- meson_free_chanlist(mc, MAXFLOW - 1);
+ meson_free_chanlist(mc, mc->flow_cnt - 1);
clk_disable_unprepare(mc->busclk);
return err;
}
@@ -309,7 +314,7 @@ static void meson_crypto_remove(struct platform_device *pdev)

meson_unregister_algs(mc);

- meson_free_chanlist(mc, MAXFLOW - 1);
+ meson_free_chanlist(mc, mc->flow_cnt - 1);

clk_disable_unprepare(mc->busclk);
}
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 1013a666c932..79177cfa8b88 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -22,8 +22,6 @@
#define MESON_OPMODE_ECB 0
#define MESON_OPMODE_CBC 1

-#define MAXFLOW 2
-
#define MAXDESC 64

#define DESC_LAST BIT(18)
@@ -62,6 +60,7 @@ struct meson_desc {
* @keylen: keylen for this flow operation
* @complete: completion for the current task on this flow
* @status: set to 1 by interrupt if task is done
+ * @irq: IRQ number for amlogic-crypto
* @t_phy: Physical address of task
* @tl: pointer to the current ce_task for this flow
* @stat_req: number of request done by this flow
@@ -70,6 +69,7 @@ struct meson_flow {
struct crypto_engine *engine;
struct completion complete;
int status;
+ int irq;
unsigned int keylen;
dma_addr_t t_phy;
struct meson_desc *tl;
@@ -85,7 +85,7 @@ struct meson_flow {
* @dev: the platform device
* @chanlist: array of all flow
* @flow: flow to use in next request
- * @irqs: IRQ numbers for amlogic-crypto
+ * @flow_cnt: flow count for amlogic-crypto
* @dbgfs_dir: Debugfs dentry for statistic directory
* @dbgfs_stats: Debugfs dentry for statistic counters
*/
@@ -95,7 +95,7 @@ struct meson_dev {
struct device *dev;
struct meson_flow *chanlist;
atomic_t flow;
- int irqs[MAXFLOW];
+ int flow_cnt;
#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
struct dentry *dbgfs_dir;
#endif
--
2.34.1


2024-02-12 13:58:09

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 05/20] drivers: crypto: meson: move get_engine_number()

Move get_engine_number() function from cipher.c to core.c

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 9 ++-------
drivers/crypto/amlogic/amlogic-gxl-core.c | 5 +++++
drivers/crypto/amlogic/amlogic-gxl.h | 2 ++
3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 1fe916b0a138..18e9e2d39b1f 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -17,11 +17,6 @@
#include <crypto/internal/skcipher.h>
#include "amlogic-gxl.h"

-static int get_engine_number(struct meson_dev *mc)
-{
- return atomic_inc_return(&mc->flow) % mc->flow_cnt;
-}
-
static bool meson_cipher_need_fallback(struct skcipher_request *areq)
{
struct scatterlist *src_sg = areq->src;
@@ -282,7 +277,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
rctx->op_dir = MESON_DECRYPT;
if (meson_cipher_need_fallback(areq))
return meson_cipher_do_fallback(areq);
- e = get_engine_number(op->mc);
+ e = meson_get_engine_number(op->mc);
engine = op->mc->chanlist[e].engine;
rctx->flow = e;

@@ -300,7 +295,7 @@ int meson_skencrypt(struct skcipher_request *areq)
rctx->op_dir = MESON_ENCRYPT;
if (meson_cipher_need_fallback(areq))
return meson_cipher_do_fallback(areq);
- e = get_engine_number(op->mc);
+ e = meson_get_engine_number(op->mc);
engine = op->mc->chanlist[e].engine;
rctx->flow = e;

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 372c30f72072..51291fdcf8b6 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -23,6 +23,11 @@

#include "amlogic-gxl.h"

+int meson_get_engine_number(struct meson_dev *mc)
+{
+ return atomic_inc_return(&mc->flow) % mc->flow_cnt;
+}
+
void meson_dma_start(struct meson_dev *mc, int flow)
{
u32 offset = (mc->pdata->descs_reg + flow) << 2;
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 59fc6a67e0a9..5f5e3115fcdf 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -163,6 +163,8 @@ struct meson_alg_template {
#endif
};

+int meson_get_engine_number(struct meson_dev *mc);
+
void meson_dma_start(struct meson_dev *mc, int flow);

int meson_enqueue(struct crypto_async_request *areq, u32 type);
--
2.34.1


2024-02-12 13:58:40

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 06/20] drivers: crypto: meson: drop status field from meson_flow

This field is used only to check for timeout. But there is more
convenient way to achive the same goal.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 13 +++++++++----
drivers/crypto/amlogic/amlogic-gxl-core.c | 1 -
drivers/crypto/amlogic/amlogic-gxl.h | 2 --
3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index 18e9e2d39b1f..dc0b100c5de2 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -219,13 +219,18 @@ static int meson_cipher(struct skcipher_request *areq)
}

reinit_completion(&mc->chanlist[flow].complete);
- mc->chanlist[flow].status = 0;
meson_dma_start(mc, flow);
- wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
- msecs_to_jiffies(500));
- if (mc->chanlist[flow].status == 0) {
+
+ err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
+ msecs_to_jiffies(500));
+ if (err == 0) {
dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
err = -EINVAL;
+ } else if (err < 0) {
+ dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
+ } else {
+ /* No error */
+ err = 0;
}

dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 51291fdcf8b6..f7c60ebffbc3 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -54,7 +54,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
for (flow = 0; flow < mc->flow_cnt; flow++) {
if (mc->chanlist[flow].irq == irq) {
if (meson_dma_ready(mc, flow)) {
- mc->chanlist[flow].status = 1;
complete(&mc->chanlist[flow].complete);
return IRQ_HANDLED;
}
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 5f5e3115fcdf..e27908992ae3 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -59,7 +59,6 @@ struct meson_desc {
* @engine: ptr to the crypto_engine for this flow
* @keylen: keylen for this flow operation
* @complete: completion for the current task on this flow
- * @status: set to 1 by interrupt if task is done
* @irq: IRQ number for amlogic-crypto
* @t_phy: Physical address of task
* @tl: pointer to the current ce_task for this flow
@@ -68,7 +67,6 @@ struct meson_desc {
struct meson_flow {
struct crypto_engine *engine;
struct completion complete;
- int status;
int irq;
unsigned int keylen;
dma_addr_t t_phy;
--
2.34.1


2024-02-12 13:58:54

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 03/20] drivers: crypto: meson: make CLK controller optional

Amlogic crypto IP doesn't take a clock input on some
SoCs: AXG / A1 / S4 / G12. So make it optional.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-core.c | 21 ++++++++-------------
drivers/crypto/amlogic/amlogic-gxl.h | 2 ++
2 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 4d1b1d5b7a54..54113c524ec5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -250,6 +250,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
static const struct meson_pdata meson_gxl_pdata = {
.descs_reg = 0x0,
.status_reg = 0x4,
+ .need_clk = true,
};

static const struct of_device_id meson_crypto_of_match_table[] = {
@@ -285,17 +286,14 @@ static int meson_crypto_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Cannot request MMIO err=%d\n", err);
return err;
}
- mc->busclk = devm_clk_get(&pdev->dev, "blkmv");
- if (IS_ERR(mc->busclk)) {
- err = PTR_ERR(mc->busclk);
- dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err);
- return err;
- }

- err = clk_prepare_enable(mc->busclk);
- if (err != 0) {
- dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
- return err;
+ if (mc->pdata->need_clk) {
+ mc->busclk = devm_clk_get_enabled(&pdev->dev, "blkmv");
+ if (IS_ERR(mc->busclk)) {
+ err = PTR_ERR(mc->busclk);
+ dev_err(&pdev->dev, "Cannot get and enable core clock err=%d\n", err);
+ return err;
+ }
}

err = meson_allocate_chanlist(mc);
@@ -322,7 +320,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
meson_unregister_algs(mc);
error_flow:
meson_free_chanlist(mc, mc->flow_cnt - 1);
- clk_disable_unprepare(mc->busclk);
return err;
}

@@ -337,8 +334,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
meson_unregister_algs(mc);

meson_free_chanlist(mc, mc->flow_cnt - 1);
-
- clk_disable_unprepare(mc->busclk);
}

static struct platform_driver meson_crypto_driver = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index 9ad75da214ff..a36b9bac63a0 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -82,10 +82,12 @@ struct meson_flow {
* struct meson_pdata - SoC series dependent data.
* @reg_descs: offset to descriptors register
* @reg_status: offset to status register
+ * @need_clk: clock input is needed
*/
struct meson_pdata {
u32 descs_reg;
u32 status_reg;
+ bool need_clk;
};

/*
--
2.34.1


2024-02-12 13:59:20

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 07/20] drivers: crypto: meson: move algs definition and cipher API to cipher.c

Because that is proper place for them. In particular,
it takes less of exported symbol between compiling entities.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 98 +++++++++++++++--
drivers/crypto/amlogic/amlogic-gxl-core.c | 110 ++++----------------
drivers/crypto/amlogic/amlogic-gxl.h | 14 +--
3 files changed, 119 insertions(+), 103 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index dc0b100c5de2..bc3092a8a2c2 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -271,7 +271,7 @@ int meson_handle_cipher_request(struct crypto_engine *engine, void *areq)
return 0;
}

-int meson_skdecrypt(struct skcipher_request *areq)
+static int meson_skdecrypt(struct skcipher_request *areq)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
@@ -289,7 +289,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
return crypto_transfer_skcipher_request_to_engine(engine, areq);
}

-int meson_skencrypt(struct skcipher_request *areq)
+static int meson_skencrypt(struct skcipher_request *areq)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
@@ -307,7 +307,7 @@ int meson_skencrypt(struct skcipher_request *areq)
return crypto_transfer_skcipher_request_to_engine(engine, areq);
}

-int meson_cipher_init(struct crypto_tfm *tfm)
+static int meson_cipher_init(struct crypto_tfm *tfm)
{
struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
struct meson_alg_template *algt;
@@ -333,7 +333,7 @@ int meson_cipher_init(struct crypto_tfm *tfm)
return 0;
}

-void meson_cipher_exit(struct crypto_tfm *tfm)
+static void meson_cipher_exit(struct crypto_tfm *tfm)
{
struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);

@@ -341,8 +341,8 @@ void meson_cipher_exit(struct crypto_tfm *tfm)
crypto_free_skcipher(op->fallback_tfm);
}

-int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
- unsigned int keylen)
+static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen)
{
struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
struct meson_dev *mc = op->mc;
@@ -369,3 +369,89 @@ int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,

return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
}
+
+static struct meson_alg_template algs[] = {
+{
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
+ .blockmode = MESON_OPMODE_CBC,
+ .alg.skcipher.base = {
+ .base = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-gxl",
+ .cra_priority = 400,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+ CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 0xf,
+ .cra_init = meson_cipher_init,
+ .cra_exit = meson_cipher_exit,
+ },
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = meson_aes_setkey,
+ .encrypt = meson_skencrypt,
+ .decrypt = meson_skdecrypt,
+ },
+ .alg.skcipher.op = {
+ .do_one_request = meson_handle_cipher_request,
+ },
+},
+{
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
+ .blockmode = MESON_OPMODE_ECB,
+ .alg.skcipher.base = {
+ .base = {
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ecb-aes-gxl",
+ .cra_priority = 400,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+ CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+ CRYPTO_ALG_NEED_FALLBACK,
+ .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 0xf,
+ .cra_init = meson_cipher_init,
+ .cra_exit = meson_cipher_exit,
+ },
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = meson_aes_setkey,
+ .encrypt = meson_skencrypt,
+ .decrypt = meson_skdecrypt,
+ },
+ .alg.skcipher.op = {
+ .do_one_request = meson_handle_cipher_request,
+ },
+},
+};
+
+int meson_cipher_register(struct meson_dev *mc)
+{
+ return meson_register_algs(mc, algs, ARRAY_SIZE(algs));
+}
+
+void meson_cipher_unregister(struct meson_dev *mc)
+{
+ meson_unregister_algs(mc, algs, ARRAY_SIZE(algs));
+}
+
+void meson_cipher_debugfs_show(struct seq_file *seq, void *v)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(algs); i++) {
+ seq_printf(seq, "%s %s %lu %lu\n",
+ algs[i].alg.skcipher.base.base.cra_driver_name,
+ algs[i].alg.skcipher.base.base.cra_name,
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ algs[i].stat_req, algs[i].stat_fb);
+#else
+ 0ul, 0ul);
+#endif
+ }
+}
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f7c60ebffbc3..22ff2768b5e5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -65,66 +65,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}

-static struct meson_alg_template mc_algs[] = {
-{
- .type = CRYPTO_ALG_TYPE_SKCIPHER,
- .blockmode = MESON_OPMODE_CBC,
- .alg.skcipher.base = {
- .base = {
- .cra_name = "cbc(aes)",
- .cra_driver_name = "cbc-aes-gxl",
- .cra_priority = 400,
- .cra_blocksize = AES_BLOCK_SIZE,
- .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
- CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
- CRYPTO_ALG_NEED_FALLBACK,
- .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
- .cra_module = THIS_MODULE,
- .cra_alignmask = 0xf,
- .cra_init = meson_cipher_init,
- .cra_exit = meson_cipher_exit,
- },
- .min_keysize = AES_MIN_KEY_SIZE,
- .max_keysize = AES_MAX_KEY_SIZE,
- .ivsize = AES_BLOCK_SIZE,
- .setkey = meson_aes_setkey,
- .encrypt = meson_skencrypt,
- .decrypt = meson_skdecrypt,
- },
- .alg.skcipher.op = {
- .do_one_request = meson_handle_cipher_request,
- },
-},
-{
- .type = CRYPTO_ALG_TYPE_SKCIPHER,
- .blockmode = MESON_OPMODE_ECB,
- .alg.skcipher.base = {
- .base = {
- .cra_name = "ecb(aes)",
- .cra_driver_name = "ecb-aes-gxl",
- .cra_priority = 400,
- .cra_blocksize = AES_BLOCK_SIZE,
- .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
- CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
- CRYPTO_ALG_NEED_FALLBACK,
- .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
- .cra_module = THIS_MODULE,
- .cra_alignmask = 0xf,
- .cra_init = meson_cipher_init,
- .cra_exit = meson_cipher_exit,
- },
- .min_keysize = AES_MIN_KEY_SIZE,
- .max_keysize = AES_MAX_KEY_SIZE,
- .setkey = meson_aes_setkey,
- .encrypt = meson_skencrypt,
- .decrypt = meson_skdecrypt,
- },
- .alg.skcipher.op = {
- .do_one_request = meson_handle_cipher_request,
- },
-},
-};
-
static int meson_debugfs_show(struct seq_file *seq, void *v)
{
struct meson_dev *mc __maybe_unused = seq->private;
@@ -138,20 +78,8 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
0ul);
#endif

- for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
- switch (mc_algs[i].type) {
- case CRYPTO_ALG_TYPE_SKCIPHER:
- seq_printf(seq, "%s %s %lu %lu\n",
- mc_algs[i].alg.skcipher.base.base.cra_driver_name,
- mc_algs[i].alg.skcipher.base.base.cra_name,
-#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
- mc_algs[i].stat_req, mc_algs[i].stat_fb);
-#else
- 0ul, 0ul);
-#endif
- break;
- }
- }
+ meson_cipher_debugfs_show(seq, v);
+
return 0;
}
DEFINE_SHOW_ATTRIBUTE(meson_debugfs);
@@ -228,38 +156,40 @@ static int meson_allocate_chanlist(struct meson_dev *mc)
return err;
}

-static int meson_register_algs(struct meson_dev *mc)
+int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+ unsigned int count)
{
int err, i;

- for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
- mc_algs[i].mc = mc;
- switch (mc_algs[i].type) {
+ for (i = 0; i < count; i++) {
+ switch (algs[i].type) {
case CRYPTO_ALG_TYPE_SKCIPHER:
- err = crypto_engine_register_skcipher(&mc_algs[i].alg.skcipher);
+ err = crypto_engine_register_skcipher(&algs[i].alg.skcipher);
if (err) {
dev_err(mc->dev, "Fail to register %s\n",
- mc_algs[i].alg.skcipher.base.base.cra_name);
- mc_algs[i].mc = NULL;
+ algs[i].alg.skcipher.base.base.cra_name);
+ meson_unregister_algs(mc, algs, count);
return err;
}
break;
}
+ algs[i].mc = mc;
}

return 0;
}

-static void meson_unregister_algs(struct meson_dev *mc)
+void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+ unsigned int count)
{
int i;

- for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
- if (!mc_algs[i].mc)
+ for (i = 0; i < count; i++) {
+ if (!algs[i].mc)
continue;
- switch (mc_algs[i].type) {
+ switch (algs[i].type) {
case CRYPTO_ALG_TYPE_SKCIPHER:
- crypto_engine_unregister_skcipher(&mc_algs[i].alg.skcipher);
+ crypto_engine_unregister_skcipher(&algs[i].alg.skcipher);
break;
}
}
@@ -318,9 +248,9 @@ static int meson_crypto_probe(struct platform_device *pdev)
if (err)
goto error_flow;

- err = meson_register_algs(mc);
+ err = meson_cipher_register(mc);
if (err)
- goto error_alg;
+ goto error_flow;

if (IS_ENABLED(CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG)) {
struct dentry *dbgfs_dir;
@@ -334,8 +264,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
}

return 0;
-error_alg:
- meson_unregister_algs(mc);
error_flow:
meson_free_chanlist(mc, mc->flow_cnt - 1);
return err;
@@ -349,7 +277,7 @@ static void meson_crypto_remove(struct platform_device *pdev)
debugfs_remove_recursive(mc->dbgfs_dir);
#endif

- meson_unregister_algs(mc);
+ meson_cipher_unregister(mc);

meson_free_chanlist(mc, mc->flow_cnt - 1);
}
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index e27908992ae3..0a03e8144977 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -167,10 +167,12 @@ void meson_dma_start(struct meson_dev *mc, int flow);

int meson_enqueue(struct crypto_async_request *areq, u32 type);

-int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
- unsigned int keylen);
-int meson_cipher_init(struct crypto_tfm *tfm);
-void meson_cipher_exit(struct crypto_tfm *tfm);
-int meson_skdecrypt(struct skcipher_request *areq);
-int meson_skencrypt(struct skcipher_request *areq);
+int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+ unsigned int count);
+void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
+ unsigned int count);
+
+int meson_cipher_register(struct meson_dev *mc);
+void meson_cipher_unregister(struct meson_dev *mc);
+void meson_cipher_debugfs_show(struct seq_file *seq, void *v);
int meson_handle_cipher_request(struct crypto_engine *engine, void *areq);
--
2.34.1


2024-02-12 14:01:06

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 14/20] drivers: crypto: meson: add support for G12-series

This platform data also can be used for A1 and S4 as fallback.
Tested via tcrypt module and with custom tests.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-core.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 429c3474028b..2ffe5994b353 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -218,11 +218,31 @@ static const struct meson_pdata meson_gxl_pdata = {
.support_192bit_key = true,
};

+static const struct meson_pdata meson_g12a_pdata = {
+ .descs_reg = 0x0,
+ .status_reg = 0x8,
+ .need_clk = false,
+ .setup_desc_cnt = 1,
+ .support_192bit_key = false,
+};
+
static const struct of_device_id meson_crypto_of_match_table[] = {
{
.compatible = "amlogic,gxl-crypto",
.data = &meson_gxl_pdata,
},
+ {
+ .compatible = "amlogic,g12a-crypto",
+ .data = &meson_g12a_pdata,
+ },
+ {
+ .compatible = "amlogic,a1-crypto",
+ .data = &meson_g12a_pdata,
+ },
+ {
+ .compatible = "amlogic,s4-crypto",
+ .data = &meson_g12a_pdata,
+ },
{},
};
MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
--
2.34.1


2024-02-12 14:01:21

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 11/20] drivers: crypto: meson: introduce hasher

Introduce support for SHA1/SHA224/SHA256 hash algos.
Tested via tcrypt and custom tests.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/Makefile | 2 +-
drivers/crypto/amlogic/amlogic-gxl-core.c | 24 +-
drivers/crypto/amlogic/amlogic-gxl-hasher.c | 452 ++++++++++++++++++++
drivers/crypto/amlogic/amlogic-gxl.h | 49 +++
4 files changed, 525 insertions(+), 2 deletions(-)
create mode 100644 drivers/crypto/amlogic/amlogic-gxl-hasher.c

diff --git a/drivers/crypto/amlogic/Makefile b/drivers/crypto/amlogic/Makefile
index 39057e62c13e..4b6b388b7880 100644
--- a/drivers/crypto/amlogic/Makefile
+++ b/drivers/crypto/amlogic/Makefile
@@ -1,2 +1,2 @@
obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic-gxl-crypto.o
-amlogic-gxl-crypto-y := amlogic-gxl-core.o amlogic-gxl-cipher.o
+amlogic-gxl-crypto-y := amlogic-gxl-core.o amlogic-gxl-cipher.o amlogic-gxl-hasher.o
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index f93e14f5717d..f3b5e004b3a5 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -20,6 +20,9 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/internal/hash.h>
+#include <linux/dma-mapping.h>

#include "amlogic-gxl.h"

@@ -172,6 +175,15 @@ int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
return err;
}
break;
+ case CRYPTO_ALG_TYPE_AHASH:
+ err = crypto_engine_register_ahash(&algs[i].alg.ahash);
+ if (err) {
+ dev_err(mc->dev, "Fail to register %s\n",
+ algs[i].alg.ahash.base.halg.base.cra_name);
+ meson_unregister_algs(mc, algs, count);
+ return err;
+ }
+ break;
}
algs[i].mc = mc;
}
@@ -191,6 +203,9 @@ void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs
case CRYPTO_ALG_TYPE_SKCIPHER:
crypto_engine_unregister_skcipher(&algs[i].alg.skcipher);
break;
+ case CRYPTO_ALG_TYPE_AHASH:
+ crypto_engine_unregister_ahash(&algs[i].alg.ahash);
+ break;
}
}
}
@@ -258,13 +273,20 @@ static int meson_crypto_probe(struct platform_device *pdev)

dbgfs_dir = debugfs_create_dir("gxl-crypto", NULL);
debugfs_create_file("stats", 0444, dbgfs_dir, mc, &meson_debugfs_fops);
-
#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
mc->dbgfs_dir = dbgfs_dir;
#endif
}

+ err = meson_hasher_register(mc);
+ if (err)
+ goto error_hasher;
+
return 0;
+
+error_hasher:
+ meson_cipher_unregister(mc);
+
error_flow:
meson_free_chanlist(mc, mc->flow_cnt - 1);
return err;
diff --git a/drivers/crypto/amlogic/amlogic-gxl-hasher.c b/drivers/crypto/amlogic/amlogic-gxl-hasher.c
new file mode 100644
index 000000000000..04f85cd4d97f
--- /dev/null
+++ b/drivers/crypto/amlogic/amlogic-gxl-hasher.c
@@ -0,0 +1,452 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Hardware asynchronous hasher for Amlogic SoC's.
+ *
+ * Copyright (c) 2023, SaluteDevices. All Rights Reserved.
+ *
+ * Author: Alexey Romanov <[email protected]>
+ */
+
+#include <linux/crypto.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <crypto/internal/hash.h>
+#include <crypto/sha1.h>
+#include <crypto/sha2.h>
+
+#include "amlogic-gxl.h"
+
+static int meson_sha_init(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+
+ memset(rctx, 0, sizeof(struct meson_hasher_req_ctx));
+
+ rctx->flow = meson_get_engine_number(tctx->mc);
+ rctx->begin_req = true;
+
+ return 0;
+}
+
+static int meson_sha_update(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+ struct crypto_engine *engine = tctx->mc->chanlist[rctx->flow].engine;
+
+ return crypto_transfer_hash_request_to_engine(engine, req);
+}
+
+static int meson_sha_final(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+ struct crypto_engine *engine = tctx->mc->chanlist[rctx->flow].engine;
+
+ rctx->final_req = true;
+
+ return crypto_transfer_hash_request_to_engine(engine, req);
+}
+
+static int meson_hasher_req_map(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_dev *mc = tctx->mc;
+ int ret;
+
+ if (!req->nbytes)
+ return 0;
+
+ ret = dma_map_sg(mc->dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
+ if (!ret) {
+ dev_err(mc->dev, "Cannot DMA MAP request data\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void meson_hasher_req_unmap(struct ahash_request *req)
+{
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_dev *mc = tctx->mc;
+
+ if (!req->nbytes)
+ return;
+
+ dma_unmap_sg(mc->dev, req->src, sg_nents(req->src), DMA_TO_DEVICE);
+}
+
+struct hasher_ctx {
+ struct crypto_async_request *areq;
+
+ unsigned int tloffset;
+ unsigned int nbytes;
+ unsigned int todo;
+
+ dma_addr_t state_addr;
+ dma_addr_t src_addr;
+ unsigned int src_offset;
+ struct scatterlist *src_sg;
+};
+
+static bool meson_final(struct hasher_ctx *ctx)
+{
+ struct ahash_request *req = ahash_request_cast(ctx->areq);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+
+ return !ctx->nbytes && rctx->final_req;
+}
+
+static int meson_fill_partial_buffer(struct hasher_ctx *ctx, unsigned int len)
+{
+ struct ahash_request *req = ahash_request_cast(ctx->areq);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+ struct meson_dev *mc = tctx->mc;
+ unsigned int blocksize = crypto_ahash_blocksize(tfm);
+ unsigned int copy;
+
+ if (len) {
+ copy = min(blocksize - rctx->partial_size, len);
+ memcpy(rctx->partial + rctx->partial_size,
+ sg_virt(ctx->src_sg) + ctx->src_offset, copy);
+
+ rctx->partial_size += copy;
+ ctx->nbytes -= copy;
+ ctx->src_offset += copy;
+ }
+
+ if (rctx->partial_size == blocksize || meson_final(ctx)) {
+ rctx->partial_addr = dma_map_single(mc->dev,
+ rctx->partial,
+ rctx->partial_size,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(mc->dev, rctx->partial_addr)) {
+ dev_err(mc->dev, "Cannot DMA MAP SHA partial buffer\n");
+ return -ENOMEM;
+ }
+
+ rctx->partial_mapped = true;
+ ctx->todo = rctx->partial_size;
+ ctx->src_addr = rctx->partial_addr;
+ }
+
+ return 0;
+}
+
+static unsigned int meson_setup_data_descs(struct hasher_ctx *ctx)
+{
+ struct ahash_request *req = ahash_request_cast(ctx->areq);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_dev *mc = tctx->mc;
+ struct meson_flow *flow = &mc->chanlist[rctx->flow];
+ struct hash_alg_common *alg = crypto_hash_alg_common(tfm);
+ struct meson_alg_template *algt = container_of(alg,
+ struct meson_alg_template, alg.ahash.base.halg);
+ struct meson_desc *desc = &flow->tl[ctx->tloffset];
+ u32 v;
+
+ ctx->tloffset++;
+
+ v = DESC_OWN | DESC_ENCRYPTION | DESC_OPMODE_SHA |
+ ctx->todo | algt->blockmode;
+ if (rctx->begin_req) {
+ rctx->begin_req = false;
+ v |= DESC_BEGIN;
+ }
+
+ if (!ctx->nbytes && rctx->final_req) {
+ rctx->final_req = false;
+ v |= DESC_END;
+ }
+
+ if (!ctx->nbytes || ctx->tloffset == MAXDESC || rctx->partial_mapped)
+ v |= DESC_LAST;
+
+ desc->t_src = cpu_to_le32(ctx->src_addr);
+ desc->t_dst = cpu_to_le32(ctx->state_addr);
+ desc->t_status = cpu_to_le32(v);
+
+ return v & DESC_LAST;
+}
+
+static int meson_kick_hardware(struct hasher_ctx *ctx)
+{
+ struct ahash_request *req = ahash_request_cast(ctx->areq);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_dev *mc = tctx->mc;
+ struct meson_flow *flow = &mc->chanlist[rctx->flow];
+ int ret;
+
+ reinit_completion(&flow->complete);
+ meson_dma_start(mc, rctx->flow);
+
+ ret = wait_for_completion_timeout(&flow->complete,
+ msecs_to_jiffies(500));
+ if (ret == 0) {
+ dev_err(mc->dev, "DMA timeout for flow %d\n", rctx->flow);
+ return -EINVAL;
+ } else if (ret < 0) {
+ dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (rctx->partial_mapped) {
+ dma_unmap_single(mc->dev, rctx->partial_addr,
+ rctx->partial_size,
+ DMA_TO_DEVICE);
+ rctx->partial_size = 0;
+ rctx->partial_mapped = false;
+ }
+
+ ctx->tloffset = 0;
+
+ return 0;
+}
+
+static void meson_setup_state_descs(struct hasher_ctx *ctx)
+{
+ struct ahash_request *req = ahash_request_cast(ctx->areq);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_dev *mc = tctx->mc;
+ struct meson_desc *desc;
+ int i;
+
+ if (ctx->tloffset || rctx->begin_req)
+ return;
+
+ for (i = 0; i < mc->pdata->setup_desc_cnt; i++) {
+ int offset = i * 16;
+
+ desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
+ desc->t_src = cpu_to_le32(ctx->state_addr + offset);
+ desc->t_dst = cpu_to_le32(offset);
+ desc->t_status = cpu_to_le32(MESON_SHA_BUFFER_SIZE |
+ DESC_MODE_KEY | DESC_OWN);
+
+ ctx->tloffset++;
+ }
+}
+
+static int meson_hasher_do_one_request(struct crypto_engine *engine, void *areq)
+{
+ struct ahash_request *req = ahash_request_cast(areq);
+ struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
+ struct meson_hasher_tfm_ctx *tctx = crypto_ahash_ctx(tfm);
+ struct meson_hasher_req_ctx *rctx = ahash_request_ctx(req);
+ struct meson_dev *mc = tctx->mc;
+ struct hasher_ctx ctx = {
+ .tloffset = 0,
+ .src_offset = 0,
+ .nbytes = req->nbytes,
+ .src_sg = req->src,
+ .areq = areq,
+ };
+ unsigned int blocksize = crypto_ahash_blocksize(tfm);
+ unsigned int digest_size = crypto_ahash_digestsize(tfm);
+ bool final_req = rctx->final_req;
+ int ret;
+
+ ctx.state_addr = dma_map_single(mc->dev, rctx->state,
+ sizeof(rctx->state), DMA_BIDIRECTIONAL);
+ ret = dma_mapping_error(mc->dev, ctx.state_addr);
+ if (ret) {
+ dev_err(mc->dev, "Cannot DMA MAP SHA state buffer");
+ goto fail_map_single;
+ }
+
+ ret = meson_hasher_req_map(req);
+ if (ret)
+ goto fail_map_req;
+
+ for (;;) {
+ unsigned int len = ctx.src_sg ?
+ min(sg_dma_len(ctx.src_sg) - ctx.src_offset, ctx.nbytes) : 0;
+
+ ctx.src_addr = 0;
+ ctx.todo = 0;
+
+ if (!rctx->final_req && !ctx.nbytes)
+ break;
+
+ meson_setup_state_descs(&ctx);
+
+ if (rctx->partial_size && rctx->partial_size < blocksize) {
+ ret = meson_fill_partial_buffer(&ctx, len);
+ if (ret)
+ goto fail;
+ } else if (len && len < blocksize) {
+ memcpy(rctx->partial, sg_virt(ctx.src_sg) + ctx.src_offset, len);
+
+ rctx->partial_size = len;
+ ctx.nbytes -= len;
+ ctx.src_offset += len;
+ } else if (len) {
+ ctx.src_addr = sg_dma_address(ctx.src_sg) + ctx.src_offset;
+ ctx.todo = min(rounddown(DESC_MAXLEN, blocksize),
+ rounddown(len, blocksize));
+ ctx.nbytes -= ctx.todo;
+ ctx.src_offset += ctx.todo;
+ }
+
+ if (ctx.src_sg && ctx.src_offset == sg_dma_len(ctx.src_sg)) {
+ ctx.src_offset = 0;
+ ctx.src_sg = sg_next(ctx.src_sg);
+ }
+
+ if (!ctx.todo && ctx.nbytes)
+ continue;
+
+ if (!ctx.todo && !rctx->final_req && !ctx.tloffset)
+ continue;
+
+ if (meson_setup_data_descs(&ctx)) {
+ ret = meson_kick_hardware(&ctx);
+ if (ret)
+ goto fail;
+ }
+ }
+
+fail:
+ meson_hasher_req_unmap(req);
+
+fail_map_req:
+ dma_unmap_single(mc->dev, ctx.state_addr, sizeof(rctx->state),
+ DMA_BIDIRECTIONAL);
+
+fail_map_single:
+ if (final_req && ret == 0)
+ memcpy(req->result, rctx->state, digest_size);
+
+ local_bh_disable();
+ crypto_finalize_hash_request(engine, req, ret);
+ local_bh_enable();
+
+ return ret;
+}
+
+static int meson_hasher_init(struct crypto_tfm *tfm)
+{
+ struct meson_hasher_tfm_ctx *tctx = crypto_tfm_ctx(tfm);
+ struct crypto_ahash *atfm = __crypto_ahash_cast(tfm);
+ struct hash_alg_common *alg = crypto_hash_alg_common(atfm);
+ struct meson_alg_template *algt = container_of(alg,
+ struct meson_alg_template, alg.ahash.base.halg);
+
+ crypto_ahash_set_reqsize(atfm, crypto_ahash_statesize(atfm));
+
+ memset(tctx, 0, sizeof(struct meson_hasher_tfm_ctx));
+
+ tctx->mc = algt->mc;
+
+ return 0;
+}
+
+static struct meson_alg_template mc_algs[] = {
+{
+ .type = CRYPTO_ALG_TYPE_AHASH,
+ .blockmode = DESC_MODE_SHA1,
+ .alg.ahash.base = {
+ .halg = {
+ .base = {
+ .cra_name = "sha1",
+ .cra_driver_name = "sha1-gxl",
+ .cra_priority = 400,
+ .cra_blocksize = SHA1_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_ASYNC,
+ .cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 0,
+ .cra_init = meson_hasher_init,
+ },
+ .digestsize = SHA1_DIGEST_SIZE,
+ .statesize = sizeof(struct meson_hasher_req_ctx),
+ },
+ .init = meson_sha_init,
+ .update = meson_sha_update,
+ .final = meson_sha_final,
+ },
+ .alg.ahash.op = {
+ .do_one_request = meson_hasher_do_one_request,
+ },
+},
+{
+ .type = CRYPTO_ALG_TYPE_AHASH,
+ .blockmode = DESC_MODE_SHA224,
+ .alg.ahash.base = {
+ .halg = {
+ .base = {
+ .cra_name = "sha224",
+ .cra_driver_name = "sha224-gxl",
+ .cra_priority = 400,
+ .cra_blocksize = SHA224_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_ASYNC,
+ .cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 0,
+ .cra_init = meson_hasher_init,
+ },
+ .digestsize = SHA224_DIGEST_SIZE,
+ .statesize = sizeof(struct meson_hasher_req_ctx),
+ },
+ .init = meson_sha_init,
+ .update = meson_sha_update,
+ .final = meson_sha_final,
+ },
+ .alg.ahash.op = {
+ .do_one_request = meson_hasher_do_one_request,
+ },
+},
+{
+ .type = CRYPTO_ALG_TYPE_AHASH,
+ .blockmode = DESC_MODE_SHA256,
+ .alg.ahash.base = {
+ .halg = {
+ .base = {
+ .cra_name = "sha256",
+ .cra_driver_name = "sha256-gxl",
+ .cra_priority = 400,
+ .cra_blocksize = SHA256_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_ASYNC,
+ .cra_ctxsize = sizeof(struct meson_hasher_tfm_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 0,
+ .cra_init = meson_hasher_init,
+ },
+ .digestsize = SHA256_DIGEST_SIZE,
+ .statesize = sizeof(struct meson_hasher_req_ctx),
+ },
+ .init = meson_sha_init,
+ .update = meson_sha_update,
+ .final = meson_sha_final,
+ },
+ .alg.ahash.op = {
+ .do_one_request = meson_hasher_do_one_request,
+ },
+},
+};
+
+int meson_hasher_register(struct meson_dev *mc)
+{
+ return meson_register_algs(mc, mc_algs, ARRAY_SIZE(mc_algs));
+}
+
+void meson_hasher_unregister(struct meson_dev *mc)
+{
+ meson_unregister_algs(mc, mc_algs, ARRAY_SIZE(mc_algs));
+}
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index e1453dd2e9f4..a07b4f6b3bcc 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -5,6 +5,7 @@
* Copyright (C) 2018-2019 Corentin LABBE <[email protected]>
*/
#include <crypto/aes.h>
+#include <crypto/sha2.h>
#include <crypto/engine.h>
#include <crypto/skcipher.h>
#include <linux/debugfs.h>
@@ -23,13 +24,25 @@

#define DESC_OPMODE_ECB (0 << 26)
#define DESC_OPMODE_CBC (1 << 26)
+#define DESC_OPMODE_SHA (0 << 26)

#define DESC_MAXLEN ((1 << 17) - 1)

+#define DESC_MODE_SHA1 (0x5 << 20)
+#define DESC_MODE_SHA224 (0x7 << 20)
+#define DESC_MODE_SHA256 (0x6 << 20)
+
#define DESC_LAST BIT(18)
+#define DESC_BEGIN BIT(24)
+#define DESC_END BIT(25)
#define DESC_ENCRYPTION BIT(28)
#define DESC_OWN BIT(31)

+#define MESON_SHA_BUFFER_SIZE (SHA256_DIGEST_SIZE + 16)
+
+#define MESON_SHA_BEGIN BIT(1)
+#define MESON_SHA_FINAL BIT(2)
+
/*
* struct meson_desc - Descriptor for DMA operations
* Note that without datasheet, some are unknown
@@ -143,6 +156,38 @@ struct meson_cipher_tfm_ctx {
struct crypto_skcipher *fallback_tfm;
};

+/*
+ * struct meson_hasher_req_ctx - context for a hasher request
+ * @state: state data
+ * @partial: partial buffer data. Contains sent data which
+ * size < blocksize
+ * @partial_size: size of the partial buffer
+ * @partial_addr: physical address of partial buffer
+ * @partial_mapped: indicates is partial buffer currently mapped or not
+ * @flags: request flags (for example, is this final req or not)
+ * @flow: the flow to use for this request
+ */
+struct meson_hasher_req_ctx {
+ u8 state[SHA256_DIGEST_SIZE + 16] ____cacheline_aligned;
+ u8 partial[SHA256_BLOCK_SIZE] ____cacheline_aligned;
+ unsigned int partial_size ____cacheline_aligned;
+ dma_addr_t partial_addr;
+ bool partial_mapped;
+
+ bool begin_req;
+ bool final_req;
+ int flow;
+};
+
+/*
+ * struct meson_hasher_tfm_ctx - context for a hasher TFM
+ * @enginectx: crypto_engine used by this TFM
+ * @mc: pointer to the private data of driver handling this TFM
+ */
+struct meson_hasher_tfm_ctx {
+ struct meson_dev *mc;
+};
+
/*
* struct meson_alg_template - crypto_alg template
* @type: the CRYPTO_ALG_TYPE for this template
@@ -157,6 +202,7 @@ struct meson_alg_template {
u32 blockmode;
union {
struct skcipher_engine_alg skcipher;
+ struct ahash_engine_alg ahash;
} alg;
struct meson_dev *mc;
#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
@@ -180,3 +226,6 @@ int meson_cipher_register(struct meson_dev *mc);
void meson_cipher_unregister(struct meson_dev *mc);
void meson_cipher_debugfs_show(struct seq_file *seq, void *v);
int meson_handle_cipher_request(struct crypto_engine *engine, void *areq);
+
+int meson_hasher_register(struct meson_dev *mc);
+void meson_hasher_unregister(struct meson_dev *mc);
--
2.34.1


2024-02-12 14:02:16

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 17/20] arch: arm64: dts: meson: a1: add crypto node

This patch adds a crypto node declaration. With the
Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <[email protected]>
---
arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
index b9fd69112535..6d11e38ca3c0 100644
--- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
@@ -653,6 +653,13 @@ sd_emmc: sd@10000 {
power-domains = <&pwrc PWRC_SD_EMMC_ID>;
status = "disabled";
};
+
+ crypto: crypto@6000 {
+ compatible = "amlogic,a1-crypto", "amlogic,g12a-crypto";
+ reg = <0x0 0x6000 0x0 0x48>;
+ interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>;
+ power-domains = <&pwrc PWRC_DMA_ID>;
+ };
};

usb: usb@fe004400 {
--
2.34.1


2024-02-12 14:02:48

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 15/20] drivers: crypto: meson: add support for AXG-series

Tested via tcrypt module and with custom tests.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-core.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 2ffe5994b353..536ad438f713 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -226,6 +226,14 @@ static const struct meson_pdata meson_g12a_pdata = {
.support_192bit_key = false,
};

+static const struct meson_pdata meson_axg_pdata = {
+ .descs_reg = 0x0,
+ .status_reg = 0x8,
+ .need_clk = false,
+ .setup_desc_cnt = 3,
+ .support_192bit_key = true,
+};
+
static const struct of_device_id meson_crypto_of_match_table[] = {
{
.compatible = "amlogic,gxl-crypto",
@@ -243,6 +251,10 @@ static const struct of_device_id meson_crypto_of_match_table[] = {
.compatible = "amlogic,s4-crypto",
.data = &meson_g12a_pdata,
},
+ {
+ .compatible = "amlogic,axg-crypto",
+ .data = &meson_axg_pdata,
+ },
{},
};
MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
--
2.34.1


2024-02-12 14:03:05

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 19/20] arch: arm64: dts: meson: g12: add crypto node

This patch adds a crypto node declaration for Amlogic G12-series.
With the Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <[email protected]>
---
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index ff68b911b729..f6d7047a579c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1709,6 +1709,12 @@ internal_ephy: ethernet-phy@8 {
};
};
};
+
+ crypto: crypto@3e000 {
+ compatible = "amlogic,g12a-crypto";
+ reg = <0x0 0x3e000 0x0 0x48>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
+ };
};

aobus: bus@ff800000 {
--
2.34.1


2024-02-12 14:03:06

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 20/20] arch: arm64: dts: meson: axg: add crypto node

This patch adds a crypto node declaration. With the
Amlogic crypto driver we can use HW implementation
of SHA1/224/256 and AES algo.

Signed-off-by: Alexey Romanov <[email protected]>
---
arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 6d12b760b90f..b19be72abdd6 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -294,6 +294,12 @@ ethmac: ethernet@ff3f0000 {
status = "disabled";
};

+ crypto: crypto@ff63e000 {
+ compatible = "amlogic,axg-crypto";
+ reg = <0x0 0xff63e000 0x0 0x48>;
+ interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
+ };
+
pcie_phy: phy@ff644000 {
compatible = "amlogic,axg-pcie-phy";
reg = <0x0 0xff644000 0x0 0x1c>;
--
2.34.1


2024-02-12 14:26:03

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 09/20] drivers: crypto: meson: process more than MAXDESCS descriptors

1. The old alhorithm was not designed to process a large
amount of memory, and therefore gave incorrect results.

2. Not all Amlogic SoC's use 3 KEY/IV descriptors.
Add keyiv descriptors count parameter to platform data.

Signed-off-by: Alexey Romanov <[email protected]>
---
drivers/crypto/amlogic/amlogic-gxl-cipher.c | 443 ++++++++++++--------
drivers/crypto/amlogic/amlogic-gxl-core.c | 1 +
drivers/crypto/amlogic/amlogic-gxl.h | 2 +
3 files changed, 281 insertions(+), 165 deletions(-)

diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
index c662c4b86e97..c1b3569a614a 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -17,35 +17,41 @@
#include <crypto/internal/skcipher.h>
#include "amlogic-gxl.h"

-static bool meson_cipher_need_fallback(struct skcipher_request *areq)
+static bool meson_cipher_need_fallback_sg(struct skcipher_request *areq,
+ struct scatterlist *sg)
{
- struct scatterlist *src_sg = areq->src;
- struct scatterlist *dst_sg = areq->dst;
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+ unsigned int blocksize = crypto_skcipher_blocksize(tfm);
+ unsigned int cryptlen = areq->cryptlen;
+
+ while (cryptlen) {
+ unsigned int len = min(cryptlen, sg->length);
+
+ if (!IS_ALIGNED(sg->offset, sizeof(u32)))
+ return true;
+ if (len % blocksize != 0)
+ return true;
+
+ cryptlen -= len;
+ sg = sg_next(sg);
+ }
+
+ return false;
+}

+static bool meson_cipher_need_fallback(struct skcipher_request *areq)
+{
if (areq->cryptlen == 0)
return true;

- if (sg_nents(src_sg) != sg_nents(dst_sg))
+ if (meson_cipher_need_fallback_sg(areq, areq->src))
return true;

- /* KEY/IV descriptors use 3 desc */
- if (sg_nents(src_sg) > MAXDESC - 3 || sg_nents(dst_sg) > MAXDESC - 3)
- return true;
+ if (areq->dst == areq->src)
+ return false;

- while (src_sg && dst_sg) {
- if ((src_sg->length % 16) != 0)
- return true;
- if ((dst_sg->length % 16) != 0)
- return true;
- if (src_sg->length != dst_sg->length)
- return true;
- if (!IS_ALIGNED(src_sg->offset, sizeof(u32)))
- return true;
- if (!IS_ALIGNED(dst_sg->offset, sizeof(u32)))
- return true;
- src_sg = sg_next(src_sg);
- dst_sg = sg_next(dst_sg);
- }
+ if (meson_cipher_need_fallback_sg(areq, areq->dst))
+ return true;

return false;
}
@@ -76,6 +82,212 @@ static int meson_cipher_do_fallback(struct skcipher_request *areq)
return err;
}

+struct cipher_ctx {
+ struct {
+ dma_addr_t addr;
+ unsigned int len;
+ } keyiv;
+
+ struct skcipher_request *areq;
+ struct scatterlist *src_sg;
+ struct scatterlist *dst_sg;
+ void *bkeyiv;
+
+ unsigned int src_offset;
+ unsigned int dst_offset;
+ unsigned int cryptlen;
+ unsigned int tloffset;
+};
+
+static int meson_map_scatterlist(struct skcipher_request *areq, struct meson_dev *mc)
+{
+ int nr_sgs, nr_sgd;
+
+ if (areq->src == areq->dst) {
+ nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
+ DMA_BIDIRECTIONAL);
+ if (!nr_sgs) {
+ dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
+ return -EINVAL;
+ }
+ } else {
+ nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
+ DMA_TO_DEVICE);
+ if (!nr_sgs) {
+ dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
+ return -EINVAL;
+ }
+
+ nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
+ DMA_FROM_DEVICE);
+ if (!nr_sgd) {
+ dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static void meson_unmap_scatterlist(struct skcipher_request *areq, struct meson_dev *mc)
+{
+ if (areq->src == areq->dst) {
+ dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
+ } else {
+ dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
+ dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
+ }
+}
+
+static void meson_setup_keyiv_descs(struct cipher_ctx *ctx)
+{
+ struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct meson_alg_template *algt = container_of(alg,
+ struct meson_alg_template, alg.skcipher.base);
+ struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+ struct meson_dev *mc = op->mc;
+ unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+ unsigned int blockmode = algt->blockmode;
+ int i;
+
+ if (ctx->tloffset)
+ return;
+
+ if (blockmode == DESC_OPMODE_CBC) {
+ memcpy(ctx->bkeyiv + AES_MAX_KEY_SIZE, ctx->areq->iv, ivsize);
+ ctx->keyiv.len = AES_MAX_KEY_SIZE + ivsize;
+ dma_sync_single_for_device(mc->dev, ctx->keyiv.addr,
+ ctx->keyiv.len, DMA_TO_DEVICE);
+ }
+
+ for (i = 0; i < mc->pdata->setup_desc_cnt; i++) {
+ struct meson_desc *desc =
+ &mc->chanlist[rctx->flow].tl[ctx->tloffset];
+ int offset = i * 16;
+
+ desc->t_src = cpu_to_le32(ctx->keyiv.addr + offset);
+ desc->t_dst = cpu_to_le32(offset);
+ desc->t_status = cpu_to_le32(DESC_OWN | DESC_MODE_KEY | ctx->keyiv.len);
+
+ ctx->tloffset++;
+ }
+}
+
+static bool meson_setup_data_descs(struct cipher_ctx *ctx)
+{
+ struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+ struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct meson_alg_template *algt = container_of(alg,
+ struct meson_alg_template,
+ alg.skcipher.base);
+ struct meson_dev *mc = op->mc;
+ struct meson_desc *desc = &mc->chanlist[rctx->flow].tl[ctx->tloffset];
+ unsigned int blocksize = crypto_skcipher_blocksize(tfm);
+ unsigned int blockmode = algt->blockmode;
+ unsigned int maxlen = rounddown(DESC_MAXLEN, blocksize);
+ unsigned int todo;
+ u32 v;
+
+ ctx->tloffset++;
+
+ todo = min(ctx->cryptlen, maxlen);
+ todo = min(todo, ctx->cryptlen);
+ todo = min(todo, sg_dma_len(ctx->src_sg) - ctx->src_offset);
+ todo = min(todo, sg_dma_len(ctx->dst_sg) - ctx->dst_offset);
+
+ desc->t_src = cpu_to_le32(sg_dma_address(ctx->src_sg) + ctx->src_offset);
+ desc->t_dst = cpu_to_le32(sg_dma_address(ctx->dst_sg) + ctx->dst_offset);
+
+ ctx->cryptlen -= todo;
+ ctx->src_offset += todo;
+ ctx->dst_offset += todo;
+
+ v = DESC_OWN | blockmode | op->keymode | todo;
+ if (rctx->op_dir == MESON_ENCRYPT)
+ v |= DESC_ENCRYPTION;
+
+ if (!ctx->cryptlen || ctx->tloffset == MAXDESC)
+ v |= DESC_LAST;
+
+ desc->t_status = cpu_to_le32(v);
+
+ return v & DESC_LAST;
+}
+
+static int meson_kick_hardware(struct cipher_ctx *ctx)
+{
+ struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(ctx->areq);
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(ctx->areq);
+ struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct meson_alg_template *algt = container_of(alg,
+ struct meson_alg_template,
+ alg.skcipher.base);
+ struct meson_dev *mc = op->mc;
+ unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+ unsigned int blockmode = algt->blockmode;
+ enum dma_data_direction new_iv_dir;
+ dma_addr_t new_iv_phys;
+ void *new_iv;
+ int err;
+
+ if (blockmode == DESC_OPMODE_CBC) {
+ struct scatterlist *sg;
+ unsigned int offset;
+
+ if (rctx->op_dir == MESON_ENCRYPT) {
+ sg = ctx->dst_sg;
+ offset = ctx->dst_offset;
+ new_iv_dir = DMA_FROM_DEVICE;
+ } else {
+ sg = ctx->src_sg;
+ offset = ctx->src_offset;
+ new_iv_dir = DMA_TO_DEVICE;
+ }
+
+ if (ctx->areq->src == ctx->areq->dst)
+ new_iv_dir = DMA_BIDIRECTIONAL;
+
+ offset -= ivsize;
+ new_iv = sg_virt(sg) + offset;
+ new_iv_phys = sg_dma_address(sg) + offset;
+ }
+
+ if (blockmode == DESC_OPMODE_CBC &&
+ rctx->op_dir == MESON_DECRYPT) {
+ dma_sync_single_for_cpu(mc->dev, new_iv_phys,
+ ivsize, new_iv_dir);
+ memcpy(ctx->areq->iv, new_iv, ivsize);
+ }
+
+ reinit_completion(&mc->chanlist[rctx->flow].complete);
+ meson_dma_start(mc, rctx->flow);
+ err = wait_for_completion_interruptible_timeout(
+ &mc->chanlist[rctx->flow].complete, msecs_to_jiffies(500));
+ if (err == 0) {
+ dev_err(mc->dev, "DMA timeout for flow %d\n", rctx->flow);
+ return -EINVAL;
+ } else if (err < 0) {
+ dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
+ return err;
+ }
+
+ if (blockmode == DESC_OPMODE_CBC &&
+ rctx->op_dir == MESON_ENCRYPT) {
+ dma_sync_single_for_cpu(mc->dev, new_iv_phys,
+ ivsize, new_iv_dir);
+ memcpy(ctx->areq->iv, new_iv, ivsize);
+ }
+
+ ctx->tloffset = 0;
+
+ return 0;
+}
+
static int meson_cipher(struct skcipher_request *areq)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
@@ -84,176 +296,77 @@ static int meson_cipher(struct skcipher_request *areq)
struct meson_dev *mc = op->mc;
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
struct meson_alg_template *algt;
- int flow = rctx->flow;
- unsigned int todo, eat, len;
- struct scatterlist *src_sg = areq->src;
- struct scatterlist *dst_sg = areq->dst;
- struct meson_desc *desc;
- int nr_sgs, nr_sgd;
- int i, err = 0;
- unsigned int keyivlen, ivsize, offset, tloffset;
- dma_addr_t phykeyiv;
- void *backup_iv = NULL, *bkeyiv;
- u32 v;
-
- algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);
+ struct cipher_ctx ctx = {
+ .areq = areq,
+ .src_offset = 0,
+ .dst_offset = 0,
+ .src_sg = areq->src,
+ .dst_sg = areq->dst,
+ .cryptlen = areq->cryptlen,
+ };
+ int err;

- dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u flow=%d\n", __func__,
+ dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u ctx.flow=%d\n", __func__,
crypto_tfm_alg_name(areq->base.tfm),
areq->cryptlen,
rctx->op_dir, crypto_skcipher_ivsize(tfm),
- op->keylen, flow);
+ op->keylen, rctx->flow);
+
+ algt = container_of(alg, struct meson_alg_template, alg.skcipher.base);

#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
algt->stat_req++;
- mc->chanlist[flow].stat_req++;
+ mc->chanlist[rctx->flow].stat_req++;
#endif

- /*
- * The hardware expect a list of meson_desc structures.
- * The 2 first structures store key
- * The third stores IV
- */
- bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
- if (!bkeyiv)
+ ctx.bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
+ if (!ctx.bkeyiv)
return -ENOMEM;

- memcpy(bkeyiv, op->key, op->keylen);
- keyivlen = op->keylen;
+ memcpy(ctx.bkeyiv, op->key, op->keylen);
+ ctx.keyiv.len = op->keylen;
+ if (ctx.keyiv.len == AES_KEYSIZE_192)
+ ctx.keyiv.len = AES_MAX_KEY_SIZE;

- ivsize = crypto_skcipher_ivsize(tfm);
- if (areq->iv && ivsize > 0) {
- if (ivsize > areq->cryptlen) {
- dev_err(mc->dev, "invalid ivsize=%d vs len=%d\n", ivsize, areq->cryptlen);
- err = -EINVAL;
- goto theend;
- }
- memcpy(bkeyiv + 32, areq->iv, ivsize);
- keyivlen = 48;
- if (rctx->op_dir == MESON_DECRYPT) {
- backup_iv = kzalloc(ivsize, GFP_KERNEL);
- if (!backup_iv) {
- err = -ENOMEM;
- goto theend;
- }
- offset = areq->cryptlen - ivsize;
- scatterwalk_map_and_copy(backup_iv, areq->src, offset,
- ivsize, 0);
- }
- }
- if (keyivlen == AES_KEYSIZE_192)
- keyivlen = AES_MAX_KEY_SIZE;
-
- phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
+ ctx.keyiv.addr = dma_map_single(mc->dev, ctx.bkeyiv, ctx.keyiv.len,
DMA_TO_DEVICE);
- err = dma_mapping_error(mc->dev, phykeyiv);
+ err = dma_mapping_error(mc->dev, ctx.keyiv.addr);
if (err) {
dev_err(mc->dev, "Cannot DMA MAP KEY IV\n");
goto theend;
}

- tloffset = 0;
- eat = 0;
- i = 0;
- while (keyivlen > eat) {
- desc = &mc->chanlist[flow].tl[tloffset];
- memset(desc, 0, sizeof(struct meson_desc));
- todo = min(keyivlen - eat, 16u);
- desc->t_src = cpu_to_le32(phykeyiv + i * 16);
- desc->t_dst = cpu_to_le32(i * 16);
- v = DESC_MODE_KEY | DESC_OWN | 16;
- desc->t_status = cpu_to_le32(v);
-
- eat += todo;
- i++;
- tloffset++;
- }
-
- if (areq->src == areq->dst) {
- nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
- DMA_BIDIRECTIONAL);
- if (!nr_sgs) {
- dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
- err = -EINVAL;
- goto theend;
- }
- nr_sgd = nr_sgs;
- } else {
- nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
- DMA_TO_DEVICE);
- if (!nr_sgs || nr_sgs > MAXDESC - 3) {
- dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
- err = -EINVAL;
- goto theend;
- }
- nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
- DMA_FROM_DEVICE);
- if (!nr_sgd || nr_sgd > MAXDESC - 3) {
- dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
- err = -EINVAL;
- goto theend;
- }
- }
-
- src_sg = areq->src;
- dst_sg = areq->dst;
- len = areq->cryptlen;
- while (src_sg) {
- desc = &mc->chanlist[flow].tl[tloffset];
- memset(desc, 0, sizeof(struct meson_desc));
-
- desc->t_src = cpu_to_le32(sg_dma_address(src_sg));
- desc->t_dst = cpu_to_le32(sg_dma_address(dst_sg));
- todo = min(len, sg_dma_len(src_sg));
- v = op->keymode | DESC_OWN | todo | algt->blockmode;
- if (rctx->op_dir)
- v |= DESC_ENCRYPTION;
- len -= todo;
-
- if (!sg_next(src_sg))
- v |= DESC_LAST;
- desc->t_status = cpu_to_le32(v);
- tloffset++;
- src_sg = sg_next(src_sg);
- dst_sg = sg_next(dst_sg);
- }
+ err = meson_map_scatterlist(areq, mc);
+ if (err)
+ goto theend;

- reinit_completion(&mc->chanlist[flow].complete);
- meson_dma_start(mc, flow);
+ ctx.tloffset = 0;

- err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
- msecs_to_jiffies(500));
- if (err == 0) {
- dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
- err = -EINVAL;
- } else if (err < 0) {
- dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
- } else {
- /* No error */
- err = 0;
- }
+ while (ctx.cryptlen) {
+ meson_setup_keyiv_descs(&ctx);

- dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
+ if (meson_setup_data_descs(&ctx)) {
+ err = meson_kick_hardware(&ctx);
+ if (err)
+ break;
+ }

- if (areq->src == areq->dst) {
- dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL);
- } else {
- dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE);
- dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE);
- }
+ if (ctx.src_offset == sg_dma_len(ctx.src_sg)) {
+ ctx.src_offset = 0;
+ ctx.src_sg = sg_next(ctx.src_sg);
+ }

- if (areq->iv && ivsize > 0) {
- if (rctx->op_dir == MESON_DECRYPT) {
- memcpy(areq->iv, backup_iv, ivsize);
- } else {
- scatterwalk_map_and_copy(areq->iv, areq->dst,
- areq->cryptlen - ivsize,
- ivsize, 0);
+ if (ctx.dst_offset == sg_dma_len(ctx.dst_sg)) {
+ ctx.dst_offset = 0;
+ ctx.dst_sg = sg_next(ctx.dst_sg);
}
}
+
+ dma_unmap_single(mc->dev, ctx.keyiv.addr, ctx.keyiv.len, DMA_TO_DEVICE);
+ meson_unmap_scatterlist(areq, mc);
+
theend:
- kfree_sensitive(bkeyiv);
- kfree_sensitive(backup_iv);
+ kfree_sensitive(ctx.bkeyiv);

return err;
}
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
index 22ff2768b5e5..f93e14f5717d 100644
--- a/drivers/crypto/amlogic/amlogic-gxl-core.c
+++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -199,6 +199,7 @@ static const struct meson_pdata meson_gxl_pdata = {
.descs_reg = 0x0,
.status_reg = 0x4,
.need_clk = true,
+ .setup_desc_cnt = 3,
};

static const struct of_device_id meson_crypto_of_match_table[] = {
diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
index a0d83c82906d..eb2f8cd72b65 100644
--- a/drivers/crypto/amlogic/amlogic-gxl.h
+++ b/drivers/crypto/amlogic/amlogic-gxl.h
@@ -83,11 +83,13 @@ struct meson_flow {
* @reg_descs: offset to descriptors register
* @reg_status: offset to status register
* @need_clk: clock input is needed
+ * @setup_desc_cnt: number of setup descriptor to configure.
*/
struct meson_pdata {
u32 descs_reg;
u32 status_reg;
bool need_clk;
+ u32 setup_desc_cnt;
};

/*
--
2.34.1


2024-02-12 14:29:20

by Alexey Romanov

[permalink] [raw]
Subject: [PATCH v4 16/20] dt-bindings: crypto: meson: support new SoC's

Now crypto module available at G12A/G12B/S4/A1/SM1/AXG.

1. Add new compatibles:
- amlogic,g12a-crypto
- amlogic,s4-crypto (uses g12a-crypto as fallback)
- amlogic,a1-crypto (uses g12a-crypto as fallback)
- amlogic,axg-crypto

2. All SoC's, exclude GXL, doesn't take a clock input for
Crypto IP. Make it required only for amlogic,gxl-crypto.

3. All SoC's, exclude GXL, uses only one interrupt flow
for Crypto IP.

4. Add power-domains in schema.

Signed-off-by: Alexey Romanov <[email protected]>
---
.../bindings/crypto/amlogic,gxl-crypto.yaml | 43 ++++++++++++++++---
1 file changed, 36 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
index 948e11ebe4ee..41f0153d58c8 100644
--- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
+++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
@@ -11,20 +11,30 @@ maintainers:

properties:
compatible:
- items:
- - const: amlogic,gxl-crypto
+ oneOf:
+ - items:
+ - enum:
+ - amlogic,a1-crypto
+ - amlogic,s4-crypto
+ - const: amlogic,g12a-crypto
+ - enum:
+ - amlogic,gxl-crypto
+ - amlogic,axg-crypto
+ - amlogic,g12a-crypto

reg:
maxItems: 1

interrupts:
- items:
- - description: Interrupt for flow 0
- - description: Interrupt for flow 1
+ minItems: 1
+ maxItems: 2

clocks:
maxItems: 1

+ power-domains:
+ maxItems: 1
+
clock-names:
const: blkmv

@@ -32,8 +42,27 @@ required:
- compatible
- reg
- interrupts
- - clocks
- - clock-names
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: amlogic,gxl-crypto
+ then:
+ required:
+ - clocks
+ - clock-names
+ properties:
+ interrupts:
+ items:
+ - description: Interrupt for flow 0
+ - description: Interrupt for flow 1
+ else:
+ properties:
+ interrupts:
+ items:
+ - description: Interrupt for flow 0

additionalProperties: false

--
2.34.1


2024-02-12 17:05:41

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v4 17/20] arch: arm64: dts: meson: a1: add crypto node

On 12/02/2024 14:51, Alexey Romanov wrote:
> This patch adds a crypto node declaration. With the
> Amlogic crypto driver we can use HW implementation
> of SHA1/224/256 and AES algo.
>
> Signed-off-by: Alexey Romanov <[email protected]>
> ---
> arch/arm64/boot/dts/amlogic/meson-a1.dtsi | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> index b9fd69112535..6d11e38ca3c0 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-a1.dtsi
> @@ -653,6 +653,13 @@ sd_emmc: sd@10000 {
> power-domains = <&pwrc PWRC_SD_EMMC_ID>;
> status = "disabled";
> };
> +
> + crypto: crypto@6000 {
> + compatible = "amlogic,a1-crypto", "amlogic,g12a-crypto";
> + reg = <0x0 0x6000 0x0 0x48>;
> + interrupts = <GIC_SPI 120 IRQ_TYPE_EDGE_RISING>;
> + power-domains = <&pwrc PWRC_DMA_ID>;
> + };
> };
>
> usb: usb@fe004400 {

Reviewed-by: Neil Armstrong <[email protected]>

2024-02-12 17:13:42

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v4 03/20] drivers: crypto: meson: make CLK controller optional

On 12/02/2024 14:50, Alexey Romanov wrote:
> Amlogic crypto IP doesn't take a clock input on some
> SoCs: AXG / A1 / S4 / G12. So make it optional.
>
> Signed-off-by: Alexey Romanov <[email protected]>
> ---
> drivers/crypto/amlogic/amlogic-gxl-core.c | 21 ++++++++-------------
> drivers/crypto/amlogic/amlogic-gxl.h | 2 ++
> 2 files changed, 10 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 4d1b1d5b7a54..54113c524ec5 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -250,6 +250,7 @@ static void meson_unregister_algs(struct meson_dev *mc)
> static const struct meson_pdata meson_gxl_pdata = {
> .descs_reg = 0x0,
> .status_reg = 0x4,
> + .need_clk = true,
> };
>
> static const struct of_device_id meson_crypto_of_match_table[] = {
> @@ -285,17 +286,14 @@ static int meson_crypto_probe(struct platform_device *pdev)
> dev_err(&pdev->dev, "Cannot request MMIO err=%d\n", err);
> return err;
> }
> - mc->busclk = devm_clk_get(&pdev->dev, "blkmv");
> - if (IS_ERR(mc->busclk)) {
> - err = PTR_ERR(mc->busclk);
> - dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err);
> - return err;
> - }
>
> - err = clk_prepare_enable(mc->busclk);
> - if (err != 0) {
> - dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
> - return err;
> + if (mc->pdata->need_clk) {
> + mc->busclk = devm_clk_get_enabled(&pdev->dev, "blkmv");
> + if (IS_ERR(mc->busclk)) {
> + err = PTR_ERR(mc->busclk);
> + dev_err(&pdev->dev, "Cannot get and enable core clock err=%d\n", err);
> + return err;
> + }
> }
>
> err = meson_allocate_chanlist(mc);
> @@ -322,7 +320,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
> meson_unregister_algs(mc);
> error_flow:
> meson_free_chanlist(mc, mc->flow_cnt - 1);
> - clk_disable_unprepare(mc->busclk);
> return err;
> }
>
> @@ -337,8 +334,6 @@ static void meson_crypto_remove(struct platform_device *pdev)
> meson_unregister_algs(mc);
>
> meson_free_chanlist(mc, mc->flow_cnt - 1);
> -
> - clk_disable_unprepare(mc->busclk);
> }
>
> static struct platform_driver meson_crypto_driver = {
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index 9ad75da214ff..a36b9bac63a0 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -82,10 +82,12 @@ struct meson_flow {
> * struct meson_pdata - SoC series dependent data.
> * @reg_descs: offset to descriptors register
> * @reg_status: offset to status register
> + * @need_clk: clock input is needed
> */
> struct meson_pdata {
> u32 descs_reg;
> u32 status_reg;
> + bool need_clk;
> };
>
> /*

You may use devm_clk_get_optional_enabled() instead, bindings will ensure
clock is provided when needed.

With this you can also drop the clk_disable_unprepare() in meson_crypto_remove().

Neil


2024-02-12 17:14:04

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v4 04/20] drivers: crypto: meson: add MMIO helpers

On 12/02/2024 14:50, Alexey Romanov wrote:
> Add MMIO access helpers: meson_dma_start() and meson_dma_ready().
>
> Signed-off-by: Alexey Romanov <[email protected]>
> ---
> drivers/crypto/amlogic/amlogic-gxl-cipher.c | 2 +-
> drivers/crypto/amlogic/amlogic-gxl-core.c | 24 ++++++++++++++++-----
> drivers/crypto/amlogic/amlogic-gxl.h | 2 ++
> 3 files changed, 22 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index 7eff3ae7356f..1fe916b0a138 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -225,7 +225,7 @@ static int meson_cipher(struct skcipher_request *areq)
>
> reinit_completion(&mc->chanlist[flow].complete);
> mc->chanlist[flow].status = 0;
> - writel(mc->chanlist[flow].t_phy | 2, mc->base + ((mc->pdata->descs_reg + flow) << 2));
> + meson_dma_start(mc, flow);
> wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> msecs_to_jiffies(500));
> if (mc->chanlist[flow].status == 0) {
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 54113c524ec5..372c30f72072 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -23,18 +23,32 @@
>
> #include "amlogic-gxl.h"
>
> +void meson_dma_start(struct meson_dev *mc, int flow)
> +{
> + u32 offset = (mc->pdata->descs_reg + flow) << 2;
> +
> + writel(mc->chanlist[flow].t_phy | 2, mc->base + offset);
> +}
> +
> +static bool meson_dma_ready(struct meson_dev *mc, int flow)
> +{
> + u32 offset = (mc->pdata->status_reg + flow) << 2;
> + u32 data = readl(mc->base + offset);
> +
> + if (data)
> + writel_relaxed(0xF, mc->base + offset);
> +
> + return data;
> +}
> +
> static irqreturn_t meson_irq_handler(int irq, void *data)
> {
> struct meson_dev *mc = (struct meson_dev *)data;
> int flow;
> - u32 p;
>
> for (flow = 0; flow < mc->flow_cnt; flow++) {
> if (mc->chanlist[flow].irq == irq) {
> - p = readl(mc->base + ((mc->pdata->status_reg + flow) << 2));
> - if (p) {
> - writel_relaxed(0xF, mc->base +
> - ((mc->pdata->status_reg + flow) << 2));
> + if (meson_dma_ready(mc, flow)) {
> mc->chanlist[flow].status = 1;
> complete(&mc->chanlist[flow].complete);
> return IRQ_HANDLED;
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index a36b9bac63a0..59fc6a67e0a9 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -163,6 +163,8 @@ struct meson_alg_template {
> #endif
> };
>
> +void meson_dma_start(struct meson_dev *mc, int flow);
> +
> int meson_enqueue(struct crypto_async_request *areq, u32 type);
>
> int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,

Reviewed-by: Neil Armstrong <[email protected]>

2024-02-12 17:14:41

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v4 05/20] drivers: crypto: meson: move get_engine_number()

On 12/02/2024 14:50, Alexey Romanov wrote:
> Move get_engine_number() function from cipher.c to core.c
>
> Signed-off-by: Alexey Romanov <[email protected]>
> ---
> drivers/crypto/amlogic/amlogic-gxl-cipher.c | 9 ++-------
> drivers/crypto/amlogic/amlogic-gxl-core.c | 5 +++++
> drivers/crypto/amlogic/amlogic-gxl.h | 2 ++
> 3 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index 1fe916b0a138..18e9e2d39b1f 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -17,11 +17,6 @@
> #include <crypto/internal/skcipher.h>
> #include "amlogic-gxl.h"
>
> -static int get_engine_number(struct meson_dev *mc)
> -{
> - return atomic_inc_return(&mc->flow) % mc->flow_cnt;
> -}
> -
> static bool meson_cipher_need_fallback(struct skcipher_request *areq)
> {
> struct scatterlist *src_sg = areq->src;
> @@ -282,7 +277,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
> rctx->op_dir = MESON_DECRYPT;
> if (meson_cipher_need_fallback(areq))
> return meson_cipher_do_fallback(areq);
> - e = get_engine_number(op->mc);
> + e = meson_get_engine_number(op->mc);
> engine = op->mc->chanlist[e].engine;
> rctx->flow = e;
>
> @@ -300,7 +295,7 @@ int meson_skencrypt(struct skcipher_request *areq)
> rctx->op_dir = MESON_ENCRYPT;
> if (meson_cipher_need_fallback(areq))
> return meson_cipher_do_fallback(areq);
> - e = get_engine_number(op->mc);
> + e = meson_get_engine_number(op->mc);
> engine = op->mc->chanlist[e].engine;
> rctx->flow = e;
>
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 372c30f72072..51291fdcf8b6 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -23,6 +23,11 @@
>
> #include "amlogic-gxl.h"
>
> +int meson_get_engine_number(struct meson_dev *mc)
> +{
> + return atomic_inc_return(&mc->flow) % mc->flow_cnt;
> +}
> +
> void meson_dma_start(struct meson_dev *mc, int flow)
> {
> u32 offset = (mc->pdata->descs_reg + flow) << 2;
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index 59fc6a67e0a9..5f5e3115fcdf 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -163,6 +163,8 @@ struct meson_alg_template {
> #endif
> };
>
> +int meson_get_engine_number(struct meson_dev *mc);
> +
> void meson_dma_start(struct meson_dev *mc, int flow);
>
> int meson_enqueue(struct crypto_async_request *areq, u32 type);

Reviewed-by: Neil Armstrong <[email protected]>

2024-02-12 17:14:59

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v4 06/20] drivers: crypto: meson: drop status field from meson_flow

On 12/02/2024 14:50, Alexey Romanov wrote:
> This field is used only to check for timeout. But there is more
> convenient way to achive the same goal.
>
> Signed-off-by: Alexey Romanov <[email protected]>
> ---
> drivers/crypto/amlogic/amlogic-gxl-cipher.c | 13 +++++++++----
> drivers/crypto/amlogic/amlogic-gxl-core.c | 1 -
> drivers/crypto/amlogic/amlogic-gxl.h | 2 --
> 3 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index 18e9e2d39b1f..dc0b100c5de2 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -219,13 +219,18 @@ static int meson_cipher(struct skcipher_request *areq)
> }
>
> reinit_completion(&mc->chanlist[flow].complete);
> - mc->chanlist[flow].status = 0;
> meson_dma_start(mc, flow);
> - wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> - msecs_to_jiffies(500));
> - if (mc->chanlist[flow].status == 0) {
> +
> + err = wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
> + msecs_to_jiffies(500));
> + if (err == 0) {
> dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
> err = -EINVAL;
> + } else if (err < 0) {
> + dev_err(mc->dev, "Waiting for DMA completion is failed (%d)\n", err);
> + } else {
> + /* No error */
> + err = 0;
> }
>
> dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index 51291fdcf8b6..f7c60ebffbc3 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -54,7 +54,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
> for (flow = 0; flow < mc->flow_cnt; flow++) {
> if (mc->chanlist[flow].irq == irq) {
> if (meson_dma_ready(mc, flow)) {
> - mc->chanlist[flow].status = 1;
> complete(&mc->chanlist[flow].complete);
> return IRQ_HANDLED;
> }
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index 5f5e3115fcdf..e27908992ae3 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -59,7 +59,6 @@ struct meson_desc {
> * @engine: ptr to the crypto_engine for this flow
> * @keylen: keylen for this flow operation
> * @complete: completion for the current task on this flow
> - * @status: set to 1 by interrupt if task is done
> * @irq: IRQ number for amlogic-crypto
> * @t_phy: Physical address of task
> * @tl: pointer to the current ce_task for this flow
> @@ -68,7 +67,6 @@ struct meson_desc {
> struct meson_flow {
> struct crypto_engine *engine;
> struct completion complete;
> - int status;
> int irq;
> unsigned int keylen;
> dma_addr_t t_phy;

Reviewed-by: Neil Armstrong <[email protected]>

2024-02-12 17:15:18

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v4 07/20] drivers: crypto: meson: move algs definition and cipher API to cipher.c

On 12/02/2024 14:50, Alexey Romanov wrote:
> Because that is proper place for them. In particular,
> it takes less of exported symbol between compiling entities.
>
> Signed-off-by: Alexey Romanov <[email protected]>
> ---
> drivers/crypto/amlogic/amlogic-gxl-cipher.c | 98 +++++++++++++++--
> drivers/crypto/amlogic/amlogic-gxl-core.c | 110 ++++----------------
> drivers/crypto/amlogic/amlogic-gxl.h | 14 +--
> 3 files changed, 119 insertions(+), 103 deletions(-)
>
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> index dc0b100c5de2..bc3092a8a2c2 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
> @@ -271,7 +271,7 @@ int meson_handle_cipher_request(struct crypto_engine *engine, void *areq)
> return 0;
> }
>
> -int meson_skdecrypt(struct skcipher_request *areq)
> +static int meson_skdecrypt(struct skcipher_request *areq)
> {
> struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
> struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
> @@ -289,7 +289,7 @@ int meson_skdecrypt(struct skcipher_request *areq)
> return crypto_transfer_skcipher_request_to_engine(engine, areq);
> }
>
> -int meson_skencrypt(struct skcipher_request *areq)
> +static int meson_skencrypt(struct skcipher_request *areq)
> {
> struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
> struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
> @@ -307,7 +307,7 @@ int meson_skencrypt(struct skcipher_request *areq)
> return crypto_transfer_skcipher_request_to_engine(engine, areq);
> }
>
> -int meson_cipher_init(struct crypto_tfm *tfm)
> +static int meson_cipher_init(struct crypto_tfm *tfm)
> {
> struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
> struct meson_alg_template *algt;
> @@ -333,7 +333,7 @@ int meson_cipher_init(struct crypto_tfm *tfm)
> return 0;
> }
>
> -void meson_cipher_exit(struct crypto_tfm *tfm)
> +static void meson_cipher_exit(struct crypto_tfm *tfm)
> {
> struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
>
> @@ -341,8 +341,8 @@ void meson_cipher_exit(struct crypto_tfm *tfm)
> crypto_free_skcipher(op->fallback_tfm);
> }
>
> -int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
> - unsigned int keylen)
> +static int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
> + unsigned int keylen)
> {
> struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
> struct meson_dev *mc = op->mc;
> @@ -369,3 +369,89 @@ int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
>
> return crypto_skcipher_setkey(op->fallback_tfm, key, keylen);
> }
> +
> +static struct meson_alg_template algs[] = {
> +{
> + .type = CRYPTO_ALG_TYPE_SKCIPHER,
> + .blockmode = MESON_OPMODE_CBC,
> + .alg.skcipher.base = {
> + .base = {
> + .cra_name = "cbc(aes)",
> + .cra_driver_name = "cbc-aes-gxl",
> + .cra_priority = 400,
> + .cra_blocksize = AES_BLOCK_SIZE,
> + .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
> + CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
> + CRYPTO_ALG_NEED_FALLBACK,
> + .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
> + .cra_module = THIS_MODULE,
> + .cra_alignmask = 0xf,
> + .cra_init = meson_cipher_init,
> + .cra_exit = meson_cipher_exit,
> + },
> + .min_keysize = AES_MIN_KEY_SIZE,
> + .max_keysize = AES_MAX_KEY_SIZE,
> + .ivsize = AES_BLOCK_SIZE,
> + .setkey = meson_aes_setkey,
> + .encrypt = meson_skencrypt,
> + .decrypt = meson_skdecrypt,
> + },
> + .alg.skcipher.op = {
> + .do_one_request = meson_handle_cipher_request,
> + },
> +},
> +{
> + .type = CRYPTO_ALG_TYPE_SKCIPHER,
> + .blockmode = MESON_OPMODE_ECB,
> + .alg.skcipher.base = {
> + .base = {
> + .cra_name = "ecb(aes)",
> + .cra_driver_name = "ecb-aes-gxl",
> + .cra_priority = 400,
> + .cra_blocksize = AES_BLOCK_SIZE,
> + .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
> + CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
> + CRYPTO_ALG_NEED_FALLBACK,
> + .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
> + .cra_module = THIS_MODULE,
> + .cra_alignmask = 0xf,
> + .cra_init = meson_cipher_init,
> + .cra_exit = meson_cipher_exit,
> + },
> + .min_keysize = AES_MIN_KEY_SIZE,
> + .max_keysize = AES_MAX_KEY_SIZE,
> + .setkey = meson_aes_setkey,
> + .encrypt = meson_skencrypt,
> + .decrypt = meson_skdecrypt,
> + },
> + .alg.skcipher.op = {
> + .do_one_request = meson_handle_cipher_request,
> + },
> +},
> +};
> +
> +int meson_cipher_register(struct meson_dev *mc)
> +{
> + return meson_register_algs(mc, algs, ARRAY_SIZE(algs));
> +}
> +
> +void meson_cipher_unregister(struct meson_dev *mc)
> +{
> + meson_unregister_algs(mc, algs, ARRAY_SIZE(algs));
> +}
> +
> +void meson_cipher_debugfs_show(struct seq_file *seq, void *v)
> +{
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(algs); i++) {
> + seq_printf(seq, "%s %s %lu %lu\n",
> + algs[i].alg.skcipher.base.base.cra_driver_name,
> + algs[i].alg.skcipher.base.base.cra_name,
> +#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
> + algs[i].stat_req, algs[i].stat_fb);
> +#else
> + 0ul, 0ul);
> +#endif
> + }
> +}
> diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c
> index f7c60ebffbc3..22ff2768b5e5 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl-core.c
> +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
> @@ -65,66 +65,6 @@ static irqreturn_t meson_irq_handler(int irq, void *data)
> return IRQ_HANDLED;
> }
>
> -static struct meson_alg_template mc_algs[] = {
> -{
> - .type = CRYPTO_ALG_TYPE_SKCIPHER,
> - .blockmode = MESON_OPMODE_CBC,
> - .alg.skcipher.base = {
> - .base = {
> - .cra_name = "cbc(aes)",
> - .cra_driver_name = "cbc-aes-gxl",
> - .cra_priority = 400,
> - .cra_blocksize = AES_BLOCK_SIZE,
> - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
> - CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
> - CRYPTO_ALG_NEED_FALLBACK,
> - .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
> - .cra_module = THIS_MODULE,
> - .cra_alignmask = 0xf,
> - .cra_init = meson_cipher_init,
> - .cra_exit = meson_cipher_exit,
> - },
> - .min_keysize = AES_MIN_KEY_SIZE,
> - .max_keysize = AES_MAX_KEY_SIZE,
> - .ivsize = AES_BLOCK_SIZE,
> - .setkey = meson_aes_setkey,
> - .encrypt = meson_skencrypt,
> - .decrypt = meson_skdecrypt,
> - },
> - .alg.skcipher.op = {
> - .do_one_request = meson_handle_cipher_request,
> - },
> -},
> -{
> - .type = CRYPTO_ALG_TYPE_SKCIPHER,
> - .blockmode = MESON_OPMODE_ECB,
> - .alg.skcipher.base = {
> - .base = {
> - .cra_name = "ecb(aes)",
> - .cra_driver_name = "ecb-aes-gxl",
> - .cra_priority = 400,
> - .cra_blocksize = AES_BLOCK_SIZE,
> - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
> - CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
> - CRYPTO_ALG_NEED_FALLBACK,
> - .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
> - .cra_module = THIS_MODULE,
> - .cra_alignmask = 0xf,
> - .cra_init = meson_cipher_init,
> - .cra_exit = meson_cipher_exit,
> - },
> - .min_keysize = AES_MIN_KEY_SIZE,
> - .max_keysize = AES_MAX_KEY_SIZE,
> - .setkey = meson_aes_setkey,
> - .encrypt = meson_skencrypt,
> - .decrypt = meson_skdecrypt,
> - },
> - .alg.skcipher.op = {
> - .do_one_request = meson_handle_cipher_request,
> - },
> -},
> -};
> -
> static int meson_debugfs_show(struct seq_file *seq, void *v)
> {
> struct meson_dev *mc __maybe_unused = seq->private;
> @@ -138,20 +78,8 @@ static int meson_debugfs_show(struct seq_file *seq, void *v)
> 0ul);
> #endif
>
> - for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
> - switch (mc_algs[i].type) {
> - case CRYPTO_ALG_TYPE_SKCIPHER:
> - seq_printf(seq, "%s %s %lu %lu\n",
> - mc_algs[i].alg.skcipher.base.base.cra_driver_name,
> - mc_algs[i].alg.skcipher.base.base.cra_name,
> -#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
> - mc_algs[i].stat_req, mc_algs[i].stat_fb);
> -#else
> - 0ul, 0ul);
> -#endif
> - break;
> - }
> - }
> + meson_cipher_debugfs_show(seq, v);
> +
> return 0;
> }
> DEFINE_SHOW_ATTRIBUTE(meson_debugfs);
> @@ -228,38 +156,40 @@ static int meson_allocate_chanlist(struct meson_dev *mc)
> return err;
> }
>
> -static int meson_register_algs(struct meson_dev *mc)
> +int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
> + unsigned int count)
> {
> int err, i;
>
> - for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
> - mc_algs[i].mc = mc;
> - switch (mc_algs[i].type) {
> + for (i = 0; i < count; i++) {
> + switch (algs[i].type) {
> case CRYPTO_ALG_TYPE_SKCIPHER:
> - err = crypto_engine_register_skcipher(&mc_algs[i].alg.skcipher);
> + err = crypto_engine_register_skcipher(&algs[i].alg.skcipher);
> if (err) {
> dev_err(mc->dev, "Fail to register %s\n",
> - mc_algs[i].alg.skcipher.base.base.cra_name);
> - mc_algs[i].mc = NULL;
> + algs[i].alg.skcipher.base.base.cra_name);
> + meson_unregister_algs(mc, algs, count);
> return err;
> }
> break;
> }
> + algs[i].mc = mc;
> }
>
> return 0;
> }
>
> -static void meson_unregister_algs(struct meson_dev *mc)
> +void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
> + unsigned int count)
> {
> int i;
>
> - for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
> - if (!mc_algs[i].mc)
> + for (i = 0; i < count; i++) {
> + if (!algs[i].mc)
> continue;
> - switch (mc_algs[i].type) {
> + switch (algs[i].type) {
> case CRYPTO_ALG_TYPE_SKCIPHER:
> - crypto_engine_unregister_skcipher(&mc_algs[i].alg.skcipher);
> + crypto_engine_unregister_skcipher(&algs[i].alg.skcipher);
> break;
> }
> }
> @@ -318,9 +248,9 @@ static int meson_crypto_probe(struct platform_device *pdev)
> if (err)
> goto error_flow;
>
> - err = meson_register_algs(mc);
> + err = meson_cipher_register(mc);
> if (err)
> - goto error_alg;
> + goto error_flow;
>
> if (IS_ENABLED(CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG)) {
> struct dentry *dbgfs_dir;
> @@ -334,8 +264,6 @@ static int meson_crypto_probe(struct platform_device *pdev)
> }
>
> return 0;
> -error_alg:
> - meson_unregister_algs(mc);
> error_flow:
> meson_free_chanlist(mc, mc->flow_cnt - 1);
> return err;
> @@ -349,7 +277,7 @@ static void meson_crypto_remove(struct platform_device *pdev)
> debugfs_remove_recursive(mc->dbgfs_dir);
> #endif
>
> - meson_unregister_algs(mc);
> + meson_cipher_unregister(mc);
>
> meson_free_chanlist(mc, mc->flow_cnt - 1);
> }
> diff --git a/drivers/crypto/amlogic/amlogic-gxl.h b/drivers/crypto/amlogic/amlogic-gxl.h
> index e27908992ae3..0a03e8144977 100644
> --- a/drivers/crypto/amlogic/amlogic-gxl.h
> +++ b/drivers/crypto/amlogic/amlogic-gxl.h
> @@ -167,10 +167,12 @@ void meson_dma_start(struct meson_dev *mc, int flow);
>
> int meson_enqueue(struct crypto_async_request *areq, u32 type);
>
> -int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
> - unsigned int keylen);
> -int meson_cipher_init(struct crypto_tfm *tfm);
> -void meson_cipher_exit(struct crypto_tfm *tfm);
> -int meson_skdecrypt(struct skcipher_request *areq);
> -int meson_skencrypt(struct skcipher_request *areq);
> +int meson_register_algs(struct meson_dev *mc, struct meson_alg_template *algs,
> + unsigned int count);
> +void meson_unregister_algs(struct meson_dev *mc, struct meson_alg_template *algs,
> + unsigned int count);
> +
> +int meson_cipher_register(struct meson_dev *mc);
> +void meson_cipher_unregister(struct meson_dev *mc);
> +void meson_cipher_debugfs_show(struct seq_file *seq, void *v);
> int meson_handle_cipher_request(struct crypto_engine *engine, void *areq);

Reviewed-by: Neil Armstrong <[email protected]>

2024-02-12 17:18:50

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v4 20/20] arch: arm64: dts: meson: axg: add crypto node

On 12/02/2024 14:51, Alexey Romanov wrote:
> This patch adds a crypto node declaration. With the
> Amlogic crypto driver we can use HW implementation
> of SHA1/224/256 and AES algo.
>
> Signed-off-by: Alexey Romanov <[email protected]>
> ---
> arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> index 6d12b760b90f..b19be72abdd6 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
> @@ -294,6 +294,12 @@ ethmac: ethernet@ff3f0000 {
> status = "disabled";
> };
>
> + crypto: crypto@ff63e000 {
> + compatible = "amlogic,axg-crypto";
> + reg = <0x0 0xff63e000 0x0 0x48>;
> + interrupts = <GIC_SPI 180 IRQ_TYPE_EDGE_RISING>;
> + };
> +
> pcie_phy: phy@ff644000 {
> compatible = "amlogic,axg-pcie-phy";
> reg = <0x0 0xff644000 0x0 0x1c>;

Reviewed-by: Neil Armstrong <[email protected]>

2024-02-13 07:21:25

by Corentin Labbe

[permalink] [raw]
Subject: Re: [PATCH v4 00/20] Support more Amlogic SoC families in crypto driver

Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a ?crit :
> Hello!
>
> This patchset expand the funcionality of the Amlogic
> crypto driver by adding support for more SoC families:
> AXG, G12A, G12B, SM1, A1, S4.
>
> Also specify and enable crypto node in device tree
> for reference Amlogic devices.
>
> Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> custom tests [1] and tcrypt module.
>
> ---
>

I started to test on Lepotato board and added patchs up to "drivers: crypto: meson: process more than MAXDESCS descriptors"
booting lead to:
[ 18.559922] gxl-crypto c883e000.crypto: will run requests pump with realtime priority
[ 18.562492] gxl-crypto c883e000.crypto: will run requests pump with realtime priority
[ 18.570328] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
[ 18.581135] Mem abort info:
[ 18.581354] ESR = 0x0000000096000006
[ 18.585138] EC = 0x25: DABT (current EL), IL = 32 bits
[ 18.593005] SET = 0, FnV = 0
[ 18.593334] EA = 0, S1PTW = 0
[ 18.597329] FSC = 0x06: level 2 translation fault
[ 18.604250] Data abort info:
[ 18.604282] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
[ 18.612243] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 18.614552] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 18.624249] user pgtable: 4k pages, 48-bit VAs, pgdp=000000007b8ab000
[ 18.626196] [0000000000000028] pgd=080000007b8ac003, p4d=080000007b8ac003, pud=080000007b8ad003, pmd=0000000000000000
[ 18.640426] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
[ 18.642929] Modules linked in: of_mdio fixed_phy fwnode_mdio sm4_ce(-) sm4 meson_rng meson_canvas libphy rng_core meson_gxbb_wdt watchdog amlogic_gxl_crypto(+) ghash_generic gcm xctr xts cts essiv authenc cmac xcbc ccm
[ 18.662164] CPU: 3 PID: 264 Comm: cryptomgr_test Not tainted 6.8.0-rc1-00052-gf70f2b0814a0 #11
[ 18.670698] Hardware name: Libre Computer AML-S905X-CC (DT)
[ 18.676220] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 18.683118] pc : meson_get_engine_number+0x2c/0x50 [amlogic_gxl_crypto]
[ 18.689674] lr : meson_skencrypt+0x38/0x8c [amlogic_gxl_crypto]
[ 18.695539] sp : ffff800081393790
[ 18.698816] x29: ffff800081393790 x28: 0000000000000400 x27: ffff800080874a80
[ 18.705888] x26: ffff800081393830 x25: ffff800081393bd8 x24: ffff000001aaa000
[ 18.712961] x23: 0000000000000001 x22: 0000000000000000 x21: ffff0000011b1c50
[ 18.720033] x20: ffff00007bac8248 x19: ffff0000011b1c00 x18: ffffffffffffffff
[ 18.727105] x17: 00000000000001a4 x16: ffff800078edc1f0 x15: ffff8000813938e0
[ 18.734178] x14: ffff800101393bd7 x13: 0000000000000000 x12: 0000000000000000
[ 18.741250] x11: 000000000000021c x10: fffffffff81213e0 x9 : 00000000000730d5
[ 18.748323] x8 : ffff0000011b1ca8 x7 : fefefefefefefefe x6 : fffffc000007a302
[ 18.755395] x5 : ffff800078eb4148 x4 : 0000000000000000 x3 : 0000000000000028
[ 18.762468] x2 : ffff000001aaa040 x1 : 0000000000000000 x0 : 0000000000000000
[ 18.769541] Call trace:
[ 18.771956] meson_get_engine_number+0x2c/0x50 [amlogic_gxl_crypto]
[ 18.778167] crypto_skcipher_encrypt+0xe0/0x124
[ 18.782651] test_skcipher_vec_cfg+0x2a8/0x6b0
[ 18.787050] test_skcipher_vec+0x80/0x1c4
[ 18.791017] alg_test_skcipher+0xbc/0x1fc
[ 18.794985] alg_test+0x140/0x628
[ 18.798262] cryptomgr_test+0x24/0x44
[ 18.801885] kthread+0x110/0x114
[ 18.805076] ret_from_fork+0x10/0x20
[ 18.808617] Code: 1b008440 d65f03c0 9100a003 f9800071 (885f7c61)
[ 18.814651] ---[ end trace 0000000000000000 ]---
[ 18.862270] meson8b-dwmac c9410000.ethernet: IRQ eth_wake_irq not found
[ 18.863897] meson8b-dwmac c9410000.ethernet: IRQ eth_lpi not found
[ 18.870349] meson8b-dwmac c9410000.ethernet: PTP uses main clock
[ 18.880548] meson8b-dwmac c9410000.ethernet: User ID: 0x11, Synopsys ID: 0x37
[ 18.882403] meson8b-dwmac c9410000.ethernet: DWMAC1000
[ 18.887926] meson8b-dwmac c9410000.ethernet: DMA HW capability register supported
[ 18.895215] meson8b-dwmac c9410000.ethernet: RX Checksum Offload Engine supported
[ 18.902627] meson8b-dwmac c9410000.ethernet: COE Type 2
[ 18.907756] meson8b-dwmac c9410000.ethernet: TX Checksum insertion supported
[ 18.914750] meson8b-dwmac c9410000.ethernet: Wake-Up On Lan supported
[ 18.921246] meson8b-dwmac c9410000.ethernet: Normal descriptors
[ 18.927017] meson8b-dwmac c9410000.ethernet: Ring mode enabled
[ 18.932782] meson8b-dwmac c9410000.ethernet: Enable RX Mitigation via HW Watchdog Timer

2024-02-15 10:57:50

by Alexey Romanov

[permalink] [raw]
Subject: Re: [PATCH v4 00/20] Support more Amlogic SoC families in crypto driver

Hello,

On Tue, Feb 13, 2024 at 08:21:12AM +0100, Corentin Labbe wrote:
> Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a 'ecrit :
> > Hello!
> >
> > This patchset expand the funcionality of the Amlogic
> > crypto driver by adding support for more SoC families:
> > AXG, G12A, G12B, SM1, A1, S4.
> >
> > Also specify and enable crypto node in device tree
> > for reference Amlogic devices.
> >
> > Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> > custom tests [1] and tcrypt module.
> >
> > ---
> >
>
> I started to test on Lepotato board and added patchs up to "drivers: crypto: meson: process more than MAXDESCS descriptors"
> booting lead to:

Can you please give me your test cases?
Which tool are you using or is it something custom?

> [ 18.559922] gxl-crypto c883e000.crypto: will run requests pump with realtime priority
> [ 18.562492] gxl-crypto c883e000.crypto: will run requests pump with realtime priority
> [ 18.570328] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000028
> [ 18.581135] Mem abort info:
> [ 18.581354] ESR = 0x0000000096000006
> [ 18.585138] EC = 0x25: DABT (current EL), IL = 32 bits
> [ 18.593005] SET = 0, FnV = 0
> [ 18.593334] EA = 0, S1PTW = 0
> [ 18.597329] FSC = 0x06: level 2 translation fault
> [ 18.604250] Data abort info:
> [ 18.604282] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
> [ 18.612243] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> [ 18.614552] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> [ 18.624249] user pgtable: 4k pages, 48-bit VAs, pgdp=000000007b8ab000
> [ 18.626196] [0000000000000028] pgd=080000007b8ac003, p4d=080000007b8ac003, pud=080000007b8ad003, pmd=0000000000000000
> [ 18.640426] Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP
> [ 18.642929] Modules linked in: of_mdio fixed_phy fwnode_mdio sm4_ce(-) sm4 meson_rng meson_canvas libphy rng_core meson_gxbb_wdt watchdog amlogic_gxl_crypto(+) ghash_generic gcm xctr xts cts essiv authenc cmac xcbc ccm
> [ 18.662164] CPU: 3 PID: 264 Comm: cryptomgr_test Not tainted 6.8.0-rc1-00052-gf70f2b0814a0 #11
> [ 18.670698] Hardware name: Libre Computer AML-S905X-CC (DT)
> [ 18.676220] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [ 18.683118] pc : meson_get_engine_number+0x2c/0x50 [amlogic_gxl_crypto]
> [ 18.689674] lr : meson_skencrypt+0x38/0x8c [amlogic_gxl_crypto]
> [ 18.695539] sp : ffff800081393790
> [ 18.698816] x29: ffff800081393790 x28: 0000000000000400 x27: ffff800080874a80
> [ 18.705888] x26: ffff800081393830 x25: ffff800081393bd8 x24: ffff000001aaa000
> [ 18.712961] x23: 0000000000000001 x22: 0000000000000000 x21: ffff0000011b1c50
> [ 18.720033] x20: ffff00007bac8248 x19: ffff0000011b1c00 x18: ffffffffffffffff
> [ 18.727105] x17: 00000000000001a4 x16: ffff800078edc1f0 x15: ffff8000813938e0
> [ 18.734178] x14: ffff800101393bd7 x13: 0000000000000000 x12: 0000000000000000
> [ 18.741250] x11: 000000000000021c x10: fffffffff81213e0 x9 : 00000000000730d5
> [ 18.748323] x8 : ffff0000011b1ca8 x7 : fefefefefefefefe x6 : fffffc000007a302
> [ 18.755395] x5 : ffff800078eb4148 x4 : 0000000000000000 x3 : 0000000000000028
> [ 18.762468] x2 : ffff000001aaa040 x1 : 0000000000000000 x0 : 0000000000000000
> [ 18.769541] Call trace:
> [ 18.771956] meson_get_engine_number+0x2c/0x50 [amlogic_gxl_crypto]
> [ 18.778167] crypto_skcipher_encrypt+0xe0/0x124
> [ 18.782651] test_skcipher_vec_cfg+0x2a8/0x6b0
> [ 18.787050] test_skcipher_vec+0x80/0x1c4
> [ 18.791017] alg_test_skcipher+0xbc/0x1fc
> [ 18.794985] alg_test+0x140/0x628
> [ 18.798262] cryptomgr_test+0x24/0x44
> [ 18.801885] kthread+0x110/0x114
> [ 18.805076] ret_from_fork+0x10/0x20
> [ 18.808617] Code: 1b008440 d65f03c0 9100a003 f9800071 (885f7c61)
> [ 18.814651] ---[ end trace 0000000000000000 ]---
> [ 18.862270] meson8b-dwmac c9410000.ethernet: IRQ eth_wake_irq not found
> [ 18.863897] meson8b-dwmac c9410000.ethernet: IRQ eth_lpi not found
> [ 18.870349] meson8b-dwmac c9410000.ethernet: PTP uses main clock
> [ 18.880548] meson8b-dwmac c9410000.ethernet: User ID: 0x11, Synopsys ID: 0x37
> [ 18.882403] meson8b-dwmac c9410000.ethernet: DWMAC1000
> [ 18.887926] meson8b-dwmac c9410000.ethernet: DMA HW capability register supported
> [ 18.895215] meson8b-dwmac c9410000.ethernet: RX Checksum Offload Engine supported
> [ 18.902627] meson8b-dwmac c9410000.ethernet: COE Type 2
> [ 18.907756] meson8b-dwmac c9410000.ethernet: TX Checksum insertion supported
> [ 18.914750] meson8b-dwmac c9410000.ethernet: Wake-Up On Lan supported
> [ 18.921246] meson8b-dwmac c9410000.ethernet: Normal descriptors
> [ 18.927017] meson8b-dwmac c9410000.ethernet: Ring mode enabled
> [ 18.932782] meson8b-dwmac c9410000.ethernet: Enable RX Mitigation via HW Watchdog Timer

--
Thank you,
Alexey

2024-02-15 14:28:52

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH v4 16/20] dt-bindings: crypto: meson: support new SoC's

On Mon, Feb 12, 2024 at 04:51:04PM +0300, Alexey Romanov wrote:
> Now crypto module available at G12A/G12B/S4/A1/SM1/AXG.
>
> 1. Add new compatibles:
> - amlogic,g12a-crypto
> - amlogic,s4-crypto (uses g12a-crypto as fallback)
> - amlogic,a1-crypto (uses g12a-crypto as fallback)
> - amlogic,axg-crypto
>
> 2. All SoC's, exclude GXL, doesn't take a clock input for
> Crypto IP. Make it required only for amlogic,gxl-crypto.
>
> 3. All SoC's, exclude GXL, uses only one interrupt flow
> for Crypto IP.
>
> 4. Add power-domains in schema.
>
> Signed-off-by: Alexey Romanov <[email protected]>
> ---
> .../bindings/crypto/amlogic,gxl-crypto.yaml | 43 ++++++++++++++++---
> 1 file changed, 36 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> index 948e11ebe4ee..41f0153d58c8 100644
> --- a/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> +++ b/Documentation/devicetree/bindings/crypto/amlogic,gxl-crypto.yaml
> @@ -11,20 +11,30 @@ maintainers:
>
> properties:
> compatible:
> - items:
> - - const: amlogic,gxl-crypto
> + oneOf:
> + - items:
> + - enum:
> + - amlogic,a1-crypto
> + - amlogic,s4-crypto
> + - const: amlogic,g12a-crypto
> + - enum:
> + - amlogic,gxl-crypto
> + - amlogic,axg-crypto
> + - amlogic,g12a-crypto
>
> reg:
> maxItems: 1
>
> interrupts:
> - items:
> - - description: Interrupt for flow 0
> - - description: Interrupt for flow 1
> + minItems: 1
> + maxItems: 2

Just keep the descrptions here and add 'minItems: 1'. Then in the
if/then schema, you only need minItems and maxItems to require 1 or 2
interrupts.

>
> clocks:
> maxItems: 1
>
> + power-domains:
> + maxItems: 1
> +
> clock-names:
> const: blkmv
>
> @@ -32,8 +42,27 @@ required:
> - compatible
> - reg
> - interrupts
> - - clocks
> - - clock-names

New chips work without clocks? Cool!

Rob

2024-02-19 06:57:39

by Corentin Labbe

[permalink] [raw]
Subject: Re: [PATCH v4 00/20] Support more Amlogic SoC families in crypto driver

Le Thu, Feb 15, 2024 at 10:47:24AM +0000, Alexey Romanov a ?crit :
> On Tue, Feb 13, 2024 at 08:21:12AM +0100, Corentin Labbe wrote:
> > Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a 'ecrit :
> > > Hello!
> > >
> > > This patchset expand the funcionality of the Amlogic
> > > crypto driver by adding support for more SoC families:
> > > AXG, G12A, G12B, SM1, A1, S4.
> > >
> > > Also specify and enable crypto node in device tree
> > > for reference Amlogic devices.
> > >
> > > Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> > > custom tests [1] and tcrypt module.
> > >
> > > ---
> > >
> >
> > added patchs up to "drivers: crypto: meson: process more than MAXDESCS descriptors"
>
> Including this patch or not?

The crash start with "drivers: crypto: meson: move algs definition and cipher API to cipher.c"

2024-02-28 20:19:45

by Corentin Labbe

[permalink] [raw]
Subject: Re: [PATCH v4 00/20] Support more Amlogic SoC families in crypto driver

Le Wed, Feb 28, 2024 at 01:37:02PM +0000, Alexey Romanov a ?crit :
> Hello,
>
> On Mon, Feb 19, 2024 at 07:57:27AM +0100, Corentin Labbe wrote:
> > Le Thu, Feb 15, 2024 at 10:47:24AM +0000, Alexey Romanov a 'ecrit :
> > > On Tue, Feb 13, 2024 at 08:21:12AM +0100, Corentin Labbe wrote:
> > > > Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a 'ecrit :
> > > > > Hello!
> > > > >
> > > > > This patchset expand the funcionality of the Amlogic
> > > > > crypto driver by adding support for more SoC families:
> > > > > AXG, G12A, G12B, SM1, A1, S4.
> > > > >
> > > > > Also specify and enable crypto node in device tree
> > > > > for reference Amlogic devices.
> > > > >
> > > > > Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> > > > > custom tests [1] and tcrypt module.
> > > > >
> > > > > ---
> > > > >
> > > >
> > > > added patchs up to "drivers: crypto: meson: process more than MAXDESCS descriptors"
> > >
> > > Including this patch or not?
> >
> > The crash start with "drivers: crypto: meson: move algs definition and cipher API to cipher.c"
>
> Unfortunately I was unable to reproduce this. I use Khadas Vim1 board
> and my custom tests (https://gist.github.com/mRrvz/3fb8943a7487ab7b943ec140706995e7).
> Tried both build as module and built-in.
>
> Can you, please, give more information? Maybe your test cases?

My test case is simple, simply load the driver.

The problem is that you moved the algs[i].mc = mc after the register of algs (in drivers: crypto: meson: move algs definition and cipher API to cipher.c)
Test could happen as soon the register is done and so mc is deferenced.

Since you didnt hit the case, I suspect you didnt test the driver as module.

Regards

2024-02-29 13:05:36

by Alexey Romanov

[permalink] [raw]
Subject: Re: [PATCH v4 00/20] Support more Amlogic SoC families in crypto driver

Hello!

On Wed, Feb 28, 2024 at 09:19:32PM +0100, Corentin Labbe wrote:
> Le Wed, Feb 28, 2024 at 01:37:02PM +0000, Alexey Romanov a 'ecrit :
> > Hello,
> >
> > On Mon, Feb 19, 2024 at 07:57:27AM +0100, Corentin Labbe wrote:
> > > Le Thu, Feb 15, 2024 at 10:47:24AM +0000, Alexey Romanov a 'ecrit :
> > > > On Tue, Feb 13, 2024 at 08:21:12AM +0100, Corentin Labbe wrote:
> > > > > Le Mon, Feb 12, 2024 at 04:50:48PM +0300, Alexey Romanov a 'ecrit :
> > > > > > Hello!
> > > > > >
> > > > > > This patchset expand the funcionality of the Amlogic
> > > > > > crypto driver by adding support for more SoC families:
> > > > > > AXG, G12A, G12B, SM1, A1, S4.
> > > > > >
> > > > > > Also specify and enable crypto node in device tree
> > > > > > for reference Amlogic devices.
> > > > > >
> > > > > > Tested on AXG, G12A/B, SM1, A1 and S4 devices via
> > > > > > custom tests [1] and tcrypt module.
> > > > > >
> > > > > > ---
> > > > > >
> > > > >
> > > > > added patchs up to "drivers: crypto: meson: process more than MAXDESCS descriptors"
> > > >
> > > > Including this patch or not?
> > >
> > > The crash start with "drivers: crypto: meson: move algs definition and cipher API to cipher.c"
> >
> > Unfortunately I was unable to reproduce this. I use Khadas Vim1 board
> > and my custom tests (https://gist.github.com/mRrvz/3fb8943a7487ab7b943ec140706995e7).
> > Tried both build as module and built-in.
> >
> > Can you, please, give more information? Maybe your test cases?
>
> My test case is simple, simply load the driver.
>
> The problem is that you moved the algs[i].mc = mc after the register of algs (in drivers: crypto: meson: move algs definition and cipher API to cipher.c)
> Test could happen as soon the register is done and so mc is deferenced.

Yeah, you are right. Will fix it. Thank you.

>
> Since you didnt hit the case, I suspect you didnt test the driver as module.

No, I test the driver as module.
I think the problem is that on my system no one uses this crypto backend
outside of my tests module, unlike your system.

>
> Regards

--
Thank you,
Alexey