| 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); |
| |