drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c

Source file repositories/reference/linux-study-clean/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
Extension
.c
Size
30859 bytes
Lines
1141
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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;
		}
		if (v & CE_ERR_ALGO_NOTSUP)
			dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
		if (v & CE_ERR_DATALEN)
			dev_err(ce->dev, "CE ERROR: data length error\n");
		if (v & CE_ERR_KEYSRAM)
			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;
		}
		if (v & CE_ERR_ALGO_NOTSUP)
			dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
		if (v & CE_ERR_DATALEN)
			dev_err(ce->dev, "CE ERROR: data length error\n");
		if (v & CE_ERR_KEYSRAM)
			dev_err(ce->dev, "CE ERROR: keysram access error for AES\n");
		break;
	case ESR_H6:
		v >>= (flow * 8);
		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;
		}
		if (v & CE_ERR_ALGO_NOTSUP)
			dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
		if (v & CE_ERR_DATALEN)
			dev_err(ce->dev, "CE ERROR: data length error\n");
		if (v & CE_ERR_KEYSRAM)
			dev_err(ce->dev, "CE ERROR: keysram access error for AES\n");
		if (v & CE_ERR_ADDR_INVALID)
			dev_err(ce->dev, "CE ERROR: address invalid\n");
		if (v & CE_ERR_KEYLADDER)
			dev_err(ce->dev, "CE ERROR: key ladder configuration error\n");
		break;
	}

	return err;
}

static irqreturn_t ce_irq_handler(int irq, void *data)
{
	struct sun8i_ce_dev *ce = (struct sun8i_ce_dev *)data;
	int flow = 0;
	u32 p;

	p = readl(ce->base + CE_ISR);
	for (flow = 0; flow < MAXFLOW; flow++) {
		if (p & (BIT(flow))) {
			writel(BIT(flow), ce->base + CE_ISR);
			ce->chanlist[flow].status = 1;
			complete(&ce->chanlist[flow].complete);
		}
	}

	return IRQ_HANDLED;
}

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.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_NEED_FALLBACK,
			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
			.cra_module = THIS_MODULE,
			.cra_alignmask = 0xf,
			.cra_init = sun8i_ce_cipher_init,

Annotation

Implementation Notes