cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sun8i-ce-core.c (29430B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * sun8i-ce-core.c - hardware cryptographic offloader for
      4 * Allwinner H3/A64/H5/H2+/H6/R40 SoC
      5 *
      6 * Copyright (C) 2015-2019 Corentin Labbe <clabbe.montjoie@gmail.com>
      7 *
      8 * Core file which registers crypto algorithms supported by the CryptoEngine.
      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-ce.h"
     29
     30/*
     31 * mod clock is lower on H3 than other SoC due to some DMA timeout occurring
     32 * with high value.
     33 * If you want to tune mod clock, loading driver and passing selftest is
     34 * insufficient, you need to test with some LUKS test (mount and write to it)
     35 */
     36static const struct ce_variant ce_h3_variant = {
     37	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
     38	},
     39	.alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
     40		CE_ALG_SHA384, CE_ALG_SHA512
     41	},
     42	.op_mode = { CE_OP_ECB, CE_OP_CBC
     43	},
     44	.ce_clks = {
     45		{ "bus", 0, 200000000 },
     46		{ "mod", 50000000, 0 },
     47		},
     48	.esr = ESR_H3,
     49	.prng = CE_ALG_PRNG,
     50	.trng = CE_ID_NOTSUPP,
     51};
     52
     53static const struct ce_variant ce_h5_variant = {
     54	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
     55	},
     56	.alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
     57		CE_ID_NOTSUPP, CE_ID_NOTSUPP
     58	},
     59	.op_mode = { CE_OP_ECB, CE_OP_CBC
     60	},
     61	.ce_clks = {
     62		{ "bus", 0, 200000000 },
     63		{ "mod", 300000000, 0 },
     64		},
     65	.esr = ESR_H5,
     66	.prng = CE_ALG_PRNG,
     67	.trng = CE_ID_NOTSUPP,
     68};
     69
     70static const struct ce_variant ce_h6_variant = {
     71	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
     72	},
     73	.alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
     74		CE_ALG_SHA384, CE_ALG_SHA512
     75	},
     76	.op_mode = { CE_OP_ECB, CE_OP_CBC
     77	},
     78	.cipher_t_dlen_in_bytes = true,
     79	.hash_t_dlen_in_bits = true,
     80	.prng_t_dlen_in_bytes = true,
     81	.trng_t_dlen_in_bytes = true,
     82	.ce_clks = {
     83		{ "bus", 0, 200000000 },
     84		{ "mod", 300000000, 0 },
     85		{ "ram", 0, 400000000 },
     86		},
     87	.esr = ESR_H6,
     88	.prng = CE_ALG_PRNG_V2,
     89	.trng = CE_ALG_TRNG_V2,
     90};
     91
     92static const struct ce_variant ce_a64_variant = {
     93	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
     94	},
     95	.alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
     96		CE_ID_NOTSUPP, CE_ID_NOTSUPP
     97	},
     98	.op_mode = { CE_OP_ECB, CE_OP_CBC
     99	},
    100	.ce_clks = {
    101		{ "bus", 0, 200000000 },
    102		{ "mod", 300000000, 0 },
    103		},
    104	.esr = ESR_A64,
    105	.prng = CE_ALG_PRNG,
    106	.trng = CE_ID_NOTSUPP,
    107};
    108
    109static const struct ce_variant ce_d1_variant = {
    110	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
    111	},
    112	.alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
    113		CE_ALG_SHA384, CE_ALG_SHA512
    114	},
    115	.op_mode = { CE_OP_ECB, CE_OP_CBC
    116	},
    117	.ce_clks = {
    118		{ "bus", 0, 200000000 },
    119		{ "mod", 300000000, 0 },
    120		{ "ram", 0, 400000000 },
    121		},
    122	.esr = ESR_D1,
    123	.prng = CE_ALG_PRNG,
    124	.trng = CE_ALG_TRNG,
    125};
    126
    127static const struct ce_variant ce_r40_variant = {
    128	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
    129	},
    130	.alg_hash = { CE_ALG_MD5, CE_ALG_SHA1, CE_ALG_SHA224, CE_ALG_SHA256,
    131		CE_ID_NOTSUPP, CE_ID_NOTSUPP
    132	},
    133	.op_mode = { CE_OP_ECB, CE_OP_CBC
    134	},
    135	.ce_clks = {
    136		{ "bus", 0, 200000000 },
    137		{ "mod", 300000000, 0 },
    138		},
    139	.esr = ESR_R40,
    140	.prng = CE_ALG_PRNG,
    141	.trng = CE_ID_NOTSUPP,
    142};
    143
    144/*
    145 * sun8i_ce_get_engine_number() get the next channel slot
    146 * This is a simple round-robin way of getting the next channel
    147 * The flow 3 is reserve for xRNG operations
    148 */
    149int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce)
    150{
    151	return atomic_inc_return(&ce->flow) % (MAXFLOW - 1);
    152}
    153
    154int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name)
    155{
    156	u32 v;
    157	int err = 0;
    158	struct ce_task *cet = ce->chanlist[flow].tl;
    159
    160#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
    161	ce->chanlist[flow].stat_req++;
    162#endif
    163
    164	mutex_lock(&ce->mlock);
    165
    166	v = readl(ce->base + CE_ICR);
    167	v |= 1 << flow;
    168	writel(v, ce->base + CE_ICR);
    169
    170	reinit_completion(&ce->chanlist[flow].complete);
    171	writel(ce->chanlist[flow].t_phy, ce->base + CE_TDQ);
    172
    173	ce->chanlist[flow].status = 0;
    174	/* Be sure all data is written before enabling the task */
    175	wmb();
    176
    177	/* Only H6 needs to write a part of t_common_ctl along with "1", but since it is ignored
    178	 * on older SoCs, we have no reason to complicate things.
    179	 */
    180	v = 1 | ((le32_to_cpu(ce->chanlist[flow].tl->t_common_ctl) & 0x7F) << 8);
    181	writel(v, ce->base + CE_TLR);
    182	mutex_unlock(&ce->mlock);
    183
    184	wait_for_completion_interruptible_timeout(&ce->chanlist[flow].complete,
    185			msecs_to_jiffies(ce->chanlist[flow].timeout));
    186
    187	if (ce->chanlist[flow].status == 0) {
    188		dev_err(ce->dev, "DMA timeout for %s (tm=%d) on flow %d\n", name,
    189			ce->chanlist[flow].timeout, flow);
    190		err = -EFAULT;
    191	}
    192	/* No need to lock for this read, the channel is locked so
    193	 * nothing could modify the error value for this channel
    194	 */
    195	v = readl(ce->base + CE_ESR);
    196	switch (ce->variant->esr) {
    197	case ESR_H3:
    198		/* Sadly, the error bit is not per flow */
    199		if (v) {
    200			dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
    201			err = -EFAULT;
    202			print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4,
    203				       cet, sizeof(struct ce_task), false);
    204		}
    205		if (v & CE_ERR_ALGO_NOTSUP)
    206			dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
    207		if (v & CE_ERR_DATALEN)
    208			dev_err(ce->dev, "CE ERROR: data length error\n");
    209		if (v & CE_ERR_KEYSRAM)
    210			dev_err(ce->dev, "CE ERROR: keysram access error for AES\n");
    211		break;
    212	case ESR_A64:
    213	case ESR_D1:
    214	case ESR_H5:
    215	case ESR_R40:
    216		v >>= (flow * 4);
    217		v &= 0xF;
    218		if (v) {
    219			dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
    220			err = -EFAULT;
    221			print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4,
    222				       cet, sizeof(struct ce_task), false);
    223		}
    224		if (v & CE_ERR_ALGO_NOTSUP)
    225			dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
    226		if (v & CE_ERR_DATALEN)
    227			dev_err(ce->dev, "CE ERROR: data length error\n");
    228		if (v & CE_ERR_KEYSRAM)
    229			dev_err(ce->dev, "CE ERROR: keysram access error for AES\n");
    230		break;
    231	case ESR_H6:
    232		v >>= (flow * 8);
    233		v &= 0xFF;
    234		if (v) {
    235			dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
    236			err = -EFAULT;
    237			print_hex_dump(KERN_INFO, "TASK: ", DUMP_PREFIX_NONE, 16, 4,
    238				       cet, sizeof(struct ce_task), false);
    239		}
    240		if (v & CE_ERR_ALGO_NOTSUP)
    241			dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
    242		if (v & CE_ERR_DATALEN)
    243			dev_err(ce->dev, "CE ERROR: data length error\n");
    244		if (v & CE_ERR_KEYSRAM)
    245			dev_err(ce->dev, "CE ERROR: keysram access error for AES\n");
    246		if (v & CE_ERR_ADDR_INVALID)
    247			dev_err(ce->dev, "CE ERROR: address invalid\n");
    248		if (v & CE_ERR_KEYLADDER)
    249			dev_err(ce->dev, "CE ERROR: key ladder configuration error\n");
    250		break;
    251	}
    252
    253	return err;
    254}
    255
    256static irqreturn_t ce_irq_handler(int irq, void *data)
    257{
    258	struct sun8i_ce_dev *ce = (struct sun8i_ce_dev *)data;
    259	int flow = 0;
    260	u32 p;
    261
    262	p = readl(ce->base + CE_ISR);
    263	for (flow = 0; flow < MAXFLOW; flow++) {
    264		if (p & (BIT(flow))) {
    265			writel(BIT(flow), ce->base + CE_ISR);
    266			ce->chanlist[flow].status = 1;
    267			complete(&ce->chanlist[flow].complete);
    268		}
    269	}
    270
    271	return IRQ_HANDLED;
    272}
    273
    274static struct sun8i_ce_alg_template ce_algs[] = {
    275{
    276	.type = CRYPTO_ALG_TYPE_SKCIPHER,
    277	.ce_algo_id = CE_ID_CIPHER_AES,
    278	.ce_blockmode = CE_ID_OP_CBC,
    279	.alg.skcipher = {
    280		.base = {
    281			.cra_name = "cbc(aes)",
    282			.cra_driver_name = "cbc-aes-sun8i-ce",
    283			.cra_priority = 400,
    284			.cra_blocksize = AES_BLOCK_SIZE,
    285			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
    286				CRYPTO_ALG_ASYNC |
    287				CRYPTO_ALG_NEED_FALLBACK,
    288			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
    289			.cra_module = THIS_MODULE,
    290			.cra_alignmask = 0xf,
    291			.cra_init = sun8i_ce_cipher_init,
    292			.cra_exit = sun8i_ce_cipher_exit,
    293		},
    294		.min_keysize	= AES_MIN_KEY_SIZE,
    295		.max_keysize	= AES_MAX_KEY_SIZE,
    296		.ivsize		= AES_BLOCK_SIZE,
    297		.setkey		= sun8i_ce_aes_setkey,
    298		.encrypt	= sun8i_ce_skencrypt,
    299		.decrypt	= sun8i_ce_skdecrypt,
    300	}
    301},
    302{
    303	.type = CRYPTO_ALG_TYPE_SKCIPHER,
    304	.ce_algo_id = CE_ID_CIPHER_AES,
    305	.ce_blockmode = CE_ID_OP_ECB,
    306	.alg.skcipher = {
    307		.base = {
    308			.cra_name = "ecb(aes)",
    309			.cra_driver_name = "ecb-aes-sun8i-ce",
    310			.cra_priority = 400,
    311			.cra_blocksize = AES_BLOCK_SIZE,
    312			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
    313				CRYPTO_ALG_ASYNC |
    314				CRYPTO_ALG_NEED_FALLBACK,
    315			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
    316			.cra_module = THIS_MODULE,
    317			.cra_alignmask = 0xf,
    318			.cra_init = sun8i_ce_cipher_init,
    319			.cra_exit = sun8i_ce_cipher_exit,
    320		},
    321		.min_keysize	= AES_MIN_KEY_SIZE,
    322		.max_keysize	= AES_MAX_KEY_SIZE,
    323		.setkey		= sun8i_ce_aes_setkey,
    324		.encrypt	= sun8i_ce_skencrypt,
    325		.decrypt	= sun8i_ce_skdecrypt,
    326	}
    327},
    328{
    329	.type = CRYPTO_ALG_TYPE_SKCIPHER,
    330	.ce_algo_id = CE_ID_CIPHER_DES3,
    331	.ce_blockmode = CE_ID_OP_CBC,
    332	.alg.skcipher = {
    333		.base = {
    334			.cra_name = "cbc(des3_ede)",
    335			.cra_driver_name = "cbc-des3-sun8i-ce",
    336			.cra_priority = 400,
    337			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
    338			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
    339				CRYPTO_ALG_ASYNC |
    340				CRYPTO_ALG_NEED_FALLBACK,
    341			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
    342			.cra_module = THIS_MODULE,
    343			.cra_alignmask = 0xf,
    344			.cra_init = sun8i_ce_cipher_init,
    345			.cra_exit = sun8i_ce_cipher_exit,
    346		},
    347		.min_keysize	= DES3_EDE_KEY_SIZE,
    348		.max_keysize	= DES3_EDE_KEY_SIZE,
    349		.ivsize		= DES3_EDE_BLOCK_SIZE,
    350		.setkey		= sun8i_ce_des3_setkey,
    351		.encrypt	= sun8i_ce_skencrypt,
    352		.decrypt	= sun8i_ce_skdecrypt,
    353	}
    354},
    355{
    356	.type = CRYPTO_ALG_TYPE_SKCIPHER,
    357	.ce_algo_id = CE_ID_CIPHER_DES3,
    358	.ce_blockmode = CE_ID_OP_ECB,
    359	.alg.skcipher = {
    360		.base = {
    361			.cra_name = "ecb(des3_ede)",
    362			.cra_driver_name = "ecb-des3-sun8i-ce",
    363			.cra_priority = 400,
    364			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
    365			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
    366				CRYPTO_ALG_ASYNC |
    367				CRYPTO_ALG_NEED_FALLBACK,
    368			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
    369			.cra_module = THIS_MODULE,
    370			.cra_alignmask = 0xf,
    371			.cra_init = sun8i_ce_cipher_init,
    372			.cra_exit = sun8i_ce_cipher_exit,
    373		},
    374		.min_keysize	= DES3_EDE_KEY_SIZE,
    375		.max_keysize	= DES3_EDE_KEY_SIZE,
    376		.setkey		= sun8i_ce_des3_setkey,
    377		.encrypt	= sun8i_ce_skencrypt,
    378		.decrypt	= sun8i_ce_skdecrypt,
    379	}
    380},
    381#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_HASH
    382{	.type = CRYPTO_ALG_TYPE_AHASH,
    383	.ce_algo_id = CE_ID_HASH_MD5,
    384	.alg.hash = {
    385		.init = sun8i_ce_hash_init,
    386		.update = sun8i_ce_hash_update,
    387		.final = sun8i_ce_hash_final,
    388		.finup = sun8i_ce_hash_finup,
    389		.digest = sun8i_ce_hash_digest,
    390		.export = sun8i_ce_hash_export,
    391		.import = sun8i_ce_hash_import,
    392		.halg = {
    393			.digestsize = MD5_DIGEST_SIZE,
    394			.statesize = sizeof(struct md5_state),
    395			.base = {
    396				.cra_name = "md5",
    397				.cra_driver_name = "md5-sun8i-ce",
    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 = MD5_HMAC_BLOCK_SIZE,
    404				.cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx),
    405				.cra_module = THIS_MODULE,
    406				.cra_init = sun8i_ce_hash_crainit,
    407				.cra_exit = sun8i_ce_hash_craexit,
    408			}
    409		}
    410	}
    411},
    412{	.type = CRYPTO_ALG_TYPE_AHASH,
    413	.ce_algo_id = CE_ID_HASH_SHA1,
    414	.alg.hash = {
    415		.init = sun8i_ce_hash_init,
    416		.update = sun8i_ce_hash_update,
    417		.final = sun8i_ce_hash_final,
    418		.finup = sun8i_ce_hash_finup,
    419		.digest = sun8i_ce_hash_digest,
    420		.export = sun8i_ce_hash_export,
    421		.import = sun8i_ce_hash_import,
    422		.halg = {
    423			.digestsize = SHA1_DIGEST_SIZE,
    424			.statesize = sizeof(struct sha1_state),
    425			.base = {
    426				.cra_name = "sha1",
    427				.cra_driver_name = "sha1-sun8i-ce",
    428				.cra_priority = 300,
    429				.cra_alignmask = 3,
    430				.cra_flags = CRYPTO_ALG_TYPE_AHASH |
    431					CRYPTO_ALG_ASYNC |
    432					CRYPTO_ALG_NEED_FALLBACK,
    433				.cra_blocksize = SHA1_BLOCK_SIZE,
    434				.cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx),
    435				.cra_module = THIS_MODULE,
    436				.cra_init = sun8i_ce_hash_crainit,
    437				.cra_exit = sun8i_ce_hash_craexit,
    438			}
    439		}
    440	}
    441},
    442{	.type = CRYPTO_ALG_TYPE_AHASH,
    443	.ce_algo_id = CE_ID_HASH_SHA224,
    444	.alg.hash = {
    445		.init = sun8i_ce_hash_init,
    446		.update = sun8i_ce_hash_update,
    447		.final = sun8i_ce_hash_final,
    448		.finup = sun8i_ce_hash_finup,
    449		.digest = sun8i_ce_hash_digest,
    450		.export = sun8i_ce_hash_export,
    451		.import = sun8i_ce_hash_import,
    452		.halg = {
    453			.digestsize = SHA224_DIGEST_SIZE,
    454			.statesize = sizeof(struct sha256_state),
    455			.base = {
    456				.cra_name = "sha224",
    457				.cra_driver_name = "sha224-sun8i-ce",
    458				.cra_priority = 300,
    459				.cra_alignmask = 3,
    460				.cra_flags = CRYPTO_ALG_TYPE_AHASH |
    461					CRYPTO_ALG_ASYNC |
    462					CRYPTO_ALG_NEED_FALLBACK,
    463				.cra_blocksize = SHA224_BLOCK_SIZE,
    464				.cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx),
    465				.cra_module = THIS_MODULE,
    466				.cra_init = sun8i_ce_hash_crainit,
    467				.cra_exit = sun8i_ce_hash_craexit,
    468			}
    469		}
    470	}
    471},
    472{	.type = CRYPTO_ALG_TYPE_AHASH,
    473	.ce_algo_id = CE_ID_HASH_SHA256,
    474	.alg.hash = {
    475		.init = sun8i_ce_hash_init,
    476		.update = sun8i_ce_hash_update,
    477		.final = sun8i_ce_hash_final,
    478		.finup = sun8i_ce_hash_finup,
    479		.digest = sun8i_ce_hash_digest,
    480		.export = sun8i_ce_hash_export,
    481		.import = sun8i_ce_hash_import,
    482		.halg = {
    483			.digestsize = SHA256_DIGEST_SIZE,
    484			.statesize = sizeof(struct sha256_state),
    485			.base = {
    486				.cra_name = "sha256",
    487				.cra_driver_name = "sha256-sun8i-ce",
    488				.cra_priority = 300,
    489				.cra_alignmask = 3,
    490				.cra_flags = CRYPTO_ALG_TYPE_AHASH |
    491					CRYPTO_ALG_ASYNC |
    492					CRYPTO_ALG_NEED_FALLBACK,
    493				.cra_blocksize = SHA256_BLOCK_SIZE,
    494				.cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx),
    495				.cra_module = THIS_MODULE,
    496				.cra_init = sun8i_ce_hash_crainit,
    497				.cra_exit = sun8i_ce_hash_craexit,
    498			}
    499		}
    500	}
    501},
    502{	.type = CRYPTO_ALG_TYPE_AHASH,
    503	.ce_algo_id = CE_ID_HASH_SHA384,
    504	.alg.hash = {
    505		.init = sun8i_ce_hash_init,
    506		.update = sun8i_ce_hash_update,
    507		.final = sun8i_ce_hash_final,
    508		.finup = sun8i_ce_hash_finup,
    509		.digest = sun8i_ce_hash_digest,
    510		.export = sun8i_ce_hash_export,
    511		.import = sun8i_ce_hash_import,
    512		.halg = {
    513			.digestsize = SHA384_DIGEST_SIZE,
    514			.statesize = sizeof(struct sha512_state),
    515			.base = {
    516				.cra_name = "sha384",
    517				.cra_driver_name = "sha384-sun8i-ce",
    518				.cra_priority = 300,
    519				.cra_alignmask = 3,
    520				.cra_flags = CRYPTO_ALG_TYPE_AHASH |
    521					CRYPTO_ALG_ASYNC |
    522					CRYPTO_ALG_NEED_FALLBACK,
    523				.cra_blocksize = SHA384_BLOCK_SIZE,
    524				.cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx),
    525				.cra_module = THIS_MODULE,
    526				.cra_init = sun8i_ce_hash_crainit,
    527				.cra_exit = sun8i_ce_hash_craexit,
    528			}
    529		}
    530	}
    531},
    532{	.type = CRYPTO_ALG_TYPE_AHASH,
    533	.ce_algo_id = CE_ID_HASH_SHA512,
    534	.alg.hash = {
    535		.init = sun8i_ce_hash_init,
    536		.update = sun8i_ce_hash_update,
    537		.final = sun8i_ce_hash_final,
    538		.finup = sun8i_ce_hash_finup,
    539		.digest = sun8i_ce_hash_digest,
    540		.export = sun8i_ce_hash_export,
    541		.import = sun8i_ce_hash_import,
    542		.halg = {
    543			.digestsize = SHA512_DIGEST_SIZE,
    544			.statesize = sizeof(struct sha512_state),
    545			.base = {
    546				.cra_name = "sha512",
    547				.cra_driver_name = "sha512-sun8i-ce",
    548				.cra_priority = 300,
    549				.cra_alignmask = 3,
    550				.cra_flags = CRYPTO_ALG_TYPE_AHASH |
    551					CRYPTO_ALG_ASYNC |
    552					CRYPTO_ALG_NEED_FALLBACK,
    553				.cra_blocksize = SHA512_BLOCK_SIZE,
    554				.cra_ctxsize = sizeof(struct sun8i_ce_hash_tfm_ctx),
    555				.cra_module = THIS_MODULE,
    556				.cra_init = sun8i_ce_hash_crainit,
    557				.cra_exit = sun8i_ce_hash_craexit,
    558			}
    559		}
    560	}
    561},
    562#endif
    563#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG
    564{
    565	.type = CRYPTO_ALG_TYPE_RNG,
    566	.alg.rng = {
    567		.base = {
    568			.cra_name		= "stdrng",
    569			.cra_driver_name	= "sun8i-ce-prng",
    570			.cra_priority		= 300,
    571			.cra_ctxsize		= sizeof(struct sun8i_ce_rng_tfm_ctx),
    572			.cra_module		= THIS_MODULE,
    573			.cra_init		= sun8i_ce_prng_init,
    574			.cra_exit		= sun8i_ce_prng_exit,
    575		},
    576		.generate               = sun8i_ce_prng_generate,
    577		.seed                   = sun8i_ce_prng_seed,
    578		.seedsize               = PRNG_SEED_SIZE,
    579	}
    580},
    581#endif
    582};
    583
    584#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
    585static int sun8i_ce_debugfs_show(struct seq_file *seq, void *v)
    586{
    587	struct sun8i_ce_dev *ce = seq->private;
    588	unsigned int i;
    589
    590	for (i = 0; i < MAXFLOW; i++)
    591		seq_printf(seq, "Channel %d: nreq %lu\n", i, ce->chanlist[i].stat_req);
    592
    593	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
    594		if (!ce_algs[i].ce)
    595			continue;
    596		switch (ce_algs[i].type) {
    597		case CRYPTO_ALG_TYPE_SKCIPHER:
    598			seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n",
    599				   ce_algs[i].alg.skcipher.base.cra_driver_name,
    600				   ce_algs[i].alg.skcipher.base.cra_name,
    601				   ce_algs[i].stat_req, ce_algs[i].stat_fb);
    602			seq_printf(seq, "\tLast fallback is: %s\n",
    603				   ce_algs[i].fbname);
    604			seq_printf(seq, "\tFallback due to 0 length: %lu\n",
    605				   ce_algs[i].stat_fb_len0);
    606			seq_printf(seq, "\tFallback due to length !mod16: %lu\n",
    607				   ce_algs[i].stat_fb_mod16);
    608			seq_printf(seq, "\tFallback due to length < IV: %lu\n",
    609				   ce_algs[i].stat_fb_leniv);
    610			seq_printf(seq, "\tFallback due to source alignment: %lu\n",
    611				   ce_algs[i].stat_fb_srcali);
    612			seq_printf(seq, "\tFallback due to dest alignment: %lu\n",
    613				   ce_algs[i].stat_fb_dstali);
    614			seq_printf(seq, "\tFallback due to source length: %lu\n",
    615				   ce_algs[i].stat_fb_srclen);
    616			seq_printf(seq, "\tFallback due to dest length: %lu\n",
    617				   ce_algs[i].stat_fb_dstlen);
    618			seq_printf(seq, "\tFallback due to SG numbers: %lu\n",
    619				   ce_algs[i].stat_fb_maxsg);
    620			break;
    621		case CRYPTO_ALG_TYPE_AHASH:
    622			seq_printf(seq, "%s %s reqs=%lu fallback=%lu\n",
    623				   ce_algs[i].alg.hash.halg.base.cra_driver_name,
    624				   ce_algs[i].alg.hash.halg.base.cra_name,
    625				   ce_algs[i].stat_req, ce_algs[i].stat_fb);
    626			seq_printf(seq, "\tLast fallback is: %s\n",
    627				   ce_algs[i].fbname);
    628			seq_printf(seq, "\tFallback due to 0 length: %lu\n",
    629				   ce_algs[i].stat_fb_len0);
    630			seq_printf(seq, "\tFallback due to length: %lu\n",
    631				   ce_algs[i].stat_fb_srclen);
    632			seq_printf(seq, "\tFallback due to alignment: %lu\n",
    633				   ce_algs[i].stat_fb_srcali);
    634			seq_printf(seq, "\tFallback due to SG numbers: %lu\n",
    635				   ce_algs[i].stat_fb_maxsg);
    636			break;
    637		case CRYPTO_ALG_TYPE_RNG:
    638			seq_printf(seq, "%s %s reqs=%lu bytes=%lu\n",
    639				   ce_algs[i].alg.rng.base.cra_driver_name,
    640				   ce_algs[i].alg.rng.base.cra_name,
    641				   ce_algs[i].stat_req, ce_algs[i].stat_bytes);
    642			break;
    643		}
    644	}
    645#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG
    646	seq_printf(seq, "HWRNG %lu %lu\n",
    647		   ce->hwrng_stat_req, ce->hwrng_stat_bytes);
    648#endif
    649	return 0;
    650}
    651
    652DEFINE_SHOW_ATTRIBUTE(sun8i_ce_debugfs);
    653#endif
    654
    655static void sun8i_ce_free_chanlist(struct sun8i_ce_dev *ce, int i)
    656{
    657	while (i >= 0) {
    658		crypto_engine_exit(ce->chanlist[i].engine);
    659		if (ce->chanlist[i].tl)
    660			dma_free_coherent(ce->dev, sizeof(struct ce_task),
    661					  ce->chanlist[i].tl,
    662					  ce->chanlist[i].t_phy);
    663		i--;
    664	}
    665}
    666
    667/*
    668 * Allocate the channel list structure
    669 */
    670static int sun8i_ce_allocate_chanlist(struct sun8i_ce_dev *ce)
    671{
    672	int i, err;
    673
    674	ce->chanlist = devm_kcalloc(ce->dev, MAXFLOW,
    675				    sizeof(struct sun8i_ce_flow), GFP_KERNEL);
    676	if (!ce->chanlist)
    677		return -ENOMEM;
    678
    679	for (i = 0; i < MAXFLOW; i++) {
    680		init_completion(&ce->chanlist[i].complete);
    681
    682		ce->chanlist[i].engine = crypto_engine_alloc_init(ce->dev, true);
    683		if (!ce->chanlist[i].engine) {
    684			dev_err(ce->dev, "Cannot allocate engine\n");
    685			i--;
    686			err = -ENOMEM;
    687			goto error_engine;
    688		}
    689		err = crypto_engine_start(ce->chanlist[i].engine);
    690		if (err) {
    691			dev_err(ce->dev, "Cannot start engine\n");
    692			goto error_engine;
    693		}
    694		ce->chanlist[i].tl = dma_alloc_coherent(ce->dev,
    695							sizeof(struct ce_task),
    696							&ce->chanlist[i].t_phy,
    697							GFP_KERNEL);
    698		if (!ce->chanlist[i].tl) {
    699			dev_err(ce->dev, "Cannot get DMA memory for task %d\n",
    700				i);
    701			err = -ENOMEM;
    702			goto error_engine;
    703		}
    704		ce->chanlist[i].bounce_iv = devm_kmalloc(ce->dev, AES_BLOCK_SIZE,
    705							 GFP_KERNEL | GFP_DMA);
    706		if (!ce->chanlist[i].bounce_iv) {
    707			err = -ENOMEM;
    708			goto error_engine;
    709		}
    710		ce->chanlist[i].backup_iv = devm_kmalloc(ce->dev, AES_BLOCK_SIZE,
    711							 GFP_KERNEL);
    712		if (!ce->chanlist[i].backup_iv) {
    713			err = -ENOMEM;
    714			goto error_engine;
    715		}
    716	}
    717	return 0;
    718error_engine:
    719	sun8i_ce_free_chanlist(ce, i);
    720	return err;
    721}
    722
    723/*
    724 * Power management strategy: The device is suspended unless a TFM exists for
    725 * one of the algorithms proposed by this driver.
    726 */
    727static int sun8i_ce_pm_suspend(struct device *dev)
    728{
    729	struct sun8i_ce_dev *ce = dev_get_drvdata(dev);
    730	int i;
    731
    732	reset_control_assert(ce->reset);
    733	for (i = 0; i < CE_MAX_CLOCKS; i++)
    734		clk_disable_unprepare(ce->ceclks[i]);
    735	return 0;
    736}
    737
    738static int sun8i_ce_pm_resume(struct device *dev)
    739{
    740	struct sun8i_ce_dev *ce = dev_get_drvdata(dev);
    741	int err, i;
    742
    743	for (i = 0; i < CE_MAX_CLOCKS; i++) {
    744		if (!ce->variant->ce_clks[i].name)
    745			continue;
    746		err = clk_prepare_enable(ce->ceclks[i]);
    747		if (err) {
    748			dev_err(ce->dev, "Cannot prepare_enable %s\n",
    749				ce->variant->ce_clks[i].name);
    750			goto error;
    751		}
    752	}
    753	err = reset_control_deassert(ce->reset);
    754	if (err) {
    755		dev_err(ce->dev, "Cannot deassert reset control\n");
    756		goto error;
    757	}
    758	return 0;
    759error:
    760	sun8i_ce_pm_suspend(dev);
    761	return err;
    762}
    763
    764static const struct dev_pm_ops sun8i_ce_pm_ops = {
    765	SET_RUNTIME_PM_OPS(sun8i_ce_pm_suspend, sun8i_ce_pm_resume, NULL)
    766};
    767
    768static int sun8i_ce_pm_init(struct sun8i_ce_dev *ce)
    769{
    770	int err;
    771
    772	pm_runtime_use_autosuspend(ce->dev);
    773	pm_runtime_set_autosuspend_delay(ce->dev, 2000);
    774
    775	err = pm_runtime_set_suspended(ce->dev);
    776	if (err)
    777		return err;
    778	pm_runtime_enable(ce->dev);
    779	return err;
    780}
    781
    782static void sun8i_ce_pm_exit(struct sun8i_ce_dev *ce)
    783{
    784	pm_runtime_disable(ce->dev);
    785}
    786
    787static int sun8i_ce_get_clks(struct sun8i_ce_dev *ce)
    788{
    789	unsigned long cr;
    790	int err, i;
    791
    792	for (i = 0; i < CE_MAX_CLOCKS; i++) {
    793		if (!ce->variant->ce_clks[i].name)
    794			continue;
    795		ce->ceclks[i] = devm_clk_get(ce->dev, ce->variant->ce_clks[i].name);
    796		if (IS_ERR(ce->ceclks[i])) {
    797			err = PTR_ERR(ce->ceclks[i]);
    798			dev_err(ce->dev, "Cannot get %s CE clock err=%d\n",
    799				ce->variant->ce_clks[i].name, err);
    800			return err;
    801		}
    802		cr = clk_get_rate(ce->ceclks[i]);
    803		if (!cr)
    804			return -EINVAL;
    805		if (ce->variant->ce_clks[i].freq > 0 &&
    806		    cr != ce->variant->ce_clks[i].freq) {
    807			dev_info(ce->dev, "Set %s clock to %lu (%lu Mhz) from %lu (%lu Mhz)\n",
    808				 ce->variant->ce_clks[i].name,
    809				 ce->variant->ce_clks[i].freq,
    810				 ce->variant->ce_clks[i].freq / 1000000,
    811				 cr, cr / 1000000);
    812			err = clk_set_rate(ce->ceclks[i], ce->variant->ce_clks[i].freq);
    813			if (err)
    814				dev_err(ce->dev, "Fail to set %s clk speed to %lu hz\n",
    815					ce->variant->ce_clks[i].name,
    816					ce->variant->ce_clks[i].freq);
    817		}
    818		if (ce->variant->ce_clks[i].max_freq > 0 &&
    819		    cr > ce->variant->ce_clks[i].max_freq)
    820			dev_warn(ce->dev, "Frequency for %s (%lu hz) is higher than datasheet's recommendation (%lu hz)",
    821				 ce->variant->ce_clks[i].name, cr,
    822				 ce->variant->ce_clks[i].max_freq);
    823	}
    824	return 0;
    825}
    826
    827static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce)
    828{
    829	int ce_method, err, id;
    830	unsigned int i;
    831
    832	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
    833		ce_algs[i].ce = ce;
    834		switch (ce_algs[i].type) {
    835		case CRYPTO_ALG_TYPE_SKCIPHER:
    836			id = ce_algs[i].ce_algo_id;
    837			ce_method = ce->variant->alg_cipher[id];
    838			if (ce_method == CE_ID_NOTSUPP) {
    839				dev_dbg(ce->dev,
    840					"DEBUG: Algo of %s not supported\n",
    841					ce_algs[i].alg.skcipher.base.cra_name);
    842				ce_algs[i].ce = NULL;
    843				break;
    844			}
    845			id = ce_algs[i].ce_blockmode;
    846			ce_method = ce->variant->op_mode[id];
    847			if (ce_method == CE_ID_NOTSUPP) {
    848				dev_dbg(ce->dev, "DEBUG: Blockmode of %s not supported\n",
    849					ce_algs[i].alg.skcipher.base.cra_name);
    850				ce_algs[i].ce = NULL;
    851				break;
    852			}
    853			dev_info(ce->dev, "Register %s\n",
    854				 ce_algs[i].alg.skcipher.base.cra_name);
    855			err = crypto_register_skcipher(&ce_algs[i].alg.skcipher);
    856			if (err) {
    857				dev_err(ce->dev, "ERROR: Fail to register %s\n",
    858					ce_algs[i].alg.skcipher.base.cra_name);
    859				ce_algs[i].ce = NULL;
    860				return err;
    861			}
    862			break;
    863		case CRYPTO_ALG_TYPE_AHASH:
    864			id = ce_algs[i].ce_algo_id;
    865			ce_method = ce->variant->alg_hash[id];
    866			if (ce_method == CE_ID_NOTSUPP) {
    867				dev_info(ce->dev,
    868					 "DEBUG: Algo of %s not supported\n",
    869					 ce_algs[i].alg.hash.halg.base.cra_name);
    870				ce_algs[i].ce = NULL;
    871				break;
    872			}
    873			dev_info(ce->dev, "Register %s\n",
    874				 ce_algs[i].alg.hash.halg.base.cra_name);
    875			err = crypto_register_ahash(&ce_algs[i].alg.hash);
    876			if (err) {
    877				dev_err(ce->dev, "ERROR: Fail to register %s\n",
    878					ce_algs[i].alg.hash.halg.base.cra_name);
    879				ce_algs[i].ce = NULL;
    880				return err;
    881			}
    882			break;
    883		case CRYPTO_ALG_TYPE_RNG:
    884			if (ce->variant->prng == CE_ID_NOTSUPP) {
    885				dev_info(ce->dev,
    886					 "DEBUG: Algo of %s not supported\n",
    887					 ce_algs[i].alg.rng.base.cra_name);
    888				ce_algs[i].ce = NULL;
    889				break;
    890			}
    891			dev_info(ce->dev, "Register %s\n",
    892				 ce_algs[i].alg.rng.base.cra_name);
    893			err = crypto_register_rng(&ce_algs[i].alg.rng);
    894			if (err) {
    895				dev_err(ce->dev, "Fail to register %s\n",
    896					ce_algs[i].alg.rng.base.cra_name);
    897				ce_algs[i].ce = NULL;
    898			}
    899			break;
    900		default:
    901			ce_algs[i].ce = NULL;
    902			dev_err(ce->dev, "ERROR: tried to register an unknown algo\n");
    903		}
    904	}
    905	return 0;
    906}
    907
    908static void sun8i_ce_unregister_algs(struct sun8i_ce_dev *ce)
    909{
    910	unsigned int i;
    911
    912	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
    913		if (!ce_algs[i].ce)
    914			continue;
    915		switch (ce_algs[i].type) {
    916		case CRYPTO_ALG_TYPE_SKCIPHER:
    917			dev_info(ce->dev, "Unregister %d %s\n", i,
    918				 ce_algs[i].alg.skcipher.base.cra_name);
    919			crypto_unregister_skcipher(&ce_algs[i].alg.skcipher);
    920			break;
    921		case CRYPTO_ALG_TYPE_AHASH:
    922			dev_info(ce->dev, "Unregister %d %s\n", i,
    923				 ce_algs[i].alg.hash.halg.base.cra_name);
    924			crypto_unregister_ahash(&ce_algs[i].alg.hash);
    925			break;
    926		case CRYPTO_ALG_TYPE_RNG:
    927			dev_info(ce->dev, "Unregister %d %s\n", i,
    928				 ce_algs[i].alg.rng.base.cra_name);
    929			crypto_unregister_rng(&ce_algs[i].alg.rng);
    930			break;
    931		}
    932	}
    933}
    934
    935static int sun8i_ce_probe(struct platform_device *pdev)
    936{
    937	struct sun8i_ce_dev *ce;
    938	int err, irq;
    939	u32 v;
    940
    941	ce = devm_kzalloc(&pdev->dev, sizeof(*ce), GFP_KERNEL);
    942	if (!ce)
    943		return -ENOMEM;
    944
    945	ce->dev = &pdev->dev;
    946	platform_set_drvdata(pdev, ce);
    947
    948	ce->variant = of_device_get_match_data(&pdev->dev);
    949	if (!ce->variant) {
    950		dev_err(&pdev->dev, "Missing Crypto Engine variant\n");
    951		return -EINVAL;
    952	}
    953
    954	ce->base = devm_platform_ioremap_resource(pdev, 0);
    955	if (IS_ERR(ce->base))
    956		return PTR_ERR(ce->base);
    957
    958	err = sun8i_ce_get_clks(ce);
    959	if (err)
    960		return err;
    961
    962	/* Get Non Secure IRQ */
    963	irq = platform_get_irq(pdev, 0);
    964	if (irq < 0)
    965		return irq;
    966
    967	ce->reset = devm_reset_control_get(&pdev->dev, NULL);
    968	if (IS_ERR(ce->reset))
    969		return dev_err_probe(&pdev->dev, PTR_ERR(ce->reset),
    970				     "No reset control found\n");
    971
    972	mutex_init(&ce->mlock);
    973	mutex_init(&ce->rnglock);
    974
    975	err = sun8i_ce_allocate_chanlist(ce);
    976	if (err)
    977		return err;
    978
    979	err = sun8i_ce_pm_init(ce);
    980	if (err)
    981		goto error_pm;
    982
    983	err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0,
    984			       "sun8i-ce-ns", ce);
    985	if (err) {
    986		dev_err(ce->dev, "Cannot request CryptoEngine Non-secure IRQ (err=%d)\n", err);
    987		goto error_irq;
    988	}
    989
    990	err = sun8i_ce_register_algs(ce);
    991	if (err)
    992		goto error_alg;
    993
    994	err = pm_runtime_resume_and_get(ce->dev);
    995	if (err < 0)
    996		goto error_alg;
    997
    998#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG
    999	sun8i_ce_hwrng_register(ce);
   1000#endif
   1001
   1002	v = readl(ce->base + CE_CTR);
   1003	v >>= CE_DIE_ID_SHIFT;
   1004	v &= CE_DIE_ID_MASK;
   1005	dev_info(&pdev->dev, "CryptoEngine Die ID %x\n", v);
   1006
   1007	pm_runtime_put_sync(ce->dev);
   1008
   1009#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
   1010	/* Ignore error of debugfs */
   1011	ce->dbgfs_dir = debugfs_create_dir("sun8i-ce", NULL);
   1012	ce->dbgfs_stats = debugfs_create_file("stats", 0444,
   1013					      ce->dbgfs_dir, ce,
   1014					      &sun8i_ce_debugfs_fops);
   1015#endif
   1016
   1017	return 0;
   1018error_alg:
   1019	sun8i_ce_unregister_algs(ce);
   1020error_irq:
   1021	sun8i_ce_pm_exit(ce);
   1022error_pm:
   1023	sun8i_ce_free_chanlist(ce, MAXFLOW - 1);
   1024	return err;
   1025}
   1026
   1027static int sun8i_ce_remove(struct platform_device *pdev)
   1028{
   1029	struct sun8i_ce_dev *ce = platform_get_drvdata(pdev);
   1030
   1031#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG
   1032	sun8i_ce_hwrng_unregister(ce);
   1033#endif
   1034
   1035	sun8i_ce_unregister_algs(ce);
   1036
   1037#ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
   1038	debugfs_remove_recursive(ce->dbgfs_dir);
   1039#endif
   1040
   1041	sun8i_ce_free_chanlist(ce, MAXFLOW - 1);
   1042
   1043	sun8i_ce_pm_exit(ce);
   1044	return 0;
   1045}
   1046
   1047static const struct of_device_id sun8i_ce_crypto_of_match_table[] = {
   1048	{ .compatible = "allwinner,sun8i-h3-crypto",
   1049	  .data = &ce_h3_variant },
   1050	{ .compatible = "allwinner,sun8i-r40-crypto",
   1051	  .data = &ce_r40_variant },
   1052	{ .compatible = "allwinner,sun20i-d1-crypto",
   1053	  .data = &ce_d1_variant },
   1054	{ .compatible = "allwinner,sun50i-a64-crypto",
   1055	  .data = &ce_a64_variant },
   1056	{ .compatible = "allwinner,sun50i-h5-crypto",
   1057	  .data = &ce_h5_variant },
   1058	{ .compatible = "allwinner,sun50i-h6-crypto",
   1059	  .data = &ce_h6_variant },
   1060	{}
   1061};
   1062MODULE_DEVICE_TABLE(of, sun8i_ce_crypto_of_match_table);
   1063
   1064static struct platform_driver sun8i_ce_driver = {
   1065	.probe		 = sun8i_ce_probe,
   1066	.remove		 = sun8i_ce_remove,
   1067	.driver		 = {
   1068		.name		= "sun8i-ce",
   1069		.pm		= &sun8i_ce_pm_ops,
   1070		.of_match_table	= sun8i_ce_crypto_of_match_table,
   1071	},
   1072};
   1073
   1074module_platform_driver(sun8i_ce_driver);
   1075
   1076MODULE_DESCRIPTION("Allwinner Crypto Engine cryptographic offloader");
   1077MODULE_LICENSE("GPL");
   1078MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>");