This source file includes following definitions.
- sun4i_ss_probe
- sun4i_ss_remove
1
2
3
4
5
6
7
8
9
10
11 #include <linux/clk.h>
12 #include <linux/crypto.h>
13 #include <linux/io.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/platform_device.h>
17 #include <crypto/scatterwalk.h>
18 #include <linux/scatterlist.h>
19 #include <linux/interrupt.h>
20 #include <linux/delay.h>
21 #include <linux/reset.h>
22
23 #include "sun4i-ss.h"
24
25 static struct sun4i_ss_alg_template ss_algs[] = {
26 { .type = CRYPTO_ALG_TYPE_AHASH,
27 .mode = SS_OP_MD5,
28 .alg.hash = {
29 .init = sun4i_hash_init,
30 .update = sun4i_hash_update,
31 .final = sun4i_hash_final,
32 .finup = sun4i_hash_finup,
33 .digest = sun4i_hash_digest,
34 .export = sun4i_hash_export_md5,
35 .import = sun4i_hash_import_md5,
36 .halg = {
37 .digestsize = MD5_DIGEST_SIZE,
38 .statesize = sizeof(struct md5_state),
39 .base = {
40 .cra_name = "md5",
41 .cra_driver_name = "md5-sun4i-ss",
42 .cra_priority = 300,
43 .cra_alignmask = 3,
44 .cra_blocksize = MD5_HMAC_BLOCK_SIZE,
45 .cra_ctxsize = sizeof(struct sun4i_req_ctx),
46 .cra_module = THIS_MODULE,
47 .cra_init = sun4i_hash_crainit
48 }
49 }
50 }
51 },
52 { .type = CRYPTO_ALG_TYPE_AHASH,
53 .mode = SS_OP_SHA1,
54 .alg.hash = {
55 .init = sun4i_hash_init,
56 .update = sun4i_hash_update,
57 .final = sun4i_hash_final,
58 .finup = sun4i_hash_finup,
59 .digest = sun4i_hash_digest,
60 .export = sun4i_hash_export_sha1,
61 .import = sun4i_hash_import_sha1,
62 .halg = {
63 .digestsize = SHA1_DIGEST_SIZE,
64 .statesize = sizeof(struct sha1_state),
65 .base = {
66 .cra_name = "sha1",
67 .cra_driver_name = "sha1-sun4i-ss",
68 .cra_priority = 300,
69 .cra_alignmask = 3,
70 .cra_blocksize = SHA1_BLOCK_SIZE,
71 .cra_ctxsize = sizeof(struct sun4i_req_ctx),
72 .cra_module = THIS_MODULE,
73 .cra_init = sun4i_hash_crainit
74 }
75 }
76 }
77 },
78 { .type = CRYPTO_ALG_TYPE_SKCIPHER,
79 .alg.crypto = {
80 .setkey = sun4i_ss_aes_setkey,
81 .encrypt = sun4i_ss_cbc_aes_encrypt,
82 .decrypt = sun4i_ss_cbc_aes_decrypt,
83 .min_keysize = AES_MIN_KEY_SIZE,
84 .max_keysize = AES_MAX_KEY_SIZE,
85 .ivsize = AES_BLOCK_SIZE,
86 .base = {
87 .cra_name = "cbc(aes)",
88 .cra_driver_name = "cbc-aes-sun4i-ss",
89 .cra_priority = 300,
90 .cra_blocksize = AES_BLOCK_SIZE,
91 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
92 .cra_ctxsize = sizeof(struct sun4i_tfm_ctx),
93 .cra_module = THIS_MODULE,
94 .cra_alignmask = 3,
95 .cra_init = sun4i_ss_cipher_init,
96 .cra_exit = sun4i_ss_cipher_exit,
97 }
98 }
99 },
100 { .type = CRYPTO_ALG_TYPE_SKCIPHER,
101 .alg.crypto = {
102 .setkey = sun4i_ss_aes_setkey,
103 .encrypt = sun4i_ss_ecb_aes_encrypt,
104 .decrypt = sun4i_ss_ecb_aes_decrypt,
105 .min_keysize = AES_MIN_KEY_SIZE,
106 .max_keysize = AES_MAX_KEY_SIZE,
107 .base = {
108 .cra_name = "ecb(aes)",
109 .cra_driver_name = "ecb-aes-sun4i-ss",
110 .cra_priority = 300,
111 .cra_blocksize = AES_BLOCK_SIZE,
112 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
113 .cra_ctxsize = sizeof(struct sun4i_tfm_ctx),
114 .cra_module = THIS_MODULE,
115 .cra_alignmask = 3,
116 .cra_init = sun4i_ss_cipher_init,
117 .cra_exit = sun4i_ss_cipher_exit,
118 }
119 }
120 },
121 { .type = CRYPTO_ALG_TYPE_SKCIPHER,
122 .alg.crypto = {
123 .setkey = sun4i_ss_des_setkey,
124 .encrypt = sun4i_ss_cbc_des_encrypt,
125 .decrypt = sun4i_ss_cbc_des_decrypt,
126 .min_keysize = DES_KEY_SIZE,
127 .max_keysize = DES_KEY_SIZE,
128 .ivsize = DES_BLOCK_SIZE,
129 .base = {
130 .cra_name = "cbc(des)",
131 .cra_driver_name = "cbc-des-sun4i-ss",
132 .cra_priority = 300,
133 .cra_blocksize = DES_BLOCK_SIZE,
134 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
135 .cra_ctxsize = sizeof(struct sun4i_req_ctx),
136 .cra_module = THIS_MODULE,
137 .cra_alignmask = 3,
138 .cra_init = sun4i_ss_cipher_init,
139 .cra_exit = sun4i_ss_cipher_exit,
140 }
141 }
142 },
143 { .type = CRYPTO_ALG_TYPE_SKCIPHER,
144 .alg.crypto = {
145 .setkey = sun4i_ss_des_setkey,
146 .encrypt = sun4i_ss_ecb_des_encrypt,
147 .decrypt = sun4i_ss_ecb_des_decrypt,
148 .min_keysize = DES_KEY_SIZE,
149 .max_keysize = DES_KEY_SIZE,
150 .base = {
151 .cra_name = "ecb(des)",
152 .cra_driver_name = "ecb-des-sun4i-ss",
153 .cra_priority = 300,
154 .cra_blocksize = DES_BLOCK_SIZE,
155 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
156 .cra_ctxsize = sizeof(struct sun4i_req_ctx),
157 .cra_module = THIS_MODULE,
158 .cra_alignmask = 3,
159 .cra_init = sun4i_ss_cipher_init,
160 .cra_exit = sun4i_ss_cipher_exit,
161 }
162 }
163 },
164 { .type = CRYPTO_ALG_TYPE_SKCIPHER,
165 .alg.crypto = {
166 .setkey = sun4i_ss_des3_setkey,
167 .encrypt = sun4i_ss_cbc_des3_encrypt,
168 .decrypt = sun4i_ss_cbc_des3_decrypt,
169 .min_keysize = DES3_EDE_KEY_SIZE,
170 .max_keysize = DES3_EDE_KEY_SIZE,
171 .ivsize = DES3_EDE_BLOCK_SIZE,
172 .base = {
173 .cra_name = "cbc(des3_ede)",
174 .cra_driver_name = "cbc-des3-sun4i-ss",
175 .cra_priority = 300,
176 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
177 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
178 .cra_ctxsize = sizeof(struct sun4i_req_ctx),
179 .cra_module = THIS_MODULE,
180 .cra_alignmask = 3,
181 .cra_init = sun4i_ss_cipher_init,
182 .cra_exit = sun4i_ss_cipher_exit,
183 }
184 }
185 },
186 { .type = CRYPTO_ALG_TYPE_SKCIPHER,
187 .alg.crypto = {
188 .setkey = sun4i_ss_des3_setkey,
189 .encrypt = sun4i_ss_ecb_des3_encrypt,
190 .decrypt = sun4i_ss_ecb_des3_decrypt,
191 .min_keysize = DES3_EDE_KEY_SIZE,
192 .max_keysize = DES3_EDE_KEY_SIZE,
193 .base = {
194 .cra_name = "ecb(des3_ede)",
195 .cra_driver_name = "ecb-des3-sun4i-ss",
196 .cra_priority = 300,
197 .cra_blocksize = DES3_EDE_BLOCK_SIZE,
198 .cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_NEED_FALLBACK,
199 .cra_ctxsize = sizeof(struct sun4i_req_ctx),
200 .cra_module = THIS_MODULE,
201 .cra_alignmask = 3,
202 .cra_init = sun4i_ss_cipher_init,
203 .cra_exit = sun4i_ss_cipher_exit,
204 }
205 }
206 },
207 #ifdef CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG
208 {
209 .type = CRYPTO_ALG_TYPE_RNG,
210 .alg.rng = {
211 .base = {
212 .cra_name = "stdrng",
213 .cra_driver_name = "sun4i_ss_rng",
214 .cra_priority = 300,
215 .cra_ctxsize = 0,
216 .cra_module = THIS_MODULE,
217 },
218 .generate = sun4i_ss_prng_generate,
219 .seed = sun4i_ss_prng_seed,
220 .seedsize = SS_SEED_LEN / BITS_PER_BYTE,
221 }
222 },
223 #endif
224 };
225
226 static int sun4i_ss_probe(struct platform_device *pdev)
227 {
228 u32 v;
229 int err, i;
230 unsigned long cr;
231 const unsigned long cr_ahb = 24 * 1000 * 1000;
232 const unsigned long cr_mod = 150 * 1000 * 1000;
233 struct sun4i_ss_ctx *ss;
234
235 if (!pdev->dev.of_node)
236 return -ENODEV;
237
238 ss = devm_kzalloc(&pdev->dev, sizeof(*ss), GFP_KERNEL);
239 if (!ss)
240 return -ENOMEM;
241
242 ss->base = devm_platform_ioremap_resource(pdev, 0);
243 if (IS_ERR(ss->base)) {
244 dev_err(&pdev->dev, "Cannot request MMIO\n");
245 return PTR_ERR(ss->base);
246 }
247
248 ss->ssclk = devm_clk_get(&pdev->dev, "mod");
249 if (IS_ERR(ss->ssclk)) {
250 err = PTR_ERR(ss->ssclk);
251 dev_err(&pdev->dev, "Cannot get SS clock err=%d\n", err);
252 return err;
253 }
254 dev_dbg(&pdev->dev, "clock ss acquired\n");
255
256 ss->busclk = devm_clk_get(&pdev->dev, "ahb");
257 if (IS_ERR(ss->busclk)) {
258 err = PTR_ERR(ss->busclk);
259 dev_err(&pdev->dev, "Cannot get AHB SS clock err=%d\n", err);
260 return err;
261 }
262 dev_dbg(&pdev->dev, "clock ahb_ss acquired\n");
263
264 ss->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
265 if (IS_ERR(ss->reset)) {
266 if (PTR_ERR(ss->reset) == -EPROBE_DEFER)
267 return PTR_ERR(ss->reset);
268 dev_info(&pdev->dev, "no reset control found\n");
269 ss->reset = NULL;
270 }
271
272
273 err = clk_prepare_enable(ss->busclk);
274 if (err) {
275 dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
276 return err;
277 }
278 err = clk_prepare_enable(ss->ssclk);
279 if (err) {
280 dev_err(&pdev->dev, "Cannot prepare_enable ssclk\n");
281 goto error_ssclk;
282 }
283
284
285
286
287
288 err = clk_set_rate(ss->ssclk, cr_mod);
289 if (err) {
290 dev_err(&pdev->dev, "Cannot set clock rate to ssclk\n");
291 goto error_clk;
292 }
293
294
295 if (ss->reset) {
296 err = reset_control_deassert(ss->reset);
297 if (err) {
298 dev_err(&pdev->dev, "Cannot deassert reset control\n");
299 goto error_clk;
300 }
301 }
302
303
304
305
306
307
308 cr = clk_get_rate(ss->busclk);
309 if (cr >= cr_ahb)
310 dev_dbg(&pdev->dev, "Clock bus %lu (%lu MHz) (must be >= %lu)\n",
311 cr, cr / 1000000, cr_ahb);
312 else
313 dev_warn(&pdev->dev, "Clock bus %lu (%lu MHz) (must be >= %lu)\n",
314 cr, cr / 1000000, cr_ahb);
315
316 cr = clk_get_rate(ss->ssclk);
317 if (cr <= cr_mod)
318 if (cr < cr_mod)
319 dev_warn(&pdev->dev, "Clock ss %lu (%lu MHz) (must be <= %lu)\n",
320 cr, cr / 1000000, cr_mod);
321 else
322 dev_dbg(&pdev->dev, "Clock ss %lu (%lu MHz) (must be <= %lu)\n",
323 cr, cr / 1000000, cr_mod);
324 else
325 dev_warn(&pdev->dev, "Clock ss is at %lu (%lu MHz) (must be <= %lu)\n",
326 cr, cr / 1000000, cr_mod);
327
328
329
330
331
332
333
334 writel(SS_ENABLED, ss->base + SS_CTL);
335 v = readl(ss->base + SS_CTL);
336 v >>= 16;
337 v &= 0x07;
338 dev_info(&pdev->dev, "Die ID %d\n", v);
339 writel(0, ss->base + SS_CTL);
340
341 ss->dev = &pdev->dev;
342
343 spin_lock_init(&ss->slock);
344
345 for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
346 ss_algs[i].ss = ss;
347 switch (ss_algs[i].type) {
348 case CRYPTO_ALG_TYPE_SKCIPHER:
349 err = crypto_register_skcipher(&ss_algs[i].alg.crypto);
350 if (err) {
351 dev_err(ss->dev, "Fail to register %s\n",
352 ss_algs[i].alg.crypto.base.cra_name);
353 goto error_alg;
354 }
355 break;
356 case CRYPTO_ALG_TYPE_AHASH:
357 err = crypto_register_ahash(&ss_algs[i].alg.hash);
358 if (err) {
359 dev_err(ss->dev, "Fail to register %s\n",
360 ss_algs[i].alg.hash.halg.base.cra_name);
361 goto error_alg;
362 }
363 break;
364 case CRYPTO_ALG_TYPE_RNG:
365 err = crypto_register_rng(&ss_algs[i].alg.rng);
366 if (err) {
367 dev_err(ss->dev, "Fail to register %s\n",
368 ss_algs[i].alg.rng.base.cra_name);
369 }
370 break;
371 }
372 }
373 platform_set_drvdata(pdev, ss);
374 return 0;
375 error_alg:
376 i--;
377 for (; i >= 0; i--) {
378 switch (ss_algs[i].type) {
379 case CRYPTO_ALG_TYPE_SKCIPHER:
380 crypto_unregister_skcipher(&ss_algs[i].alg.crypto);
381 break;
382 case CRYPTO_ALG_TYPE_AHASH:
383 crypto_unregister_ahash(&ss_algs[i].alg.hash);
384 break;
385 case CRYPTO_ALG_TYPE_RNG:
386 crypto_unregister_rng(&ss_algs[i].alg.rng);
387 break;
388 }
389 }
390 if (ss->reset)
391 reset_control_assert(ss->reset);
392 error_clk:
393 clk_disable_unprepare(ss->ssclk);
394 error_ssclk:
395 clk_disable_unprepare(ss->busclk);
396 return err;
397 }
398
399 static int sun4i_ss_remove(struct platform_device *pdev)
400 {
401 int i;
402 struct sun4i_ss_ctx *ss = platform_get_drvdata(pdev);
403
404 for (i = 0; i < ARRAY_SIZE(ss_algs); i++) {
405 switch (ss_algs[i].type) {
406 case CRYPTO_ALG_TYPE_SKCIPHER:
407 crypto_unregister_skcipher(&ss_algs[i].alg.crypto);
408 break;
409 case CRYPTO_ALG_TYPE_AHASH:
410 crypto_unregister_ahash(&ss_algs[i].alg.hash);
411 break;
412 case CRYPTO_ALG_TYPE_RNG:
413 crypto_unregister_rng(&ss_algs[i].alg.rng);
414 break;
415 }
416 }
417
418 writel(0, ss->base + SS_CTL);
419 if (ss->reset)
420 reset_control_assert(ss->reset);
421 clk_disable_unprepare(ss->busclk);
422 clk_disable_unprepare(ss->ssclk);
423 return 0;
424 }
425
426 static const struct of_device_id a20ss_crypto_of_match_table[] = {
427 { .compatible = "allwinner,sun4i-a10-crypto" },
428 {}
429 };
430 MODULE_DEVICE_TABLE(of, a20ss_crypto_of_match_table);
431
432 static struct platform_driver sun4i_ss_driver = {
433 .probe = sun4i_ss_probe,
434 .remove = sun4i_ss_remove,
435 .driver = {
436 .name = "sun4i-ss",
437 .of_match_table = a20ss_crypto_of_match_table,
438 },
439 };
440
441 module_platform_driver(sun4i_ss_driver);
442
443 MODULE_ALIAS("platform:sun4i-ss");
444 MODULE_DESCRIPTION("Allwinner Security System cryptographic accelerator");
445 MODULE_LICENSE("GPL");
446 MODULE_AUTHOR("Corentin LABBE <clabbe.montjoie@gmail.com>");