]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/crypto/caam/ctrl.c
crypto: caam - split RNG4 instantiation function
[karo-tx-linux.git] / drivers / crypto / caam / ctrl.c
1 /*
2  * CAAM control-plane driver backend
3  * Controller-level driver, kernel property detection, initialization
4  *
5  * Copyright 2008-2012 Freescale Semiconductor, Inc.
6  */
7
8 #include "compat.h"
9 #include "regs.h"
10 #include "intern.h"
11 #include "jr.h"
12 #include "desc_constr.h"
13 #include "error.h"
14 #include "ctrl.h"
15
16 /*
17  * Descriptor to instantiate RNG State Handle 0 in normal mode and
18  * load the JDKEK, TDKEK and TDSK registers
19  */
20 static void build_instantiation_desc(u32 *desc)
21 {
22         u32 *jump_cmd;
23
24         init_job_desc(desc, 0);
25
26         /* INIT RNG in non-test mode */
27         append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
28                          OP_ALG_AS_INIT);
29
30         /* wait for done */
31         jump_cmd = append_jump(desc, JUMP_CLASS_CLASS1);
32         set_jump_tgt_here(desc, jump_cmd);
33
34         /*
35          * load 1 to clear written reg:
36          * resets the done interrupt and returns the RNG to idle.
37          */
38         append_load_imm_u32(desc, 1, LDST_SRCDST_WORD_CLRW);
39
40         /* generate secure keys (non-test) */
41         append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
42                          OP_ALG_RNG4_SK);
43
44         append_jump(desc, JUMP_CLASS_CLASS1 | JUMP_TYPE_HALT);
45 }
46
47
48 /*
49  * run_descriptor_deco0 - runs a descriptor on DECO0, under direct control of
50  *                        the software (no JR/QI used).
51  * @ctrldev - pointer to device
52  * Return: - 0 if no error occurred
53  *         - -ENODEV if the DECO couldn't be acquired
54  *         - -EAGAIN if an error occurred while executing the descriptor
55  */
56 static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc)
57 {
58         struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
59         struct caam_full __iomem *topregs;
60         unsigned int timeout = 100000;
61         u32 deco_dbg_reg, flags;
62         int i, ret = 0;
63
64         /* Set the bit to request direct access to DECO0 */
65         topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
66         setbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
67
68         while (!(rd_reg32(&topregs->ctrl.deco_rq) & DECORR_DEN0) &&
69                                                                  --timeout)
70                 cpu_relax();
71
72         if (!timeout) {
73                 dev_err(ctrldev, "failed to acquire DECO 0\n");
74                 clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
75                 return -ENODEV;
76         }
77
78         for (i = 0; i < desc_len(desc); i++)
79                 wr_reg32(&topregs->deco.descbuf[i], *(desc + i));
80
81         flags = DECO_JQCR_WHL;
82         /*
83          * If the descriptor length is longer than 4 words, then the
84          * FOUR bit in JRCTRL register must be set.
85          */
86         if (desc_len(desc) >= 4)
87                 flags |= DECO_JQCR_FOUR;
88
89         /* Instruct the DECO to execute it */
90         wr_reg32(&topregs->deco.jr_ctl_hi, flags);
91
92         timeout = 10000000;
93         do {
94                 deco_dbg_reg = rd_reg32(&topregs->deco.desc_dbg);
95                 /*
96                  * If an error occured in the descriptor, then
97                  * the DECO status field will be set to 0x0D
98                  */
99                 if ((deco_dbg_reg & DESC_DBG_DECO_STAT_MASK) ==
100                     DESC_DBG_DECO_STAT_HOST_ERR)
101                         break;
102                 cpu_relax();
103         } while ((deco_dbg_reg & DESC_DBG_DECO_STAT_VALID) && --timeout);
104
105         if (!timeout) {
106                 dev_err(ctrldev, "failed to instantiate RNG\n");
107                 ret = -EIO;
108         }
109
110         /* Mark the DECO as free */
111         clrbits32(&topregs->ctrl.deco_rq, DECORR_RQD0ENABLE);
112
113         if (!timeout)
114                 return -EAGAIN;
115
116         return 0;
117 }
118
119 /*
120  * instantiate_rng - builds and executes a descriptor on DECO0,
121  *                   which initializes the RNG block.
122  * @ctrldev - pointer to device
123  * Return: - 0 if no error occurred
124  *         - -ENOMEM if there isn't enough memory to allocate the descriptor
125  *         - -ENODEV if DECO0 couldn't be acquired
126  *         - -EAGAIN if an error occurred when executing the descriptor
127  *            f.i. there was a RNG hardware error due to not "good enough"
128  *            entropy being aquired.
129  */
130 static int instantiate_rng(struct device *ctrldev)
131 {
132         u32 *desc;
133         int ret = 0;
134
135         desc = kmalloc(CAAM_CMD_SZ * 7, GFP_KERNEL);
136         if (!desc)
137                 return -ENOMEM;
138         /* Create the descriptor for instantiating RNG State Handle 0 */
139         build_instantiation_desc(desc);
140
141         /* Try to run it through DECO0 */
142         ret = run_descriptor_deco0(ctrldev, desc);
143
144         kfree(desc);
145
146         return ret;
147 }
148
149 static int caam_remove(struct platform_device *pdev)
150 {
151         struct device *ctrldev;
152         struct caam_drv_private *ctrlpriv;
153         struct caam_drv_private_jr *jrpriv;
154         struct caam_full __iomem *topregs;
155         int ring, ret = 0;
156
157         ctrldev = &pdev->dev;
158         ctrlpriv = dev_get_drvdata(ctrldev);
159         topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
160
161         /* shut down JobRs */
162         for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
163                 ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
164                 jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
165                 irq_dispose_mapping(jrpriv->irq);
166         }
167
168         /* Shut down debug views */
169 #ifdef CONFIG_DEBUG_FS
170         debugfs_remove_recursive(ctrlpriv->dfs_root);
171 #endif
172
173         /* Unmap controller region */
174         iounmap(&topregs->ctrl);
175
176         kfree(ctrlpriv->jrdev);
177         kfree(ctrlpriv);
178
179         return ret;
180 }
181
182 /*
183  * kick_trng - sets the various parameters for enabling the initialization
184  *             of the RNG4 block in CAAM
185  * @pdev - pointer to the platform device
186  * @ent_delay - Defines the length (in system clocks) of each entropy sample.
187  */
188 static void kick_trng(struct platform_device *pdev, int ent_delay)
189 {
190         struct device *ctrldev = &pdev->dev;
191         struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
192         struct caam_full __iomem *topregs;
193         struct rng4tst __iomem *r4tst;
194         u32 val;
195
196         topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
197         r4tst = &topregs->ctrl.r4tst[0];
198
199         /* put RNG4 into program mode */
200         setbits32(&r4tst->rtmctl, RTMCTL_PRGM);
201
202         /*
203          * Performance-wise, it does not make sense to
204          * set the delay to a value that is lower
205          * than the last one that worked (i.e. the state handles
206          * were instantiated properly. Thus, instead of wasting
207          * time trying to set the values controlling the sample
208          * frequency, the function simply returns.
209          */
210         val = (rd_reg32(&r4tst->rtsdctl) & RTSDCTL_ENT_DLY_MASK)
211               >> RTSDCTL_ENT_DLY_SHIFT;
212         if (ent_delay <= val) {
213                 /* put RNG4 into run mode */
214                 clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
215                 return;
216         }
217
218         val = rd_reg32(&r4tst->rtsdctl);
219         val = (val & ~RTSDCTL_ENT_DLY_MASK) |
220               (ent_delay << RTSDCTL_ENT_DLY_SHIFT);
221         wr_reg32(&r4tst->rtsdctl, val);
222         /* min. freq. count, equal to 1/4 of the entropy sample length */
223         wr_reg32(&r4tst->rtfrqmin, ent_delay >> 2);
224         /* max. freq. count, equal to 8 times the entropy sample length */
225         wr_reg32(&r4tst->rtfrqmax, ent_delay << 3);
226         /* put RNG4 into run mode */
227         clrbits32(&r4tst->rtmctl, RTMCTL_PRGM);
228 }
229
230 /**
231  * caam_get_era() - Return the ERA of the SEC on SoC, based
232  * on the SEC_VID register.
233  * Returns the ERA number (1..4) or -ENOTSUPP if the ERA is unknown.
234  * @caam_id - the value of the SEC_VID register
235  **/
236 int caam_get_era(u64 caam_id)
237 {
238         struct sec_vid *sec_vid = (struct sec_vid *)&caam_id;
239         static const struct {
240                 u16 ip_id;
241                 u8 maj_rev;
242                 u8 era;
243         } caam_eras[] = {
244                 {0x0A10, 1, 1},
245                 {0x0A10, 2, 2},
246                 {0x0A12, 1, 3},
247                 {0x0A14, 1, 3},
248                 {0x0A14, 2, 4},
249                 {0x0A16, 1, 4},
250                 {0x0A11, 1, 4}
251         };
252         int i;
253
254         for (i = 0; i < ARRAY_SIZE(caam_eras); i++)
255                 if (caam_eras[i].ip_id == sec_vid->ip_id &&
256                         caam_eras[i].maj_rev == sec_vid->maj_rev)
257                                 return caam_eras[i].era;
258
259         return -ENOTSUPP;
260 }
261 EXPORT_SYMBOL(caam_get_era);
262
263 /* Probe routine for CAAM top (controller) level */
264 static int caam_probe(struct platform_device *pdev)
265 {
266         int ret, ring, rspec, ent_delay = RTSDCTL_ENT_DLY_MIN;
267         u64 caam_id;
268         struct device *dev;
269         struct device_node *nprop, *np;
270         struct caam_ctrl __iomem *ctrl;
271         struct caam_full __iomem *topregs;
272         struct caam_drv_private *ctrlpriv;
273 #ifdef CONFIG_DEBUG_FS
274         struct caam_perfmon *perfmon;
275 #endif
276         u64 cha_vid;
277
278         ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL);
279         if (!ctrlpriv)
280                 return -ENOMEM;
281
282         dev = &pdev->dev;
283         dev_set_drvdata(dev, ctrlpriv);
284         ctrlpriv->pdev = pdev;
285         nprop = pdev->dev.of_node;
286
287         /* Get configuration properties from device tree */
288         /* First, get register page */
289         ctrl = of_iomap(nprop, 0);
290         if (ctrl == NULL) {
291                 dev_err(dev, "caam: of_iomap() failed\n");
292                 return -ENOMEM;
293         }
294         ctrlpriv->ctrl = (struct caam_ctrl __force *)ctrl;
295
296         /* topregs used to derive pointers to CAAM sub-blocks only */
297         topregs = (struct caam_full __iomem *)ctrl;
298
299         /* Get the IRQ of the controller (for security violations only) */
300         ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL);
301
302         /*
303          * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
304          * long pointers in master configuration register
305          */
306         setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE |
307                   (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
308
309         if (sizeof(dma_addr_t) == sizeof(u64))
310                 if (of_device_is_compatible(nprop, "fsl,sec-v5.0"))
311                         dma_set_mask(dev, DMA_BIT_MASK(40));
312                 else
313                         dma_set_mask(dev, DMA_BIT_MASK(36));
314         else
315                 dma_set_mask(dev, DMA_BIT_MASK(32));
316
317         /*
318          * Detect and enable JobRs
319          * First, find out how many ring spec'ed, allocate references
320          * for all, then go probe each one.
321          */
322         rspec = 0;
323         for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring")
324                 rspec++;
325         if (!rspec) {
326                 /* for backward compatible with device trees */
327                 for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring")
328                         rspec++;
329         }
330
331         ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL);
332         if (ctrlpriv->jrdev == NULL) {
333                 iounmap(&topregs->ctrl);
334                 return -ENOMEM;
335         }
336
337         ring = 0;
338         ctrlpriv->total_jobrs = 0;
339         for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
340                 caam_jr_probe(pdev, np, ring);
341                 ctrlpriv->total_jobrs++;
342                 ring++;
343         }
344         if (!ring) {
345                 for_each_compatible_node(np, NULL, "fsl,sec4.0-job-ring") {
346                         caam_jr_probe(pdev, np, ring);
347                         ctrlpriv->total_jobrs++;
348                         ring++;
349                 }
350         }
351
352         /* Check to see if QI present. If so, enable */
353         ctrlpriv->qi_present = !!(rd_reg64(&topregs->ctrl.perfmon.comp_parms) &
354                                   CTPR_QI_MASK);
355         if (ctrlpriv->qi_present) {
356                 ctrlpriv->qi = (struct caam_queue_if __force *)&topregs->qi;
357                 /* This is all that's required to physically enable QI */
358                 wr_reg32(&topregs->qi.qi_control_lo, QICTL_DQEN);
359         }
360
361         /* If no QI and no rings specified, quit and go home */
362         if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) {
363                 dev_err(dev, "no queues configured, terminating\n");
364                 caam_remove(pdev);
365                 return -ENOMEM;
366         }
367
368         cha_vid = rd_reg64(&topregs->ctrl.perfmon.cha_id);
369
370         /*
371          * If SEC has RNG version >= 4 and RNG state handle has not been
372          * already instantiated, do RNG instantiation
373          */
374         if ((cha_vid & CHA_ID_RNG_MASK) >> CHA_ID_RNG_SHIFT >= 4 &&
375             !(rd_reg32(&topregs->ctrl.r4tst[0].rdsta) & RDSTA_IF0)) {
376                 do {
377                         kick_trng(pdev, ent_delay);
378                         ret = instantiate_rng(dev);
379                         ent_delay += 400;
380                 } while ((ret == -EAGAIN) && (ent_delay < RTSDCTL_ENT_DLY_MAX));
381                 if (ret) {
382                         dev_err(dev, "failed to instantiate RNG");
383                         caam_remove(pdev);
384                         return ret;
385                 }
386
387                 /* Enable RDB bit so that RNG works faster */
388                 setbits32(&topregs->ctrl.scfgr, SCFGR_RDBENABLE);
389         }
390
391         /* NOTE: RTIC detection ought to go here, around Si time */
392
393         caam_id = rd_reg64(&topregs->ctrl.perfmon.caam_id);
394
395         /* Report "alive" for developer to see */
396         dev_info(dev, "device ID = 0x%016llx (Era %d)\n", caam_id,
397                  caam_get_era(caam_id));
398         dev_info(dev, "job rings = %d, qi = %d\n",
399                  ctrlpriv->total_jobrs, ctrlpriv->qi_present);
400
401 #ifdef CONFIG_DEBUG_FS
402         /*
403          * FIXME: needs better naming distinction, as some amalgamation of
404          * "caam" and nprop->full_name. The OF name isn't distinctive,
405          * but does separate instances
406          */
407         perfmon = (struct caam_perfmon __force *)&ctrl->perfmon;
408
409         ctrlpriv->dfs_root = debugfs_create_dir("caam", NULL);
410         ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);
411
412         /* Controller-level - performance monitor counters */
413         ctrlpriv->ctl_rq_dequeued =
414                 debugfs_create_u64("rq_dequeued",
415                                    S_IRUSR | S_IRGRP | S_IROTH,
416                                    ctrlpriv->ctl, &perfmon->req_dequeued);
417         ctrlpriv->ctl_ob_enc_req =
418                 debugfs_create_u64("ob_rq_encrypted",
419                                    S_IRUSR | S_IRGRP | S_IROTH,
420                                    ctrlpriv->ctl, &perfmon->ob_enc_req);
421         ctrlpriv->ctl_ib_dec_req =
422                 debugfs_create_u64("ib_rq_decrypted",
423                                    S_IRUSR | S_IRGRP | S_IROTH,
424                                    ctrlpriv->ctl, &perfmon->ib_dec_req);
425         ctrlpriv->ctl_ob_enc_bytes =
426                 debugfs_create_u64("ob_bytes_encrypted",
427                                    S_IRUSR | S_IRGRP | S_IROTH,
428                                    ctrlpriv->ctl, &perfmon->ob_enc_bytes);
429         ctrlpriv->ctl_ob_prot_bytes =
430                 debugfs_create_u64("ob_bytes_protected",
431                                    S_IRUSR | S_IRGRP | S_IROTH,
432                                    ctrlpriv->ctl, &perfmon->ob_prot_bytes);
433         ctrlpriv->ctl_ib_dec_bytes =
434                 debugfs_create_u64("ib_bytes_decrypted",
435                                    S_IRUSR | S_IRGRP | S_IROTH,
436                                    ctrlpriv->ctl, &perfmon->ib_dec_bytes);
437         ctrlpriv->ctl_ib_valid_bytes =
438                 debugfs_create_u64("ib_bytes_validated",
439                                    S_IRUSR | S_IRGRP | S_IROTH,
440                                    ctrlpriv->ctl, &perfmon->ib_valid_bytes);
441
442         /* Controller level - global status values */
443         ctrlpriv->ctl_faultaddr =
444                 debugfs_create_u64("fault_addr",
445                                    S_IRUSR | S_IRGRP | S_IROTH,
446                                    ctrlpriv->ctl, &perfmon->faultaddr);
447         ctrlpriv->ctl_faultdetail =
448                 debugfs_create_u32("fault_detail",
449                                    S_IRUSR | S_IRGRP | S_IROTH,
450                                    ctrlpriv->ctl, &perfmon->faultdetail);
451         ctrlpriv->ctl_faultstatus =
452                 debugfs_create_u32("fault_status",
453                                    S_IRUSR | S_IRGRP | S_IROTH,
454                                    ctrlpriv->ctl, &perfmon->status);
455
456         /* Internal covering keys (useful in non-secure mode only) */
457         ctrlpriv->ctl_kek_wrap.data = &ctrlpriv->ctrl->kek[0];
458         ctrlpriv->ctl_kek_wrap.size = KEK_KEY_SIZE * sizeof(u32);
459         ctrlpriv->ctl_kek = debugfs_create_blob("kek",
460                                                 S_IRUSR |
461                                                 S_IRGRP | S_IROTH,
462                                                 ctrlpriv->ctl,
463                                                 &ctrlpriv->ctl_kek_wrap);
464
465         ctrlpriv->ctl_tkek_wrap.data = &ctrlpriv->ctrl->tkek[0];
466         ctrlpriv->ctl_tkek_wrap.size = KEK_KEY_SIZE * sizeof(u32);
467         ctrlpriv->ctl_tkek = debugfs_create_blob("tkek",
468                                                  S_IRUSR |
469                                                  S_IRGRP | S_IROTH,
470                                                  ctrlpriv->ctl,
471                                                  &ctrlpriv->ctl_tkek_wrap);
472
473         ctrlpriv->ctl_tdsk_wrap.data = &ctrlpriv->ctrl->tdsk[0];
474         ctrlpriv->ctl_tdsk_wrap.size = KEK_KEY_SIZE * sizeof(u32);
475         ctrlpriv->ctl_tdsk = debugfs_create_blob("tdsk",
476                                                  S_IRUSR |
477                                                  S_IRGRP | S_IROTH,
478                                                  ctrlpriv->ctl,
479                                                  &ctrlpriv->ctl_tdsk_wrap);
480 #endif
481         return 0;
482 }
483
484 static struct of_device_id caam_match[] = {
485         {
486                 .compatible = "fsl,sec-v4.0",
487         },
488         {
489                 .compatible = "fsl,sec4.0",
490         },
491         {},
492 };
493 MODULE_DEVICE_TABLE(of, caam_match);
494
495 static struct platform_driver caam_driver = {
496         .driver = {
497                 .name = "caam",
498                 .owner = THIS_MODULE,
499                 .of_match_table = caam_match,
500         },
501         .probe       = caam_probe,
502         .remove      = caam_remove,
503 };
504
505 module_platform_driver(caam_driver);
506
507 MODULE_LICENSE("GPL");
508 MODULE_DESCRIPTION("FSL CAAM request backend");
509 MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");