2013-09-09 15:59:17

by Porosanu Alexandru

[permalink] [raw]
Subject: [PATCH 0/7] crypto: caam - RNG4 patches and fixes

This patch series attempts to fix some identified issues and add some new
functionalities regarding the RNG4 block in the CAAM driver:
o if the CAAM driver isn't properly instantiated (e.g. RNG4 initialization
fails), then there's an illegal memory access generated by the modules
depending on it; patch 1 in the patch-set fixes this;
o if the CAAM module is removed, the state handles are not uninstantiated;
patch 3 in the patch-set adds the necessary descriptor to uninstantiate
state handle 0;
o the RNG4 block in CAAM needs to be 'seeded' first before being used
for generating pseudo-random data. The 'seeding' is done by getting
entropy from the TRNG ring oscillator. The RTFRQMAX register controls
the maximum allowable number of samples that can be acquired during
an entropy sample. Depending on the clock at which the RNG4 block
(and for that matter the SEC block) runs, it's possible that a
hard-coded value for the maximum frequency is inadequate, i.e. more
samples than needed are taken. This leads to failures on devices
like BSC913x. Patch number 2 fixes this issue by using a kind of
a software loop to increase the maximum number of samples taken
until the state handle can be properly initialized; o there are two
state handles present in the RNG4 block and only one
is initialized; patch 5 in the patch-set fixes this issue, also
adding the necessary code for deinstantiation only the handles that were
instantiated by the driver.

Alex Porosanu (7):
crypto: caam - fix RNG state handle instantiation descriptor
crypto: caam - fix hash, alg and rng registration if CAAM driver not
initialized
crypto: caam - fix RNG4 instantiation
crypto: caam - split RNG4 instantiation function
crypto: caam - uninstantiate RNG state handle 0 if instantiated by
caam driver
crypto: caam - fix RNG4 AAI defines
crypto: caam - enable instantiation of all RNG4 state handles

drivers/crypto/caam/caamalg.c | 7 +
drivers/crypto/caam/caamhash.c | 7 +
drivers/crypto/caam/caamrng.c | 7 +
drivers/crypto/caam/ctrl.c | 400 +++++++++++++++++++++++++++++++---------
drivers/crypto/caam/desc.h | 17 +-
drivers/crypto/caam/intern.h | 6 +
drivers/crypto/caam/regs.h | 14 +-
7 files changed, 364 insertions(+), 94 deletions(-)

--
1.7.7.6


2013-09-09 15:59:17

by Porosanu Alexandru

[permalink] [raw]
Subject: [PATCH 1/7] crypto: caam - fix RNG state handle instantiation descriptor

The way the DECO runs a descriptor through the direct (debug)
interface is different from the JRI interface: the DECO will
continue to try and execute the next commands, after the descriptor
buffer has ended. This leads to unpredictable results and possibly
to locking up of the DECO. This patch adds a halt command at the
end of the descriptor to ensure the DECO halts when it reaches
the end of the descriptor buffer.

Signed-off-by: Alex Porosanu <[email protected]>
---
drivers/crypto/caam/ctrl.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index b010d42..11c7f29 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -73,6 +73,8 @@ static void build_instantiation_desc(u32 *desc)
/* generate secure keys (non-test) */
append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
OP_ALG_RNG4_SK);
+
+ append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
}

static int instantiate_rng(struct device *ctrldev)
@@ -83,7 +85,7 @@ static int instantiate_rng(struct device *ctrldev)
u32 *desc;
int i, ret = 0;

- desc = kmalloc(CAAM_CMD_SZ * 6, GFP_KERNEL | GFP_DMA);
+ desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL | GFP_DMA);
if (!desc) {
dev_err(ctrldev, "can't allocate RNG init descriptor memory\n");
return -ENOMEM;
--
1.7.7.6

2013-09-09 15:59:23

by Porosanu Alexandru

[permalink] [raw]
Subject: [PATCH 2/7] crypto: caam - fix hash, alg and rng registration if CAAM driver not initialized

If the CAAM driver initialization failed (due to various reasons, e.g. RNG4
initialization failed), then the registration of hash/algorithms/rng shouldn't
take place. This patch adds the necessary code to prevent this registration.

Signed-off-by: Alex Porosanu <[email protected]>
---
drivers/crypto/caam/caamalg.c | 7 +++++++
drivers/crypto/caam/caamhash.c | 7 +++++++
drivers/crypto/caam/caamrng.c | 7 +++++++
3 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 7c63b72..86a0d41 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -2209,6 +2209,13 @@ static int __init caam_algapi_init(void)
priv = dev_get_drvdata(ctrldev);
of_node_put(dev_node);

+ /*
+ * If priv is NULL, it's probably because the caam driver wasn't
+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+ */
+ if (!priv)
+ return -ENODEV;
+
INIT_LIST_HEAD(&priv->alg_list);

atomic_set(&priv->tfm_count, -1);
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index e732bd9..ca6218e 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -1833,6 +1833,13 @@ static int __init caam_algapi_hash_init(void)
priv = dev_get_drvdata(ctrldev);
of_node_put(dev_node);

+ /*
+ * If priv is NULL, it's probably because the caam driver wasn't
+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+ */
+ if (!priv)
+ return -ENODEV;
+
INIT_LIST_HEAD(&priv->hash_list);

atomic_set(&priv->tfm_count, -1);
diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c
index d1939a9..588ad22 100644
--- a/drivers/crypto/caam/caamrng.c
+++ b/drivers/crypto/caam/caamrng.c
@@ -298,6 +298,13 @@ static int __init caam_rng_init(void)
priv = dev_get_drvdata(ctrldev);
of_node_put(dev_node);

+ /*
+ * If priv is NULL, it's probably because the caam driver wasn't
+ * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
+ */
+ if (!priv)
+ return -ENODEV;
+
caam_init_rng(&rng_ctx, priv->jrdev[0]);

dev_info(priv->jrdev[0], "registering rng-caam\n");
--
1.7.7.6

2013-09-09 15:59:27

by Porosanu Alexandru

[permalink] [raw]
Subject: [PATCH 3/7] crypto: caam - fix RNG4 instantiation

The RNG4 block in CAAM needs to be 'seeded' first before being used
for generating pseudo-random data. The 'seeding' is done by getting
entropy from the TRNG ring oscillator. The RTFRQMAX register controls
the maximum allowable number of samples that can be aquired during
an entropy sample. Depending on the clock at which the RNG4 block
(and for that matter the SEC block) runs, it's possible that a
hard-coded value for the maximum frequency is inadequate, i.e. more
samples than needed are taken. This is an error, and thus the RNG4
block doesn't get initialized. The patch attempts to alleviate
this issue by trying with progressivly larger frequencies, until
the number of samples is adequate.
This patch also fixes how a descriptor is deemed as being finished:
instead of checking the VALID field in the DECO debug register,
it makes sure that the DECO is idle, by checking the DECO state field
of the said register.

Signed-off-by: Alex Porosanu <[email protected]>
---
drivers/crypto/caam/ctrl.c | 63 ++++++++++++++++++++++++++++++++-----------
drivers/crypto/caam/regs.h | 7 +++-
2 files changed, 52 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 11c7f29..d5fe5f5 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -82,7 +82,7 @@ static int instantiate_rng(struct device *ctrldev)
struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
struct caam_full __iomem *topregs;
unsigned int timeout = 100000;
- u32 *desc;
+ u32 *desc, deco_dbg_reg;
int i, ret = 0;

desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL | GFP_DMA);
@@ -112,9 +112,17 @@ static int instantiate_rng(struct device *ctrldev)
wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR);

timeout = 10000000;
- while ((rd_reg32(&topregs->deco.desc_dbg) & DECO_DBG_VALID) &&
- --timeout)
+ do {
+ deco_dbg_reg = rd_reg32(&topregs->deco.desc_dbg);
+ /*
+ * If an error occured in the descriptor, then
+ * the DECO status field will be set to 0x0D
+ */
+ if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
+ DESC_DBG_DECO_STAT_HOST_ERR)
+ break;
cpu_relax();
+ } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);

if (!timeout) {
dev_err(ctrldev, "failed to instantiate RNG\n");
@@ -128,10 +136,12 @@ out:
}

/*
- * By default, the TRNG runs for 200 clocks per sample;
- * 1600 clocks per sample generates better entropy.
+ * kick_trng - sets the various parameters for enabling the initialization
+ * of the RNG4 block in CAAM
+ * @pdev - pointer to the platform device
+ * @ent_delay - Defines the length (in system clocks) of each entropy sample.
*/
-static void kick_trng(struct platform_device *pdev)
+static void kick_trng(struct platform_device *pdev, int ent_delay)
{
struct device *ctrldev = &pdev->dev;
struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
@@ -144,14 +154,31 @@ static void kick_trng(struct platform_device *pdev)

/* put RNG4 into program mode */
setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
- /* 1600 clocks per sample */
+
+ /*
+ * Performance-wise, it does not make sense to
+ * set the delay to a value that is lower
+ * than the last one that worked (i.e. the state handles
+ * were instantiated properly. Thus, instead of wasting
+ * time trying to set the values controlling the sample
+ * frequency, the function simply returns.
+ */
+ val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
+ >> RTSDCTL_ENT_DLY_SHIFT;
+ if (ent_delay <= val) {
+ /* put RNG4 into run mode */
+ clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
+ return;
+ }
+
val = rd_reg32(&r4tst->rtsdctl);
- val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT);
+ val = (val & ~RTSDCTL_ENT_DLY_MASK) |
+ (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
wr_reg32(&r4tst->rtsdctl, val);
- /* min. freq. count */
- wr_reg32(&r4tst->rtfrqmin, 400);
- /* max. freq. count */
- wr_reg32(&r4tst->rtfrqmax, 6400);
+ /* min. freq. count, equal to 1/4 of the entropy sample length */
+ wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
+ /* max. freq. count, equal to 8 times the entropy sample length */
+ wr_reg32(&r4tst->rtfrqmax, ent_delay << 3);
/* put RNG4 into run mode */
clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
}
@@ -192,7 +219,7 @@ EXPORT_SYMBOL(caam_get_era);
/* Probe routine for CAAM top (controller) level */
static int caam_probe(struct platform_device *pdev)
{
- int ret, ring, rspec;
+ int ret, ring, rspec, ent_delay = RTSDCTL_ENT_DLY_MIN;
u64 caam_id;
struct device *dev;
struct device_node *nprop, *np;
@@ -298,13 +325,17 @@ static int caam_probe(struct platform_device *pdev)

/*
* If SEC has RNG version >= 4 and RNG state handle has not been
- * already instantiated ,do RNG instantiation
+ * already instantiated, do RNG instantiation
*/
if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
!(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
- kick_trng(pdev);
- ret = instantiate_rng(dev);
+ do {
+ kick_trng(pdev, ent_delay);
+ ret = instantiate_rng(dev);
+ ent_delay += 400;
+ } while ((ret == -EIO) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
if (ret) {
+ dev_err(dev, "failed to instantiate RNG");
caam_remove(pdev);
return ret;
}
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index 4455396..9aa9f71 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -255,6 +255,8 @@ struct rng4tst {
};
#define RTSDCTL_ENT_DLY_SHIFT 16
#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
+#define RTSDCTL_ENT_DLY_MIN 1200
+#define RTSDCTL_ENT_DLY_MAX 12800
u32 rtsdctl; /* seed control register */
union {
u32 rtsblim; /* PRGM=1: sparse bit limit register */
@@ -706,12 +708,13 @@ struct caam_deco {
u32 rsvd29[48];
u32 descbuf[64]; /* DxDESB - Descriptor buffer */
u32 rscvd30[193];
+#define DESC_DBG_DECO_STAT_HOST_ERR 0x00D00000
+#define DESC_DBG_DECO_STAT_VALID 0x80000000
+#define DESC_DBG_DECO_STAT_MASK 0x00F00000
u32 desc_dbg; /* DxDDR - DECO Debug Register */
u32 rsvd31[126];
};

-/* DECO DBG Register Valid Bit*/
-#define DECO_DBG_VALID 0x80000000
#define DECO_JQCR_WHL 0x20000000
#define DECO_JQCR_FOUR 0x10000000

--
1.7.7.6

2013-09-09 15:59:28

by Porosanu Alexandru

[permalink] [raw]
Subject: [PATCH 5/7] crypto: caam - uninstantiate RNG state handle 0 if instantiated by caam driver

If the caam driver module instantiates the RNG state handle 0, then
upon the removal of the module, the RNG state handle is left
initialized. This patch takes care of reverting the state of the
handle back to its previous uninstantatied state.

Signed-off-by: Alex Porosanu <[email protected]>
---
drivers/crypto/caam/ctrl.c | 57 +++++++++++++++++++++++++++++++++++++----
drivers/crypto/caam/intern.h | 6 ++++
2 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 3ad032f..9e9215a 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -44,6 +44,17 @@ static void build_instantiation_desc(u32 *desc)
append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
}

+/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
+static void build_deinstantiation_desc(u32 *desc)
+{
+ init_job_desc(desc, 0);
+
+ /* Uninstantiate State Handle 0 */
+ append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+ OP_ALG_AS_INITFINAL);
+
+ append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
+}

/*
* run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
@@ -59,7 +70,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
struct caam_full __iomem *topregs;
unsigned int timeout = 100000;
u32 deco_dbg_reg, flags;
- int i, ret = 0;
+ int i;

/* Set the bit to request direct access to DECO0 */
topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
@@ -102,11 +113,6 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
cpu_relax();
} while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);

- if (!timeout) {
- dev_err(ctrldev, "failed to instantiate RNG\n");
- ret = -EIO;
- }
-
/* Mark the DECO as free */
clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);

@@ -146,6 +152,39 @@ static int instantiate_rng(struct device *ctrldev)
return ret;
}

+/*
+ * deinstantiate_rng - builds and executes a descriptor on DECO0,
+ * which deinitializes the RNG block.
+ * @ctrldev - pointer to device
+ *
+ * Return: - 0 if no error occurred
+ * - -ENOMEM if there isn't enough memory to allocate the descriptor
+ * - -ENODEV if DECO0 couldn't be acquired
+ * - -EAGAIN if an error occurred when executing the descriptor
+ */
+static int deinstantiate_rng(struct device *ctrldev)
+{
+ u32 *desc;
+ int i, ret = 0;
+
+ desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+
+ /* Create the descriptor for deinstantating RNG State Handle 0 */
+ build_deinstantiation_desc(desc);
+
+ /* Try to run it through DECO0 */
+ ret = run_descriptor_deco0(ctrldev, desc);
+
+ if (ret)
+ dev_err(ctrldev, "failed to deinstantiate RNG\n");
+
+ kfree(desc);
+
+ return ret;
+}
+
static int caam_remove(struct platform_device *pdev)
{
struct device *ctrldev;
@@ -165,6 +204,10 @@ static int caam_remove(struct platform_device *pdev)
irq_dispose_mapping(jrpriv->irq);
}

+ /* De-initialize RNG if it was initialized by this driver. */
+ if (ctrlpriv->rng4_init)
+ deinstantiate_rng(ctrldev);
+
/* Shut down debug views */
#ifdef CONFIG_DEBUG_FS
debugfs_remove_recursive(ctrlpriv->dfs_root);
@@ -384,6 +427,8 @@ static int caam_probe(struct platform_device *pdev)
return ret;
}

+ ctrlpriv->rng4_init = 1;
+
/* Enable RDB bit so that RNG works faster */
setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE);
}
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index 34c4b9f..ada2429 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -87,6 +87,12 @@ struct caam_drv_private {
/* list of registered hash algorithms (mk generic context handle?) */
struct list_head hash_list;

+ /* RNG4 block */
+ bool rng4_init; /* If RNG4 block is initialized by this driver,
+ then this will be set; if it was initialized
+ by another entity (e.g. u-boot), it will be
+ cleared. */
+
/*
* debugfs entries for developer view into driver/device
* variables at runtime.
--
1.7.7.6

2013-09-09 15:59:36

by Porosanu Alexandru

[permalink] [raw]
Subject: [PATCH 7/7] crypto: caam - enable instantiation of all RNG4 state handles

RNG4 block contains multiple (i.e. 2) state handles that can be
initialized. This patch adds the necessary code for detecting
which of the two state handles has been instantiated by another
piece of software e.g. u-boot and instantiate the other one (or
both if none was instantiated). Only the state handle(s)
instantiated by this driver will be deinstantiated when removing
the module.

Signed-off-by: Alex Porosanu <[email protected]>
---
drivers/crypto/caam/ctrl.c | 206 ++++++++++++++++++++++++++++++++----------
drivers/crypto/caam/intern.h | 8 +-
drivers/crypto/caam/regs.h | 7 ++-
3 files changed, 169 insertions(+), 52 deletions(-)

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 29cbec1..26438cd 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -17,41 +17,49 @@
* Descriptor to instantiate RNG State Handle 0 in normal mode and
* load the JDKEK, TDKEK and TDSK registers
*/
-static void build_instantiation_desc(u32 *desc)
+static void build_instantiation_desc(u32 *desc, int handle, int do_sk)
{
- u32 *jump_cmd;
+ u32 *jump_cmd, op_flags;

init_job_desc(desc, 0);

+ op_flags = OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+ (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INIT;
+
/* INIT RNG in non-test mode */
- append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- OP_ALG_AS_INIT);
+ append_operation(desc, op_flags);

- /* wait for done */
- jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
- set_jump_tgt_here(desc, jump_cmd);
+ if (!handle && do_sk) {
+ /*
+ * For SH0, Secure Keys must be generated as well
+ */

- /*
- * load 1 to clear written reg:
- * resets the done interrupt and returns the RNG to idle.
- */
- append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+ /* wait for done */
+ jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
+ set_jump_tgt_here(desc, jump_cmd);

- /* generate secure keys (non-test) */
- append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- OP_ALG_AAI_RNG4_SK);
+ /*
+ * load 1 to clear written reg:
+ * resets the done interrrupt and returns the RNG to idle.
+ */
+ append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
+
+ /* Initialize State Handle */
+ append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
+ OP_ALG_AAI_RNG4_SK);
+ }

append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
}

/* Descriptor for deinstantiation of State Handle 0 of the RNG block. */
-static void build_deinstantiation_desc(u32 *desc)
+static void build_deinstantiation_desc(u32 *desc, int handle)
{
init_job_desc(desc, 0);

/* Uninstantiate State Handle 0 */
append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- OP_ALG_AS_INITFINAL);
+ (handle << OP_ALG_AAI_SHIFT) | OP_ALG_AS_INITFINAL);

append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
}
@@ -60,11 +68,14 @@ static void build_deinstantiation_desc(u32 *desc)
* run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
* the software (no JR/QI used).
* @ctrldev - pointer to device
+ * @status - descriptor status, after being run
+ *
* Return: - 0 if no error occurred
* - -ENODEV if the DECO couldn't be acquired
* - -EAGAIN if an error occurred while executing the descriptor
*/
-static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
+static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc,
+ u32 *status)
{
struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
struct caam_full __iomem *topregs;
@@ -113,6 +124,9 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
cpu_relax();
} while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);

+ *status = rd_reg32(&topregs->deco.op_status_hi) &
+ DECO_OP_STATUS_HI_ERR_MASK;
+
/* Mark the DECO as free */
clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);

@@ -126,6 +140,14 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
* instantiate_rng - builds and executes a descriptor on DECO0,
* which initializes the RNG block.
* @ctrldev - pointer to device
+ * @state_handle_mask - bitmask containing the instantiation status
+ * for the RNG4 state handles which exist in
+ * the RNG4 block: 1 if it's been instantiated
+ * by an external entry, 0 otherwise.
+ * @gen_sk - generate data to be loaded into the JDKEK, TDKEK and TDSK;
+ * Caution: this can be done only once; if the keys need to be
+ * regenerated, a POR is required
+ *
* Return: - 0 if no error occurred
* - -ENOMEM if there isn't enough memory to allocate the descriptor
* - -ENODEV if DECO0 couldn't be acquired
@@ -133,19 +155,56 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
* f.i. there was a RNG hardware error due to not "good enough"
* entropy being aquired.
*/
-static int instantiate_rng(struct device *ctrldev)
+static int instantiate_rng(struct device *ctrldev, int state_handle_mask,
+ int gen_sk)
{
- u32 *desc;
- int ret = 0;
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+ struct caam_full __iomem *topregs;
+ struct rng4tst __iomem *r4tst;
+ u32 *desc, status, rdsta_val;
+ int ret = 0, sh_idx;
+
+ topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+ r4tst = &topregs->ctrl.r4tst[0];

desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
if (!desc)
return -ENOMEM;
- /* Create the descriptor for instantiating RNG State Handle 0 */
- build_instantiation_desc(desc);

- /* Try to run it through DECO0 */
- ret = run_descriptor_deco0(ctrldev, desc);
+ for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+ /*
+ * If the corresponding bit is set, this state handle
+ * was initialized by somebody else, so it's left alone.
+ */
+ if ((1 << sh_idx) & state_handle_mask)
+ continue;
+
+ /* Create the descriptor for instantiating RNG State Handle */
+ build_instantiation_desc(desc, sh_idx, gen_sk);
+
+ /* Try to run it through DECO0 */
+ ret = run_descriptor_deco0(ctrldev, desc, &status);
+
+ /*
+ * If ret is not 0, or descriptor status is not 0, then
+ * something went wrong. No need to try the next state
+ * handle (if available), bail out here.
+ * Also, if for some reason, the State Handle didn't get
+ * instantiated although the descriptor has finished
+ * without any error (HW optimizations for later
+ * CAAM eras), then try again.
+ */
+ rdsta_val =
+ rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IFMASK;
+ if (status || !(rdsta_val & (1 << sh_idx)))
+ ret = -EAGAIN;
+ if (ret)
+ break;
+
+ dev_info(ctrldev, "Instantiated RNG4 SH%d\n", sh_idx);
+ /* Clear the contents before recreating the descriptor */
+ memset(desc, 0x00, CAAM_CMD_SZ * 7);
+ }

kfree(desc);

@@ -156,29 +215,49 @@ static int instantiate_rng(struct device *ctrldev)
* deinstantiate_rng - builds and executes a descriptor on DECO0,
* which deinitializes the RNG block.
* @ctrldev - pointer to device
+ * @state_handle_mask - bitmask containing the instantiation status
+ * for the RNG4 state handles which exist in
+ * the RNG4 block: 1 if it's been instantiated
*
* Return: - 0 if no error occurred
* - -ENOMEM if there isn't enough memory to allocate the descriptor
* - -ENODEV if DECO0 couldn't be acquired
* - -EAGAIN if an error occurred when executing the descriptor
*/
-static int deinstantiate_rng(struct device *ctrldev)
+static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask)
{
- u32 *desc;
- int i, ret = 0;
+ u32 *desc, status;
+ int sh_idx, ret = 0;

desc = kmalloc(CAAM_CMD_SZ * 3, GFP_KERNEL);
if (!desc)
return -ENOMEM;

- /* Create the descriptor for deinstantating RNG State Handle 0 */
- build_deinstantiation_desc(desc);
-
- /* Try to run it through DECO0 */
- ret = run_descriptor_deco0(ctrldev, desc);
-
- if (ret)
- dev_err(ctrldev, "failed to deinstantiate RNG\n");
+ for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) {
+ /*
+ * If the corresponding bit is set, then it means the state
+ * handle was initialized by us, and thus it needs to be
+ * deintialized as well
+ */
+ if ((1 << sh_idx) & state_handle_mask) {
+ /*
+ * Create the descriptor for deinstantating this state
+ * handle
+ */
+ build_deinstantiation_desc(desc, sh_idx);
+
+ /* Try to run it through DECO0 */
+ ret = run_descriptor_deco0(ctrldev, desc, &status);
+
+ if (ret || status) {
+ dev_err(ctrldev,
+ "Failed to deinstantiate RNG4 SH%d\n",
+ sh_idx);
+ break;
+ }
+ dev_info(ctrldev, "Deinstantiated RNG4 SH%d\n", sh_idx);
+ }
+ }

kfree(desc);

@@ -204,9 +283,9 @@ static int caam_remove(struct platform_device *pdev)
irq_dispose_mapping(jrpriv->irq);
}

- /* De-initialize RNG if it was initialized by this driver. */
- if (ctrlpriv->rng4_init)
- deinstantiate_rng(ctrldev);
+ /* De-initialize RNG state handles initialized by this driver. */
+ if (ctrlpriv->rng4_sh_init)
+ deinstantiate_rng(ctrldev, ctrlpriv->rng4_sh_init);

/* Shut down debug views */
#ifdef CONFIG_DEBUG_FS
@@ -306,7 +385,7 @@ EXPORT_SYMBOL(caam_get_era);
/* Probe routine for CAAM top (controller) level */
static int caam_probe(struct platform_device *pdev)
{
- int ret, ring, rspec, ent_delay = RTSDCTL_ENT_DLY_MIN;
+ int ret, ring, rspec, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
u64 caam_id;
struct device *dev;
struct device_node *nprop, *np;
@@ -414,20 +493,53 @@ static int caam_probe(struct platform_device *pdev)
* If SEC has RNG version >= 4 and RNG state handle has not been
* already instantiated, do RNG instantiation
*/
- if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
- !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
+ if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4) {
+ ctrlpriv->rng4_sh_init =
+ rd_reg32(&topregs->ctrl.r4tst[0].rdsta);
+ /*
+ * If the secure keys (TDKEK, JDKEK, TDSK), were already
+ * generated, signal this to the function that is instantiating
+ * the state handles. An error would occur if RNG4 attempts
+ * to regenerate these keys before the next POR.
+ */
+ gen_sk = ctrlpriv->rng4_sh_init & RDSTA_SKVN ? 0 : 1;
+ ctrlpriv->rng4_sh_init &= RDSTA_IFMASK;
do {
- kick_trng(pdev, ent_delay);
- ret = instantiate_rng(dev);
- ent_delay += 400;
+ int inst_handles =
+ rd_reg32(&topregs->ctrl.r4tst[0].rdsta) &
+ RDSTA_IFMASK;
+ /*
+ * If either SH were instantiated by somebody else
+ * (e.g. u-boot) then it is assumed that the entropy
+ * parameters are properly set and thus the function
+ * setting these (kick_trng(...)) is skipped.
+ * Also, if a handle was instantiated, do not change
+ * the TRNG parameters.
+ */
+ if (!(ctrlpriv->rng4_sh_init || inst_handles)) {
+ kick_trng(pdev, ent_delay);
+ ent_delay += 400;
+ }
+ /*
+ * if instantiate_rng(...) fails, the loop will rerun
+ * and the kick_trng(...) function will modfiy the
+ * upper and lower limits of the entropy sampling
+ * interval, leading to a sucessful initialization of
+ * the RNG.
+ */
+ ret = instantiate_rng(dev, inst_handles,
+ gen_sk);
} while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
if (ret) {
dev_err(dev, "failed to instantiate RNG");
caam_remove(pdev);
return ret;
}
-
- ctrlpriv->rng4_init = 1;
+ /*
+ * Set handles init'ed by this module as the complement of the
+ * already initialized ones
+ */
+ ctrlpriv->rng4_sh_init = ~ctrlpriv->rng4_sh_init & RDSTA_IFMASK;

/* Enable RDB bit so that RNG works faster */
setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE);
diff --git a/drivers/crypto/caam/intern.h b/drivers/crypto/caam/intern.h
index ada2429..bbc1ac9 100644
--- a/drivers/crypto/caam/intern.h
+++ b/drivers/crypto/caam/intern.h
@@ -87,11 +87,11 @@ struct caam_drv_private {
/* list of registered hash algorithms (mk generic context handle?) */
struct list_head hash_list;

+#define RNG4_MAX_HANDLES 2
/* RNG4 block */
- bool rng4_init; /* If RNG4 block is initialized by this driver,
- then this will be set; if it was initialized
- by another entity (e.g. u-boot), it will be
- cleared. */
+ u32 rng4_sh_init; /* This bitmap shows which of the State
+ Handles of the RNG4 block are initialized
+ by this driver */

/*
* debugfs entries for developer view into driver/device
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index 9aa9f71..d50174f 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -245,7 +245,7 @@ struct rngtst {

/* RNG4 TRNG test registers */
struct rng4tst {
-#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
+#define RTMCTL_PRGM 0x00010000 /* 1 -> program mode, 0 -> run mode */
u32 rtmctl; /* misc. control register */
u32 rtscmisc; /* statistical check misc. register */
u32 rtpkrrng; /* poker range register */
@@ -268,7 +268,11 @@ struct rng4tst {
u32 rtfrqcnt; /* PRGM=0: freq. count register */
};
u32 rsvd1[40];
+#define RDSTA_SKVT 0x80000000
+#define RDSTA_SKVN 0x40000000
#define RDSTA_IF0 0x00000001
+#define RDSTA_IF1 0x00000002
+#define RDSTA_IFMASK (RDSTA_IF1 | RDSTA_IF0)
u32 rdsta;
u32 rsvd2[15];
};
@@ -694,6 +698,7 @@ struct caam_deco {
u32 jr_ctl_hi; /* CxJRR - JobR Control Register @800 */
u32 jr_ctl_lo;
u64 jr_descaddr; /* CxDADR - JobR Descriptor Address */
+#define DECO_OP_STATUS_HI_ERR_MASK 0xF00000FF
u32 op_status_hi; /* DxOPSTA - DECO Operation Status */
u32 op_status_lo;
u32 rsvd24[2];
--
1.7.7.6

2013-09-09 15:59:32

by Porosanu Alexandru

[permalink] [raw]
Subject: [PATCH 6/7] crypto: caam - fix RNG4 AAI defines

RNG4 defines in desc.h were incomplete (bits AI & PS were missing),
while SK was set as an ALG related bit. This patchs adds the
missing bits and corrects the SK bit.

Signed-off-by: Alex Porosanu <[email protected]>
---
drivers/crypto/caam/ctrl.c | 2 +-
drivers/crypto/caam/desc.h | 17 +++++++++--------
2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 9e9215a..29cbec1 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -39,7 +39,7 @@ static void build_instantiation_desc(u32 *desc)

/* generate secure keys (non-test) */
append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
- OP_ALG_RNG4_SK);
+ OP_ALG_AAI_RNG4_SK);

append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
}
diff --git a/drivers/crypto/caam/desc.h b/drivers/crypto/caam/desc.h
index 53b296f..7e4500f 100644
--- a/drivers/crypto/caam/desc.h
+++ b/drivers/crypto/caam/desc.h
@@ -1155,8 +1155,15 @@ struct sec4_sg_entry {

/* randomizer AAI set */
#define OP_ALG_AAI_RNG (0x00 << OP_ALG_AAI_SHIFT)
-#define OP_ALG_AAI_RNG_NOZERO (0x10 << OP_ALG_AAI_SHIFT)
-#define OP_ALG_AAI_RNG_ODD (0x20 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_NZB (0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_OBP (0x20 << OP_ALG_AAI_SHIFT)
+
+/* RNG4 AAI set */
+#define OP_ALG_AAI_RNG4_SH_0 (0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SH_1 (0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_PS (0x40 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_AI (0x80 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG4_SK (0x100 << OP_ALG_AAI_SHIFT)

/* hmac/smac AAI set */
#define OP_ALG_AAI_HASH (0x00 << OP_ALG_AAI_SHIFT)
@@ -1178,12 +1185,6 @@ struct sec4_sg_entry {
#define OP_ALG_AAI_GSM (0x10 << OP_ALG_AAI_SHIFT)
#define OP_ALG_AAI_EDGE (0x20 << OP_ALG_AAI_SHIFT)

-/* RNG4 set */
-#define OP_ALG_RNG4_SHIFT 4
-#define OP_ALG_RNG4_MASK (0x1f3 << OP_ALG_RNG4_SHIFT)
-
-#define OP_ALG_RNG4_SK (0x100 << OP_ALG_RNG4_SHIFT)
-
#define OP_ALG_AS_SHIFT 2
#define OP_ALG_AS_MASK (0x3 << OP_ALG_AS_SHIFT)
#define OP_ALG_AS_UPDATE (0 << OP_ALG_AS_SHIFT)
--
1.7.7.6

2013-09-09 15:59:26

by Porosanu Alexandru

[permalink] [raw]
Subject: [PATCH 4/7] crypto: caam - split RNG4 instantiation function

This patch splits the RNG4 state handle instantiation
function into two parts: one that handles the creation
of the descriptor which instructs the CAAM to perform
the instantiation of the state handle and another
function that performs the running of the said descriptor
using the DECO debug mechanism.

Signed-off-by: Alex Porosanu <[email protected]>
---
drivers/crypto/caam/ctrl.c | 140 +++++++++++++++++++++++++++++---------------
1 files changed, 92 insertions(+), 48 deletions(-)

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index d5fe5f5..3ad032f 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -13,39 +13,6 @@
#include "error.h"
#include "ctrl.h"

-static int caam_remove(struct platform_device *pdev)
-{
- struct device *ctrldev;
- struct caam_drv_private *ctrlpriv;
- struct caam_drv_private_jr *jrpriv;
- struct caam_full __iomem *topregs;
- int ring, ret = 0;
-
- ctrldev = &pdev->dev;
- ctrlpriv = dev_get_drvdata(ctrldev);
- topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
-
- /* shut down JobRs */
- for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
- ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
- jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
- irq_dispose_mapping(jrpriv->irq);
- }
-
- /* Shut down debug views */
-#ifdef CONFIG_DEBUG_FS
- debugfs_remove_recursive(ctrlpriv->dfs_root);
-#endif
-
- /* Unmap controller region */
- iounmap(&topregs->ctrl);
-
- kfree(ctrlpriv->jrdev);
- kfree(ctrlpriv);
-
- return ret;
-}
-
/*
* Descriptor to instantiate RNG State Handle 0 in normal mode and
* load the JDKEK, TDKEK and TDSK registers
@@ -77,21 +44,23 @@ static void build_instantiation_desc(u32 *desc)
append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
}

-static int instantiate_rng(struct device *ctrldev)
+
+/*
+ * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
+ * the software (no JR/QI used).
+ * @ctrldev - pointer to device
+ * Return: - 0 if no error occurred
+ * - -ENODEV if the DECO couldn't be acquired
+ * - -EAGAIN if an error occurred while executing the descriptor
+ */
+static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
{
struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
struct caam_full __iomem *topregs;
unsigned int timeout = 100000;
- u32 *desc, deco_dbg_reg;
+ u32 deco_dbg_reg, flags;
int i, ret = 0;

- desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL | GFP_DMA);
- if (!desc) {
- dev_err(ctrldev, "can't allocate RNG init descriptor memory\n");
- return -ENOMEM;
- }
- build_instantiation_desc(desc);
-
/* Set the bit to request direct access to DECO0 */
topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
setbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
@@ -102,14 +71,23 @@ static int instantiate_rng(struct device *ctrldev)

if (!timeout) {
dev_err(ctrldev, "failed to acquire DECO 0\n");
- ret = -EIO;
- goto out;
+ clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
+ return -ENODEV;
}

for (i = 0; i < desc_len(desc); i++)
- topregs->deco.descbuf[i] = *(desc + i);
+ wr_reg32(&topregs->deco.descbuf[i], *(desc + i));

- wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR);
+ flags = DECO_JQCR_WHL;
+ /*
+ * If the descriptor length is longer than 4 words, then the
+ * FOUR bit in JRCTRL register must be set.
+ */
+ if (desc_len(desc) >= 4)
+ flags |= DECO_JQCR_FOUR;
+
+ /* Instruct the DECO to execute it */
+ wr_reg32(&topregs->deco.jr_ctl_hi, flags);

timeout = 10000000;
do {
@@ -129,9 +107,75 @@ static int instantiate_rng(struct device *ctrldev)
ret = -EIO;
}

+ /* Mark the DECO as free */
clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
-out:
+
+ if (!timeout)
+ return -EAGAIN;
+
+ return 0;
+}
+
+/*
+ * instantiate_rng - builds and executes a descriptor on DECO0,
+ * which initializes the RNG block.
+ * @ctrldev - pointer to device
+ * Return: - 0 if no error occurred
+ * - -ENOMEM if there isn't enough memory to allocate the descriptor
+ * - -ENODEV if DECO0 couldn't be acquired
+ * - -EAGAIN if an error occurred when executing the descriptor
+ * f.i. there was a RNG hardware error due to not "good enough"
+ * entropy being aquired.
+ */
+static int instantiate_rng(struct device *ctrldev)
+{
+ u32 *desc;
+ int ret = 0;
+
+ desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
+ if (!desc)
+ return -ENOMEM;
+ /* Create the descriptor for instantiating RNG State Handle 0 */
+ build_instantiation_desc(desc);
+
+ /* Try to run it through DECO0 */
+ ret = run_descriptor_deco0(ctrldev, desc);
+
kfree(desc);
+
+ return ret;
+}
+
+static int caam_remove(struct platform_device *pdev)
+{
+ struct device *ctrldev;
+ struct caam_drv_private *ctrlpriv;
+ struct caam_drv_private_jr *jrpriv;
+ struct caam_full __iomem *topregs;
+ int ring, ret = 0;
+
+ ctrldev = &pdev->dev;
+ ctrlpriv = dev_get_drvdata(ctrldev);
+ topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+
+ /* shut down JobRs */
+ for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
+ ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
+ jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
+ irq_dispose_mapping(jrpriv->irq);
+ }
+
+ /* Shut down debug views */
+#ifdef CONFIG_DEBUG_FS
+ debugfs_remove_recursive(ctrlpriv->dfs_root);
+#endif
+
+ /* Unmap controller region */
+ iounmap(&topregs->ctrl);
+
+ kfree(ctrlpriv->jrdev);
+ kfree(ctrlpriv);
+
return ret;
}

@@ -333,7 +377,7 @@ static int caam_probe(struct platform_device *pdev)
kick_trng(pdev, ent_delay);
ret = instantiate_rng(dev);
ent_delay += 400;
- } while ((ret == -EIO) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
+ } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
if (ret) {
dev_err(dev, "failed to instantiate RNG");
caam_remove(pdev);
--
1.7.7.6

2013-09-13 12:23:33

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH 0/7] crypto: caam - RNG4 patches and fixes

On Mon, Sep 09, 2013 at 06:56:27PM +0300, Alex Porosanu wrote:
> This patch series attempts to fix some identified issues and add some new
> functionalities regarding the RNG4 block in the CAAM driver:
> o if the CAAM driver isn't properly instantiated (e.g. RNG4 initialization
> fails), then there's an illegal memory access generated by the modules
> depending on it; patch 1 in the patch-set fixes this;
> o if the CAAM module is removed, the state handles are not uninstantiated;
> patch 3 in the patch-set adds the necessary descriptor to uninstantiate
> state handle 0;
> o the RNG4 block in CAAM needs to be 'seeded' first before being used
> for generating pseudo-random data. The 'seeding' is done by getting
> entropy from the TRNG ring oscillator. The RTFRQMAX register controls
> the maximum allowable number of samples that can be acquired during
> an entropy sample. Depending on the clock at which the RNG4 block
> (and for that matter the SEC block) runs, it's possible that a
> hard-coded value for the maximum frequency is inadequate, i.e. more
> samples than needed are taken. This leads to failures on devices
> like BSC913x. Patch number 2 fixes this issue by using a kind of
> a software loop to increase the maximum number of samples taken
> until the state handle can be properly initialized; o there are two
> state handles present in the RNG4 block and only one
> is initialized; patch 5 in the patch-set fixes this issue, also
> adding the necessary code for deinstantiation only the handles that were
> instantiated by the driver.

All applied. Thanks.
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt