diff mbox series

crypto: caam - optimize RNG sample size

Message ID 20230612083042.1256966-1-meenakshi.aggarwal@nxp.com (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show
Series crypto: caam - optimize RNG sample size | expand

Commit Message

Meenakshi Aggarwal June 12, 2023, 8:30 a.m. UTC
From: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>

TRNG "sample size" (the total number of entropy samples that will be taken
during entropy generation) default / POR value is very conservatively
set to 2500.

Let's set it to 512, the same as the caam driver in U-boot
(drivers/crypto/fsl_caam.c) does.

This solves the issue of RNG performance dropping after a suspend/resume
cycle on parts where caam loses power, since the initial U-boot setttings
are lost and kernel does not restore them when resuming.

Note: when changing the sample size, the self-test parameters need to be
updated accordingly.

Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
---
 drivers/crypto/caam/ctrl.c | 52 +++++++++++++++++++++++---------------
 drivers/crypto/caam/regs.h | 14 ++++++++--
 2 files changed, 44 insertions(+), 22 deletions(-)

Comments

Gaurav Jain June 15, 2023, 11:51 a.m. UTC | #1
Reviewed-by: Gaurav Jain <gaurav.jain@nxp.com>

> -----Original Message-----
> From: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
> Sent: Monday, June 12, 2023 2:01 PM
> To: Horia Geanta <horia.geanta@nxp.com>; Varun Sethi <V.Sethi@nxp.com>;
> Pankaj Gupta <pankaj.gupta@nxp.com>; Gaurav Jain <gaurav.jain@nxp.com>;
> herbert@gondor.apana.org.au; davem@davemloft.net; linux-
> crypto@vger.kernel.org; linux-kernel@vger.kernel.org
> Cc: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
> Subject: [PATCH] crypto: caam - optimize RNG sample size
> 
> From: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
> 
> TRNG "sample size" (the total number of entropy samples that will be taken
> during entropy generation) default / POR value is very conservatively set to 2500.
> 
> Let's set it to 512, the same as the caam driver in U-boot
> (drivers/crypto/fsl_caam.c) does.
> 
> This solves the issue of RNG performance dropping after a suspend/resume
> cycle on parts where caam loses power, since the initial U-boot setttings are lost
> and kernel does not restore them when resuming.
> 
> Note: when changing the sample size, the self-test parameters need to be
> updated accordingly.
> 
> Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
> Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
> ---
>  drivers/crypto/caam/ctrl.c | 52 +++++++++++++++++++++++---------------
>  drivers/crypto/caam/regs.h | 14 ++++++++--
>  2 files changed, 44 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index
> 62dd069942e4..b06bb64c6c23 100644
> --- a/drivers/crypto/caam/ctrl.c
> +++ b/drivers/crypto/caam/ctrl.c
> @@ -352,7 +352,7 @@ static void kick_trng(struct device *dev, int ent_delay)
>  	struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
>  	struct caam_ctrl __iomem *ctrl;
>  	struct rng4tst __iomem *r4tst;
> -	u32 val;
> +	u32 val, rtsdctl;
> 
>  	ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
>  	r4tst = &ctrl->r4tst[0];
> @@ -368,26 +368,38 @@ static void kick_trng(struct device *dev, int ent_delay)
>  	 * Performance-wise, it does not make sense to
>  	 * set the delay to a value that is lower
>  	 * than the last one that worked (i.e. the state handles
> -	 * were instantiated properly. Thus, instead of wasting
> -	 * time trying to set the values controlling the sample
> -	 * frequency, the function simply returns.
> +	 * were instantiated properly).
>  	 */
> -	val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
> -	      >> RTSDCTL_ENT_DLY_SHIFT;
> -	if (ent_delay <= val)
> -		goto start_rng;
> -
> -	val = rd_reg32(&r4tst->rtsdctl);
> -	val = (val & ~RTSDCTL_ENT_DLY_MASK) |
> -	      (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
> -	wr_reg32(&r4tst->rtsdctl, val);
> -	/* min. freq. count, equal to 1/4 of the entropy sample length */
> -	wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
> -	/* max. freq. count, equal to 16 times the entropy sample length */
> -	wr_reg32(&r4tst->rtfrqmax, ent_delay << 4);
> -	/* read the control register */
> -	val = rd_reg32(&r4tst->rtmctl);
> -start_rng:
> +	rtsdctl = rd_reg32(&r4tst->rtsdctl);
> +	val = (rtsdctl & RTSDCTL_ENT_DLY_MASK) >> RTSDCTL_ENT_DLY_SHIFT;
> +	if (ent_delay > val) {
> +		val = ent_delay;
> +		/* min. freq. count, equal to 1/4 of the entropy sample length
> */
> +		wr_reg32(&r4tst->rtfrqmin, val >> 2);
> +		/* max. freq. count, equal to 16 times the entropy sample
> length */
> +		wr_reg32(&r4tst->rtfrqmax, val << 4);
> +	}
> +
> +	wr_reg32(&r4tst->rtsdctl, (val << RTSDCTL_ENT_DLY_SHIFT) |
> +		 RTSDCTL_SAMP_SIZE_VAL);
> +
> +	/*
> +	 * To avoid reprogramming the self-test parameters over and over again,
> +	 * use RTSDCTL[SAMP_SIZE] as an indicator.
> +	 */
> +	if ((rtsdctl & RTSDCTL_SAMP_SIZE_MASK) != RTSDCTL_SAMP_SIZE_VAL)
> {
> +		wr_reg32(&r4tst->rtscmisc, (2 << 16) | 32);
> +		wr_reg32(&r4tst->rtpkrrng, 570);
> +		wr_reg32(&r4tst->rtpkrmax, 1600);
> +		wr_reg32(&r4tst->rtscml, (122 << 16) | 317);
> +		wr_reg32(&r4tst->rtscrl[0], (80 << 16) | 107);
> +		wr_reg32(&r4tst->rtscrl[1], (57 << 16) | 62);
> +		wr_reg32(&r4tst->rtscrl[2], (39 << 16) | 39);
> +		wr_reg32(&r4tst->rtscrl[3], (27 << 16) | 26);
> +		wr_reg32(&r4tst->rtscrl[4], (19 << 16) | 18);
> +		wr_reg32(&r4tst->rtscrl[5], (18 << 16) | 17);
> +	}
> +
>  	/*
>  	 * select raw sampling in both entropy shifter
>  	 * and statistical checker; ; put RNG4 into run mode diff --git
> a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h index
> 66928f8a0c4b..189e74c21f0c 100644
> --- a/drivers/crypto/caam/regs.h
> +++ b/drivers/crypto/caam/regs.h
> @@ -3,7 +3,7 @@
>   * CAAM hardware register-level view
>   *
>   * Copyright 2008-2011 Freescale Semiconductor, Inc.
> - * Copyright 2018 NXP
> + * Copyright 2018, 2023 NXP
>   */
> 
>  #ifndef REGS_H
> @@ -523,6 +523,8 @@ struct rng4tst {
>  #define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
> #define RTSDCTL_ENT_DLY_MIN 3200  #define RTSDCTL_ENT_DLY_MAX 12800
> +#define RTSDCTL_SAMP_SIZE_MASK 0xffff
> +#define RTSDCTL_SAMP_SIZE_VAL 512
>  	u32 rtsdctl;		/* seed control register */
>  	union {
>  		u32 rtsblim;	/* PRGM=1: sparse bit limit register */
> @@ -534,7 +536,15 @@ struct rng4tst {
>  		u32 rtfrqmax;	/* PRGM=1: freq. count max. limit register */
>  		u32 rtfrqcnt;	/* PRGM=0: freq. count register */
>  	};
> -	u32 rsvd1[40];
> +	union {
> +		u32 rtscmc;	/* statistical check run monobit count */
> +		u32 rtscml;	/* statistical check run monobit limit */
> +	};
> +	union {
> +		u32 rtscrc[6];	/* statistical check run length count */
> +		u32 rtscrl[6];	/* statistical check run length limit */
> +	};
> +	u32 rsvd1[33];
>  #define RDSTA_SKVT 0x80000000
>  #define RDSTA_SKVN 0x40000000
>  #define RDSTA_PR0 BIT(4)
> --
> 2.25.1
Herbert Xu June 23, 2023, 8:21 a.m. UTC | #2
On Mon, Jun 12, 2023 at 10:30:42AM +0200, meenakshi.aggarwal@nxp.com wrote:
> From: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
> 
> TRNG "sample size" (the total number of entropy samples that will be taken
> during entropy generation) default / POR value is very conservatively
> set to 2500.
> 
> Let's set it to 512, the same as the caam driver in U-boot
> (drivers/crypto/fsl_caam.c) does.
> 
> This solves the issue of RNG performance dropping after a suspend/resume
> cycle on parts where caam loses power, since the initial U-boot setttings
> are lost and kernel does not restore them when resuming.
> 
> Note: when changing the sample size, the self-test parameters need to be
> updated accordingly.
> 
> Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
> Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@nxp.com>
> ---
>  drivers/crypto/caam/ctrl.c | 52 +++++++++++++++++++++++---------------
>  drivers/crypto/caam/regs.h | 14 ++++++++--
>  2 files changed, 44 insertions(+), 22 deletions(-)

Patch applied.  Thanks.
diff mbox series

Patch

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 62dd069942e4..b06bb64c6c23 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -352,7 +352,7 @@  static void kick_trng(struct device *dev, int ent_delay)
 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev);
 	struct caam_ctrl __iomem *ctrl;
 	struct rng4tst __iomem *r4tst;
-	u32 val;
+	u32 val, rtsdctl;
 
 	ctrl = (struct caam_ctrl __iomem *)ctrlpriv->ctrl;
 	r4tst = &ctrl->r4tst[0];
@@ -368,26 +368,38 @@  static void kick_trng(struct device *dev, int ent_delay)
 	 * Performance-wise, it does not make sense to
 	 * set the delay to a value that is lower
 	 * than the last one that worked (i.e. the state handles
-	 * were instantiated properly. Thus, instead of wasting
-	 * time trying to set the values controlling the sample
-	 * frequency, the function simply returns.
+	 * were instantiated properly).
 	 */
-	val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
-	      >> RTSDCTL_ENT_DLY_SHIFT;
-	if (ent_delay <= val)
-		goto start_rng;
-
-	val = rd_reg32(&r4tst->rtsdctl);
-	val = (val & ~RTSDCTL_ENT_DLY_MASK) |
-	      (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
-	wr_reg32(&r4tst->rtsdctl, val);
-	/* min. freq. count, equal to 1/4 of the entropy sample length */
-	wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
-	/* max. freq. count, equal to 16 times the entropy sample length */
-	wr_reg32(&r4tst->rtfrqmax, ent_delay << 4);
-	/* read the control register */
-	val = rd_reg32(&r4tst->rtmctl);
-start_rng:
+	rtsdctl = rd_reg32(&r4tst->rtsdctl);
+	val = (rtsdctl & RTSDCTL_ENT_DLY_MASK) >> RTSDCTL_ENT_DLY_SHIFT;
+	if (ent_delay > val) {
+		val = ent_delay;
+		/* min. freq. count, equal to 1/4 of the entropy sample length */
+		wr_reg32(&r4tst->rtfrqmin, val >> 2);
+		/* max. freq. count, equal to 16 times the entropy sample length */
+		wr_reg32(&r4tst->rtfrqmax, val << 4);
+	}
+
+	wr_reg32(&r4tst->rtsdctl, (val << RTSDCTL_ENT_DLY_SHIFT) |
+		 RTSDCTL_SAMP_SIZE_VAL);
+
+	/*
+	 * To avoid reprogramming the self-test parameters over and over again,
+	 * use RTSDCTL[SAMP_SIZE] as an indicator.
+	 */
+	if ((rtsdctl & RTSDCTL_SAMP_SIZE_MASK) != RTSDCTL_SAMP_SIZE_VAL) {
+		wr_reg32(&r4tst->rtscmisc, (2 << 16) | 32);
+		wr_reg32(&r4tst->rtpkrrng, 570);
+		wr_reg32(&r4tst->rtpkrmax, 1600);
+		wr_reg32(&r4tst->rtscml, (122 << 16) | 317);
+		wr_reg32(&r4tst->rtscrl[0], (80 << 16) | 107);
+		wr_reg32(&r4tst->rtscrl[1], (57 << 16) | 62);
+		wr_reg32(&r4tst->rtscrl[2], (39 << 16) | 39);
+		wr_reg32(&r4tst->rtscrl[3], (27 << 16) | 26);
+		wr_reg32(&r4tst->rtscrl[4], (19 << 16) | 18);
+		wr_reg32(&r4tst->rtscrl[5], (18 << 16) | 17);
+	}
+
 	/*
 	 * select raw sampling in both entropy shifter
 	 * and statistical checker; ; put RNG4 into run mode
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index 66928f8a0c4b..189e74c21f0c 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -3,7 +3,7 @@ 
  * CAAM hardware register-level view
  *
  * Copyright 2008-2011 Freescale Semiconductor, Inc.
- * Copyright 2018 NXP
+ * Copyright 2018, 2023 NXP
  */
 
 #ifndef REGS_H
@@ -523,6 +523,8 @@  struct rng4tst {
 #define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
 #define RTSDCTL_ENT_DLY_MIN 3200
 #define RTSDCTL_ENT_DLY_MAX 12800
+#define RTSDCTL_SAMP_SIZE_MASK 0xffff
+#define RTSDCTL_SAMP_SIZE_VAL 512
 	u32 rtsdctl;		/* seed control register */
 	union {
 		u32 rtsblim;	/* PRGM=1: sparse bit limit register */
@@ -534,7 +536,15 @@  struct rng4tst {
 		u32 rtfrqmax;	/* PRGM=1: freq. count max. limit register */
 		u32 rtfrqcnt;	/* PRGM=0: freq. count register */
 	};
-	u32 rsvd1[40];
+	union {
+		u32 rtscmc;	/* statistical check run monobit count */
+		u32 rtscml;	/* statistical check run monobit limit */
+	};
+	union {
+		u32 rtscrc[6];	/* statistical check run length count */
+		u32 rtscrl[6];	/* statistical check run length limit */
+	};
+	u32 rsvd1[33];
 #define RDSTA_SKVT 0x80000000
 #define RDSTA_SKVN 0x40000000
 #define RDSTA_PR0 BIT(4)