aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/caam
diff options
context:
space:
mode:
authorAlex Porosanu <alexandru.porosanu@freescale.com>2013-09-09 11:56:30 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2013-09-13 07:43:54 -0400
commit84cf48278bc94dfc1b4ffafa987ae115abcc625a (patch)
tree8b30b20f3b154353122f64966ddde7a110275fa2 /drivers/crypto/caam
parentb2744dfd39c51e6fd56e79ff2eabf9953d45027e (diff)
crypto: caam - fix RNG4 instantiation
The RNG4 block in CAAM needs to be 'seeded' first before being used for generating pseudo-random data. The 'seeding' is done by getting entropy from the TRNG ring oscillator. The RTFRQMAX register controls the maximum allowable number of samples that can be aquired during an entropy sample. Depending on the clock at which the RNG4 block (and for that matter the SEC block) runs, it's possible that a hard-coded value for the maximum frequency is inadequate, i.e. more samples than needed are taken. This is an error, and thus the RNG4 block doesn't get initialized. The patch attempts to alleviate this issue by trying with progressivly larger frequencies, until the number of samples is adequate. This patch also fixes how a descriptor is deemed as being finished: instead of checking the VALID field in the DECO debug register, it makes sure that the DECO is idle, by checking the DECO state field of the said register. Signed-off-by: Alex Porosanu <alexandru.porosanu@freescale.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/caam')
-rw-r--r--drivers/crypto/caam/ctrl.c63
-rw-r--r--drivers/crypto/caam/regs.h7
2 files changed, 52 insertions, 18 deletions
diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index 11c7f295857b..d5fe5f57108c 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -82,7 +82,7 @@ static int instantiate_rng(struct device *ctrldev)
82 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); 82 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
83 struct caam_full __iomem *topregs; 83 struct caam_full __iomem *topregs;
84 unsigned int timeout = 100000; 84 unsigned int timeout = 100000;
85 u32 *desc; 85 u32 *desc, deco_dbg_reg;
86 int i, ret = 0; 86 int i, ret = 0;
87 87
88 desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL | GFP_DMA); 88 desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL | GFP_DMA);
@@ -112,9 +112,17 @@ static int instantiate_rng(struct device *ctrldev)
112 wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR); 112 wr_reg32(&topregs->deco.jr_ctl_hi, DECO_JQCR_WHL | DECO_JQCR_FOUR);
113 113
114 timeout = 10000000; 114 timeout = 10000000;
115 while ((rd_reg32(&topregs->deco.desc_dbg) & DECO_DBG_VALID) && 115 do {
116 --timeout) 116 deco_dbg_reg = rd_reg32(&topregs->deco.desc_dbg);
117 /*
118 * If an error occured in the descriptor, then
119 * the DECO status field will be set to 0x0D
120 */
121 if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
122 DESC_DBG_DECO_STAT_HOST_ERR)
123 break;
117 cpu_relax(); 124 cpu_relax();
125 } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
118 126
119 if (!timeout) { 127 if (!timeout) {
120 dev_err(ctrldev, "failed to instantiate RNG\n"); 128 dev_err(ctrldev, "failed to instantiate RNG\n");
@@ -128,10 +136,12 @@ out:
128} 136}
129 137
130/* 138/*
131 * By default, the TRNG runs for 200 clocks per sample; 139 * kick_trng - sets the various parameters for enabling the initialization
132 * 1600 clocks per sample generates better entropy. 140 * of the RNG4 block in CAAM
141 * @pdev - pointer to the platform device
142 * @ent_delay - Defines the length (in system clocks) of each entropy sample.
133 */ 143 */
134static void kick_trng(struct platform_device *pdev) 144static void kick_trng(struct platform_device *pdev, int ent_delay)
135{ 145{
136 struct device *ctrldev = &pdev->dev; 146 struct device *ctrldev = &pdev->dev;
137 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev); 147 struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
@@ -144,14 +154,31 @@ static void kick_trng(struct platform_device *pdev)
144 154
145 /* put RNG4 into program mode */ 155 /* put RNG4 into program mode */
146 setbits32(&r4tst->rtmctl, RTMCTL_PRGM); 156 setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
147 /* 1600 clocks per sample */ 157
158 /*
159 * Performance-wise, it does not make sense to
160 * set the delay to a value that is lower
161 * than the last one that worked (i.e. the state handles
162 * were instantiated properly. Thus, instead of wasting
163 * time trying to set the values controlling the sample
164 * frequency, the function simply returns.
165 */
166 val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
167 >> RTSDCTL_ENT_DLY_SHIFT;
168 if (ent_delay <= val) {
169 /* put RNG4 into run mode */
170 clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
171 return;
172 }
173
148 val = rd_reg32(&r4tst->rtsdctl); 174 val = rd_reg32(&r4tst->rtsdctl);
149 val = (val & ~RTSDCTL_ENT_DLY_MASK) | (1600 << RTSDCTL_ENT_DLY_SHIFT); 175 val = (val & ~RTSDCTL_ENT_DLY_MASK) |
176 (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
150 wr_reg32(&r4tst->rtsdctl, val); 177 wr_reg32(&r4tst->rtsdctl, val);
151 /* min. freq. count */ 178 /* min. freq. count, equal to 1/4 of the entropy sample length */
152 wr_reg32(&r4tst->rtfrqmin, 400); 179 wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
153 /* max. freq. count */ 180 /* max. freq. count, equal to 8 times the entropy sample length */
154 wr_reg32(&r4tst->rtfrqmax, 6400); 181 wr_reg32(&r4tst->rtfrqmax, ent_delay << 3);
155 /* put RNG4 into run mode */ 182 /* put RNG4 into run mode */
156 clrbits32(&r4tst->rtmctl, RTMCTL_PRGM); 183 clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
157} 184}
@@ -192,7 +219,7 @@ EXPORT_SYMBOL(caam_get_era);
192/* Probe routine for CAAM top (controller) level */ 219/* Probe routine for CAAM top (controller) level */
193static int caam_probe(struct platform_device *pdev) 220static int caam_probe(struct platform_device *pdev)
194{ 221{
195 int ret, ring, rspec; 222 int ret, ring, rspec, ent_delay = RTSDCTL_ENT_DLY_MIN;
196 u64 caam_id; 223 u64 caam_id;
197 struct device *dev; 224 struct device *dev;
198 struct device_node *nprop, *np; 225 struct device_node *nprop, *np;
@@ -298,13 +325,17 @@ static int caam_probe(struct platform_device *pdev)
298 325
299 /* 326 /*
300 * If SEC has RNG version >= 4 and RNG state handle has not been 327 * If SEC has RNG version >= 4 and RNG state handle has not been
301 * already instantiated ,do RNG instantiation 328 * already instantiated, do RNG instantiation
302 */ 329 */
303 if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 && 330 if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
304 !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) { 331 !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
305 kick_trng(pdev); 332 do {
306 ret = instantiate_rng(dev); 333 kick_trng(pdev, ent_delay);
334 ret = instantiate_rng(dev);
335 ent_delay += 400;
336 } while ((ret == -EIO) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
307 if (ret) { 337 if (ret) {
338 dev_err(dev, "failed to instantiate RNG");
308 caam_remove(pdev); 339 caam_remove(pdev);
309 return ret; 340 return ret;
310 } 341 }
diff --git a/drivers/crypto/caam/regs.h b/drivers/crypto/caam/regs.h
index 4455396918de..9aa9f718a6fc 100644
--- a/drivers/crypto/caam/regs.h
+++ b/drivers/crypto/caam/regs.h
@@ -255,6 +255,8 @@ struct rng4tst {
255 }; 255 };
256#define RTSDCTL_ENT_DLY_SHIFT 16 256#define RTSDCTL_ENT_DLY_SHIFT 16
257#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT) 257#define RTSDCTL_ENT_DLY_MASK (0xffff << RTSDCTL_ENT_DLY_SHIFT)
258#define RTSDCTL_ENT_DLY_MIN 1200
259#define RTSDCTL_ENT_DLY_MAX 12800
258 u32 rtsdctl; /* seed control register */ 260 u32 rtsdctl; /* seed control register */
259 union { 261 union {
260 u32 rtsblim; /* PRGM=1: sparse bit limit register */ 262 u32 rtsblim; /* PRGM=1: sparse bit limit register */
@@ -706,12 +708,13 @@ struct caam_deco {
706 u32 rsvd29[48]; 708 u32 rsvd29[48];
707 u32 descbuf[64]; /* DxDESB - Descriptor buffer */ 709 u32 descbuf[64]; /* DxDESB - Descriptor buffer */
708 u32 rscvd30[193]; 710 u32 rscvd30[193];
711#define DESC_DBG_DECO_STAT_HOST_ERR 0x00D00000
712#define DESC_DBG_DECO_STAT_VALID 0x80000000
713#define DESC_DBG_DECO_STAT_MASK 0x00F00000
709 u32 desc_dbg; /* DxDDR - DECO Debug Register */ 714 u32 desc_dbg; /* DxDDR - DECO Debug Register */
710 u32 rsvd31[126]; 715 u32 rsvd31[126];
711}; 716};
712 717
713/* DECO DBG Register Valid Bit*/
714#define DECO_DBG_VALID 0x80000000
715#define DECO_JQCR_WHL 0x20000000 718#define DECO_JQCR_WHL 0x20000000
716#define DECO_JQCR_FOUR 0x10000000 719#define DECO_JQCR_FOUR 0x10000000
717 720