diff options
Diffstat (limited to 'target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch')
-rw-r--r-- | target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch b/target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch new file mode 100644 index 0000000000..c4c22a1cd5 --- /dev/null +++ b/target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch @@ -0,0 +1,248 @@ +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); + |