From 43f8f404e2e8cd81baa4d89706e40901c466c7bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horia=20Geant=C4=83?= 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ă Reviewed-by: Valentin Ciocoi Radulescu Signed-off-by: Franck LENORMAND Signed-off-by: Leonard Crestez Signed-off-by: Dong Aisheng --- 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);