diff options
Diffstat (limited to 'drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c')
| -rw-r--r-- | drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 313 |
1 files changed, 212 insertions, 101 deletions
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c index 00194d1d9ae6..c16bb6ce6ee3 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c @@ -7,23 +7,26 @@ * * Core file which registers crypto algorithms supported by the CryptoEngine. * - * You could find a link for the datasheet in Documentation/arm/sunxi.rst + * You could find a link for the datasheet in Documentation/arch/arm/sunxi.rst */ + +#include <crypto/engine.h> +#include <crypto/internal/hash.h> +#include <crypto/internal/rng.h> +#include <crypto/internal/skcipher.h> #include <linux/clk.h> -#include <linux/crypto.h> #include <linux/delay.h> #include <linux/dma-mapping.h> +#include <linux/err.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/irq.h> +#include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> -#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> -#include <crypto/internal/rng.h> -#include <crypto/internal/skcipher.h> #include "sun8i-ce.h" @@ -89,6 +92,30 @@ static const struct ce_variant ce_h6_variant = { .trng = CE_ALG_TRNG_V2, }; +static const struct ce_variant ce_h616_variant = { + .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, + }, + .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256, + CE_ALG_SHA384, CE_ALG_SHA512 + }, + .op_mode = { CE_OP_ECB, CE_OP_CBC + }, + .cipher_t_dlen_in_bytes = true, + .hash_t_dlen_in_bits = true, + .prng_t_dlen_in_bytes = true, + .trng_t_dlen_in_bytes = true, + .needs_word_addresses = true, + .ce_clks = { + { "bus", 0, 200000000 }, + { "mod", 300000000, 0 }, + { "ram", 0, 400000000 }, + { "trng", 0, 0 }, + }, + .esr = ESR_H6, + .prng = CE_ALG_PRNG_V2, + .trng = CE_ALG_TRNG_V2, +}; + static const struct ce_variant ce_a64_variant = { .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, }, @@ -106,6 +133,25 @@ static const struct ce_variant ce_a64_variant = { .trng = CE_ID_NOTSUPP, }; +static const struct ce_variant ce_d1_variant = { + .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, + }, + .alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256, + CE_ALG_SHA384, CE_ALG_SHA512 + }, + .op_mode = { CE_OP_ECB, CE_OP_CBC + }, + .ce_clks = { + { "bus", 0, 200000000 }, + { "mod", 300000000, 0 }, + { "ram", 0, 400000000 }, + { "trng", 0, 0 }, + }, + .esr = ESR_D1, + .prng = CE_ALG_PRNG, + .trng = CE_ALG_TRNG, +}; + static const struct ce_variant ce_r40_variant = { .alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES, }, @@ -123,6 +169,12 @@ static const struct ce_variant ce_r40_variant = { .trng = CE_ID_NOTSUPP, }; +static void sun8i_ce_dump_task_descriptors(struct sun8i_ce_flow *chan) +{ + print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4, + chan->tl, sizeof(struct ce_task), false); +} + /* * sun8i_ce_get_engine_number() get the next channel slot * This is a simple round-robin way of getting the next channel @@ -137,7 +189,6 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) { u32 v; int err = 0; - struct ce_task *cet = ce->chanlist[flow].tl; #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG ce->chanlist[flow].stat_req++; @@ -150,7 +201,7 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) writel(v, ce->base + CE_ICR); reinit_completion(&ce->chanlist[flow].complete); - writel(ce->chanlist[flow].t_phy, ce->base + CE_TDQ); + writel(desc_addr_val(ce, ce->chanlist[flow].t_phy), ce->base + CE_TDQ); ce->chanlist[flow].status = 0; /* Be sure all data is written before enabling the task */ @@ -164,11 +215,10 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) mutex_unlock(&ce->mlock); wait_for_completion_interruptible_timeout(&ce->chanlist[flow].complete, - msecs_to_jiffies(ce->chanlist[flow].timeout)); + msecs_to_jiffies(CE_DMA_TIMEOUT_MS)); if (ce->chanlist[flow].status == 0) { - dev_err(ce->dev, "DMA timeout for %s (tm=%d) on flow %d\n", name, - ce->chanlist[flow].timeout, flow); + dev_err(ce->dev, "DMA timeout for %s on flow %d\n", name, flow); err = -EFAULT; } /* No need to lock for this read, the channel is locked so @@ -180,9 +230,8 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) /* Sadly, the error bit is not per flow */ if (v) { dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow); + sun8i_ce_dump_task_descriptors(&ce->chanlist[flow]); err = -EFAULT; - print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4, - cet, sizeof(struct ce_task), false); } if (v & CE_ERR_ALGO_NOTSUP) dev_err(ce->dev, "CE ERROR: algorithm not supported\n"); @@ -192,15 +241,15 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) dev_err(ce->dev, "CE ERROR: keysram access error for AES\n"); break; case ESR_A64: + case ESR_D1: case ESR_H5: case ESR_R40: v >>= (flow * 4); v &= 0xF; if (v) { dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow); + sun8i_ce_dump_task_descriptors(&ce->chanlist[flow]); err = -EFAULT; - print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4, - cet, sizeof(struct ce_task), false); } if (v & CE_ERR_ALGO_NOTSUP) dev_err(ce->dev, "CE ERROR: algorithm not supported\n"); @@ -214,9 +263,8 @@ int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) v &= 0xFF; if (v) { dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow); + sun8i_ce_dump_task_descriptors(&ce->chanlist[flow]); err = -EFAULT; - print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4, - cet, sizeof(struct ce_task), false); } if (v & CE_ERR_ALGO_NOTSUP) dev_err(ce->dev, "CE ERROR: algorithm not supported\n"); @@ -257,14 +305,14 @@ static struct sun8i_ce_alg_template ce_algs[] = { .type = CRYPTO_ALG_TYPE_SKCIPHER, .ce_algo_id = CE_ID_CIPHER_AES, .ce_blockmode = CE_ID_OP_CBC, - .alg.skcipher = { + .alg.skcipher.base = { .base = { .cra_name = "cbc(aes)", .cra_driver_name = "cbc-aes-sun8i-ce", .cra_priority = 400, .cra_blocksize = AES_BLOCK_SIZE, .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | - CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx), .cra_module = THIS_MODULE, @@ -278,20 +326,23 @@ static struct sun8i_ce_alg_template ce_algs[] = { .setkey = sun8i_ce_aes_setkey, .encrypt = sun8i_ce_skencrypt, .decrypt = sun8i_ce_skdecrypt, - } + }, + .alg.skcipher.op = { + .do_one_request = sun8i_ce_cipher_do_one, + }, }, { .type = CRYPTO_ALG_TYPE_SKCIPHER, .ce_algo_id = CE_ID_CIPHER_AES, .ce_blockmode = CE_ID_OP_ECB, - .alg.skcipher = { + .alg.skcipher.base = { .base = { .cra_name = "ecb(aes)", .cra_driver_name = "ecb-aes-sun8i-ce", .cra_priority = 400, .cra_blocksize = AES_BLOCK_SIZE, .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | - CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx), .cra_module = THIS_MODULE, @@ -304,20 +355,23 @@ static struct sun8i_ce_alg_template ce_algs[] = { .setkey = sun8i_ce_aes_setkey, .encrypt = sun8i_ce_skencrypt, .decrypt = sun8i_ce_skdecrypt, - } + }, + .alg.skcipher.op = { + .do_one_request = sun8i_ce_cipher_do_one, + }, }, { .type = CRYPTO_ALG_TYPE_SKCIPHER, .ce_algo_id = CE_ID_CIPHER_DES3, .ce_blockmode = CE_ID_OP_CBC, - .alg.skcipher = { + .alg.skcipher.base = { .base = { .cra_name = "cbc(des3_ede)", .cra_driver_name = "cbc-des3-sun8i-ce", .cra_priority = 400, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | - CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx), .cra_module = THIS_MODULE, @@ -331,20 +385,23 @@ static struct sun8i_ce_alg_template ce_algs[] = { .setkey = sun8i_ce_des3_setkey, .encrypt = sun8i_ce_skencrypt, .decrypt = sun8i_ce_skdecrypt, - } + }, + .alg.skcipher.op = { + .do_one_request = sun8i_ce_cipher_do_one, + }, }, { .type = CRYPTO_ALG_TYPE_SKCIPHER, .ce_algo_id = CE_ID_CIPHER_DES3, .ce_blockmode = CE_ID_OP_ECB, - .alg.skcipher = { + .alg.skcipher.base = { .base = { .cra_name = "ecb(des3_ede)", .cra_driver_name = "ecb-des3-sun8i-ce", .cra_priority = 400, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | - CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | + CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx), .cra_module = THIS_MODULE, @@ -357,12 +414,15 @@ static struct sun8i_ce_alg_template ce_algs[] = { .setkey = sun8i_ce_des3_setkey, .encrypt = sun8i_ce_skencrypt, .decrypt = sun8i_ce_skdecrypt, - } + }, + .alg.skcipher.op = { + .do_one_request = sun8i_ce_cipher_do_one, + }, }, #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_HASH { .type = CRYPTO_ALG_TYPE_AHASH, .ce_algo_id = CE_ID_HASH_MD5, - .alg.hash = { + .alg.hash.base = { .init = sun8i_ce_hash_init, .update = sun8i_ce_hash_update, .final = sun8i_ce_hash_final, @@ -370,6 +430,8 @@ static struct sun8i_ce_alg_template ce_algs[] = { .digest = sun8i_ce_hash_digest, .export = sun8i_ce_hash_export, .import = sun8i_ce_hash_import, + .init_tfm = sun8i_ce_hash_init_tfm, + .exit_tfm = sun8i_ce_hash_exit_tfm, .halg = { .digestsize = MD5_DIGEST_SIZE, .statesize = sizeof(struct md5_state), @@ -377,22 +439,23 @@ static struct sun8i_ce_alg_template ce_algs[] = { .cra_name = "md5", .cra_driver_name = "md5-sun8i-ce", .cra_priority = 300, - .cra_alignmask = 3, .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = MD5_HMAC_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), .cra_module = THIS_MODULE, - .cra_init = sun8i_ce_hash_crainit, - .cra_exit = sun8i_ce_hash_craexit, } } - } + }, + .alg.hash.op = { + .do_one_request = sun8i_ce_hash_run, + }, + }, { .type = CRYPTO_ALG_TYPE_AHASH, .ce_algo_id = CE_ID_HASH_SHA1, - .alg.hash = { + .alg.hash.base = { .init = sun8i_ce_hash_init, .update = sun8i_ce_hash_update, .final = sun8i_ce_hash_final, @@ -400,6 +463,8 @@ static struct sun8i_ce_alg_template ce_algs[] = { .digest = sun8i_ce_hash_digest, .export = sun8i_ce_hash_export, .import = sun8i_ce_hash_import, + .init_tfm = sun8i_ce_hash_init_tfm, + .exit_tfm = sun8i_ce_hash_exit_tfm, .halg = { .digestsize = SHA1_DIGEST_SIZE, .statesize = sizeof(struct sha1_state), @@ -407,22 +472,22 @@ static struct sun8i_ce_alg_template ce_algs[] = { .cra_name = "sha1", .cra_driver_name = "sha1-sun8i-ce", .cra_priority = 300, - .cra_alignmask = 3, .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), .cra_module = THIS_MODULE, - .cra_init = sun8i_ce_hash_crainit, - .cra_exit = sun8i_ce_hash_craexit, } } - } + }, + .alg.hash.op = { + .do_one_request = sun8i_ce_hash_run, + }, }, { .type = CRYPTO_ALG_TYPE_AHASH, .ce_algo_id = CE_ID_HASH_SHA224, - .alg.hash = { + .alg.hash.base = { .init = sun8i_ce_hash_init, .update = sun8i_ce_hash_update, .final = sun8i_ce_hash_final, @@ -430,6 +495,8 @@ static struct sun8i_ce_alg_template ce_algs[] = { .digest = sun8i_ce_hash_digest, .export = sun8i_ce_hash_export, .import = sun8i_ce_hash_import, + .init_tfm = sun8i_ce_hash_init_tfm, + .exit_tfm = sun8i_ce_hash_exit_tfm, .halg = { .digestsize = SHA224_DIGEST_SIZE, .statesize = sizeof(struct sha256_state), @@ -437,22 +504,22 @@ static struct sun8i_ce_alg_template ce_algs[] = { .cra_name = "sha224", .cra_driver_name = "sha224-sun8i-ce", .cra_priority = 300, - .cra_alignmask = 3, .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA224_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), .cra_module = THIS_MODULE, - .cra_init = sun8i_ce_hash_crainit, - .cra_exit = sun8i_ce_hash_craexit, } } - } + }, + .alg.hash.op = { + .do_one_request = sun8i_ce_hash_run, + }, }, { .type = CRYPTO_ALG_TYPE_AHASH, .ce_algo_id = CE_ID_HASH_SHA256, - .alg.hash = { + .alg.hash.base = { .init = sun8i_ce_hash_init, .update = sun8i_ce_hash_update, .final = sun8i_ce_hash_final, @@ -460,6 +527,8 @@ static struct sun8i_ce_alg_template ce_algs[] = { .digest = sun8i_ce_hash_digest, .export = sun8i_ce_hash_export, .import = sun8i_ce_hash_import, + .init_tfm = sun8i_ce_hash_init_tfm, + .exit_tfm = sun8i_ce_hash_exit_tfm, .halg = { .digestsize = SHA256_DIGEST_SIZE, .statesize = sizeof(struct sha256_state), @@ -467,22 +536,22 @@ static struct sun8i_ce_alg_template ce_algs[] = { .cra_name = "sha256", .cra_driver_name = "sha256-sun8i-ce", .cra_priority = 300, - .cra_alignmask = 3, .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA256_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), .cra_module = THIS_MODULE, - .cra_init = sun8i_ce_hash_crainit, - .cra_exit = sun8i_ce_hash_craexit, } } - } + }, + .alg.hash.op = { + .do_one_request = sun8i_ce_hash_run, + }, }, { .type = CRYPTO_ALG_TYPE_AHASH, .ce_algo_id = CE_ID_HASH_SHA384, - .alg.hash = { + .alg.hash.base = { .init = sun8i_ce_hash_init, .update = sun8i_ce_hash_update, .final = sun8i_ce_hash_final, @@ -490,6 +559,8 @@ static struct sun8i_ce_alg_template ce_algs[] = { .digest = sun8i_ce_hash_digest, .export = sun8i_ce_hash_export, .import = sun8i_ce_hash_import, + .init_tfm = sun8i_ce_hash_init_tfm, + .exit_tfm = sun8i_ce_hash_exit_tfm, .halg = { .digestsize = SHA384_DIGEST_SIZE, .statesize = sizeof(struct sha512_state), @@ -497,22 +568,22 @@ static struct sun8i_ce_alg_template ce_algs[] = { .cra_name = "sha384", .cra_driver_name = "sha384-sun8i-ce", .cra_priority = 300, - .cra_alignmask = 3, .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA384_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), .cra_module = THIS_MODULE, - .cra_init = sun8i_ce_hash_crainit, - .cra_exit = sun8i_ce_hash_craexit, } } - } + }, + .alg.hash.op = { + .do_one_request = sun8i_ce_hash_run, + }, }, { .type = CRYPTO_ALG_TYPE_AHASH, .ce_algo_id = CE_ID_HASH_SHA512, - .alg.hash = { + .alg.hash.base = { .init = sun8i_ce_hash_init, .update = sun8i_ce_hash_update, .final = sun8i_ce_hash_final, @@ -520,6 +591,8 @@ static struct sun8i_ce_alg_template ce_algs[] = { .digest = sun8i_ce_hash_digest, .export = sun8i_ce_hash_export, .import = sun8i_ce_hash_import, + .init_tfm = sun8i_ce_hash_init_tfm, + .exit_tfm = sun8i_ce_hash_exit_tfm, .halg = { .digestsize = SHA512_DIGEST_SIZE, .statesize = sizeof(struct sha512_state), @@ -527,18 +600,18 @@ static struct sun8i_ce_alg_template ce_algs[] = { .cra_name = "sha512", .cra_driver_name = "sha512-sun8i-ce", .cra_priority = 300, - .cra_alignmask = 3, .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA512_BLOCK_SIZE, .cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx), .cra_module = THIS_MODULE, - .cra_init = sun8i_ce_hash_crainit, - .cra_exit = sun8i_ce_hash_craexit, } } - } + }, + .alg.hash.op = { + .do_one_request = sun8i_ce_hash_run, + }, }, #endif #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG @@ -562,40 +635,73 @@ static struct sun8i_ce_alg_template ce_algs[] = { #endif }; -#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v) { - struct sun8i_ce_dev *ce = seq->private; + struct sun8i_ce_dev *ce __maybe_unused = seq->private; unsigned int i; for (i = 0; i < MAXFLOW; i++) - seq_printf(seq, "Channel %d: nreq %lu\n", i, ce->chanlist[i].stat_req); + seq_printf(seq, "Channel %d: nreq %lu\n", i, +#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG + ce->chanlist[i].stat_req); +#else + 0ul); +#endif for (i = 0; i < ARRAY_SIZE(ce_algs); i++) { if (!ce_algs[i].ce) continue; switch (ce_algs[i].type) { case CRYPTO_ALG_TYPE_SKCIPHER: - seq_printf(seq, "%s %s %lu %lu\n", - ce_algs[i].alg.skcipher.base.cra_driver_name, - ce_algs[i].alg.skcipher.base.cra_name, + seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", + ce_algs[i].alg.skcipher.base.base.cra_driver_name, + ce_algs[i].alg.skcipher.base.base.cra_name, ce_algs[i].stat_req, ce_algs[i].stat_fb); + seq_printf(seq, "\tLast fallback is: %s\n", + ce_algs[i].fbname); + seq_printf(seq, "\tFallback due to 0 length: %lu\n", + ce_algs[i].stat_fb_len0); + seq_printf(seq, "\tFallback due to length !mod16: %lu\n", + ce_algs[i].stat_fb_mod16); + seq_printf(seq, "\tFallback due to length < IV: %lu\n", + ce_algs[i].stat_fb_leniv); + seq_printf(seq, "\tFallback due to source alignment: %lu\n", + ce_algs[i].stat_fb_srcali); + seq_printf(seq, "\tFallback due to dest alignment: %lu\n", + ce_algs[i].stat_fb_dstali); + seq_printf(seq, "\tFallback due to source length: %lu\n", + ce_algs[i].stat_fb_srclen); + seq_printf(seq, "\tFallback due to dest length: %lu\n", + ce_algs[i].stat_fb_dstlen); + seq_printf(seq, "\tFallback due to SG numbers: %lu\n", + ce_algs[i].stat_fb_maxsg); break; case CRYPTO_ALG_TYPE_AHASH: - seq_printf(seq, "%s %s %lu %lu\n", - ce_algs[i].alg.hash.halg.base.cra_driver_name, - ce_algs[i].alg.hash.halg.base.cra_name, + seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", + ce_algs[i].alg.hash.base.halg.base.cra_driver_name, + ce_algs[i].alg.hash.base.halg.base.cra_name, ce_algs[i].stat_req, ce_algs[i].stat_fb); + seq_printf(seq, "\tLast fallback is: %s\n", + ce_algs[i].fbname); + seq_printf(seq, "\tFallback due to 0 length: %lu\n", + ce_algs[i].stat_fb_len0); + seq_printf(seq, "\tFallback due to length: %lu\n", + ce_algs[i].stat_fb_srclen); + seq_printf(seq, "\tFallback due to alignment: %lu\n", + ce_algs[i].stat_fb_srcali); + seq_printf(seq, "\tFallback due to SG numbers: %lu\n", + ce_algs[i].stat_fb_maxsg); break; case CRYPTO_ALG_TYPE_RNG: - seq_printf(seq, "%s %s %lu %lu\n", + seq_printf(seq, "%s %s reqs=%lu bytes=%lu\n", ce_algs[i].alg.rng.base.cra_driver_name, ce_algs[i].alg.rng.base.cra_name, ce_algs[i].stat_req, ce_algs[i].stat_bytes); break; } } -#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG +#if defined(CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG) && \ + defined(CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG) seq_printf(seq, "HWRNG %lu %lu\n", ce->hwrng_stat_req, ce->hwrng_stat_bytes); #endif @@ -603,7 +709,6 @@ static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v) } DEFINE_SHOW_ATTRIBUTE(sun8i_ce_debugfs); -#endif static void sun8i_ce_free_chanlist(struct sun8i_ce_dev *ce, int i) { @@ -716,13 +821,12 @@ static int sun8i_ce_pm_init(struct sun8i_ce_dev *ce) err = pm_runtime_set_suspended(ce->dev); if (err) return err; - pm_runtime_enable(ce->dev); - return err; -} -static void sun8i_ce_pm_exit(struct sun8i_ce_dev *ce) -{ - pm_runtime_disable(ce->dev); + err = devm_pm_runtime_enable(ce->dev); + if (err) + return err; + + return 0; } static int sun8i_ce_get_clks(struct sun8i_ce_dev *ce) @@ -779,7 +883,7 @@ static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce) if (ce_method == CE_ID_NOTSUPP) { dev_dbg(ce->dev, "DEBUG: Algo of %s not supported\n", - ce_algs[i].alg.skcipher.base.cra_name); + ce_algs[i].alg.skcipher.base.base.cra_name); ce_algs[i].ce = NULL; break; } @@ -787,16 +891,16 @@ static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce) ce_method = ce->variant->op_mode[id]; if (ce_method == CE_ID_NOTSUPP) { dev_dbg(ce->dev, "DEBUG: Blockmode of %s not supported\n", - ce_algs[i].alg.skcipher.base.cra_name); + ce_algs[i].alg.skcipher.base.base.cra_name); ce_algs[i].ce = NULL; break; } dev_info(ce->dev, "Register %s\n", - ce_algs[i].alg.skcipher.base.cra_name); - err = crypto_register_skcipher(&ce_algs[i].alg.skcipher); + ce_algs[i].alg.skcipher.base.base.cra_name); + err = crypto_engine_register_skcipher(&ce_algs[i].alg.skcipher); if (err) { dev_err(ce->dev, "ERROR: Fail to register %s\n", - ce_algs[i].alg.skcipher.base.cra_name); + ce_algs[i].alg.skcipher.base.base.cra_name); ce_algs[i].ce = NULL; return err; } @@ -807,16 +911,16 @@ static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce) if (ce_method == CE_ID_NOTSUPP) { dev_info(ce->dev, "DEBUG: Algo of %s not supported\n", - ce_algs[i].alg.hash.halg.base.cra_name); + ce_algs[i].alg.hash.base.halg.base.cra_name); ce_algs[i].ce = NULL; break; } dev_info(ce->dev, "Register %s\n", - ce_algs[i].alg.hash.halg.base.cra_name); - err = crypto_register_ahash(&ce_algs[i].alg.hash); + ce_algs[i].alg.hash.base.halg.base.cra_name); + err = crypto_engine_register_ahash(&ce_algs[i].alg.hash); if (err) { dev_err(ce->dev, "ERROR: Fail to register %s\n", - ce_algs[i].alg.hash.halg.base.cra_name); + ce_algs[i].alg.hash.base.halg.base.cra_name); ce_algs[i].ce = NULL; return err; } @@ -856,13 +960,13 @@ static void sun8i_ce_unregister_algs(struct sun8i_ce_dev *ce) switch (ce_algs[i].type) { case CRYPTO_ALG_TYPE_SKCIPHER: dev_info(ce->dev, "Unregister %d %s\n", i, - ce_algs[i].alg.skcipher.base.cra_name); - crypto_unregister_skcipher(&ce_algs[i].alg.skcipher); + ce_algs[i].alg.skcipher.base.base.cra_name); + crypto_engine_unregister_skcipher(&ce_algs[i].alg.skcipher); break; case CRYPTO_ALG_TYPE_AHASH: dev_info(ce->dev, "Unregister %d %s\n", i, - ce_algs[i].alg.hash.halg.base.cra_name); - crypto_unregister_ahash(&ce_algs[i].alg.hash); + ce_algs[i].alg.hash.base.halg.base.cra_name); + crypto_engine_unregister_ahash(&ce_algs[i].alg.hash); break; case CRYPTO_ALG_TYPE_RNG: dev_info(ce->dev, "Unregister %d %s\n", i, @@ -925,7 +1029,7 @@ static int sun8i_ce_probe(struct platform_device *pdev) "sun8i-ce-ns", ce); if (err) { dev_err(ce->dev, "Cannot request CryptoEngine Non-secure IRQ (err=%d)\n", err); - goto error_irq; + goto error_pm; } err = sun8i_ce_register_algs(ce); @@ -947,25 +1051,31 @@ static int sun8i_ce_probe(struct platform_device *pdev) pm_runtime_put_sync(ce->dev); + if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG)) { + struct dentry *dbgfs_dir; + struct dentry *dbgfs_stats __maybe_unused; + + /* Ignore error of debugfs */ + dbgfs_dir = debugfs_create_dir("sun8i-ce", NULL); + dbgfs_stats = debugfs_create_file("stats", 0444, + dbgfs_dir, ce, + &sun8i_ce_debugfs_fops); + #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG - /* Ignore error of debugfs */ - ce->dbgfs_dir = debugfs_create_dir("sun8i-ce", NULL); - ce->dbgfs_stats = debugfs_create_file("stats", 0444, - ce->dbgfs_dir, ce, - &sun8i_ce_debugfs_fops); + ce->dbgfs_dir = dbgfs_dir; + ce->dbgfs_stats = dbgfs_stats; #endif + } return 0; error_alg: sun8i_ce_unregister_algs(ce); -error_irq: - sun8i_ce_pm_exit(ce); error_pm: sun8i_ce_free_chanlist(ce, MAXFLOW - 1); return err; } -static int sun8i_ce_remove(struct platform_device *pdev) +static void sun8i_ce_remove(struct platform_device *pdev) { struct sun8i_ce_dev *ce = platform_get_drvdata(pdev); @@ -980,9 +1090,6 @@ static int sun8i_ce_remove(struct platform_device *pdev) #endif sun8i_ce_free_chanlist(ce, MAXFLOW - 1); - - sun8i_ce_pm_exit(ce); - return 0; } static const struct of_device_id sun8i_ce_crypto_of_match_table[] = { @@ -990,12 +1097,16 @@ static const struct of_device_id sun8i_ce_crypto_of_match_table[] = { .data = &ce_h3_variant }, { .compatible = "allwinner,sun8i-r40-crypto", .data = &ce_r40_variant }, + { .compatible = "allwinner,sun20i-d1-crypto", + .data = &ce_d1_variant }, { .compatible = "allwinner,sun50i-a64-crypto", .data = &ce_a64_variant }, { .compatible = "allwinner,sun50i-h5-crypto", .data = &ce_h5_variant }, { .compatible = "allwinner,sun50i-h6-crypto", .data = &ce_h6_variant }, + { .compatible = "allwinner,sun50i-h616-crypto", + .data = &ce_h616_variant }, {} }; MODULE_DEVICE_TABLE(of, sun8i_ce_crypto_of_match_table); |
