1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * sun8i-ss-core.c - hardware cryptographic offloader for 4 * Allwinner A80/A83T SoC 5 * 6 * Copyright (C) 2015-2019 Corentin Labbe <clabbe.montjoie@gmail.com> 7 * 8 * Core file which registers crypto algorithms supported by the SecuritySystem 9 * 10 * You could find a link for the datasheet in Documentation/arm/sunxi.rst 11 */ 12 #include <linux/clk.h> 13 #include <linux/crypto.h> 14 #include <linux/delay.h> 15 #include <linux/dma-mapping.h> 16 #include <linux/interrupt.h> 17 #include <linux/io.h> 18 #include <linux/irq.h> 19 #include <linux/module.h> 20 #include <linux/of.h> 21 #include <linux/of_device.h> 22 #include <linux/platform_device.h> 23 #include <linux/pm_runtime.h> 24 #include <linux/reset.h> 25 #include <crypto/internal/rng.h> 26 #include <crypto/internal/skcipher.h> 27 28 #include "sun8i-ss.h" 29 30 static const struct ss_variant ss_a80_variant = { 31 .alg_cipher = { SS_ALG_AES, SS_ALG_DES, SS_ALG_3DES, 32 }, 33 .alg_hash = { SS_ID_NOTSUPP, SS_ID_NOTSUPP, SS_ID_NOTSUPP, SS_ID_NOTSUPP, 34 }, 35 .op_mode = { SS_OP_ECB, SS_OP_CBC, 36 }, 37 .ss_clks = { 38 { "bus", 0, 300 * 1000 * 1000 }, 39 { "mod", 0, 300 * 1000 * 1000 }, 40 } 41 }; 42 43 static const struct ss_variant ss_a83t_variant = { 44 .alg_cipher = { SS_ALG_AES, SS_ALG_DES, SS_ALG_3DES, 45 }, 46 .alg_hash = { SS_ALG_MD5, SS_ALG_SHA1, SS_ALG_SHA224, SS_ALG_SHA256, 47 }, 48 .op_mode = { SS_OP_ECB, SS_OP_CBC, 49 }, 50 .ss_clks = { 51 { "bus", 0, 300 * 1000 * 1000 }, 52 { "mod", 0, 300 * 1000 * 1000 }, 53 } 54 }; 55 56 /* 57 * sun8i_ss_get_engine_number() get the next channel slot 58 * This is a simple round-robin way of getting the next channel 59 */ 60 int sun8i_ss_get_engine_number(struct sun8i_ss_dev *ss) 61 { 62 return atomic_inc_return(&ss->flow) % MAXFLOW; 63 } 64 65 int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx, 66 const char *name) 67 { 68 int flow = rctx->flow; 69 u32 v = SS_START; 70 int i; 71 72 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 73 ss->flows[flow].stat_req++; 74 #endif 75 76 /* choose between stream0/stream1 */ 77 if (flow) 78 v |= SS_FLOW1; 79 else 80 v |= SS_FLOW0; 81 82 v |= rctx->op_mode; 83 v |= rctx->method; 84 85 if (rctx->op_dir) 86 v |= SS_DECRYPTION; 87 88 switch (rctx->keylen) { 89 case 128 / 8: 90 v |= SS_AES_128BITS << 7; 91 break; 92 case 192 / 8: 93 v |= SS_AES_192BITS << 7; 94 break; 95 case 256 / 8: 96 v |= SS_AES_256BITS << 7; 97 break; 98 } 99 100 for (i = 0; i < MAX_SG; i++) { 101 if (!rctx->t_dst[i].addr) 102 break; 103 104 mutex_lock(&ss->mlock); 105 writel(rctx->p_key, ss->base + SS_KEY_ADR_REG); 106 107 if (i == 0) { 108 if (rctx->p_iv) 109 writel(rctx->p_iv, ss->base + SS_IV_ADR_REG); 110 } else { 111 if (rctx->biv) { 112 if (rctx->op_dir == SS_ENCRYPTION) 113 writel(rctx->t_dst[i - 1].addr + rctx->t_dst[i - 1].len * 4 - rctx->ivlen, ss->base + SS_IV_ADR_REG); 114 else 115 writel(rctx->t_src[i - 1].addr + rctx->t_src[i - 1].len * 4 - rctx->ivlen, ss->base + SS_IV_ADR_REG); 116 } 117 } 118 119 dev_dbg(ss->dev, 120 "Processing SG %d on flow %d %s ctl=%x %d to %d method=%x opmode=%x opdir=%x srclen=%d\n", 121 i, flow, name, v, 122 rctx->t_src[i].len, rctx->t_dst[i].len, 123 rctx->method, rctx->op_mode, 124 rctx->op_dir, rctx->t_src[i].len); 125 126 writel(rctx->t_src[i].addr, ss->base + SS_SRC_ADR_REG); 127 writel(rctx->t_dst[i].addr, ss->base + SS_DST_ADR_REG); 128 writel(rctx->t_src[i].len, ss->base + SS_LEN_ADR_REG); 129 130 reinit_completion(&ss->flows[flow].complete); 131 ss->flows[flow].status = 0; 132 wmb(); 133 134 writel(v, ss->base + SS_CTL_REG); 135 mutex_unlock(&ss->mlock); 136 wait_for_completion_interruptible_timeout(&ss->flows[flow].complete, 137 msecs_to_jiffies(2000)); 138 if (ss->flows[flow].status == 0) { 139 dev_err(ss->dev, "DMA timeout for %s\n", name); 140 return -EFAULT; 141 } 142 } 143 144 return 0; 145 } 146 147 static irqreturn_t ss_irq_handler(int irq, void *data) 148 { 149 struct sun8i_ss_dev *ss = (struct sun8i_ss_dev *)data; 150 int flow = 0; 151 u32 p; 152 153 p = readl(ss->base + SS_INT_STA_REG); 154 for (flow = 0; flow < MAXFLOW; flow++) { 155 if (p & (BIT(flow))) { 156 writel(BIT(flow), ss->base + SS_INT_STA_REG); 157 ss->flows[flow].status = 1; 158 complete(&ss->flows[flow].complete); 159 } 160 } 161 162 return IRQ_HANDLED; 163 } 164 165 static struct sun8i_ss_alg_template ss_algs[] = { 166 { 167 .type = CRYPTO_ALG_TYPE_SKCIPHER, 168 .ss_algo_id = SS_ID_CIPHER_AES, 169 .ss_blockmode = SS_ID_OP_CBC, 170 .alg.skcipher = { 171 .base = { 172 .cra_name = "cbc(aes)", 173 .cra_driver_name = "cbc-aes-sun8i-ss", 174 .cra_priority = 400, 175 .cra_blocksize = AES_BLOCK_SIZE, 176 .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | 177 CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | 178 CRYPTO_ALG_NEED_FALLBACK, 179 .cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx), 180 .cra_module = THIS_MODULE, 181 .cra_alignmask = 0xf, 182 .cra_init = sun8i_ss_cipher_init, 183 .cra_exit = sun8i_ss_cipher_exit, 184 }, 185 .min_keysize = AES_MIN_KEY_SIZE, 186 .max_keysize = AES_MAX_KEY_SIZE, 187 .ivsize = AES_BLOCK_SIZE, 188 .setkey = sun8i_ss_aes_setkey, 189 .encrypt = sun8i_ss_skencrypt, 190 .decrypt = sun8i_ss_skdecrypt, 191 } 192 }, 193 { 194 .type = CRYPTO_ALG_TYPE_SKCIPHER, 195 .ss_algo_id = SS_ID_CIPHER_AES, 196 .ss_blockmode = SS_ID_OP_ECB, 197 .alg.skcipher = { 198 .base = { 199 .cra_name = "ecb(aes)", 200 .cra_driver_name = "ecb-aes-sun8i-ss", 201 .cra_priority = 400, 202 .cra_blocksize = AES_BLOCK_SIZE, 203 .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | 204 CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | 205 CRYPTO_ALG_NEED_FALLBACK, 206 .cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx), 207 .cra_module = THIS_MODULE, 208 .cra_alignmask = 0xf, 209 .cra_init = sun8i_ss_cipher_init, 210 .cra_exit = sun8i_ss_cipher_exit, 211 }, 212 .min_keysize = AES_MIN_KEY_SIZE, 213 .max_keysize = AES_MAX_KEY_SIZE, 214 .setkey = sun8i_ss_aes_setkey, 215 .encrypt = sun8i_ss_skencrypt, 216 .decrypt = sun8i_ss_skdecrypt, 217 } 218 }, 219 { 220 .type = CRYPTO_ALG_TYPE_SKCIPHER, 221 .ss_algo_id = SS_ID_CIPHER_DES3, 222 .ss_blockmode = SS_ID_OP_CBC, 223 .alg.skcipher = { 224 .base = { 225 .cra_name = "cbc(des3_ede)", 226 .cra_driver_name = "cbc-des3-sun8i-ss", 227 .cra_priority = 400, 228 .cra_blocksize = DES3_EDE_BLOCK_SIZE, 229 .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | 230 CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | 231 CRYPTO_ALG_NEED_FALLBACK, 232 .cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx), 233 .cra_module = THIS_MODULE, 234 .cra_alignmask = 0xf, 235 .cra_init = sun8i_ss_cipher_init, 236 .cra_exit = sun8i_ss_cipher_exit, 237 }, 238 .min_keysize = DES3_EDE_KEY_SIZE, 239 .max_keysize = DES3_EDE_KEY_SIZE, 240 .ivsize = DES3_EDE_BLOCK_SIZE, 241 .setkey = sun8i_ss_des3_setkey, 242 .encrypt = sun8i_ss_skencrypt, 243 .decrypt = sun8i_ss_skdecrypt, 244 } 245 }, 246 { 247 .type = CRYPTO_ALG_TYPE_SKCIPHER, 248 .ss_algo_id = SS_ID_CIPHER_DES3, 249 .ss_blockmode = SS_ID_OP_ECB, 250 .alg.skcipher = { 251 .base = { 252 .cra_name = "ecb(des3_ede)", 253 .cra_driver_name = "ecb-des3-sun8i-ss", 254 .cra_priority = 400, 255 .cra_blocksize = DES3_EDE_BLOCK_SIZE, 256 .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | 257 CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | 258 CRYPTO_ALG_NEED_FALLBACK, 259 .cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx), 260 .cra_module = THIS_MODULE, 261 .cra_alignmask = 0xf, 262 .cra_init = sun8i_ss_cipher_init, 263 .cra_exit = sun8i_ss_cipher_exit, 264 }, 265 .min_keysize = DES3_EDE_KEY_SIZE, 266 .max_keysize = DES3_EDE_KEY_SIZE, 267 .setkey = sun8i_ss_des3_setkey, 268 .encrypt = sun8i_ss_skencrypt, 269 .decrypt = sun8i_ss_skdecrypt, 270 } 271 }, 272 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG 273 { 274 .type = CRYPTO_ALG_TYPE_RNG, 275 .alg.rng = { 276 .base = { 277 .cra_name = "stdrng", 278 .cra_driver_name = "sun8i-ss-prng", 279 .cra_priority = 300, 280 .cra_ctxsize = sizeof(struct sun8i_ss_rng_tfm_ctx), 281 .cra_module = THIS_MODULE, 282 .cra_init = sun8i_ss_prng_init, 283 .cra_exit = sun8i_ss_prng_exit, 284 }, 285 .generate = sun8i_ss_prng_generate, 286 .seed = sun8i_ss_prng_seed, 287 .seedsize = PRNG_SEED_SIZE, 288 } 289 }, 290 #endif 291 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_HASH 292 { .type = CRYPTO_ALG_TYPE_AHASH, 293 .ss_algo_id = SS_ID_HASH_MD5, 294 .alg.hash = { 295 .init = sun8i_ss_hash_init, 296 .update = sun8i_ss_hash_update, 297 .final = sun8i_ss_hash_final, 298 .finup = sun8i_ss_hash_finup, 299 .digest = sun8i_ss_hash_digest, 300 .export = sun8i_ss_hash_export, 301 .import = sun8i_ss_hash_import, 302 .halg = { 303 .digestsize = MD5_DIGEST_SIZE, 304 .statesize = sizeof(struct md5_state), 305 .base = { 306 .cra_name = "md5", 307 .cra_driver_name = "md5-sun8i-ss", 308 .cra_priority = 300, 309 .cra_alignmask = 3, 310 .cra_flags = CRYPTO_ALG_TYPE_AHASH | 311 CRYPTO_ALG_ASYNC | 312 CRYPTO_ALG_NEED_FALLBACK, 313 .cra_blocksize = MD5_HMAC_BLOCK_SIZE, 314 .cra_ctxsize = sizeof(struct sun8i_ss_hash_tfm_ctx), 315 .cra_module = THIS_MODULE, 316 .cra_init = sun8i_ss_hash_crainit, 317 .cra_exit = sun8i_ss_hash_craexit, 318 } 319 } 320 } 321 }, 322 { .type = CRYPTO_ALG_TYPE_AHASH, 323 .ss_algo_id = SS_ID_HASH_SHA1, 324 .alg.hash = { 325 .init = sun8i_ss_hash_init, 326 .update = sun8i_ss_hash_update, 327 .final = sun8i_ss_hash_final, 328 .finup = sun8i_ss_hash_finup, 329 .digest = sun8i_ss_hash_digest, 330 .export = sun8i_ss_hash_export, 331 .import = sun8i_ss_hash_import, 332 .halg = { 333 .digestsize = SHA1_DIGEST_SIZE, 334 .statesize = sizeof(struct sha1_state), 335 .base = { 336 .cra_name = "sha1", 337 .cra_driver_name = "sha1-sun8i-ss", 338 .cra_priority = 300, 339 .cra_alignmask = 3, 340 .cra_flags = CRYPTO_ALG_TYPE_AHASH | 341 CRYPTO_ALG_ASYNC | 342 CRYPTO_ALG_NEED_FALLBACK, 343 .cra_blocksize = SHA1_BLOCK_SIZE, 344 .cra_ctxsize = sizeof(struct sun8i_ss_hash_tfm_ctx), 345 .cra_module = THIS_MODULE, 346 .cra_init = sun8i_ss_hash_crainit, 347 .cra_exit = sun8i_ss_hash_craexit, 348 } 349 } 350 } 351 }, 352 { .type = CRYPTO_ALG_TYPE_AHASH, 353 .ss_algo_id = SS_ID_HASH_SHA224, 354 .alg.hash = { 355 .init = sun8i_ss_hash_init, 356 .update = sun8i_ss_hash_update, 357 .final = sun8i_ss_hash_final, 358 .finup = sun8i_ss_hash_finup, 359 .digest = sun8i_ss_hash_digest, 360 .export = sun8i_ss_hash_export, 361 .import = sun8i_ss_hash_import, 362 .halg = { 363 .digestsize = SHA224_DIGEST_SIZE, 364 .statesize = sizeof(struct sha256_state), 365 .base = { 366 .cra_name = "sha224", 367 .cra_driver_name = "sha224-sun8i-ss", 368 .cra_priority = 300, 369 .cra_alignmask = 3, 370 .cra_flags = CRYPTO_ALG_TYPE_AHASH | 371 CRYPTO_ALG_ASYNC | 372 CRYPTO_ALG_NEED_FALLBACK, 373 .cra_blocksize = SHA224_BLOCK_SIZE, 374 .cra_ctxsize = sizeof(struct sun8i_ss_hash_tfm_ctx), 375 .cra_module = THIS_MODULE, 376 .cra_init = sun8i_ss_hash_crainit, 377 .cra_exit = sun8i_ss_hash_craexit, 378 } 379 } 380 } 381 }, 382 { .type = CRYPTO_ALG_TYPE_AHASH, 383 .ss_algo_id = SS_ID_HASH_SHA256, 384 .alg.hash = { 385 .init = sun8i_ss_hash_init, 386 .update = sun8i_ss_hash_update, 387 .final = sun8i_ss_hash_final, 388 .finup = sun8i_ss_hash_finup, 389 .digest = sun8i_ss_hash_digest, 390 .export = sun8i_ss_hash_export, 391 .import = sun8i_ss_hash_import, 392 .halg = { 393 .digestsize = SHA256_DIGEST_SIZE, 394 .statesize = sizeof(struct sha256_state), 395 .base = { 396 .cra_name = "sha256", 397 .cra_driver_name = "sha256-sun8i-ss", 398 .cra_priority = 300, 399 .cra_alignmask = 3, 400 .cra_flags = CRYPTO_ALG_TYPE_AHASH | 401 CRYPTO_ALG_ASYNC | 402 CRYPTO_ALG_NEED_FALLBACK, 403 .cra_blocksize = SHA256_BLOCK_SIZE, 404 .cra_ctxsize = sizeof(struct sun8i_ss_hash_tfm_ctx), 405 .cra_module = THIS_MODULE, 406 .cra_init = sun8i_ss_hash_crainit, 407 .cra_exit = sun8i_ss_hash_craexit, 408 } 409 } 410 } 411 }, 412 #endif 413 }; 414 415 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 416 static int sun8i_ss_debugfs_show(struct seq_file *seq, void *v) 417 { 418 struct sun8i_ss_dev *ss = seq->private; 419 unsigned int i; 420 421 for (i = 0; i < MAXFLOW; i++) 422 seq_printf(seq, "Channel %d: nreq %lu\n", i, ss->flows[i].stat_req); 423 424 for (i = 0; i < ARRAY_SIZE(ss_algs); i++) { 425 if (!ss_algs[i].ss) 426 continue; 427 switch (ss_algs[i].type) { 428 case CRYPTO_ALG_TYPE_SKCIPHER: 429 seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", 430 ss_algs[i].alg.skcipher.base.cra_driver_name, 431 ss_algs[i].alg.skcipher.base.cra_name, 432 ss_algs[i].stat_req, ss_algs[i].stat_fb); 433 break; 434 case CRYPTO_ALG_TYPE_RNG: 435 seq_printf(seq, "%s %s reqs=%lu tsize=%lu\n", 436 ss_algs[i].alg.rng.base.cra_driver_name, 437 ss_algs[i].alg.rng.base.cra_name, 438 ss_algs[i].stat_req, ss_algs[i].stat_bytes); 439 break; 440 case CRYPTO_ALG_TYPE_AHASH: 441 seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", 442 ss_algs[i].alg.hash.halg.base.cra_driver_name, 443 ss_algs[i].alg.hash.halg.base.cra_name, 444 ss_algs[i].stat_req, ss_algs[i].stat_fb); 445 break; 446 } 447 } 448 return 0; 449 } 450 451 DEFINE_SHOW_ATTRIBUTE(sun8i_ss_debugfs); 452 #endif 453 454 static void sun8i_ss_free_flows(struct sun8i_ss_dev *ss, int i) 455 { 456 while (i >= 0) { 457 crypto_engine_exit(ss->flows[i].engine); 458 i--; 459 } 460 } 461 462 /* 463 * Allocate the flow list structure 464 */ 465 static int allocate_flows(struct sun8i_ss_dev *ss) 466 { 467 int i, err; 468 469 ss->flows = devm_kcalloc(ss->dev, MAXFLOW, sizeof(struct sun8i_ss_flow), 470 GFP_KERNEL); 471 if (!ss->flows) 472 return -ENOMEM; 473 474 for (i = 0; i < MAXFLOW; i++) { 475 init_completion(&ss->flows[i].complete); 476 477 ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true); 478 if (!ss->flows[i].engine) { 479 dev_err(ss->dev, "Cannot allocate engine\n"); 480 i--; 481 err = -ENOMEM; 482 goto error_engine; 483 } 484 err = crypto_engine_start(ss->flows[i].engine); 485 if (err) { 486 dev_err(ss->dev, "Cannot start engine\n"); 487 goto error_engine; 488 } 489 } 490 return 0; 491 error_engine: 492 sun8i_ss_free_flows(ss, i); 493 return err; 494 } 495 496 /* 497 * Power management strategy: The device is suspended unless a TFM exists for 498 * one of the algorithms proposed by this driver. 499 */ 500 static int sun8i_ss_pm_suspend(struct device *dev) 501 { 502 struct sun8i_ss_dev *ss = dev_get_drvdata(dev); 503 int i; 504 505 reset_control_assert(ss->reset); 506 for (i = 0; i < SS_MAX_CLOCKS; i++) 507 clk_disable_unprepare(ss->ssclks[i]); 508 return 0; 509 } 510 511 static int sun8i_ss_pm_resume(struct device *dev) 512 { 513 struct sun8i_ss_dev *ss = dev_get_drvdata(dev); 514 int err, i; 515 516 for (i = 0; i < SS_MAX_CLOCKS; i++) { 517 if (!ss->variant->ss_clks[i].name) 518 continue; 519 err = clk_prepare_enable(ss->ssclks[i]); 520 if (err) { 521 dev_err(ss->dev, "Cannot prepare_enable %s\n", 522 ss->variant->ss_clks[i].name); 523 goto error; 524 } 525 } 526 err = reset_control_deassert(ss->reset); 527 if (err) { 528 dev_err(ss->dev, "Cannot deassert reset control\n"); 529 goto error; 530 } 531 /* enable interrupts for all flows */ 532 writel(BIT(0) | BIT(1), ss->base + SS_INT_CTL_REG); 533 534 return 0; 535 error: 536 sun8i_ss_pm_suspend(dev); 537 return err; 538 } 539 540 static const struct dev_pm_ops sun8i_ss_pm_ops = { 541 SET_RUNTIME_PM_OPS(sun8i_ss_pm_suspend, sun8i_ss_pm_resume, NULL) 542 }; 543 544 static int sun8i_ss_pm_init(struct sun8i_ss_dev *ss) 545 { 546 int err; 547 548 pm_runtime_use_autosuspend(ss->dev); 549 pm_runtime_set_autosuspend_delay(ss->dev, 2000); 550 551 err = pm_runtime_set_suspended(ss->dev); 552 if (err) 553 return err; 554 pm_runtime_enable(ss->dev); 555 return err; 556 } 557 558 static void sun8i_ss_pm_exit(struct sun8i_ss_dev *ss) 559 { 560 pm_runtime_disable(ss->dev); 561 } 562 563 static int sun8i_ss_register_algs(struct sun8i_ss_dev *ss) 564 { 565 int ss_method, err, id; 566 unsigned int i; 567 568 for (i = 0; i < ARRAY_SIZE(ss_algs); i++) { 569 ss_algs[i].ss = ss; 570 switch (ss_algs[i].type) { 571 case CRYPTO_ALG_TYPE_SKCIPHER: 572 id = ss_algs[i].ss_algo_id; 573 ss_method = ss->variant->alg_cipher[id]; 574 if (ss_method == SS_ID_NOTSUPP) { 575 dev_info(ss->dev, 576 "DEBUG: Algo of %s not supported\n", 577 ss_algs[i].alg.skcipher.base.cra_name); 578 ss_algs[i].ss = NULL; 579 break; 580 } 581 id = ss_algs[i].ss_blockmode; 582 ss_method = ss->variant->op_mode[id]; 583 if (ss_method == SS_ID_NOTSUPP) { 584 dev_info(ss->dev, "DEBUG: Blockmode of %s not supported\n", 585 ss_algs[i].alg.skcipher.base.cra_name); 586 ss_algs[i].ss = NULL; 587 break; 588 } 589 dev_info(ss->dev, "DEBUG: Register %s\n", 590 ss_algs[i].alg.skcipher.base.cra_name); 591 err = crypto_register_skcipher(&ss_algs[i].alg.skcipher); 592 if (err) { 593 dev_err(ss->dev, "Fail to register %s\n", 594 ss_algs[i].alg.skcipher.base.cra_name); 595 ss_algs[i].ss = NULL; 596 return err; 597 } 598 break; 599 case CRYPTO_ALG_TYPE_RNG: 600 err = crypto_register_rng(&ss_algs[i].alg.rng); 601 if (err) { 602 dev_err(ss->dev, "Fail to register %s\n", 603 ss_algs[i].alg.rng.base.cra_name); 604 ss_algs[i].ss = NULL; 605 } 606 break; 607 case CRYPTO_ALG_TYPE_AHASH: 608 id = ss_algs[i].ss_algo_id; 609 ss_method = ss->variant->alg_hash[id]; 610 if (ss_method == SS_ID_NOTSUPP) { 611 dev_info(ss->dev, 612 "DEBUG: Algo of %s not supported\n", 613 ss_algs[i].alg.hash.halg.base.cra_name); 614 ss_algs[i].ss = NULL; 615 break; 616 } 617 dev_info(ss->dev, "Register %s\n", 618 ss_algs[i].alg.hash.halg.base.cra_name); 619 err = crypto_register_ahash(&ss_algs[i].alg.hash); 620 if (err) { 621 dev_err(ss->dev, "ERROR: Fail to register %s\n", 622 ss_algs[i].alg.hash.halg.base.cra_name); 623 ss_algs[i].ss = NULL; 624 return err; 625 } 626 break; 627 default: 628 ss_algs[i].ss = NULL; 629 dev_err(ss->dev, "ERROR: tried to register an unknown algo\n"); 630 } 631 } 632 return 0; 633 } 634 635 static void sun8i_ss_unregister_algs(struct sun8i_ss_dev *ss) 636 { 637 unsigned int i; 638 639 for (i = 0; i < ARRAY_SIZE(ss_algs); i++) { 640 if (!ss_algs[i].ss) 641 continue; 642 switch (ss_algs[i].type) { 643 case CRYPTO_ALG_TYPE_SKCIPHER: 644 dev_info(ss->dev, "Unregister %d %s\n", i, 645 ss_algs[i].alg.skcipher.base.cra_name); 646 crypto_unregister_skcipher(&ss_algs[i].alg.skcipher); 647 break; 648 case CRYPTO_ALG_TYPE_RNG: 649 dev_info(ss->dev, "Unregister %d %s\n", i, 650 ss_algs[i].alg.rng.base.cra_name); 651 crypto_unregister_rng(&ss_algs[i].alg.rng); 652 break; 653 case CRYPTO_ALG_TYPE_AHASH: 654 dev_info(ss->dev, "Unregister %d %s\n", i, 655 ss_algs[i].alg.hash.halg.base.cra_name); 656 crypto_unregister_ahash(&ss_algs[i].alg.hash); 657 break; 658 } 659 } 660 } 661 662 static int sun8i_ss_get_clks(struct sun8i_ss_dev *ss) 663 { 664 unsigned long cr; 665 int err, i; 666 667 for (i = 0; i < SS_MAX_CLOCKS; i++) { 668 if (!ss->variant->ss_clks[i].name) 669 continue; 670 ss->ssclks[i] = devm_clk_get(ss->dev, ss->variant->ss_clks[i].name); 671 if (IS_ERR(ss->ssclks[i])) { 672 err = PTR_ERR(ss->ssclks[i]); 673 dev_err(ss->dev, "Cannot get %s SS clock err=%d\n", 674 ss->variant->ss_clks[i].name, err); 675 return err; 676 } 677 cr = clk_get_rate(ss->ssclks[i]); 678 if (!cr) 679 return -EINVAL; 680 if (ss->variant->ss_clks[i].freq > 0 && 681 cr != ss->variant->ss_clks[i].freq) { 682 dev_info(ss->dev, "Set %s clock to %lu (%lu Mhz) from %lu (%lu Mhz)\n", 683 ss->variant->ss_clks[i].name, 684 ss->variant->ss_clks[i].freq, 685 ss->variant->ss_clks[i].freq / 1000000, 686 cr, cr / 1000000); 687 err = clk_set_rate(ss->ssclks[i], ss->variant->ss_clks[i].freq); 688 if (err) 689 dev_err(ss->dev, "Fail to set %s clk speed to %lu hz\n", 690 ss->variant->ss_clks[i].name, 691 ss->variant->ss_clks[i].freq); 692 } 693 if (ss->variant->ss_clks[i].max_freq > 0 && 694 cr > ss->variant->ss_clks[i].max_freq) 695 dev_warn(ss->dev, "Frequency for %s (%lu hz) is higher than datasheet's recommendation (%lu hz)", 696 ss->variant->ss_clks[i].name, cr, 697 ss->variant->ss_clks[i].max_freq); 698 } 699 return 0; 700 } 701 702 static int sun8i_ss_probe(struct platform_device *pdev) 703 { 704 struct sun8i_ss_dev *ss; 705 int err, irq; 706 u32 v; 707 708 ss = devm_kzalloc(&pdev->dev, sizeof(*ss), GFP_KERNEL); 709 if (!ss) 710 return -ENOMEM; 711 712 ss->dev = &pdev->dev; 713 platform_set_drvdata(pdev, ss); 714 715 ss->variant = of_device_get_match_data(&pdev->dev); 716 if (!ss->variant) { 717 dev_err(&pdev->dev, "Missing Crypto Engine variant\n"); 718 return -EINVAL; 719 } 720 721 ss->base = devm_platform_ioremap_resource(pdev, 0); 722 if (IS_ERR(ss->base)) 723 return PTR_ERR(ss->base); 724 725 err = sun8i_ss_get_clks(ss); 726 if (err) 727 return err; 728 729 irq = platform_get_irq(pdev, 0); 730 if (irq < 0) 731 return irq; 732 733 ss->reset = devm_reset_control_get(&pdev->dev, NULL); 734 if (IS_ERR(ss->reset)) 735 return dev_err_probe(&pdev->dev, PTR_ERR(ss->reset), 736 "No reset control found\n"); 737 738 mutex_init(&ss->mlock); 739 740 err = allocate_flows(ss); 741 if (err) 742 return err; 743 744 err = sun8i_ss_pm_init(ss); 745 if (err) 746 goto error_pm; 747 748 err = devm_request_irq(&pdev->dev, irq, ss_irq_handler, 0, "sun8i-ss", ss); 749 if (err) { 750 dev_err(ss->dev, "Cannot request SecuritySystem IRQ (err=%d)\n", err); 751 goto error_irq; 752 } 753 754 err = sun8i_ss_register_algs(ss); 755 if (err) 756 goto error_alg; 757 758 err = pm_runtime_resume_and_get(ss->dev); 759 if (err < 0) 760 goto error_alg; 761 762 v = readl(ss->base + SS_CTL_REG); 763 v >>= SS_DIE_ID_SHIFT; 764 v &= SS_DIE_ID_MASK; 765 dev_info(&pdev->dev, "Security System Die ID %x\n", v); 766 767 pm_runtime_put_sync(ss->dev); 768 769 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 770 /* Ignore error of debugfs */ 771 ss->dbgfs_dir = debugfs_create_dir("sun8i-ss", NULL); 772 ss->dbgfs_stats = debugfs_create_file("stats", 0444, 773 ss->dbgfs_dir, ss, 774 &sun8i_ss_debugfs_fops); 775 #endif 776 777 return 0; 778 error_alg: 779 sun8i_ss_unregister_algs(ss); 780 error_irq: 781 sun8i_ss_pm_exit(ss); 782 error_pm: 783 sun8i_ss_free_flows(ss, MAXFLOW - 1); 784 return err; 785 } 786 787 static int sun8i_ss_remove(struct platform_device *pdev) 788 { 789 struct sun8i_ss_dev *ss = platform_get_drvdata(pdev); 790 791 sun8i_ss_unregister_algs(ss); 792 793 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG 794 debugfs_remove_recursive(ss->dbgfs_dir); 795 #endif 796 797 sun8i_ss_free_flows(ss, MAXFLOW - 1); 798 799 sun8i_ss_pm_exit(ss); 800 801 return 0; 802 } 803 804 static const struct of_device_id sun8i_ss_crypto_of_match_table[] = { 805 { .compatible = "allwinner,sun8i-a83t-crypto", 806 .data = &ss_a83t_variant }, 807 { .compatible = "allwinner,sun9i-a80-crypto", 808 .data = &ss_a80_variant }, 809 {} 810 }; 811 MODULE_DEVICE_TABLE(of, sun8i_ss_crypto_of_match_table); 812 813 static struct platform_driver sun8i_ss_driver = { 814 .probe = sun8i_ss_probe, 815 .remove = sun8i_ss_remove, 816 .driver = { 817 .name = "sun8i-ss", 818 .pm = &sun8i_ss_pm_ops, 819 .of_match_table = sun8i_ss_crypto_of_match_table, 820 }, 821 }; 822 823 module_platform_driver(sun8i_ss_driver); 824 825 MODULE_DESCRIPTION("Allwinner SecuritySystem cryptographic offloader"); 826 MODULE_LICENSE("GPL"); 827 MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>"); 828