2013-02-21 12:19:33

by javier Martin

[permalink] [raw]
Subject: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

This series of patches provide AES-ECB and AES-CBC support
for the SAHARA2 cryptographic accelerator which is inside the i.MX27 SoC.
It is expected that more algorithms will be supported in the future.

For testing, a Visstrim M10 board has been used and the code related
to this platform has been included too.

[PATCH 1/3] i.MX27: Add platform support for SAHARA2.
[PATCH 2/3] crypto: sahara: Add driver for SAHARA2 accelerator.
[PATCH 3/3] Visstrim M10: Add support for SAHARA2 module.


2013-02-21 12:19:34

by javier Martin

[permalink] [raw]
Subject: [PATCH 1/3] i.MX27: Add platform support for SAHARA2.

i.MX27 devices include this HW cryptographic
accelerator.

Signed-off-by: Javier Martin <[email protected]>
---
arch/arm/mach-imx/clk-imx27.c | 2 ++
arch/arm/mach-imx/devices-imx27.h | 4 +++
arch/arm/mach-imx/devices/Kconfig | 4 +++
arch/arm/mach-imx/devices/Makefile | 1 +
arch/arm/mach-imx/devices/devices-common.h | 8 +++++
arch/arm/mach-imx/devices/platform-imx27-sahara.c | 37 +++++++++++++++++++++
6 files changed, 56 insertions(+)
create mode 100644 arch/arm/mach-imx/devices/platform-imx27-sahara.c

diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index 4c1d1e4..0b9664a 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -253,6 +253,8 @@ int __init mx27_clocks_init(unsigned long fref)
clk_register_clkdev(clk[nfc_baud_gate], NULL, "imx27-nand.0");
clk_register_clkdev(clk[vpu_baud_gate], "per", "coda-imx27.0");
clk_register_clkdev(clk[vpu_ahb_gate], "ahb", "coda-imx27.0");
+ clk_register_clkdev(clk[sahara_ahb_gate], "ahb", "sahara-imx27.0");
+ clk_register_clkdev(clk[sahara_ipg_gate], "ipg", "sahara-imx27.0");
clk_register_clkdev(clk[dma_ahb_gate], "ahb", "imx27-dma");
clk_register_clkdev(clk[dma_ipg_gate], "ipg", "imx27-dma");
clk_register_clkdev(clk[fec_ipg_gate], "ipg", "imx27-fec.0");
diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h
index 1309625..3bc95d8 100644
--- a/arch/arm/mach-imx/devices-imx27.h
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -20,6 +20,10 @@ extern const struct imx_imx27_coda_data imx27_coda_data;
#define imx27_add_coda() \
imx_add_imx27_coda(&imx27_coda_data)

+extern const struct imx_imx27_sahara_data imx27_sahara_data;
+#define imx27_add_sahara() \
+ imx_add_imx27_sahara(&imx27_sahara_data)
+
extern const struct imx_imx2_wdt_data imx27_imx2_wdt_data;
#define imx27_add_imx2_wdt() \
imx_add_imx2_wdt(&imx27_imx2_wdt_data)
diff --git a/arch/arm/mach-imx/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig
index 9a8f1ca..3edaa8d 100644
--- a/arch/arm/mach-imx/devices/Kconfig
+++ b/arch/arm/mach-imx/devices/Kconfig
@@ -20,6 +20,10 @@ config IMX_HAVE_PLATFORM_IMX27_CODA
bool
default y if SOC_IMX27

+config IMX_HAVE_PLATFORM_IMX27_SAHARA
+ bool
+ default y if SOC_IMX27
+
config IMX_HAVE_PLATFORM_IMX2_WDT
bool

diff --git a/arch/arm/mach-imx/devices/Makefile b/arch/arm/mach-imx/devices/Makefile
index 6acf37e..f5534a2 100644
--- a/arch/arm/mach-imx/devices/Makefile
+++ b/arch/arm/mach-imx/devices/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_GPIO_KEYS) += platform-gpio_keys.o
obj-y += platform-gpio-mxc.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX21_HCD) += platform-imx21-hcd.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX27_CODA) += platform-imx27-coda.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX27_SAHARA) += platform-imx27-sahara.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX2_WDT) += platform-imx2-wdt.o
obj-$(CONFIG_IMX_HAVE_PLATFORM_IMXDI_RTC) += platform-imxdi_rtc.o
obj-y += platform-imx-dma.o
diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h
index 6277baf..48065b2 100644
--- a/arch/arm/mach-imx/devices/devices-common.h
+++ b/arch/arm/mach-imx/devices/devices-common.h
@@ -91,6 +91,14 @@ struct imx_imx27_coda_data {
struct platform_device *__init imx_add_imx27_coda(
const struct imx_imx27_coda_data *data);

+struct imx_imx27_sahara_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init imx_add_imx27_sahara(
+ const struct imx_imx27_sahara_data *data);
+
struct imx_imx2_wdt_data {
int id;
resource_size_t iobase;
diff --git a/arch/arm/mach-imx/devices/platform-imx27-sahara.c b/arch/arm/mach-imx/devices/platform-imx27-sahara.c
new file mode 100644
index 0000000..94288f4
--- /dev/null
+++ b/arch/arm/mach-imx/devices/platform-imx27-sahara.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Vista Silicon
+ * Javier Martin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include "../hardware.h"
+#include "devices-common.h"
+
+#ifdef CONFIG_SOC_IMX27
+const struct imx_imx27_sahara_data imx27_sahara_data __initconst = {
+ .iobase = MX27_SAHARA_BASE_ADDR,
+ .iosize = SZ_2K,
+ .irq = MX27_INT_SAHARA,
+};
+#endif
+
+struct platform_device *__init imx_add_imx27_sahara(
+ const struct imx_imx27_sahara_data *data)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+ return imx_add_platform_device_dmamask("sahara-imx27", 0, res, 2, NULL,
+ 0, DMA_BIT_MASK(32));
+}
--
1.7.9.5

2013-02-21 12:19:37

by javier Martin

[permalink] [raw]
Subject: [PATCH 2/3] crypto: sahara: Add driver for SAHARA2 accelerator.

SAHARA2 HW module is included in the i.MX27 SoC from
Freescale. It is capable of performing cipher algorithms
such as AES, 3DES..., hashing and RNG too.

This driver provides support for AES-CBC and AES-ECB
by now.

Signed-off-by: Javier Martin <[email protected]>
---
drivers/crypto/Kconfig | 10 +
drivers/crypto/Makefile | 1 +
drivers/crypto/sahara.c | 1050 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 1061 insertions(+)
create mode 100644 drivers/crypto/sahara.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 87ec4d0..3a5c597 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -276,6 +276,16 @@ config CRYPTO_DEV_PICOXCELL

Saying m here will build a module named pipcoxcell_crypto.

+config CRYPTO_DEV_SAHARA
+ tristate "Support for SAHARA crypto accelerator"
+ depends on MACH_MX27 && EXPERIMENTAL
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_AES
+ select CRYPTO_ECB
+ help
+ This option enables support for the SAHARA HW crypto accelerator
+ found in some Freescale i.MX chips.
+
config CRYPTO_DEV_S5P
tristate "Support for Samsung S5PV210 crypto accelerator"
depends on ARCH_S5PV210
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 880a47b..38ce13d 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
+obj-$(CONFIG_CRYPTO_DEV_SAHARA) += sahara.o
obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o
obj-$(CONFIG_CRYPTO_DEV_UX500) += ux500/
diff --git a/drivers/crypto/sahara.c b/drivers/crypto/sahara.c
new file mode 100644
index 0000000..e880029
--- /dev/null
+++ b/drivers/crypto/sahara.c
@@ -0,0 +1,1050 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for SAHARA cryptographic accelerator.
+ *
+ * Copyright (c) 2013 Vista Silicon S.L.
+ * Author: Javier Martin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * Based on omap-aes.c and tegra-aes.c
+ */
+
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+
+#include <linux/clk.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#define SAHARA_NAME "sahara"
+#define SAHARA_VERSION_3 3
+#define SAHARA_TIMEOUT_MS 1000
+#define SAHARA_MAX_HW_DESC 2
+#define SAHARA_MAX_HW_LINK 20
+
+#define FLAGS_MODE_MASK 0x000f
+#define FLAGS_ENCRYPT BIT(0)
+#define FLAGS_CBC BIT(1)
+#define FLAGS_NEW_KEY BIT(3)
+#define FLAGS_BUSY 4
+
+#define SAHARA_HDR_BASE 0x00800000
+#define SAHARA_HDR_SKHA_ALG_AES 0
+#define SAHARA_HDR_SKHA_OP_ENC (1 << 2)
+#define SAHARA_HDR_SKHA_MODE_ECB (0 << 3)
+#define SAHARA_HDR_SKHA_MODE_CBC (1 << 3)
+#define SAHARA_HDR_FORM_DATA (5 << 16)
+#define SAHARA_HDR_FORM_KEY (8 << 16)
+#define SAHARA_HDR_LLO (1 << 24)
+#define SAHARA_HDR_CHA_SKHA (1 << 28)
+#define SAHARA_HDR_CHA_MDHA (2 << 28)
+#define SAHARA_HDR_PARITY_BIT (1 << 31)
+
+/* SAHARA can only process one request at a time */
+#define SAHARA_QUEUE_LENGTH 1
+
+#define SAHARA_REG_VERSION 0x00
+#define SAHARA_REG_DAR 0x04
+#define SAHARA_REG_CONTROL 0x08
+#define SAHARA_CONTROL_SET_THROTTLE(x) (((x) & 0xff) << 24)
+#define SAHARA_CONTROL_SET_MAXBURST(x) (((x) & 0xff) << 16)
+#define SAHARA_CONTROL_RNG_AUTORSD (1 << 7)
+#define SAHARA_CONTROL_ENABLE_INT (1 << 4)
+#define SAHARA_REG_CMD 0x0C
+#define SAHARA_CMD_RESET (1 << 0)
+#define SAHARA_CMD_CLEAR_INT (1 << 8)
+#define SAHARA_CMD_CLEAR_ERR (1 << 9)
+#define SAHARA_CMD_SINGLE_STEP (1 << 10)
+#define SAHARA_CMD_MODE_BATCH (1 << 16)
+#define SAHARA_CMD_MODE_DEBUG (1 << 18)
+#define SAHARA_REG_STATUS 0x10
+#define SAHARA_STATUS_GET_STATE(x) ((x) & 0x7)
+#define SAHARA_STATE_IDLE 0
+#define SAHARA_STATE_BUSY 1
+#define SAHARA_STATE_ERR 2
+#define SAHARA_STATE_FAULT 3
+#define SAHARA_STATE_COMPLETE 4
+#define SAHARA_STATE_COMP_FLAG (1 << 2)
+#define SAHARA_STATUS_DAR_FULL (1 << 3)
+#define SAHARA_STATUS_ERROR (1 << 4)
+#define SAHARA_STATUS_SECURE (1 << 5)
+#define SAHARA_STATUS_FAIL (1 << 6)
+#define SAHARA_STATUS_INIT (1 << 7)
+#define SAHARA_STATUS_RNG_RESEED (1 << 8)
+#define SAHARA_STATUS_ACTIVE_RNG (1 << 9)
+#define SAHARA_STATUS_ACTIVE_MDHA (1 << 10)
+#define SAHARA_STATUS_ACTIVE_SKHA (1 << 11)
+#define SAHARA_STATUS_MODE_BATCH (1 << 16)
+#define SAHARA_STATUS_MODE_DEDICATED (1 << 17)
+#define SAHARA_STATUS_MODE_DEBUG (1 << 18)
+#define SAHARA_STATUS_GET_ISTATE(x) (((x) >> 24) & 0xff)
+#define SAHARA_REG_ERRSTATUS 0x14
+#define SAHARA_ERRSTATUS_GET_SOURCE(x) ((x) & 0xf)
+#define SAHARA_ERRSOURCE_CHA 14
+#define SAHARA_ERRSOURCE_DMA 15
+#define SAHARA_ERRSTATUS_DMA_DIR (1 << 8)
+#define SAHARA_ERRSTATUS_GET_DMASZ(x)(((x) >> 9) & 0x3)
+#define SAHARA_ERRSTATUS_GET_DMASRC(x) (((x) >> 13) & 0x7)
+#define SAHARA_ERRSTATUS_GET_CHASRC(x) (((x) >> 16) & 0xfff)
+#define SAHARA_ERRSTATUS_GET_CHAERR(x) (((x) >> 28) & 0x3)
+#define SAHARA_REG_FADDR 0x18
+#define SAHARA_REG_CDAR 0x1C
+#define SAHARA_REG_IDAR 0x20
+
+struct sahara_hw_desc {
+ u32 hdr;
+ u32 len1;
+ dma_addr_t p1;
+ u32 len2;
+ dma_addr_t p2;
+ dma_addr_t next;
+};
+
+struct sahara_hw_link {
+ u32 len;
+ dma_addr_t p;
+ dma_addr_t next;
+};
+
+struct sahara_ctx {
+ struct sahara_dev *dev;
+ unsigned long flags;
+ int keylen;
+ u8 key[AES_KEYSIZE_128];
+ struct crypto_ablkcipher *fallback;
+};
+
+struct sahara_aes_reqctx {
+ unsigned long mode;
+};
+
+struct sahara_dev {
+ struct device *device;
+ void __iomem *regs_base;
+ struct clk *clk_ipg;
+ struct clk *clk_ahb;
+
+ struct sahara_ctx *ctx;
+ spinlock_t lock;
+ struct crypto_queue queue;
+ unsigned long flags;
+
+ struct tasklet_struct done_task;
+ struct tasklet_struct queue_task;
+
+ struct sahara_hw_desc *hw_desc[SAHARA_MAX_HW_DESC];
+ dma_addr_t hw_phys_desc[SAHARA_MAX_HW_DESC];
+
+ u8 *key_base;
+ dma_addr_t key_phys_base;
+
+ u8 *iv_base;
+ dma_addr_t iv_phys_base;
+
+ struct sahara_hw_link *hw_link[SAHARA_MAX_HW_LINK];
+ dma_addr_t hw_phys_link[SAHARA_MAX_HW_LINK];
+
+ struct ablkcipher_request *req;
+ size_t total;
+ struct scatterlist *in_sg;
+ unsigned int nb_in_sg;
+ struct scatterlist *out_sg;
+ unsigned int nb_out_sg;
+
+ u32 error;
+ struct timer_list watchdog;
+};
+
+static struct sahara_dev *dev_ptr;
+
+static inline void sahara_write(struct sahara_dev *dev, u32 data, u32 reg)
+{
+ writel(data, dev->regs_base + reg);
+}
+
+static inline unsigned int sahara_read(struct sahara_dev *dev, u32 reg)
+{
+ return readl(dev->regs_base + reg);
+}
+
+static u32 sahara_aes_key_hdr(struct sahara_dev *dev)
+{
+ u32 hdr = SAHARA_HDR_BASE | SAHARA_HDR_SKHA_ALG_AES |
+ SAHARA_HDR_FORM_KEY | SAHARA_HDR_LLO |
+ SAHARA_HDR_CHA_SKHA | SAHARA_HDR_PARITY_BIT;
+
+ if (dev->flags & FLAGS_CBC) {
+ hdr |= SAHARA_HDR_SKHA_MODE_CBC;
+ hdr ^= SAHARA_HDR_PARITY_BIT;
+ }
+
+ if (dev->flags & FLAGS_ENCRYPT) {
+ hdr |= SAHARA_HDR_SKHA_OP_ENC;
+ hdr ^= SAHARA_HDR_PARITY_BIT;
+ }
+
+ return hdr;
+}
+
+static u32 sahara_aes_data_link_hdr(struct sahara_dev *dev)
+{
+ return SAHARA_HDR_BASE | SAHARA_HDR_FORM_DATA |
+ SAHARA_HDR_CHA_SKHA | SAHARA_HDR_PARITY_BIT;
+}
+
+static int sahara_sg_length(struct scatterlist *sg,
+ unsigned int total)
+{
+ int sg_nb;
+ unsigned int len;
+ struct scatterlist *sg_list;
+
+ sg_nb = 0;
+ sg_list = sg;
+
+ while (total) {
+ len = min(sg_list->length, total);
+
+ sg_nb++;
+ total -= len;
+
+ sg_list = sg_next(sg_list);
+ if (!sg_list)
+ total = 0;
+ }
+
+ return sg_nb;
+}
+
+static char *sahara_err_src[16] = {
+ "No error",
+ "Header error",
+ "Descriptor length error",
+ "Descriptor length or pointer error",
+ "Link length error",
+ "Link pointer error",
+ "Input buffer error",
+ "Output buffer error",
+ "Output buffer starvation",
+ "Internal state fault",
+ "General descriptor problem",
+ "Reserved",
+ "Descriptor address error",
+ "Link address error",
+ "CHA error",
+ "DMA error"
+};
+
+static char *sahara_err_dmasize[4] = {
+ "Byte transfer",
+ "Half-word transfer",
+ "Word transfer",
+ "Reserved"
+};
+
+static char *sahara_err_dmasrc[8] = {
+ "No error",
+ "AHB bus error",
+ "Internal IP bus error",
+ "Parity error",
+ "DMA crosses 256 byte boundary",
+ "DMA is busy",
+ "Reserved",
+ "DMA HW error"
+};
+
+static char *sahara_cha_errsrc[12] = {
+ "Input buffer non-empty",
+ "Illegal address",
+ "Illegal mode",
+ "Illegal data size",
+ "Illegal key size",
+ "Write during processing",
+ "CTX read during processing",
+ "HW error",
+ "Input buffer disabled/underflow",
+ "Output buffer disabled/overflow",
+ "DES key parity error",
+ "Reserved"
+};
+
+static char *sahara_cha_err[4] = { "No error", "SKHA", "MDHA", "RNG" };
+
+static void sahara_decode_error(struct sahara_dev *dev, unsigned int error)
+{
+ u8 source = SAHARA_ERRSTATUS_GET_SOURCE(error);
+ u16 chasrc = ffs(SAHARA_ERRSTATUS_GET_CHASRC(error));
+
+ dev_err(dev->device, "%s: Error Register = 0x%08x\n", __func__, error);
+
+ dev_err(dev->device, " - %s.\n", sahara_err_src[source]);
+
+ if (source == SAHARA_ERRSOURCE_DMA) {
+ if (error & SAHARA_ERRSTATUS_DMA_DIR)
+ dev_err(dev->device, " * DMA read.\n");
+ else
+ dev_err(dev->device, " * DMA write.\n");
+
+ dev_err(dev->device, " * %s.\n",
+ sahara_err_dmasize[SAHARA_ERRSTATUS_GET_DMASZ(error)]);
+ dev_err(dev->device, " * %s.\n",
+ sahara_err_dmasrc[SAHARA_ERRSTATUS_GET_DMASRC(error)]);
+ } else if (source == SAHARA_ERRSOURCE_CHA) {
+ dev_err(dev->device, " * %s.\n",
+ sahara_cha_errsrc[chasrc]);
+ dev_err(dev->device, " * %s.\n",
+ sahara_cha_err[SAHARA_ERRSTATUS_GET_CHAERR(error)]);
+ }
+ dev_err(dev->device, "\n");
+}
+
+#ifdef DEBUG
+
+static char *sahara_state[4] = { "Idle", "Busy", "Error", "HW Fault" };
+
+static void sahara_decode_status(struct sahara_dev *dev, unsigned int status)
+{
+ u8 state = SAHARA_STATUS_GET_STATE(status);
+
+ dev_dbg(dev->device, "%s: Status Register = 0x%08x\n",
+ __func__, status);
+
+ dev_dbg(dev->device, " - State = %d:\n", state);
+ if (state & SAHARA_STATE_COMP_FLAG)
+ dev_dbg(dev->device, " * Descriptor completed. IRQ pending.\n");
+
+ dev_dbg(dev->device, " * %s.\n",
+ sahara_state[state & ~SAHARA_STATE_COMP_FLAG]);
+
+ if (status & SAHARA_STATUS_DAR_FULL)
+ dev_dbg(dev->device, " - DAR Full.\n");
+ if (status & SAHARA_STATUS_ERROR)
+ dev_dbg(dev->device, " - Error.\n");
+ if (status & SAHARA_STATUS_SECURE)
+ dev_dbg(dev->device, " - Secure.\n");
+ if (status & SAHARA_STATUS_FAIL)
+ dev_dbg(dev->device, " - Fail.\n");
+ if (status & SAHARA_STATUS_RNG_RESEED)
+ dev_dbg(dev->device, " - RNG Reseed Request.\n");
+ if (status & SAHARA_STATUS_ACTIVE_RNG)
+ dev_dbg(dev->device, " - RNG Active.\n");
+ if (status & SAHARA_STATUS_ACTIVE_MDHA)
+ dev_dbg(dev->device, " - MDHA Active.\n");
+ if (status & SAHARA_STATUS_ACTIVE_SKHA)
+ dev_dbg(dev->device, " - SKHA Active.\n");
+
+ if (status & SAHARA_STATUS_MODE_BATCH)
+ dev_dbg(dev->device, " - Batch Mode.\n");
+ else if (status & SAHARA_STATUS_MODE_DEDICATED)
+ dev_dbg(dev->device, " - Decidated Mode.\n");
+ else if (status & SAHARA_STATUS_MODE_DEBUG)
+ dev_dbg(dev->device, " - Debug Mode.\n");
+
+ dev_dbg(dev->device, " - Internal state = 0x%02x\n",
+ SAHARA_STATUS_GET_ISTATE(status));
+
+ dev_dbg(dev->device, "Current DAR: 0x%08x\n",
+ sahara_read(dev, SAHARA_REG_CDAR));
+ dev_dbg(dev->device, "Initial DAR: 0x%08x\n\n",
+ sahara_read(dev, SAHARA_REG_IDAR));
+}
+
+static void sahara_dump_descriptors(struct sahara_dev *dev)
+{
+ int i;
+
+ for (i = 0; i < SAHARA_MAX_HW_DESC; i++) {
+ dev_dbg(dev->device, "Descriptor (%d) (0x%08x):\n",
+ i, dev->hw_phys_desc[i]);
+ dev_dbg(dev->device, "\thdr = 0x%08x\n", dev->hw_desc[i]->hdr);
+ dev_dbg(dev->device, "\tlen1 = %u\n", dev->hw_desc[i]->len1);
+ dev_dbg(dev->device, "\tp1 = 0x%08x\n", dev->hw_desc[i]->p1);
+ dev_dbg(dev->device, "\tlen2 = %u\n", dev->hw_desc[i]->len2);
+ dev_dbg(dev->device, "\tp2 = 0x%08x\n", dev->hw_desc[i]->p2);
+ dev_dbg(dev->device, "\tnext = 0x%08x\n",
+ dev->hw_desc[i]->next);
+ }
+ dev_dbg(dev->device, "\n");
+}
+
+static void sahara_dump_links(struct sahara_dev *dev)
+{
+ int i;
+
+ for (i = 0; i < SAHARA_MAX_HW_LINK; i++) {
+ dev_dbg(dev->device, "Link (%d) (0x%08x):\n",
+ i, dev->hw_phys_link[i]);
+ dev_dbg(dev->device, "\tlen = %u\n", dev->hw_link[i]->len);
+ dev_dbg(dev->device, "\tp = 0x%08x\n", dev->hw_link[i]->p);
+ dev_dbg(dev->device, "\tnext = 0x%08x\n",
+ dev->hw_link[i]->next);
+ }
+ dev_dbg(dev->device, "\n");
+}
+
+#endif /* DEBUG */
+
+static void sahara_aes_done_task(unsigned long data)
+{
+ struct sahara_dev *dev = (struct sahara_dev *)data;
+ unsigned long flags;
+
+ dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg,
+ DMA_TO_DEVICE);
+ dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg,
+ DMA_FROM_DEVICE);
+
+ spin_lock_irqsave(&dev->lock, flags);
+ clear_bit(FLAGS_BUSY, &dev->flags);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ dev->req->base.complete(&dev->req->base, dev->error);
+}
+
+void sahara_watchdog(unsigned long data)
+{
+ struct sahara_dev *dev = (struct sahara_dev *)data;
+ unsigned int err = sahara_read(dev, SAHARA_REG_ERRSTATUS);
+#ifdef DEBUG
+ unsigned int stat = sahara_read(dev, SAHARA_REG_STATUS);
+ sahara_decode_status(dev, stat);
+#endif
+
+ sahara_decode_error(dev, err);
+ dev->error = -ETIMEDOUT;
+ sahara_aes_done_task(data);
+}
+
+static int sahara_hw_descriptor_create(struct sahara_dev *dev)
+{
+ struct sahara_ctx *ctx = dev->ctx;
+ struct scatterlist *sg;
+ int ret;
+ int i, j;
+
+ /* Copy new key if necessary */
+ if (ctx->flags & FLAGS_NEW_KEY) {
+ memcpy(dev->key_base, ctx->key, ctx->keylen);
+ ctx->flags &= ~FLAGS_NEW_KEY;
+
+ if (dev->flags & FLAGS_CBC) {
+ dev->hw_desc[0]->len1 = AES_BLOCK_SIZE;
+ dev->hw_desc[0]->p1 = dev->iv_phys_base;
+ } else {
+ dev->hw_desc[0]->len1 = 0;
+ dev->hw_desc[0]->p1 = 0;
+ }
+ dev->hw_desc[0]->len2 = ctx->keylen;
+ dev->hw_desc[0]->p2 = dev->key_phys_base;
+ dev->hw_desc[0]->next = dev->hw_phys_desc[1];
+ }
+ dev->hw_desc[0]->hdr = sahara_aes_key_hdr(dev);
+
+ dev->nb_in_sg = sahara_sg_length(dev->in_sg, dev->total);
+ dev->nb_out_sg = sahara_sg_length(dev->out_sg, dev->total);
+ if ((dev->nb_in_sg + dev->nb_out_sg) > SAHARA_MAX_HW_LINK) {
+ dev_err(dev->device, "not enough hw links (%d)\n",
+ dev->nb_in_sg + dev->nb_out_sg);
+ return -EINVAL;
+ }
+
+ ret = dma_map_sg(dev->device, dev->in_sg, dev->nb_in_sg,
+ DMA_TO_DEVICE);
+ if (ret != dev->nb_in_sg) {
+ dev_err(dev->device, "couldn't map in sg\n");
+ goto unmap_in;
+ }
+ ret = dma_map_sg(dev->device, dev->out_sg, dev->nb_out_sg,
+ DMA_FROM_DEVICE);
+ if (ret != dev->nb_out_sg) {
+ dev_err(dev->device, "couldn't map out sg\n");
+ goto unmap_out;
+ }
+
+ /* Create input links */
+ dev->hw_desc[1]->p1 = dev->hw_phys_link[0];
+ sg = dev->in_sg;
+ for (i = 0; i < dev->nb_in_sg; i++) {
+ dev->hw_link[i]->len = sg->length;
+ dev->hw_link[i]->p = sg->dma_address;
+ if (i == (dev->nb_in_sg - 1)) {
+ dev->hw_link[i]->next = 0;
+ } else {
+ dev->hw_link[i]->next = dev->hw_phys_link[i + 1];
+ sg = sg_next(sg);
+ }
+ }
+
+ /* Create output links */
+ dev->hw_desc[1]->p2 = dev->hw_phys_link[i];
+ sg = dev->out_sg;
+ for (j = i; j < dev->nb_out_sg + i; j++) {
+ dev->hw_link[j]->len = sg->length;
+ dev->hw_link[j]->p = sg->dma_address;
+ if (j == (dev->nb_out_sg + i - 1)) {
+ dev->hw_link[j]->next = 0;
+ } else {
+ dev->hw_link[j]->next = dev->hw_phys_link[j + 1];
+ sg = sg_next(sg);
+ }
+ }
+
+ /* Fill remaining fields of hw_desc[1] */
+ dev->hw_desc[1]->hdr = sahara_aes_data_link_hdr(dev);
+ dev->hw_desc[1]->len1 = dev->total;
+ dev->hw_desc[1]->len2 = dev->total;
+ dev->hw_desc[1]->next = 0;
+
+#ifdef DEBUG
+ sahara_dump_descriptors(dev);
+ sahara_dump_links(dev);
+#endif
+
+ /* Start processing descriptor chain. */
+ mod_timer(&dev->watchdog,
+ jiffies + msecs_to_jiffies(SAHARA_TIMEOUT_MS));
+ sahara_write(dev, dev->hw_phys_desc[0], SAHARA_REG_DAR);
+
+ return 0;
+
+unmap_out:
+ dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg,
+ DMA_TO_DEVICE);
+unmap_in:
+ dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg,
+ DMA_FROM_DEVICE);
+
+ return -EINVAL;
+}
+
+static void sahara_aes_queue_task(unsigned long data)
+{
+ struct sahara_dev *dev = (struct sahara_dev *)data;
+ struct crypto_async_request *async_req, *backlog;
+ struct sahara_ctx *ctx;
+ struct sahara_aes_reqctx *rctx;
+ struct ablkcipher_request *req;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&dev->lock, flags);
+ backlog = crypto_get_backlog(&dev->queue);
+ async_req = crypto_dequeue_request(&dev->queue);
+ if (!async_req)
+ clear_bit(FLAGS_BUSY, &dev->flags);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ if (!async_req)
+ return;
+
+ if (backlog)
+ backlog->complete(backlog, -EINPROGRESS);
+
+ req = ablkcipher_request_cast(async_req);
+
+ /* Request is ready to be dispatched by the device */
+ dev_dbg(dev->device,
+ "dispatch request (nbytes=%d, src=%p, dst=%p)\n",
+ req->nbytes, req->src, req->dst);
+
+ /* assign new request to device */
+ dev->req = req;
+ dev->total = req->nbytes;
+ dev->in_sg = req->src;
+ dev->out_sg = req->dst;
+
+ rctx = ablkcipher_request_ctx(req);
+ ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req));
+ rctx->mode &= FLAGS_MODE_MASK;
+ dev->flags = (dev->flags & ~FLAGS_MODE_MASK) | rctx->mode;
+
+ if ((dev->flags & FLAGS_CBC) && req->info)
+ memcpy(dev->iv_base, req->info, AES_KEYSIZE_128);
+
+ /* assign new context to device */
+ ctx->dev = dev;
+ dev->ctx = ctx;
+
+ ret = sahara_hw_descriptor_create(dev);
+ if (ret < 0) {
+ spin_lock_irqsave(&dev->lock, flags);
+ clear_bit(FLAGS_BUSY, &dev->flags);
+ spin_unlock_irqrestore(&dev->lock, flags);
+ dev->req->base.complete(&dev->req->base, ret);
+ }
+}
+
+static int sahara_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct sahara_ctx *ctx = crypto_ablkcipher_ctx(tfm);
+ int ret;
+
+ ctx->keylen = keylen;
+
+ /* SAHARA only supports 128bit keys */
+ if (keylen == AES_KEYSIZE_128) {
+ memcpy(ctx->key, key, keylen);
+ ctx->flags |= FLAGS_NEW_KEY;
+ return 0;
+ }
+
+ if (keylen != AES_KEYSIZE_128 &&
+ keylen != AES_KEYSIZE_192 && keylen != AES_KEYSIZE_256)
+ return -EINVAL;
+
+ /*
+ * The requested key size is not supported by HW, do a fallback.
+ */
+ ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
+ ctx->fallback->base.crt_flags |=
+ (tfm->base.crt_flags & CRYPTO_TFM_REQ_MASK);
+
+ ret = crypto_ablkcipher_setkey(ctx->fallback, key, keylen);
+ if (ret) {
+ struct crypto_tfm *tfm_aux = crypto_ablkcipher_tfm(tfm);
+
+ tfm_aux->crt_flags &= ~CRYPTO_TFM_RES_MASK;
+ tfm_aux->crt_flags |=
+ (ctx->fallback->base.crt_flags & CRYPTO_TFM_RES_MASK);
+ }
+ return ret;
+}
+
+static int sahara_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
+{
+ struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
+ crypto_ablkcipher_reqtfm(req));
+ struct sahara_aes_reqctx *rctx = ablkcipher_request_ctx(req);
+ struct sahara_dev *dev = dev_ptr;
+ unsigned long flags;
+ int err = 0;
+ int busy;
+
+ dev_dbg(dev->device, "nbytes: %d, enc: %d, cbc: %d\n",
+ req->nbytes, !!(mode & FLAGS_ENCRYPT), !!(mode & FLAGS_CBC));
+
+ if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) {
+ dev_err(dev->device,
+ "request size is not exact amount of AES blocks\n");
+ return -EINVAL;
+ }
+
+ ctx->dev = dev;
+
+ rctx->mode = mode;
+ spin_lock_irqsave(&dev->lock, flags);
+ err = ablkcipher_enqueue_request(&dev->queue, req);
+ busy = test_and_set_bit(FLAGS_BUSY, &dev->flags);
+ spin_unlock_irqrestore(&dev->lock, flags);
+
+ if (!busy)
+ tasklet_schedule(&dev->queue_task);
+
+ return err;
+}
+
+static int sahara_aes_ecb_encrypt(struct ablkcipher_request *req)
+{
+ struct crypto_tfm *tfm =
+ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
+ struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
+ crypto_ablkcipher_reqtfm(req));
+ int err;
+
+ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
+ ablkcipher_request_set_tfm(req, ctx->fallback);
+ err = crypto_ablkcipher_encrypt(req);
+ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
+ return err;
+ }
+
+ return sahara_aes_crypt(req, FLAGS_ENCRYPT);
+}
+
+static int sahara_aes_ecb_decrypt(struct ablkcipher_request *req)
+{
+ struct crypto_tfm *tfm =
+ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
+ struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
+ crypto_ablkcipher_reqtfm(req));
+ int err;
+
+ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
+ ablkcipher_request_set_tfm(req, ctx->fallback);
+ err = crypto_ablkcipher_decrypt(req);
+ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
+ return err;
+ }
+
+ return sahara_aes_crypt(req, 0);
+}
+
+static int sahara_aes_cbc_encrypt(struct ablkcipher_request *req)
+{
+ struct crypto_tfm *tfm =
+ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
+ struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
+ crypto_ablkcipher_reqtfm(req));
+ int err;
+
+ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
+ ablkcipher_request_set_tfm(req, ctx->fallback);
+ err = crypto_ablkcipher_encrypt(req);
+ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
+ return err;
+ }
+
+ return sahara_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC);
+}
+
+static int sahara_aes_cbc_decrypt(struct ablkcipher_request *req)
+{
+ struct crypto_tfm *tfm =
+ crypto_ablkcipher_tfm(crypto_ablkcipher_reqtfm(req));
+ struct sahara_ctx *ctx = crypto_ablkcipher_ctx(
+ crypto_ablkcipher_reqtfm(req));
+ int err;
+
+ if (unlikely(ctx->keylen != AES_KEYSIZE_128)) {
+ ablkcipher_request_set_tfm(req, ctx->fallback);
+ err = crypto_ablkcipher_decrypt(req);
+ ablkcipher_request_set_tfm(req, __crypto_ablkcipher_cast(tfm));
+ return err;
+ }
+
+ return sahara_aes_crypt(req, FLAGS_CBC);
+}
+
+static int sahara_aes_cra_init(struct crypto_tfm *tfm)
+{
+ const char *name = tfm->__crt_alg->cra_name;
+ struct sahara_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ ctx->fallback = crypto_alloc_ablkcipher(name, 0,
+ CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(ctx->fallback)) {
+ pr_err("Error allocating fallback algo %s\n", name);
+ return PTR_ERR(ctx->fallback);
+ }
+
+ tfm->crt_ablkcipher.reqsize = sizeof(struct sahara_aes_reqctx);
+
+ return 0;
+}
+
+static void sahara_aes_cra_exit(struct crypto_tfm *tfm)
+{
+ struct sahara_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (ctx->fallback)
+ crypto_free_ablkcipher(ctx->fallback);
+ ctx->fallback = NULL;
+}
+
+static struct crypto_alg aes_algs[] = {
+{
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "sahara-ecb-aes",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+ CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct sahara_ctx),
+ .cra_alignmask = 0x0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = sahara_aes_cra_init,
+ .cra_exit = sahara_aes_cra_exit,
+ .cra_u.ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE ,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = sahara_aes_setkey,
+ .encrypt = sahara_aes_ecb_encrypt,
+ .decrypt = sahara_aes_ecb_decrypt,
+ }
+}, {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "sahara-cbc-aes",
+ .cra_priority = 300,
+ .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+ CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct sahara_ctx),
+ .cra_alignmask = 0x0,
+ .cra_type = &crypto_ablkcipher_type,
+ .cra_module = THIS_MODULE,
+ .cra_init = sahara_aes_cra_init,
+ .cra_exit = sahara_aes_cra_exit,
+ .cra_u.ablkcipher = {
+ .min_keysize = AES_MIN_KEY_SIZE ,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = sahara_aes_setkey,
+ .encrypt = sahara_aes_cbc_encrypt,
+ .decrypt = sahara_aes_cbc_decrypt,
+ }
+}
+};
+
+static irqreturn_t sahara_irq_handler(int irq, void *data)
+{
+ struct sahara_dev *dev = (struct sahara_dev *)data;
+ unsigned int stat = sahara_read(dev, SAHARA_REG_STATUS);
+ unsigned int err = sahara_read(dev, SAHARA_REG_ERRSTATUS);
+
+ del_timer(&dev->watchdog);
+
+ sahara_write(dev, SAHARA_CMD_CLEAR_INT | SAHARA_CMD_CLEAR_ERR,
+ SAHARA_REG_CMD);
+
+#ifdef DEBUG
+ sahara_decode_status(dev, stat);
+#endif
+
+ if (SAHARA_STATUS_GET_STATE(stat) == SAHARA_STATE_BUSY) {
+ return IRQ_NONE;
+ } else if (SAHARA_STATUS_GET_STATE(stat) == SAHARA_STATE_COMPLETE) {
+ dev->error = 0;
+ } else {
+ sahara_decode_error(dev, err);
+ dev->error = -EINVAL;
+ }
+
+ tasklet_schedule(&dev->done_task);
+
+ return IRQ_HANDLED;
+}
+
+
+static int sahara_register_algs(struct sahara_dev *dev)
+{
+ int err, i, j;
+
+ for (i = 0; i < ARRAY_SIZE(aes_algs); i++) {
+ INIT_LIST_HEAD(&aes_algs[i].cra_list);
+ err = crypto_register_alg(&aes_algs[i]);
+ if (err)
+ goto err_aes_algs;
+ }
+
+ return 0;
+
+err_aes_algs:
+ for (j = 0; j < i; j++)
+ crypto_unregister_alg(&aes_algs[j]);
+
+ return err;
+}
+
+static void sahara_unregister_algs(struct sahara_dev *dev)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(aes_algs); i++)
+ crypto_unregister_alg(&aes_algs[i]);
+}
+
+static struct platform_device_id sahara_platform_ids[] = {
+ { .name = "sahara-imx27" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, sahara_platform_ids);
+
+static int __devinit sahara_probe(struct platform_device *pdev)
+{
+ struct sahara_dev *dev;
+ struct resource *res;
+ u32 version;
+ int irq;
+ int err;
+ int i;
+
+ dev = devm_kzalloc(&pdev->dev, sizeof(struct sahara_dev), GFP_KERNEL);
+ if (dev == NULL) {
+ dev_err(&pdev->dev, "unable to alloc data struct.\n");
+ return -ENOMEM;
+ }
+
+ dev->device = &pdev->dev;
+ platform_set_drvdata(pdev, dev);
+
+ /* Get the base address */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to get memory region resource\n");
+ return -ENODEV;
+ }
+
+ if (devm_request_mem_region(&pdev->dev, res->start,
+ resource_size(res), SAHARA_NAME) == NULL) {
+ dev_err(&pdev->dev, "failed to request memory region\n");
+ return -ENOENT;
+ }
+ dev->regs_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!dev->regs_base) {
+ dev_err(&pdev->dev, "failed to ioremap address region\n");
+ return -ENOENT;
+ }
+
+ /* Get the IRQ */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get irq resource\n");
+ return irq;
+ }
+
+ if (devm_request_irq(&pdev->dev, irq, sahara_irq_handler,
+ 0, SAHARA_NAME, dev) < 0) {
+ dev_err(&pdev->dev, "failed to request irq\n");
+ return -ENOENT;
+ }
+
+ /* clocks */
+ dev->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+ if (IS_ERR(dev->clk_ipg)) {
+ dev_err(&pdev->dev, "Could not get ipg clock\n");
+ return PTR_ERR(dev->clk_ipg);
+ }
+
+ dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
+ if (IS_ERR(dev->clk_ahb)) {
+ dev_err(&pdev->dev, "Could not get ahb clock\n");
+ return PTR_ERR(dev->clk_ahb);
+ }
+
+ /* Allocate HW descriptors */
+ dev->hw_desc[0] = dma_alloc_coherent(&pdev->dev,
+ SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc),
+ &dev->hw_phys_desc[0], GFP_KERNEL);
+ if (!dev->hw_desc[0]) {
+ dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
+ return -ENOMEM;
+ }
+ dev->hw_desc[1] = dev->hw_desc[0] + 1;
+ dev->hw_phys_desc[1] = dev->hw_phys_desc[0] +
+ sizeof(struct sahara_hw_desc);
+
+ /* Allocate space for iv and key */
+ dev->key_base = dma_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128,
+ &dev->key_phys_base, GFP_KERNEL);
+ if (!dev->key_base) {
+ dev_err(&pdev->dev, "Could not allocate memory for key\n");
+ err = -ENOMEM;
+ goto err_key;
+ }
+ dev->iv_base = dev->key_base + AES_KEYSIZE_128;
+ dev->iv_phys_base = dev->key_phys_base + AES_KEYSIZE_128;
+
+ /* Allocate space for HW links */
+ dev->hw_link[0] = dma_alloc_coherent(&pdev->dev,
+ SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link),
+ &dev->hw_phys_link[0], GFP_KERNEL);
+ if (!dev->hw_link) {
+ dev_err(&pdev->dev, "Could not allocate hw links\n");
+ err = -ENOMEM;
+ goto err_link;
+ }
+ for (i = 1; i < SAHARA_MAX_HW_LINK; i++) {
+ dev->hw_phys_link[i] = dev->hw_phys_link[i - 1] +
+ sizeof(struct sahara_hw_link);
+ dev->hw_link[i] = dev->hw_link[i - 1] + 1;
+ }
+
+ crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH);
+
+ dev_ptr = dev;
+
+ tasklet_init(&dev->queue_task, sahara_aes_queue_task,
+ (unsigned long)dev);
+ tasklet_init(&dev->done_task, sahara_aes_done_task,
+ (unsigned long)dev);
+
+ init_timer(&dev->watchdog);
+ dev->watchdog.function = &sahara_watchdog;
+ dev->watchdog.data = (unsigned long)dev;
+
+ clk_prepare_enable(dev->clk_ipg);
+ clk_prepare_enable(dev->clk_ahb);
+
+ version = sahara_read(dev, SAHARA_REG_VERSION);
+ if (version != SAHARA_VERSION_3) {
+ dev_err(&pdev->dev, "SAHARA version %d not supported\n",
+ version);
+ err = -ENODEV;
+ goto err_algs;
+ }
+
+ sahara_write(dev, SAHARA_CMD_RESET | SAHARA_CMD_MODE_BATCH,
+ SAHARA_REG_CMD);
+ sahara_write(dev, SAHARA_CONTROL_SET_THROTTLE(0) |
+ SAHARA_CONTROL_SET_MAXBURST(8) |
+ SAHARA_CONTROL_RNG_AUTORSD |
+ SAHARA_CONTROL_ENABLE_INT,
+ SAHARA_REG_CONTROL);
+
+ err = sahara_register_algs(dev);
+ if (err)
+ goto err_algs;
+
+ dev_info(&pdev->dev, "SAHARA version %d initialized\n", version);
+
+ return 0;
+
+err_algs:
+ dev_ptr = NULL;
+ kfree(dev->key_base);
+ clk_disable_unprepare(dev->clk_ipg);
+ clk_disable_unprepare(dev->clk_ahb);
+err_link:
+ kfree(dev->key_base);
+err_key:
+ kfree(dev->hw_desc[0]);
+ return err;
+}
+
+static int __devexit sahara_remove(struct platform_device *pdev)
+{
+ struct sahara_dev *dev = platform_get_drvdata(pdev);
+
+ kfree(dev->key_base);
+ kfree(dev->hw_desc[0]);
+
+ tasklet_kill(&dev->done_task);
+ tasklet_kill(&dev->queue_task);
+
+ sahara_unregister_algs(dev);
+
+ clk_disable_unprepare(dev->clk_ipg);
+ clk_disable_unprepare(dev->clk_ahb);
+
+ dev_ptr = NULL;
+
+ return 0;
+}
+
+static struct platform_driver sahara_driver = {
+ .probe = sahara_probe,
+ .remove = __devexit_p(sahara_remove),
+ .driver = {
+ .name = SAHARA_NAME,
+ .owner = THIS_MODULE,
+ },
+ .id_table = sahara_platform_ids,
+};
+
+module_platform_driver(sahara_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Javier Martin <[email protected]>");
+MODULE_DESCRIPTION("SAHARA2 HW crypto accelerator");
--
1.7.9.5

2013-02-21 12:19:39

by javier Martin

[permalink] [raw]
Subject: [PATCH 3/3] Visstrim M10: Add support for SAHARA2 module.


Signed-off-by: Javier Martin <[email protected]>
---
arch/arm/mach-imx/Kconfig | 1 +
arch/arm/mach-imx/mach-imx27_visstrim_m10.c | 1 +
2 files changed, 2 insertions(+)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 1ad0d76..d232a56 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -402,6 +402,7 @@ config MACH_IMX27_VISSTRIM_M10
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MX2_CAMERA
select IMX_HAVE_PLATFORM_MX2_EMMA
+ select IMX_HAVE_PLATFORM_IMX27_SAHARA
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_MMC
select LEDS_GPIO_REGISTER
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index 318bd8d..b051592 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -565,6 +565,7 @@ static void __init visstrim_m10_board_init(void)
imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata);
imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata);
imx27_add_fec(NULL);
+ imx27_add_sahara();
imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata,
--
1.7.9.5

2013-02-21 12:59:49

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

On Thursday 21 February 2013, Javier Martin wrote:
> This series of patches provide AES-ECB and AES-CBC support
> for the SAHARA2 cryptographic accelerator which is inside the i.MX27 SoC.
> It is expected that more algorithms will be supported in the future.
>
> For testing, a Visstrim M10 board has been used and the code related
> to this platform has been included too.

As a new device driver, this needs to be supported on the DT based imx27
machines, while support for the individual board files seems unnecessary.

How about converting the Visstrim M10 board file over to DT so you don't
have to add any more infrastructure for imx that we will just have to
remove again one day?

Arnd

2013-02-21 13:14:05

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 2/3] crypto: sahara: Add driver for SAHARA2 accelerator.

On Thursday 21 February 2013, Javier Martin wrote:
> +
> +struct sahara_dev {
> + struct device *device;
> + void __iomem *regs_base;
> + struct clk *clk_ipg;
> + struct clk *clk_ahb;
> +
> + struct sahara_ctx *ctx;
> + spinlock_t lock;
> + struct crypto_queue queue;
> + unsigned long flags;
> +
> + struct tasklet_struct done_task;
> + struct tasklet_struct queue_task;
> +
> + struct sahara_hw_desc *hw_desc[SAHARA_MAX_HW_DESC];
> + dma_addr_t hw_phys_desc[SAHARA_MAX_HW_DESC];
> +
> + u8 *key_base;
> + dma_addr_t key_phys_base;
> +
> + u8 *iv_base;
> + dma_addr_t iv_phys_base;
> +
> + struct sahara_hw_link *hw_link[SAHARA_MAX_HW_LINK];
> + dma_addr_t hw_phys_link[SAHARA_MAX_HW_LINK];
> +
> + struct ablkcipher_request *req;
> + size_t total;
> + struct scatterlist *in_sg;
> + unsigned int nb_in_sg;
> + struct scatterlist *out_sg;
> + unsigned int nb_out_sg;
> +
> + u32 error;
> + struct timer_list watchdog;
> +};
> +
> +static struct sahara_dev *dev_ptr;

Please remove this global device pointer, it should not be needed, since you
can store the pointer in the context object.


> +#ifdef DEBUG
> +
> +static char *sahara_state[4] = { "Idle", "Busy", "Error", "HW Fault" };
> +
> +static void sahara_decode_status(struct sahara_dev *dev, unsigned int status)
> +{
> + u8 state = SAHARA_STATUS_GET_STATE(status);

You can simplify the code a lot if you replace the #ifdef around the function
with an

if (!IS_ENBLED(DEBUG))
return;

at the start of the function. That will lead to gcc completely removing the
code an everything referenced by it.


> +static void sahara_aes_done_task(unsigned long data)
> +{
> + struct sahara_dev *dev = (struct sahara_dev *)data;
> + unsigned long flags;
> +
> + dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg,
> + DMA_TO_DEVICE);
> + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg,
> + DMA_FROM_DEVICE);
> +
> + spin_lock_irqsave(&dev->lock, flags);
> + clear_bit(FLAGS_BUSY, &dev->flags);
> + spin_unlock_irqrestore(&dev->lock, flags);
> +
> + dev->req->base.complete(&dev->req->base, dev->error);
> +}

Does dev->lock have to be irq-disabled? You don't seem to take it
from an interrupt handler.

Also, when you know that code is called without irqs enabled and
you just want to disable them, you can use the cheaper spin_lock_irq()
rather than spin_lock_irqsave().

In short, use either spin_lock_irq or spin_lock here. When protecting
against a tasklet, you will need spin_lock_bh.

> +
> +void sahara_watchdog(unsigned long data)
> +{
> + struct sahara_dev *dev = (struct sahara_dev *)data;
> + unsigned int err = sahara_read(dev, SAHARA_REG_ERRSTATUS);
> +#ifdef DEBUG
> + unsigned int stat = sahara_read(dev, SAHARA_REG_STATUS);
> + sahara_decode_status(dev, stat);
> +#endif

When you kill off the #ifdef, you should move this sahara_read()
call into the sahara_decode_status() function so it gets
compiled conditionally.

> +static struct platform_device_id sahara_platform_ids[] = {
> + { .name = "sahara-imx27" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(platform, sahara_platform_ids);

You are missing the of_device_ids here. We probably don't even
need the platform_device_id list and can instead mandate that
this is only used by platforms that are already converted to
DT booting.

Please also add a DT binding document for this driver that mentions
the name and the resources that need to be provided.

Arnd

2013-02-21 14:18:37

by javier Martin

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

Hi Arnd,

On 21 February 2013 13:59, Arnd Bergmann <[email protected]> wrote:
> On Thursday 21 February 2013, Javier Martin wrote:
>> This series of patches provide AES-ECB and AES-CBC support
>> for the SAHARA2 cryptographic accelerator which is inside the i.MX27 SoC.
>> It is expected that more algorithms will be supported in the future.
>>
>> For testing, a Visstrim M10 board has been used and the code related
>> to this platform has been included too.
>
> As a new device driver, this needs to be supported on the DT based imx27
> machines, while support for the individual board files seems unnecessary.
>
> How about converting the Visstrim M10 board file over to DT so you don't
> have to add any more infrastructure for imx that we will just have to
> remove again one day?

We know about the existence of DT and the constant migration process
that is taking place towards it.

Moreover we are strongly interested in converting the Visstrim SM10
platform to DT. Unfortunately, there are several issues that need to
be solved so that Visstrim M10 can be fully converted to DT:
- full SoC camera DT support
- DT support for ov7670
- pinctrl support for i.MX27

Furthermore, we have limited resources at the moment and we have to
decide priorities. But having an hybrid platform-DT support is our
next task for Visstrim M10.

However, I understand your concern about new drivers having DT
support. Maybe a good approach could be that I added compile-tested
only DT support for this driver and remove platform support for
mainline submission (although we maintain it internally in our
repositories).

What do you think?

Regards.
--
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
http://www.vista-silicon.com

2013-02-21 14:35:27

by javier Martin

[permalink] [raw]
Subject: Re: [PATCH 2/3] crypto: sahara: Add driver for SAHARA2 accelerator.

Hi Arnd,
thanks for your review.

On 21 February 2013 14:13, Arnd Bergmann <[email protected]> wrote:
> On Thursday 21 February 2013, Javier Martin wrote:
>> +
>> +struct sahara_dev {
>> + struct device *device;
>> + void __iomem *regs_base;
>> + struct clk *clk_ipg;
>> + struct clk *clk_ahb;
>> +
>> + struct sahara_ctx *ctx;
>> + spinlock_t lock;
>> + struct crypto_queue queue;
>> + unsigned long flags;
>> +
>> + struct tasklet_struct done_task;
>> + struct tasklet_struct queue_task;
>> +
>> + struct sahara_hw_desc *hw_desc[SAHARA_MAX_HW_DESC];
>> + dma_addr_t hw_phys_desc[SAHARA_MAX_HW_DESC];
>> +
>> + u8 *key_base;
>> + dma_addr_t key_phys_base;
>> +
>> + u8 *iv_base;
>> + dma_addr_t iv_phys_base;
>> +
>> + struct sahara_hw_link *hw_link[SAHARA_MAX_HW_LINK];
>> + dma_addr_t hw_phys_link[SAHARA_MAX_HW_LINK];
>> +
>> + struct ablkcipher_request *req;
>> + size_t total;
>> + struct scatterlist *in_sg;
>> + unsigned int nb_in_sg;
>> + struct scatterlist *out_sg;
>> + unsigned int nb_out_sg;
>> +
>> + u32 error;
>> + struct timer_list watchdog;
>> +};
>> +
>> +static struct sahara_dev *dev_ptr;
>
> Please remove this global device pointer, it should not be needed, since you
> can store the pointer in the context object.

Ok. Looks cleaner this way.


>
>> +#ifdef DEBUG
>> +
>> +static char *sahara_state[4] = { "Idle", "Busy", "Error", "HW Fault" };
>> +
>> +static void sahara_decode_status(struct sahara_dev *dev, unsigned int status)
>> +{
>> + u8 state = SAHARA_STATUS_GET_STATE(status);
>
> You can simplify the code a lot if you replace the #ifdef around the function
> with an
>
> if (!IS_ENBLED(DEBUG))
> return;
>
> at the start of the function. That will lead to gcc completely removing the
> code an everything referenced by it.
>

Great. Thank you for the tip.

>> +static void sahara_aes_done_task(unsigned long data)
>> +{
>> + struct sahara_dev *dev = (struct sahara_dev *)data;
>> + unsigned long flags;
>> +
>> + dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg,
>> + DMA_TO_DEVICE);
>> + dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg,
>> + DMA_FROM_DEVICE);
>> +
>> + spin_lock_irqsave(&dev->lock, flags);
>> + clear_bit(FLAGS_BUSY, &dev->flags);
>> + spin_unlock_irqrestore(&dev->lock, flags);
>> +
>> + dev->req->base.complete(&dev->req->base, dev->error);
>> +}
>
> Does dev->lock have to be irq-disabled? You don't seem to take it
> from an interrupt handler.
>
> Also, when you know that code is called without irqs enabled and
> you just want to disable them, you can use the cheaper spin_lock_irq()
> rather than spin_lock_irqsave().
>
> In short, use either spin_lock_irq or spin_lock here. When protecting
> against a tasklet, you will need spin_lock_bh.

You are right, dev->lock is only held by encrypt()/decrypt() callbacks
and some tasklets so spin_lock() and spin_lock_bh() seem suitable
here.

>> +
>> +void sahara_watchdog(unsigned long data)
>> +{
>> + struct sahara_dev *dev = (struct sahara_dev *)data;
>> + unsigned int err = sahara_read(dev, SAHARA_REG_ERRSTATUS);
>> +#ifdef DEBUG
>> + unsigned int stat = sahara_read(dev, SAHARA_REG_STATUS);
>> + sahara_decode_status(dev, stat);
>> +#endif
>
> When you kill off the #ifdef, you should move this sahara_read()
> call into the sahara_decode_status() function so it gets
> compiled conditionally.
>

All right.

>> +static struct platform_device_id sahara_platform_ids[] = {
>> + { .name = "sahara-imx27" },
>> + { /* sentinel */ }
>> +};
>> +MODULE_DEVICE_TABLE(platform, sahara_platform_ids);
>
> You are missing the of_device_ids here. We probably don't even
> need the platform_device_id list and can instead mandate that
> this is only used by platforms that are already converted to
> DT booting.
>
> Please also add a DT binding document for this driver that mentions
> the name and the resources that need to be provided.

Please, take a look at 0/3 to discuss about this matter.

Regards.

--
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
http://www.vista-silicon.com

2013-02-21 14:41:16

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

On Thursday 21 February 2013, javier Martin wrote:
> We know about the existence of DT and the constant migration process
> that is taking place towards it.
>
> Moreover we are strongly interested in converting the Visstrim SM10
> platform to DT. Unfortunately, there are several issues that need to
> be solved so that Visstrim M10 can be fully converted to DT:
> - full SoC camera DT support
> - DT support for ov7670
> - pinctrl support for i.MX27

Ok, I see. Full device tree support is certainly asking too much then.

> Furthermore, we have limited resources at the moment and we have to
> decide priorities. But having an hybrid platform-DT support is our
> next task for Visstrim M10.

Ok, cool.

> However, I understand your concern about new drivers having DT
> support. Maybe a good approach could be that I added compile-tested
> only DT support for this driver and remove platform support for
> mainline submission (although we maintain it internally in our
> repositories).
>
> What do you think?

Sounds good. Since it sounds like the hardware is available in all
imx27 device, maybe someone else can test your driver on an imx27
board that already has partial DT support when you add it to
arch/arm/boot/dts/imx27.dtsi?

Is there any reason why an imx27 based board would not support this
driver? Are there any other chips that could use it, e.g. imx25 or
imx6?

Arnd

2013-02-21 14:57:34

by javier Martin

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

On 21 February 2013 15:40, Arnd Bergmann <[email protected]> wrote:
> On Thursday 21 February 2013, javier Martin wrote:
>> We know about the existence of DT and the constant migration process
>> that is taking place towards it.
>>
>> Moreover we are strongly interested in converting the Visstrim SM10
>> platform to DT. Unfortunately, there are several issues that need to
>> be solved so that Visstrim M10 can be fully converted to DT:
>> - full SoC camera DT support
>> - DT support for ov7670
>> - pinctrl support for i.MX27
>
> Ok, I see. Full device tree support is certainly asking too much then.
>
>> Furthermore, we have limited resources at the moment and we have to
>> decide priorities. But having an hybrid platform-DT support is our
>> next task for Visstrim M10.
>
> Ok, cool.
>
>> However, I understand your concern about new drivers having DT
>> support. Maybe a good approach could be that I added compile-tested
>> only DT support for this driver and remove platform support for
>> mainline submission (although we maintain it internally in our
>> repositories).
>>
>> What do you think?
>
> Sounds good. Since it sounds like the hardware is available in all
> imx27 device, maybe someone else can test your driver on an imx27
> board that already has partial DT support when you add it to
> arch/arm/boot/dts/imx27.dtsi?

Yes, since the module is integrated in i.MX27 that seems the way to go.

> Is there any reason why an imx27 based board would not support this
> driver? Are there any other chips that could use it, e.g. imx25 or
> imx6?

No, there's no reason for an i.mx27 board not to support this driver
since the module doesn't have any external interfaces.

I think other i.MX chips have similar devices but I am not sure to
what extent they are compatible or not. Probably Sascha Hauer or Shawn
Guo (already in CC) could tell better than me since they have a wider
view on the i.MX range.

Regards.
--
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
http://www.vista-silicon.com

2013-02-21 15:18:47

by Sascha Hauer

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

On Thu, Feb 21, 2013 at 03:18:36PM +0100, javier Martin wrote:
> Hi Arnd,
>
> On 21 February 2013 13:59, Arnd Bergmann <[email protected]> wrote:
> > On Thursday 21 February 2013, Javier Martin wrote:
> >> This series of patches provide AES-ECB and AES-CBC support
> >> for the SAHARA2 cryptographic accelerator which is inside the i.MX27 SoC.
> >> It is expected that more algorithms will be supported in the future.
> >>
> >> For testing, a Visstrim M10 board has been used and the code related
> >> to this platform has been included too.
> >
> > As a new device driver, this needs to be supported on the DT based imx27
> > machines, while support for the individual board files seems unnecessary.
> >
> > How about converting the Visstrim M10 board file over to DT so you don't
> > have to add any more infrastructure for imx that we will just have to
> > remove again one day?
>
> We know about the existence of DT and the constant migration process
> that is taking place towards it.
>
> Moreover we are strongly interested in converting the Visstrim SM10
> platform to DT. Unfortunately, there are several issues that need to
> be solved so that Visstrim M10 can be fully converted to DT:
> - full SoC camera DT support
> - DT support for ov7670
> - pinctrl support for i.MX27

For the pinctrl stuff I suggest doing what we have done for the newer
i.MX SoCs before we had pinctrl: Match by board compatible string and
call into the board code for using the static pinctrl tables which are
already there. I would like to have propert pinctrl support for the
older i.MX, but probably the motivation for writing it is quite low for
the older SoCs.

We have a patch in the queue converting the clock lookups for i.MX27 to
dt which should be ready for posting soon.

Then the main road blockers should be out of the way to get rid of the
bulk of the board code.

Sascha

--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2013-02-21 15:23:17

by javier Martin

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

On 21 February 2013 16:18, Sascha Hauer <[email protected]> wrote:
> On Thu, Feb 21, 2013 at 03:18:36PM +0100, javier Martin wrote:
>> Hi Arnd,
>>
>> On 21 February 2013 13:59, Arnd Bergmann <[email protected]> wrote:
>> > On Thursday 21 February 2013, Javier Martin wrote:
>> >> This series of patches provide AES-ECB and AES-CBC support
>> >> for the SAHARA2 cryptographic accelerator which is inside the i.MX27 SoC.
>> >> It is expected that more algorithms will be supported in the future.
>> >>
>> >> For testing, a Visstrim M10 board has been used and the code related
>> >> to this platform has been included too.
>> >
>> > As a new device driver, this needs to be supported on the DT based imx27
>> > machines, while support for the individual board files seems unnecessary.
>> >
>> > How about converting the Visstrim M10 board file over to DT so you don't
>> > have to add any more infrastructure for imx that we will just have to
>> > remove again one day?
>>
>> We know about the existence of DT and the constant migration process
>> that is taking place towards it.
>>
>> Moreover we are strongly interested in converting the Visstrim SM10
>> platform to DT. Unfortunately, there are several issues that need to
>> be solved so that Visstrim M10 can be fully converted to DT:
>> - full SoC camera DT support
>> - DT support for ov7670
>> - pinctrl support for i.MX27
>
> For the pinctrl stuff I suggest doing what we have done for the newer
> i.MX SoCs before we had pinctrl: Match by board compatible string and
> call into the board code for using the static pinctrl tables which are
> already there. I would like to have propert pinctrl support for the
> older i.MX, but probably the motivation for writing it is quite low for
> the older SoCs.

OK, I take a look at it.

> We have a patch in the queue converting the clock lookups for i.MX27 to
> dt which should be ready for posting soon.

Great.

> Then the main road blockers should be out of the way to get rid of the
> bulk of the board code.


--
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
http://www.vista-silicon.com

2013-02-21 15:23:20

by Sascha Hauer

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

On Thu, Feb 21, 2013 at 02:40:59PM +0000, Arnd Bergmann wrote:
> On Thursday 21 February 2013, javier Martin wrote:
> > We know about the existence of DT and the constant migration process
> > that is taking place towards it.
> >
> > Moreover we are strongly interested in converting the Visstrim SM10
> > platform to DT. Unfortunately, there are several issues that need to
> > be solved so that Visstrim M10 can be fully converted to DT:
> > - full SoC camera DT support
> > - DT support for ov7670
> > - pinctrl support for i.MX27
>
> Ok, I see. Full device tree support is certainly asking too much then.
>
> > Furthermore, we have limited resources at the moment and we have to
> > decide priorities. But having an hybrid platform-DT support is our
> > next task for Visstrim M10.
>
> Ok, cool.
>
> > However, I understand your concern about new drivers having DT
> > support. Maybe a good approach could be that I added compile-tested
> > only DT support for this driver and remove platform support for
> > mainline submission (although we maintain it internally in our
> > repositories).
> >
> > What do you think?
>
> Sounds good. Since it sounds like the hardware is available in all
> imx27 device, maybe someone else can test your driver on an imx27
> board that already has partial DT support when you add it to
> arch/arm/boot/dts/imx27.dtsi?
>
> Is there any reason why an imx27 based board would not support this
> driver? Are there any other chips that could use it, e.g. imx25 or
> imx6?

Neither i.MX25, i.MX31 nor i.MX21 have this unit. I haven't checked the
others, but I assume this is i.MX27 only.

Sascha

--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |

2013-02-21 15:40:48

by Fabio Estevam

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

On Thu, Feb 21, 2013 at 12:23 PM, Sascha Hauer <[email protected]> wrote:

> Neither i.MX25, i.MX31 nor i.MX21 have this unit. I haven't checked the
> others, but I assume this is i.MX27 only.

There is Sahara variants on mx51/mx53.

2013-02-21 16:40:25

by Arnaud Patard

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

Fabio Estevam <[email protected]> writes:
Hi,

> On Thu, Feb 21, 2013 at 12:23 PM, Sascha Hauer <[email protected]> wrote:
>
>> Neither i.MX25, i.MX31 nor i.MX21 have this unit. I haven't checked the
>> others, but I assume this is i.MX27 only.
>
> There is Sahara variants on mx51/mx53.

How different are the variants ? I've a imx51 device with DT support so
if someone running sahara on a system with DT is needed, I can be this
person (as long as a way to test it is provided too).

Arnaud

2013-02-21 16:47:24

by Fabio Estevam

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

On Thu, Feb 21, 2013 at 1:40 PM, Arnaud Patard
<[email protected]> wrote:

> How different are the variants ? I've a imx51 device with DT support so
> if someone running sahara on a system with DT is needed, I can be this
> person (as long as a way to test it is provided too).

mx27 has Saharav2, mx51 has Saharav4. I didn't check the differences
in detail though.

For mx51 the Sahara block is described in the document "MCIMX51
Applications Processor Security Reference Manual, Rev. 1"

I can also test the sahara dt support on a mx27pdk.

2013-02-21 21:01:24

by Arnaud Patard

[permalink] [raw]
Subject: Re: [PATCH 0/3] crypto: sahara: Add support for SAHARA in i.MX27.

Fabio Estevam <[email protected]> writes:

Hi,

> On Thu, Feb 21, 2013 at 1:40 PM, Arnaud Patard
> <[email protected]> wrote:
>
>> How different are the variants ? I've a imx51 device with DT support so
>> if someone running sahara on a system with DT is needed, I can be this
>> person (as long as a way to test it is provided too).
>
> mx27 has Saharav2, mx51 has Saharav4. I didn't check the differences
> in detail though.
>
> For mx51 the Sahara block is described in the document "MCIMX51
> Applications Processor Security Reference Manual, Rev. 1"

Sorry but this document is not freely available so I can't look at it.

Arnaud

2013-02-23 20:18:32

by Arnaud Patard

[permalink] [raw]
Subject: Re: [PATCH 2/3] crypto: sahara: Add driver for SAHARA2 accelerator.

Javier Martin <[email protected]> writes:

Hi,

> SAHARA2 HW module is included in the i.MX27 SoC from
> Freescale. It is capable of performing cipher algorithms
> such as AES, 3DES..., hashing and RNG too.
>
> This driver provides support for AES-CBC and AES-ECB
> by now.
>

[...]

> + int irq;
> + int err;
> + int i;
> +
> + dev = devm_kzalloc(&pdev->dev, sizeof(struct sahara_dev), GFP_KERNEL);
> + if (dev == NULL) {
> + dev_err(&pdev->dev, "unable to alloc data struct.\n");
> + return -ENOMEM;
> + }
> +
> + dev->device = &pdev->dev;
> + platform_set_drvdata(pdev, dev);
> +
> + /* Get the base address */
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + if (!res) {
> + dev_err(&pdev->dev, "failed to get memory region resource\n");
> + return -ENODEV;
> + }
> +
> + if (devm_request_mem_region(&pdev->dev, res->start,
> + resource_size(res), SAHARA_NAME) == NULL) {
> + dev_err(&pdev->dev, "failed to request memory region\n");
> + return -ENOENT;
> + }
> + dev->regs_base = devm_ioremap(&pdev->dev, res->start,
> + resource_size(res));
> + if (!dev->regs_base) {
> + dev_err(&pdev->dev, "failed to ioremap address region\n");
> + return -ENOENT;
> + }
> +
> + /* Get the IRQ */
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0) {
> + dev_err(&pdev->dev, "failed to get irq resource\n");
> + return irq;
> + }
> +
> + if (devm_request_irq(&pdev->dev, irq, sahara_irq_handler,
> + 0, SAHARA_NAME, dev) < 0) {
> + dev_err(&pdev->dev, "failed to request irq\n");
> + return -ENOENT;
> + }
> +
> + /* clocks */
> + dev->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
> + if (IS_ERR(dev->clk_ipg)) {
> + dev_err(&pdev->dev, "Could not get ipg clock\n");
> + return PTR_ERR(dev->clk_ipg);
> + }
> +
> + dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
> + if (IS_ERR(dev->clk_ahb)) {
> + dev_err(&pdev->dev, "Could not get ahb clock\n");
> + return PTR_ERR(dev->clk_ahb);
> + }
> +
> + /* Allocate HW descriptors */
> + dev->hw_desc[0] = dma_alloc_coherent(&pdev->dev,
> + SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc),
> + &dev->hw_phys_desc[0], GFP_KERNEL);
> + if (!dev->hw_desc[0]) {
> + dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
> + return -ENOMEM;
> + }
> + dev->hw_desc[1] = dev->hw_desc[0] + 1;
> + dev->hw_phys_desc[1] = dev->hw_phys_desc[0] +
> + sizeof(struct sahara_hw_desc);
> +
> + /* Allocate space for iv and key */
> + dev->key_base = dma_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128,
> + &dev->key_phys_base, GFP_KERNEL);
> + if (!dev->key_base) {
> + dev_err(&pdev->dev, "Could not allocate memory for key\n");
> + err = -ENOMEM;
> + goto err_key;
> + }
> + dev->iv_base = dev->key_base + AES_KEYSIZE_128;
> + dev->iv_phys_base = dev->key_phys_base + AES_KEYSIZE_128;
> +
> + /* Allocate space for HW links */
> + dev->hw_link[0] = dma_alloc_coherent(&pdev->dev,
> + SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link),
> + &dev->hw_phys_link[0], GFP_KERNEL);
> + if (!dev->hw_link) {
> + dev_err(&pdev->dev, "Could not allocate hw links\n");
> + err = -ENOMEM;
> + goto err_link;
> + }
> + for (i = 1; i < SAHARA_MAX_HW_LINK; i++) {
> + dev->hw_phys_link[i] = dev->hw_phys_link[i - 1] +
> + sizeof(struct sahara_hw_link);
> + dev->hw_link[i] = dev->hw_link[i - 1] + 1;
> + }
> +
> + crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH);
> +
> + dev_ptr = dev;
> +
> + tasklet_init(&dev->queue_task, sahara_aes_queue_task,
> + (unsigned long)dev);
> + tasklet_init(&dev->done_task, sahara_aes_done_task,
> + (unsigned long)dev);
> +
> + init_timer(&dev->watchdog);
> + dev->watchdog.function = &sahara_watchdog;
> + dev->watchdog.data = (unsigned long)dev;
> +
> + clk_prepare_enable(dev->clk_ipg);
> + clk_prepare_enable(dev->clk_ahb);
> +
> + version = sahara_read(dev, SAHARA_REG_VERSION);
> + if (version != SAHARA_VERSION_3) {

According to fsl kernel tree on linaro.org, on imx5 (sahara 4), the
register layout is different so a new check should be added:
(version >> 8) & 0xff == 4

> + dev_err(&pdev->dev, "SAHARA version %d not supported\n",
> + version);
> + err = -ENODEV;
> + goto err_algs;
> + }
> +
> + sahara_write(dev, SAHARA_CMD_RESET | SAHARA_CMD_MODE_BATCH,
> + SAHARA_REG_CMD);
> + sahara_write(dev, SAHARA_CONTROL_SET_THROTTLE(0) |
> + SAHARA_CONTROL_SET_MAXBURST(8) |
> + SAHARA_CONTROL_RNG_AUTORSD |
> + SAHARA_CONTROL_ENABLE_INT,
> + SAHARA_REG_CONTROL);
> +
> + err = sahara_register_algs(dev);
> + if (err)
> + goto err_algs;
> +
> + dev_info(&pdev->dev, "SAHARA version %d initialized\n", version);
> +
> + return 0;
> +
> +err_algs:
> + dev_ptr = NULL;
> + kfree(dev->key_base);
> + clk_disable_unprepare(dev->clk_ipg);
> + clk_disable_unprepare(dev->clk_ahb);
> +err_link:
> + kfree(dev->key_base);

you're freeing 2 time key_base but not hw_link

> +err_key:
> + kfree(dev->hw_desc[0]);

This one makes my kernel oops. Can be also reproduced by unloading the
module.

> + return err;
> +}
> +
> +static int __devexit sahara_remove(struct platform_device *pdev)

__devinit & __devexit are gone.

> +{
> + struct sahara_dev *dev = platform_get_drvdata(pdev);
> +
> + kfree(dev->key_base);
> + kfree(dev->hw_desc[0]);

missing kfree for hw_link too ?

Other than the remarks above, I'm hitting this while loading the kernel:

kernel: [ 49.305657] sahara 83ff8000.sahara: nbytes: 16, enc: 1, cbc: 0
kernel: [ 53.625599] BUG: spinlock lockup suspected on CPU#0, cryptomgr_test/2040
kernel: [ 53.625772] lock: 0xc27a1824, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
kernel: [ 53.625943] Backtrace:
kernel: [ 53.626061] [<c0010e34>] (dump_backtrace+0x0/0x10c) from [<c05173d0>] (dump_stack+0x18/0x1c)
kernel: [ 53.626251] r6:0fd84000 r5:c27a1824 r4:00000000 r3:c24f26c0
kernel: [ 53.626444] [<c05173b8>] (dump_stack+0x0/0x1c) from [<c051ab18>] (spin_dump+0x80/0x94)
kernel: [ 53.626621] [<c051aa98>] (spin_dump+0x0/0x94) from [<c01f680c>] (do_raw_spin_lock+0xe8/0x12c)
kernel: [ 53.626792] r5:00000000 r4:0fd84000
kernel: [ 53.626913] [<c01f6724>] (do_raw_spin_lock+0x0/0x12c) from [<c051ed14>] (_raw_spin_lock_irqsave+0x64/0x70)
kernel: [ 53.627133] [<c051ecb0>] (_raw_spin_lock_irqsave+0x0/0x70) from [<bf00d388>] (sahara_aes_crypt+0x7c/0x100 [sahara])
kernel: [ 53.627363] r6:00000001 r5:c20b8580 r4:c27a1810
kernel: [ 53.627525] [<bf00d30c>] (sahara_aes_crypt+0x0/0x100 [sahara]) from [<bf00d538>] (sahara_aes_ecb_encrypt+0x48/0x4c [sahara])
kernel: [ 53.627744] r8:c2755d28 r7:df9f3000 r6:00000001 r5:c20b8b00 r4:c20b8580
kernel: [ 53.627970] [<bf00d4f0>] (sahara_aes_ecb_encrypt+0x0/0x4c [sahara]) from [<c01cce08>] (__test_skcipher+0x22c/0x874)
kernel: [ 53.628176] r5:c0772794 r4:c0772794
kernel: [ 53.628293] [<c01ccbdc>] (__test_skcipher+0x0/0x874) from [<c01ceb68>] (test_skcipher+0x2c/0x58)
kernel: [ 53.628483] [<c01ceb3c>] (test_skcipher+0x0/0x58) from [<c01cec08>] (alg_test_skcipher+0x74/0xac)
kernel: [ 53.628660] r7:dfbfe9c0 r6:c0539aac r5:c20b8b00 r4:00000000
kernel: [ 53.628840] [<c01ceb94>] (alg_test_skcipher+0x0/0xac) from [<c01ce54c>] (alg_test+0x154/0x1c8)
kernel: [ 53.629014] r7:ffffffff r6:00000185 r5:dfbfe9c0 r4:00000000
kernel: [ 53.632986] [<c01ce3f8>] (alg_test+0x0/0x1c8) from [<c01cc280>] (cryptomgr_test+0x2c/0x50)

Despite this, the test seems to succeed and the sahara interrupt is
increasing so it may be working.


Arnaud

2013-02-26 10:35:00

by javier Martin

[permalink] [raw]
Subject: Re: [PATCH 2/3] crypto: sahara: Add driver for SAHARA2 accelerator.

Hi Arnaud,
thank you for your feedback. Sorry, I always forget to test my drivers
as modules.

I'll address the issues you pointed out, as well as the improvements
suggested by Arnd, for v2.

Regards.

On 23 February 2013 21:16, Arnaud Patard <[email protected]> wrote:
> Javier Martin <[email protected]> writes:
>
> Hi,
>
>> SAHARA2 HW module is included in the i.MX27 SoC from
>> Freescale. It is capable of performing cipher algorithms
>> such as AES, 3DES..., hashing and RNG too.
>>
>> This driver provides support for AES-CBC and AES-ECB
>> by now.
>>
>
> [...]
>
>> + int irq;
>> + int err;
>> + int i;
>> +
>> + dev = devm_kzalloc(&pdev->dev, sizeof(struct sahara_dev), GFP_KERNEL);
>> + if (dev == NULL) {
>> + dev_err(&pdev->dev, "unable to alloc data struct.\n");
>> + return -ENOMEM;
>> + }
>> +
>> + dev->device = &pdev->dev;
>> + platform_set_drvdata(pdev, dev);
>> +
>> + /* Get the base address */
>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> + if (!res) {
>> + dev_err(&pdev->dev, "failed to get memory region resource\n");
>> + return -ENODEV;
>> + }
>> +
>> + if (devm_request_mem_region(&pdev->dev, res->start,
>> + resource_size(res), SAHARA_NAME) == NULL) {
>> + dev_err(&pdev->dev, "failed to request memory region\n");
>> + return -ENOENT;
>> + }
>> + dev->regs_base = devm_ioremap(&pdev->dev, res->start,
>> + resource_size(res));
>> + if (!dev->regs_base) {
>> + dev_err(&pdev->dev, "failed to ioremap address region\n");
>> + return -ENOENT;
>> + }
>> +
>> + /* Get the IRQ */
>> + irq = platform_get_irq(pdev, 0);
>> + if (irq < 0) {
>> + dev_err(&pdev->dev, "failed to get irq resource\n");
>> + return irq;
>> + }
>> +
>> + if (devm_request_irq(&pdev->dev, irq, sahara_irq_handler,
>> + 0, SAHARA_NAME, dev) < 0) {
>> + dev_err(&pdev->dev, "failed to request irq\n");
>> + return -ENOENT;
>> + }
>> +
>> + /* clocks */
>> + dev->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
>> + if (IS_ERR(dev->clk_ipg)) {
>> + dev_err(&pdev->dev, "Could not get ipg clock\n");
>> + return PTR_ERR(dev->clk_ipg);
>> + }
>> +
>> + dev->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
>> + if (IS_ERR(dev->clk_ahb)) {
>> + dev_err(&pdev->dev, "Could not get ahb clock\n");
>> + return PTR_ERR(dev->clk_ahb);
>> + }
>> +
>> + /* Allocate HW descriptors */
>> + dev->hw_desc[0] = dma_alloc_coherent(&pdev->dev,
>> + SAHARA_MAX_HW_DESC * sizeof(struct sahara_hw_desc),
>> + &dev->hw_phys_desc[0], GFP_KERNEL);
>> + if (!dev->hw_desc[0]) {
>> + dev_err(&pdev->dev, "Could not allocate hw descriptors\n");
>> + return -ENOMEM;
>> + }
>> + dev->hw_desc[1] = dev->hw_desc[0] + 1;
>> + dev->hw_phys_desc[1] = dev->hw_phys_desc[0] +
>> + sizeof(struct sahara_hw_desc);
>> +
>> + /* Allocate space for iv and key */
>> + dev->key_base = dma_alloc_coherent(&pdev->dev, 2 * AES_KEYSIZE_128,
>> + &dev->key_phys_base, GFP_KERNEL);
>> + if (!dev->key_base) {
>> + dev_err(&pdev->dev, "Could not allocate memory for key\n");
>> + err = -ENOMEM;
>> + goto err_key;
>> + }
>> + dev->iv_base = dev->key_base + AES_KEYSIZE_128;
>> + dev->iv_phys_base = dev->key_phys_base + AES_KEYSIZE_128;
>> +
>> + /* Allocate space for HW links */
>> + dev->hw_link[0] = dma_alloc_coherent(&pdev->dev,
>> + SAHARA_MAX_HW_LINK * sizeof(struct sahara_hw_link),
>> + &dev->hw_phys_link[0], GFP_KERNEL);
>> + if (!dev->hw_link) {
>> + dev_err(&pdev->dev, "Could not allocate hw links\n");
>> + err = -ENOMEM;
>> + goto err_link;
>> + }
>> + for (i = 1; i < SAHARA_MAX_HW_LINK; i++) {
>> + dev->hw_phys_link[i] = dev->hw_phys_link[i - 1] +
>> + sizeof(struct sahara_hw_link);
>> + dev->hw_link[i] = dev->hw_link[i - 1] + 1;
>> + }
>> +
>> + crypto_init_queue(&dev->queue, SAHARA_QUEUE_LENGTH);
>> +
>> + dev_ptr = dev;
>> +
>> + tasklet_init(&dev->queue_task, sahara_aes_queue_task,
>> + (unsigned long)dev);
>> + tasklet_init(&dev->done_task, sahara_aes_done_task,
>> + (unsigned long)dev);
>> +
>> + init_timer(&dev->watchdog);
>> + dev->watchdog.function = &sahara_watchdog;
>> + dev->watchdog.data = (unsigned long)dev;
>> +
>> + clk_prepare_enable(dev->clk_ipg);
>> + clk_prepare_enable(dev->clk_ahb);
>> +
>> + version = sahara_read(dev, SAHARA_REG_VERSION);
>> + if (version != SAHARA_VERSION_3) {
>
> According to fsl kernel tree on linaro.org, on imx5 (sahara 4), the
> register layout is different so a new check should be added:
> (version >> 8) & 0xff == 4
>
>> + dev_err(&pdev->dev, "SAHARA version %d not supported\n",
>> + version);
>> + err = -ENODEV;
>> + goto err_algs;
>> + }
>> +
>> + sahara_write(dev, SAHARA_CMD_RESET | SAHARA_CMD_MODE_BATCH,
>> + SAHARA_REG_CMD);
>> + sahara_write(dev, SAHARA_CONTROL_SET_THROTTLE(0) |
>> + SAHARA_CONTROL_SET_MAXBURST(8) |
>> + SAHARA_CONTROL_RNG_AUTORSD |
>> + SAHARA_CONTROL_ENABLE_INT,
>> + SAHARA_REG_CONTROL);
>> +
>> + err = sahara_register_algs(dev);
>> + if (err)
>> + goto err_algs;
>> +
>> + dev_info(&pdev->dev, "SAHARA version %d initialized\n", version);
>> +
>> + return 0;
>> +
>> +err_algs:
>> + dev_ptr = NULL;
>> + kfree(dev->key_base);
>> + clk_disable_unprepare(dev->clk_ipg);
>> + clk_disable_unprepare(dev->clk_ahb);
>> +err_link:
>> + kfree(dev->key_base);
>
> you're freeing 2 time key_base but not hw_link
>
>> +err_key:
>> + kfree(dev->hw_desc[0]);
>
> This one makes my kernel oops. Can be also reproduced by unloading the
> module.
>
>> + return err;
>> +}
>> +
>> +static int __devexit sahara_remove(struct platform_device *pdev)
>
> __devinit & __devexit are gone.
>
>> +{
>> + struct sahara_dev *dev = platform_get_drvdata(pdev);
>> +
>> + kfree(dev->key_base);
>> + kfree(dev->hw_desc[0]);
>
> missing kfree for hw_link too ?
>
> Other than the remarks above, I'm hitting this while loading the kernel:
>
> kernel: [ 49.305657] sahara 83ff8000.sahara: nbytes: 16, enc: 1, cbc: 0
> kernel: [ 53.625599] BUG: spinlock lockup suspected on CPU#0, cryptomgr_test/2040
> kernel: [ 53.625772] lock: 0xc27a1824, .magic: 00000000, .owner: <none>/-1, .owner_cpu: 0
> kernel: [ 53.625943] Backtrace:
> kernel: [ 53.626061] [<c0010e34>] (dump_backtrace+0x0/0x10c) from [<c05173d0>] (dump_stack+0x18/0x1c)
> kernel: [ 53.626251] r6:0fd84000 r5:c27a1824 r4:00000000 r3:c24f26c0
> kernel: [ 53.626444] [<c05173b8>] (dump_stack+0x0/0x1c) from [<c051ab18>] (spin_dump+0x80/0x94)
> kernel: [ 53.626621] [<c051aa98>] (spin_dump+0x0/0x94) from [<c01f680c>] (do_raw_spin_lock+0xe8/0x12c)
> kernel: [ 53.626792] r5:00000000 r4:0fd84000
> kernel: [ 53.626913] [<c01f6724>] (do_raw_spin_lock+0x0/0x12c) from [<c051ed14>] (_raw_spin_lock_irqsave+0x64/0x70)
> kernel: [ 53.627133] [<c051ecb0>] (_raw_spin_lock_irqsave+0x0/0x70) from [<bf00d388>] (sahara_aes_crypt+0x7c/0x100 [sahara])
> kernel: [ 53.627363] r6:00000001 r5:c20b8580 r4:c27a1810
> kernel: [ 53.627525] [<bf00d30c>] (sahara_aes_crypt+0x0/0x100 [sahara]) from [<bf00d538>] (sahara_aes_ecb_encrypt+0x48/0x4c [sahara])
> kernel: [ 53.627744] r8:c2755d28 r7:df9f3000 r6:00000001 r5:c20b8b00 r4:c20b8580
> kernel: [ 53.627970] [<bf00d4f0>] (sahara_aes_ecb_encrypt+0x0/0x4c [sahara]) from [<c01cce08>] (__test_skcipher+0x22c/0x874)
> kernel: [ 53.628176] r5:c0772794 r4:c0772794
> kernel: [ 53.628293] [<c01ccbdc>] (__test_skcipher+0x0/0x874) from [<c01ceb68>] (test_skcipher+0x2c/0x58)
> kernel: [ 53.628483] [<c01ceb3c>] (test_skcipher+0x0/0x58) from [<c01cec08>] (alg_test_skcipher+0x74/0xac)
> kernel: [ 53.628660] r7:dfbfe9c0 r6:c0539aac r5:c20b8b00 r4:00000000
> kernel: [ 53.628840] [<c01ceb94>] (alg_test_skcipher+0x0/0xac) from [<c01ce54c>] (alg_test+0x154/0x1c8)
> kernel: [ 53.629014] r7:ffffffff r6:00000185 r5:dfbfe9c0 r4:00000000
> kernel: [ 53.632986] [<c01ce3f8>] (alg_test+0x0/0x1c8) from [<c01cc280>] (cryptomgr_test+0x2c/0x50)
>
> Despite this, the test seems to succeed and the sahara interrupt is
> increasing so it may be working.
>
>
> Arnaud



--
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
http://www.vista-silicon.com