aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/804-crypto-0040-LF-292-1-crypto-caam-refactor-RNG-initialization.patch
diff options
context:
space:
mode:
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.patch248
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);
+