blob: fdcef1de8152cbd2841f6222462322f0a1988ff9 [file] [log] [blame]
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -07001/*
2 * Copyright (c) 2011-2013, 2015, 2017 The Linux Foundation. All rights
3 * reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 and
7 * only version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 */
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/device.h>
19#include <linux/platform_device.h>
20#include <linux/hw_random.h>
21#include <linux/clk.h>
22#include <linux/slab.h>
23#include <linux/io.h>
24#include <linux/err.h>
25#include <linux/types.h>
26#include <soc/qcom/socinfo.h>
27#include <linux/msm-bus.h>
28#include <linux/qrng.h>
29#include <linux/fs.h>
30#include <linux/cdev.h>
31#include <linux/delay.h>
32#include <linux/crypto.h>
33#include <crypto/internal/rng.h>
34
35#include <linux/platform_data/qcom_crypto_device.h>
36
37
38
39#define DRIVER_NAME "msm_rng"
40
41/* Device specific register offsets */
42#define PRNG_DATA_OUT_OFFSET 0x0000
43#define PRNG_STATUS_OFFSET 0x0004
44#define PRNG_LFSR_CFG_OFFSET 0x0100
45#define PRNG_CONFIG_OFFSET 0x0104
46
47/* Device specific register masks and config values */
48#define PRNG_LFSR_CFG_MASK 0xFFFF0000
49#define PRNG_LFSR_CFG_CLOCKS 0x0000DDDD
50#define PRNG_CONFIG_MASK 0xFFFFFFFD
51#define PRNG_HW_ENABLE 0x00000002
52
53#define MAX_HW_FIFO_DEPTH 16 /* FIFO is 16 words deep */
54#define MAX_HW_FIFO_SIZE (MAX_HW_FIFO_DEPTH * 4) /* FIFO is 32 bits wide */
55
Zhen Kong7339a0e2017-11-08 12:53:11 -080056#define RETRY_MAX_CNT 5 /* max retry times to read register */
57#define RETRY_DELAY_INTERVAL 440 /* retry delay interval in us */
58
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -070059struct msm_rng_device {
60 struct platform_device *pdev;
61 void __iomem *base;
62 struct clk *prng_clk;
63 uint32_t qrng_perf_client;
64 struct mutex rng_lock;
65};
66
67struct msm_rng_device msm_rng_device_info;
68static struct msm_rng_device *msm_rng_dev_cached;
69struct mutex cached_rng_lock;
70static long msm_rng_ioctl(struct file *filp, unsigned int cmd,
71 unsigned long arg)
72{
73 long ret = 0;
74
75 switch (cmd) {
76 case QRNG_IOCTL_RESET_BUS_BANDWIDTH:
77 pr_info("calling msm_rng_bus_scale(LOW)\n");
78 ret = msm_bus_scale_client_update_request(
79 msm_rng_device_info.qrng_perf_client, 0);
80 if (ret)
81 pr_err("failed qrng_reset_bus_bw, ret = %ld\n", ret);
82 break;
83 default:
84 pr_err("Unsupported IOCTL call");
85 break;
86 }
87 return ret;
88}
89
90/*
91 *
92 * This function calls hardware random bit generator directory and retuns it
93 * back to caller
94 *
95 */
96static int msm_rng_direct_read(struct msm_rng_device *msm_rng_dev,
97 void *data, size_t max)
98{
99 struct platform_device *pdev;
100 void __iomem *base;
101 size_t currsize = 0;
Zhen Kong7339a0e2017-11-08 12:53:11 -0800102 u32 val = 0;
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700103 u32 *retdata = data;
104 int ret;
105 int failed = 0;
106
107 pdev = msm_rng_dev->pdev;
108 base = msm_rng_dev->base;
109
110 /* no room for word data */
111 if (max < 4)
112 return 0;
113
114 mutex_lock(&msm_rng_dev->rng_lock);
115
116 if (msm_rng_dev->qrng_perf_client) {
117 ret = msm_bus_scale_client_update_request(
118 msm_rng_dev->qrng_perf_client, 1);
Zhen Kong7339a0e2017-11-08 12:53:11 -0800119 if (ret) {
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700120 pr_err("bus_scale_client_update_req failed!\n");
Zhen Kong7339a0e2017-11-08 12:53:11 -0800121 goto bus_err;
122 }
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700123 }
124 /* enable PRNG clock */
125 ret = clk_prepare_enable(msm_rng_dev->prng_clk);
126 if (ret) {
Zhen Kong7339a0e2017-11-08 12:53:11 -0800127 pr_err("failed to enable prng clock\n");
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700128 goto err;
129 }
130 /* read random data from h/w */
131 do {
132 /* check status bit if data is available */
Zhen Kong7339a0e2017-11-08 12:53:11 -0800133 if (!(readl_relaxed(base + PRNG_STATUS_OFFSET)
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700134 & 0x00000001)) {
Zhen Kong7339a0e2017-11-08 12:53:11 -0800135 if (failed++ == RETRY_MAX_CNT) {
136 if (currsize == 0)
137 pr_err("Data not available\n");
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700138 break;
139 }
Zhen Kong7339a0e2017-11-08 12:53:11 -0800140 udelay(RETRY_DELAY_INTERVAL);
141 } else {
142
143 /* read FIFO */
144 val = readl_relaxed(base + PRNG_DATA_OUT_OFFSET);
145
146 /* write data back to callers pointer */
147 *(retdata++) = val;
148 currsize += 4;
149 /* make sure we stay on 32bit boundary */
150 if ((max - currsize) < 4)
151 break;
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700152 }
153
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700154 } while (currsize < max);
155
156 /* vote to turn off clock */
157 clk_disable_unprepare(msm_rng_dev->prng_clk);
158err:
159 if (msm_rng_dev->qrng_perf_client) {
160 ret = msm_bus_scale_client_update_request(
161 msm_rng_dev->qrng_perf_client, 0);
162 if (ret)
163 pr_err("bus_scale_client_update_req failed!\n");
164 }
Zhen Kong7339a0e2017-11-08 12:53:11 -0800165bus_err:
AnilKumar Chimataa2ba95f2017-04-18 13:00:04 -0700166 mutex_unlock(&msm_rng_dev->rng_lock);
167
168 val = 0L;
169 return currsize;
170}
171static int msm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
172{
173 struct msm_rng_device *msm_rng_dev;
174 int rv = 0;
175
176 msm_rng_dev = (struct msm_rng_device *)rng->priv;
177 rv = msm_rng_direct_read(msm_rng_dev, data, max);
178
179 return rv;
180}
181
182
183static struct hwrng msm_rng = {
184 .name = DRIVER_NAME,
185 .read = msm_rng_read,
186 .quality = 700,
187};
188
189static int msm_rng_enable_hw(struct msm_rng_device *msm_rng_dev)
190{
191 unsigned long val = 0;
192 unsigned long reg_val = 0;
193 int ret = 0;
194
195 if (msm_rng_dev->qrng_perf_client) {
196 ret = msm_bus_scale_client_update_request(
197 msm_rng_dev->qrng_perf_client, 1);
198 if (ret)
199 pr_err("bus_scale_client_update_req failed!\n");
200 }
201 /* Enable the PRNG CLK */
202 ret = clk_prepare_enable(msm_rng_dev->prng_clk);
203 if (ret) {
204 dev_err(&(msm_rng_dev->pdev)->dev,
205 "failed to enable clock in probe\n");
206 return -EPERM;
207 }
208
209 /* Enable PRNG h/w only if it is NOT ON */
210 val = readl_relaxed(msm_rng_dev->base + PRNG_CONFIG_OFFSET) &
211 PRNG_HW_ENABLE;
212 /* PRNG H/W is not ON */
213 if (val != PRNG_HW_ENABLE) {
214 val = readl_relaxed(msm_rng_dev->base + PRNG_LFSR_CFG_OFFSET);
215 val &= PRNG_LFSR_CFG_MASK;
216 val |= PRNG_LFSR_CFG_CLOCKS;
217 writel_relaxed(val, msm_rng_dev->base + PRNG_LFSR_CFG_OFFSET);
218
219 /* The PRNG CONFIG register should be first written */
220 mb();
221
222 reg_val = readl_relaxed(msm_rng_dev->base + PRNG_CONFIG_OFFSET)
223 & PRNG_CONFIG_MASK;
224 reg_val |= PRNG_HW_ENABLE;
225 writel_relaxed(reg_val, msm_rng_dev->base + PRNG_CONFIG_OFFSET);
226
227 /* The PRNG clk should be disabled only after we enable the
228 * PRNG h/w by writing to the PRNG CONFIG register.
229 */
230 mb();
231 }
232 clk_disable_unprepare(msm_rng_dev->prng_clk);
233
234 if (msm_rng_dev->qrng_perf_client) {
235 ret = msm_bus_scale_client_update_request(
236 msm_rng_dev->qrng_perf_client, 0);
237 if (ret)
238 pr_err("bus_scale_client_update_req failed!\n");
239 }
240
241 return 0;
242}
243
244static const struct file_operations msm_rng_fops = {
245 .unlocked_ioctl = msm_rng_ioctl,
246};
247static struct class *msm_rng_class;
248static struct cdev msm_rng_cdev;
249
250static int msm_rng_probe(struct platform_device *pdev)
251{
252 struct resource *res;
253 struct msm_rng_device *msm_rng_dev = NULL;
254 void __iomem *base = NULL;
255 bool configure_qrng = true;
256 int error = 0;
257 int ret = 0;
258 struct device *dev;
259
260 struct msm_bus_scale_pdata *qrng_platform_support = NULL;
261
262 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
263 if (res == NULL) {
264 dev_err(&pdev->dev, "invalid address\n");
265 error = -EFAULT;
266 goto err_exit;
267 }
268
269 msm_rng_dev = kzalloc(sizeof(struct msm_rng_device), GFP_KERNEL);
270 if (!msm_rng_dev) {
271 error = -ENOMEM;
272 goto err_exit;
273 }
274
275 base = ioremap(res->start, resource_size(res));
276 if (!base) {
277 dev_err(&pdev->dev, "ioremap failed\n");
278 error = -ENOMEM;
279 goto err_iomap;
280 }
281 msm_rng_dev->base = base;
282
283 /* create a handle for clock control */
284 if ((pdev->dev.of_node) && (of_property_read_bool(pdev->dev.of_node,
285 "qcom,msm-rng-iface-clk")))
286 msm_rng_dev->prng_clk = clk_get(&pdev->dev,
287 "iface_clk");
288 else
289 msm_rng_dev->prng_clk = clk_get(&pdev->dev, "core_clk");
290 if (IS_ERR(msm_rng_dev->prng_clk)) {
291 dev_err(&pdev->dev, "failed to register clock source\n");
292 error = -EPERM;
293 goto err_clk_get;
294 }
295
296 /* save away pdev and register driver data */
297 msm_rng_dev->pdev = pdev;
298 platform_set_drvdata(pdev, msm_rng_dev);
299
300 if (pdev->dev.of_node) {
301 /* Register bus client */
302 qrng_platform_support = msm_bus_cl_get_pdata(pdev);
303 msm_rng_dev->qrng_perf_client = msm_bus_scale_register_client(
304 qrng_platform_support);
305 msm_rng_device_info.qrng_perf_client =
306 msm_rng_dev->qrng_perf_client;
307 if (!msm_rng_dev->qrng_perf_client)
308 pr_err("Unable to register bus client\n");
309 }
310
311 /* Enable rng h/w for the targets which can access the entire
312 * address space of PRNG.
313 */
314 if ((pdev->dev.of_node) && (of_property_read_bool(pdev->dev.of_node,
315 "qcom,no-qrng-config")))
316 configure_qrng = false;
317 if (configure_qrng) {
318 error = msm_rng_enable_hw(msm_rng_dev);
319 if (error)
320 goto rollback_clk;
321 }
322
323 mutex_init(&msm_rng_dev->rng_lock);
324 mutex_init(&cached_rng_lock);
325
326 /* register with hwrng framework */
327 msm_rng.priv = (unsigned long) msm_rng_dev;
328 error = hwrng_register(&msm_rng);
329 if (error) {
330 dev_err(&pdev->dev, "failed to register hwrng\n");
331 error = -EPERM;
332 goto rollback_clk;
333 }
334 ret = register_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME, &msm_rng_fops);
335
336 msm_rng_class = class_create(THIS_MODULE, "msm-rng");
337 if (IS_ERR(msm_rng_class)) {
338 pr_err("class_create failed\n");
339 return PTR_ERR(msm_rng_class);
340 }
341
342 dev = device_create(msm_rng_class, NULL, MKDEV(QRNG_IOC_MAGIC, 0),
343 NULL, "msm-rng");
344 if (IS_ERR(dev)) {
345 pr_err("Device create failed\n");
346 error = PTR_ERR(dev);
347 goto unregister_chrdev;
348 }
349 cdev_init(&msm_rng_cdev, &msm_rng_fops);
350 msm_rng_dev_cached = msm_rng_dev;
351 return error;
352
353unregister_chrdev:
354 unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
355rollback_clk:
356 clk_put(msm_rng_dev->prng_clk);
357err_clk_get:
358 iounmap(msm_rng_dev->base);
359err_iomap:
360 kzfree(msm_rng_dev);
361err_exit:
362 return error;
363}
364
365static int msm_rng_remove(struct platform_device *pdev)
366{
367 struct msm_rng_device *msm_rng_dev = platform_get_drvdata(pdev);
368
369 unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
370 hwrng_unregister(&msm_rng);
371 clk_put(msm_rng_dev->prng_clk);
372 iounmap(msm_rng_dev->base);
373 platform_set_drvdata(pdev, NULL);
374 if (msm_rng_dev->qrng_perf_client)
375 msm_bus_scale_unregister_client(msm_rng_dev->qrng_perf_client);
376
377 kzfree(msm_rng_dev);
378 msm_rng_dev_cached = NULL;
379 return 0;
380}
381
382static int qrng_get_random(struct crypto_rng *tfm, const u8 *src,
383 unsigned int slen, u8 *rdata,
384 unsigned int dlen)
385{
386 int sizeread = 0;
387 int rv = -EFAULT;
388
389 if (!msm_rng_dev_cached) {
390 pr_err("%s: msm_rng_dev is not initialized.\n", __func__);
391 rv = -ENODEV;
392 goto err_exit;
393 }
394
395 if (!rdata) {
396 pr_err("%s: data buffer is null!\n", __func__);
397 rv = -EINVAL;
398 goto err_exit;
399 }
400
401 if (signal_pending(current) ||
402 mutex_lock_interruptible(&cached_rng_lock)) {
403 pr_err("%s: mutex lock interrupted!\n", __func__);
404 rv = -ERESTARTSYS;
405 goto err_exit;
406 }
407 sizeread = msm_rng_direct_read(msm_rng_dev_cached, rdata, dlen);
408
409 if (sizeread == dlen)
410 rv = 0;
411
412 mutex_unlock(&cached_rng_lock);
413err_exit:
414 return rv;
415
416}
417
418static int qrng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
419{
420 return 0;
421}
422
423static struct rng_alg rng_algs[] = { {
424 .generate = qrng_get_random,
425 .seed = qrng_reset,
426 .seedsize = 0,
427 .base = {
428 .cra_name = "qrng",
429 .cra_driver_name = "fips_hw_qrng",
430 .cra_priority = 300,
431 .cra_ctxsize = 0,
432 .cra_module = THIS_MODULE,
433 }
434} };
435
436static const struct of_device_id qrng_match[] = {
437 { .compatible = "qcom,msm-rng",
438 },
439 {}
440};
441
442static struct platform_driver rng_driver = {
443 .probe = msm_rng_probe,
444 .remove = msm_rng_remove,
445 .driver = {
446 .name = DRIVER_NAME,
447 .owner = THIS_MODULE,
448 .of_match_table = qrng_match,
449 }
450};
451
452static int __init msm_rng_init(void)
453{
454 int ret;
455
456 msm_rng_dev_cached = NULL;
457 ret = platform_driver_register(&rng_driver);
458 if (ret) {
459 pr_err("%s: platform_driver_register error:%d\n",
460 __func__, ret);
461 goto err_exit;
462 }
463 ret = crypto_register_rngs(rng_algs, ARRAY_SIZE(rng_algs));
464 if (ret) {
465 pr_err("%s: crypto_register_algs error:%d\n",
466 __func__, ret);
467 goto err_exit;
468 }
469
470err_exit:
471 return ret;
472}
473
474module_init(msm_rng_init);
475
476static void __exit msm_rng_exit(void)
477{
478 crypto_unregister_rngs(rng_algs, ARRAY_SIZE(rng_algs));
479 platform_driver_unregister(&rng_driver);
480}
481
482module_exit(msm_rng_exit);
483
484MODULE_DESCRIPTION("QTI MSM Random Number Driver");
485MODULE_LICENSE("GPL v2");