drivers/crypto/marvell/octeontx/otx_cptvf_algs.c

Source file repositories/reference/linux-study-clean/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
Extension
.c
Size
43608 bytes
Lines
1638
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

struct cpt_device_desc {
	enum otx_cptpf_type pf_type;
	struct pci_dev *dev;
	int num_queues;
};

struct cpt_device_table {
	atomic_t count;
	struct cpt_device_desc desc[CPT_MAX_VF_NUM];
};

static struct cpt_device_table se_devices = {
	.count = ATOMIC_INIT(0)
};

static struct cpt_device_table ae_devices = {
	.count = ATOMIC_INIT(0)
};

static struct otx_cpt_sdesc *alloc_sdesc(struct crypto_shash *alg);

static inline int get_se_device(struct pci_dev **pdev, int *cpu_num)
{
	int count, ret = 0;

	count = atomic_read(&se_devices.count);
	if (count < 1)
		return -ENODEV;

	*cpu_num = get_cpu();

	if (se_devices.desc[0].pf_type == OTX_CPT_SE) {
		/*
		 * On OcteonTX platform there is one CPT instruction queue bound
		 * to each VF. We get maximum performance if one CPT queue
		 * is available for each cpu otherwise CPT queues need to be
		 * shared between cpus.
		 */
		if (*cpu_num >= count)
			*cpu_num %= count;
		*pdev = se_devices.desc[*cpu_num].dev;
	} else {
		pr_err("Unknown PF type %d\n", se_devices.desc[0].pf_type);
		ret = -EINVAL;
	}
	put_cpu();

	return ret;
}

static inline int validate_hmac_cipher_null(struct otx_cpt_req_info *cpt_req)
{
	struct otx_cpt_req_ctx *rctx;
	struct aead_request *req;
	struct crypto_aead *tfm;

	req = container_of(cpt_req->areq, struct aead_request, base);
	tfm = crypto_aead_reqtfm(req);
	rctx = aead_request_ctx_dma(req);
	if (memcmp(rctx->fctx.hmac.s.hmac_calc,
		   rctx->fctx.hmac.s.hmac_recv,
		   crypto_aead_authsize(tfm)) != 0)
		return -EBADMSG;

	return 0;
}

static void otx_cpt_aead_callback(int status, void *arg1, void *arg2)
{
	struct otx_cpt_info_buffer *cpt_info = arg2;
	struct crypto_async_request *areq = arg1;
	struct otx_cpt_req_info *cpt_req;
	struct pci_dev *pdev;

	if (!cpt_info)
		goto complete;

	cpt_req = cpt_info->req;
	if (!status) {
		/*
		 * When selected cipher is NULL we need to manually
		 * verify whether calculated hmac value matches
		 * received hmac value
		 */
		if (cpt_req->req_type == OTX_CPT_AEAD_ENC_DEC_NULL_REQ &&
		    !cpt_req->is_enc)
			status = validate_hmac_cipher_null(cpt_req);
	}
	pdev = cpt_info->pdev;
	do_request_cleanup(pdev, cpt_info);

Annotation

Implementation Notes