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 | 171 |
1 files changed, 109 insertions, 62 deletions
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c index 07ea0cc82b16..1c2c32d0568e 100644 --- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c +++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c @@ -9,21 +9,25 @@ * * 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" @@ -277,7 +281,7 @@ 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", @@ -298,13 +302,16 @@ 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", @@ -324,13 +331,16 @@ 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", @@ -351,13 +361,16 @@ 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", @@ -377,12 +390,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, @@ -390,6 +406,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), @@ -404,15 +422,17 @@ static struct sun8i_ce_alg_template ce_algs[] = { .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, @@ -420,6 +440,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), @@ -434,15 +456,16 @@ static struct sun8i_ce_alg_template ce_algs[] = { .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, @@ -450,6 +473,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), @@ -464,15 +489,16 @@ static struct sun8i_ce_alg_template ce_algs[] = { .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, @@ -480,6 +506,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), @@ -494,15 +522,16 @@ static struct sun8i_ce_alg_template ce_algs[] = { .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, @@ -510,6 +539,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), @@ -524,15 +555,16 @@ static struct sun8i_ce_alg_template ce_algs[] = { .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, @@ -540,6 +572,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), @@ -554,11 +588,12 @@ static struct sun8i_ce_alg_template ce_algs[] = { .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 @@ -582,14 +617,18 @@ 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) @@ -597,8 +636,8 @@ static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v) switch (ce_algs[i].type) { case CRYPTO_ALG_TYPE_SKCIPHER: seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", - ce_algs[i].alg.skcipher.base.cra_driver_name, - ce_algs[i].alg.skcipher.base.cra_name, + 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); @@ -621,8 +660,8 @@ static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v) break; case CRYPTO_ALG_TYPE_AHASH: seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n", - ce_algs[i].alg.hash.halg.base.cra_driver_name, - ce_algs[i].alg.hash.halg.base.cra_name, + 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); @@ -643,7 +682,8 @@ static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v) 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 @@ -651,7 +691,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) { @@ -839,7 +878,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; } @@ -847,16 +886,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; } @@ -867,16 +906,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; } @@ -916,13 +955,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, @@ -1007,13 +1046,21 @@ 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 __maybe_unused; + 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: |