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