mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-27 17:18:59 +00:00
249 lines
7.9 KiB
Diff
249 lines
7.9 KiB
Diff
|
From 43f8f404e2e8cd81baa4d89706e40901c466c7bb Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com>
|
||
|
Date: Fri, 21 Feb 2020 11:48:39 +0100
|
||
|
Subject: [PATCH] LF-292-1 crypto: caam - refactor RNG initialization
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
RNG (re-)initialization will be needed on pm resume path,
|
||
|
thus refactor the corresponding code out of the probe callback.
|
||
|
|
||
|
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
|
||
|
Reviewed-by: Valentin Ciocoi Radulescu <valentin.ciocoi@nxp.com>
|
||
|
Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com>
|
||
|
Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
|
||
|
Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
|
||
|
---
|
||
|
drivers/crypto/caam/ctrl.c | 189 ++++++++++++++++++++++++---------------------
|
||
|
1 file changed, 102 insertions(+), 87 deletions(-)
|
||
|
|
||
|
--- a/drivers/crypto/caam/ctrl.c
|
||
|
+++ b/drivers/crypto/caam/ctrl.c
|
||
|
@@ -327,13 +327,12 @@ static int instantiate_rng(struct device
|
||
|
/*
|
||
|
* kick_trng - sets the various parameters for enabling the initialization
|
||
|
* of the RNG4 block in CAAM
|
||
|
- * @pdev - pointer to the platform device
|
||
|
+ * @dev - pointer to the controller device
|
||
|
* @ent_delay - Defines the length (in system clocks) of each entropy sample.
|
||
|
*/
|
||
|
-static void kick_trng(struct platform_device *pdev, int ent_delay)
|
||
|
+static void kick_trng(struct device *dev, int ent_delay)
|
||
|
{
|
||
|
- struct device *ctrldev = &pdev->dev;
|
||
|
- struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
|
||
|
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
|
||
|
struct caam_ctrl __iomem *ctrl;
|
||
|
struct rng4tst __iomem *r4tst;
|
||
|
u32 val;
|
||
|
@@ -571,10 +570,105 @@ static void caam_dma_dev_unregister(void
|
||
|
platform_device_unregister(data);
|
||
|
}
|
||
|
|
||
|
+static int caam_ctrl_rng_init(struct device *dev)
|
||
|
+{
|
||
|
+ struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
|
||
|
+ struct caam_ctrl __iomem *ctrl = ctrlpriv->ctrl;
|
||
|
+ int ret, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
|
||
|
+ u8 rng_vid;
|
||
|
+
|
||
|
+ if (ctrlpriv->era < 10) {
|
||
|
+ struct caam_perfmon __iomem *perfmon;
|
||
|
+
|
||
|
+ perfmon = ctrlpriv->total_jobrs ?
|
||
|
+ (struct caam_perfmon *)&ctrlpriv->jr[0]->perfmon :
|
||
|
+ (struct caam_perfmon *)&ctrl->perfmon;
|
||
|
+
|
||
|
+ rng_vid = (rd_reg32(&perfmon->cha_id_ls) &
|
||
|
+ CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
|
||
|
+ } else {
|
||
|
+ struct version_regs __iomem *vreg;
|
||
|
+
|
||
|
+ vreg = ctrlpriv->total_jobrs ?
|
||
|
+ (struct version_regs *)&ctrlpriv->jr[0]->vreg :
|
||
|
+ (struct version_regs *)&ctrl->vreg;
|
||
|
+
|
||
|
+ rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>
|
||
|
+ CHA_VER_VID_SHIFT;
|
||
|
+ }
|
||
|
+
|
||
|
+ /*
|
||
|
+ * If SEC has RNG version >= 4 and RNG state handle has not been
|
||
|
+ * already instantiated, do RNG instantiation
|
||
|
+ * In case of SoCs with Management Complex, RNG is managed by MC f/w.
|
||
|
+ */
|
||
|
+ if (!ctrlpriv->mc_en && rng_vid >= 4) {
|
||
|
+ ctrlpriv->rng4_sh_init =
|
||
|
+ rd_reg32(&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 {
|
||
|
+ int inst_handles =
|
||
|
+ rd_reg32(&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)) {
|
||
|
+ dev_info(dev,
|
||
|
+ "Entropy delay = %u\n",
|
||
|
+ ent_delay);
|
||
|
+ kick_trng(dev, ent_delay);
|
||
|
+ ent_delay += 400;
|
||
|
+ }
|
||
|
+ /*
|
||
|
+ * if instantiate_rng(...) fails, the loop will rerun
|
||
|
+ * and the kick_trng(...) function will modify 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);
|
||
|
+ if (ret == -EAGAIN)
|
||
|
+ /*
|
||
|
+ * if here, the loop will rerun,
|
||
|
+ * so don't hog the CPU
|
||
|
+ */
|
||
|
+ cpu_relax();
|
||
|
+ } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
|
||
|
+ if (ret) {
|
||
|
+ dev_err(dev, "failed to instantiate RNG");
|
||
|
+ return ret;
|
||
|
+ }
|
||
|
+ /*
|
||
|
+ * 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 */
|
||
|
+ clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
/* Probe routine for CAAM top (controller) level */
|
||
|
static int caam_probe(struct platform_device *pdev)
|
||
|
{
|
||
|
- int ret, ring, gen_sk, ent_delay = RTSDCTL_ENT_DLY_MIN;
|
||
|
+ int ret, ring;
|
||
|
u64 caam_id;
|
||
|
const struct soc_device_attribute *imx_soc_match;
|
||
|
static struct platform_device_info caam_dma_pdev_info = {
|
||
|
@@ -592,7 +686,6 @@ static int caam_probe(struct platform_de
|
||
|
struct dentry *dfs_root;
|
||
|
#endif
|
||
|
u32 scfgr, comp_params;
|
||
|
- u8 rng_vid;
|
||
|
int pg_size;
|
||
|
int BLOCK_OFFSET = 0;
|
||
|
bool reg_access = true;
|
||
|
@@ -875,90 +968,12 @@ set_dma_mask:
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
- if (!reg_access)
|
||
|
- goto report_live;
|
||
|
-
|
||
|
- if (ctrlpriv->era < 10) {
|
||
|
- rng_vid = (rd_reg32(&perfmon->cha_id_ls) &
|
||
|
- CHA_ID_LS_RNG_MASK) >> CHA_ID_LS_RNG_SHIFT;
|
||
|
- } else {
|
||
|
- struct version_regs __iomem *vreg;
|
||
|
-
|
||
|
- vreg = ring ? (struct version_regs *)&ctrlpriv->jr[0]->vreg :
|
||
|
- (struct version_regs *)&ctrl->vreg;
|
||
|
-
|
||
|
- rng_vid = (rd_reg32(&vreg->rng) & CHA_VER_VID_MASK) >>
|
||
|
- CHA_VER_VID_SHIFT;
|
||
|
- }
|
||
|
-
|
||
|
- /*
|
||
|
- * If SEC has RNG version >= 4 and RNG state handle has not been
|
||
|
- * already instantiated, do RNG instantiation
|
||
|
- * In case of SoCs with Management Complex, RNG is managed by MC f/w.
|
||
|
- */
|
||
|
- if (!ctrlpriv->mc_en && rng_vid >= 4) {
|
||
|
- ctrlpriv->rng4_sh_init =
|
||
|
- rd_reg32(&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 {
|
||
|
- int inst_handles =
|
||
|
- rd_reg32(&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)) {
|
||
|
- dev_info(dev,
|
||
|
- "Entropy delay = %u\n",
|
||
|
- ent_delay);
|
||
|
- 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);
|
||
|
- if (ret == -EAGAIN)
|
||
|
- /*
|
||
|
- * if here, the loop will rerun,
|
||
|
- * so don't hog the CPU
|
||
|
- */
|
||
|
- cpu_relax();
|
||
|
- } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
|
||
|
- if (ret) {
|
||
|
- dev_err(dev, "failed to instantiate RNG");
|
||
|
+ if (reg_access) {
|
||
|
+ ret = caam_ctrl_rng_init(dev);
|
||
|
+ if (ret)
|
||
|
return ret;
|
||
|
- }
|
||
|
- /*
|
||
|
- * 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 */
|
||
|
- clrsetbits_32(&ctrl->scfgr, 0, SCFGR_RDBENABLE);
|
||
|
}
|
||
|
|
||
|
- /* NOTE: RTIC detection ought to go here, around Si time */
|
||
|
-
|
||
|
-report_live:
|
||
|
caam_id = (u64)rd_reg32(&perfmon->caam_id_ms) << 32 |
|
||
|
(u64)rd_reg32(&perfmon->caam_id_ls);
|
||
|
|