xref: /openbmc/linux/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c (revision 87832e937c808a7ebc41254b408362e3255c87c9)
119d8e8c7SSrujana Challa // SPDX-License-Identifier: GPL-2.0-only
219d8e8c7SSrujana Challa /* Copyright (C) 2020 Marvell. */
319d8e8c7SSrujana Challa 
419d8e8c7SSrujana Challa #include "otx2_cpt_common.h"
519d8e8c7SSrujana Challa #include "otx2_cptvf.h"
68ec8015aSSrujana Challa #include "otx2_cptlf.h"
76f03f0e8SSrujana Challa #include "otx2_cptvf_algs.h"
8eb33cd91SSrujana Challa #include "cn10k_cpt.h"
919d8e8c7SSrujana Challa #include <rvu_reg.h>
1019d8e8c7SSrujana Challa 
114cd8c315SSrujana Challa #define OTX2_CPTVF_DRV_NAME "rvu_cptvf"
1219d8e8c7SSrujana Challa 
cptvf_enable_pfvf_mbox_intrs(struct otx2_cptvf_dev * cptvf)1319d8e8c7SSrujana Challa static void cptvf_enable_pfvf_mbox_intrs(struct otx2_cptvf_dev *cptvf)
1419d8e8c7SSrujana Challa {
1519d8e8c7SSrujana Challa 	/* Clear interrupt if any */
1619d8e8c7SSrujana Challa 	otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0, OTX2_RVU_VF_INT,
1719d8e8c7SSrujana Challa 			 0x1ULL);
1819d8e8c7SSrujana Challa 
1919d8e8c7SSrujana Challa 	/* Enable PF-VF interrupt */
2019d8e8c7SSrujana Challa 	otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0,
2119d8e8c7SSrujana Challa 			 OTX2_RVU_VF_INT_ENA_W1S, 0x1ULL);
2219d8e8c7SSrujana Challa }
2319d8e8c7SSrujana Challa 
cptvf_disable_pfvf_mbox_intrs(struct otx2_cptvf_dev * cptvf)2419d8e8c7SSrujana Challa static void cptvf_disable_pfvf_mbox_intrs(struct otx2_cptvf_dev *cptvf)
2519d8e8c7SSrujana Challa {
2619d8e8c7SSrujana Challa 	/* Disable PF-VF interrupt */
2719d8e8c7SSrujana Challa 	otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0,
2819d8e8c7SSrujana Challa 			 OTX2_RVU_VF_INT_ENA_W1C, 0x1ULL);
2919d8e8c7SSrujana Challa 
3019d8e8c7SSrujana Challa 	/* Clear interrupt if any */
3119d8e8c7SSrujana Challa 	otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0, OTX2_RVU_VF_INT,
3219d8e8c7SSrujana Challa 			 0x1ULL);
3319d8e8c7SSrujana Challa }
3419d8e8c7SSrujana Challa 
cptvf_register_interrupts(struct otx2_cptvf_dev * cptvf)3519d8e8c7SSrujana Challa static int cptvf_register_interrupts(struct otx2_cptvf_dev *cptvf)
3619d8e8c7SSrujana Challa {
3719d8e8c7SSrujana Challa 	int ret, irq;
38b33fa5ffSDan Carpenter 	int num_vec;
3919d8e8c7SSrujana Challa 
4019d8e8c7SSrujana Challa 	num_vec = pci_msix_vec_count(cptvf->pdev);
4119d8e8c7SSrujana Challa 	if (num_vec <= 0)
4219d8e8c7SSrujana Challa 		return -EINVAL;
4319d8e8c7SSrujana Challa 
4419d8e8c7SSrujana Challa 	/* Enable MSI-X */
4519d8e8c7SSrujana Challa 	ret = pci_alloc_irq_vectors(cptvf->pdev, num_vec, num_vec,
4619d8e8c7SSrujana Challa 				    PCI_IRQ_MSIX);
4719d8e8c7SSrujana Challa 	if (ret < 0) {
4819d8e8c7SSrujana Challa 		dev_err(&cptvf->pdev->dev,
4919d8e8c7SSrujana Challa 			"Request for %d msix vectors failed\n", num_vec);
5019d8e8c7SSrujana Challa 		return ret;
5119d8e8c7SSrujana Challa 	}
5219d8e8c7SSrujana Challa 	irq = pci_irq_vector(cptvf->pdev, OTX2_CPT_VF_INT_VEC_E_MBOX);
5319d8e8c7SSrujana Challa 	/* Register VF<=>PF mailbox interrupt handler */
5419d8e8c7SSrujana Challa 	ret = devm_request_irq(&cptvf->pdev->dev, irq,
5519d8e8c7SSrujana Challa 			       otx2_cptvf_pfvf_mbox_intr, 0,
5619d8e8c7SSrujana Challa 			       "CPTPFVF Mbox", cptvf);
5719d8e8c7SSrujana Challa 	if (ret)
5819d8e8c7SSrujana Challa 		return ret;
5919d8e8c7SSrujana Challa 	/* Enable PF-VF mailbox interrupts */
6019d8e8c7SSrujana Challa 	cptvf_enable_pfvf_mbox_intrs(cptvf);
6119d8e8c7SSrujana Challa 
6219d8e8c7SSrujana Challa 	ret = otx2_cpt_send_ready_msg(&cptvf->pfvf_mbox, cptvf->pdev);
6319d8e8c7SSrujana Challa 	if (ret) {
6419d8e8c7SSrujana Challa 		dev_warn(&cptvf->pdev->dev,
6519d8e8c7SSrujana Challa 			 "PF not responding to mailbox, deferring probe\n");
6619d8e8c7SSrujana Challa 		cptvf_disable_pfvf_mbox_intrs(cptvf);
6719d8e8c7SSrujana Challa 		return -EPROBE_DEFER;
6819d8e8c7SSrujana Challa 	}
6919d8e8c7SSrujana Challa 	return 0;
7019d8e8c7SSrujana Challa }
7119d8e8c7SSrujana Challa 
cptvf_pfvf_mbox_init(struct otx2_cptvf_dev * cptvf)7219d8e8c7SSrujana Challa static int cptvf_pfvf_mbox_init(struct otx2_cptvf_dev *cptvf)
7319d8e8c7SSrujana Challa {
744cd8c315SSrujana Challa 	struct pci_dev *pdev = cptvf->pdev;
754cd8c315SSrujana Challa 	resource_size_t offset, size;
7619d8e8c7SSrujana Challa 	int ret;
7719d8e8c7SSrujana Challa 
788ae5c4d1STejun Heo 	cptvf->pfvf_mbox_wq =
798ae5c4d1STejun Heo 		alloc_ordered_workqueue("cpt_pfvf_mailbox",
808ae5c4d1STejun Heo 					WQ_HIGHPRI | WQ_MEM_RECLAIM);
8119d8e8c7SSrujana Challa 	if (!cptvf->pfvf_mbox_wq)
8219d8e8c7SSrujana Challa 		return -ENOMEM;
8319d8e8c7SSrujana Challa 
844cd8c315SSrujana Challa 	if (test_bit(CN10K_MBOX, &cptvf->cap_flag)) {
854cd8c315SSrujana Challa 		/* For cn10k platform, VF mailbox region is in its BAR2
864cd8c315SSrujana Challa 		 * register space
874cd8c315SSrujana Challa 		 */
884cd8c315SSrujana Challa 		cptvf->pfvf_mbox_base = cptvf->reg_base +
894cd8c315SSrujana Challa 					CN10K_CPT_VF_MBOX_REGION;
904cd8c315SSrujana Challa 	} else {
914cd8c315SSrujana Challa 		offset = pci_resource_start(pdev, PCI_MBOX_BAR_NUM);
924cd8c315SSrujana Challa 		size = pci_resource_len(pdev, PCI_MBOX_BAR_NUM);
934cd8c315SSrujana Challa 		/* Map PF-VF mailbox memory */
944cd8c315SSrujana Challa 		cptvf->pfvf_mbox_base = devm_ioremap_wc(&pdev->dev, offset,
954cd8c315SSrujana Challa 							size);
964cd8c315SSrujana Challa 		if (!cptvf->pfvf_mbox_base) {
974cd8c315SSrujana Challa 			dev_err(&pdev->dev, "Unable to map BAR4\n");
984cd8c315SSrujana Challa 			ret = -ENOMEM;
994cd8c315SSrujana Challa 			goto free_wqe;
1004cd8c315SSrujana Challa 		}
1014cd8c315SSrujana Challa 	}
1024cd8c315SSrujana Challa 
10319d8e8c7SSrujana Challa 	ret = otx2_mbox_init(&cptvf->pfvf_mbox, cptvf->pfvf_mbox_base,
1044cd8c315SSrujana Challa 			     pdev, cptvf->reg_base, MBOX_DIR_VFPF, 1);
10519d8e8c7SSrujana Challa 	if (ret)
10619d8e8c7SSrujana Challa 		goto free_wqe;
10719d8e8c7SSrujana Challa 
1084cd8c315SSrujana Challa 	ret = otx2_cpt_mbox_bbuf_init(cptvf, pdev);
1094cd8c315SSrujana Challa 	if (ret)
1104cd8c315SSrujana Challa 		goto destroy_mbox;
1114cd8c315SSrujana Challa 
11219d8e8c7SSrujana Challa 	INIT_WORK(&cptvf->pfvf_mbox_work, otx2_cptvf_pfvf_mbox_handler);
11319d8e8c7SSrujana Challa 	return 0;
11419d8e8c7SSrujana Challa 
1154cd8c315SSrujana Challa destroy_mbox:
1164cd8c315SSrujana Challa 	otx2_mbox_destroy(&cptvf->pfvf_mbox);
11719d8e8c7SSrujana Challa free_wqe:
11819d8e8c7SSrujana Challa 	destroy_workqueue(cptvf->pfvf_mbox_wq);
11919d8e8c7SSrujana Challa 	return ret;
12019d8e8c7SSrujana Challa }
12119d8e8c7SSrujana Challa 
cptvf_pfvf_mbox_destroy(struct otx2_cptvf_dev * cptvf)12219d8e8c7SSrujana Challa static void cptvf_pfvf_mbox_destroy(struct otx2_cptvf_dev *cptvf)
12319d8e8c7SSrujana Challa {
12419d8e8c7SSrujana Challa 	destroy_workqueue(cptvf->pfvf_mbox_wq);
12519d8e8c7SSrujana Challa 	otx2_mbox_destroy(&cptvf->pfvf_mbox);
12619d8e8c7SSrujana Challa }
12719d8e8c7SSrujana Challa 
cptlf_work_handler(unsigned long data)1288ec8015aSSrujana Challa static void cptlf_work_handler(unsigned long data)
1298ec8015aSSrujana Challa {
1308ec8015aSSrujana Challa 	otx2_cpt_post_process((struct otx2_cptlf_wqe *) data);
1318ec8015aSSrujana Challa }
1328ec8015aSSrujana Challa 
cleanup_tasklet_work(struct otx2_cptlfs_info * lfs)1338ec8015aSSrujana Challa static void cleanup_tasklet_work(struct otx2_cptlfs_info *lfs)
1348ec8015aSSrujana Challa {
1358ec8015aSSrujana Challa 	int i;
1368ec8015aSSrujana Challa 
1378ec8015aSSrujana Challa 	for (i = 0; i <  lfs->lfs_num; i++) {
1388ec8015aSSrujana Challa 		if (!lfs->lf[i].wqe)
1398ec8015aSSrujana Challa 			continue;
1408ec8015aSSrujana Challa 
1418ec8015aSSrujana Challa 		tasklet_kill(&lfs->lf[i].wqe->work);
1428ec8015aSSrujana Challa 		kfree(lfs->lf[i].wqe);
1438ec8015aSSrujana Challa 		lfs->lf[i].wqe = NULL;
1448ec8015aSSrujana Challa 	}
1458ec8015aSSrujana Challa }
1468ec8015aSSrujana Challa 
init_tasklet_work(struct otx2_cptlfs_info * lfs)1478ec8015aSSrujana Challa static int init_tasklet_work(struct otx2_cptlfs_info *lfs)
1488ec8015aSSrujana Challa {
1498ec8015aSSrujana Challa 	struct otx2_cptlf_wqe *wqe;
1508ec8015aSSrujana Challa 	int i, ret = 0;
1518ec8015aSSrujana Challa 
1528ec8015aSSrujana Challa 	for (i = 0; i < lfs->lfs_num; i++) {
1538ec8015aSSrujana Challa 		wqe = kzalloc(sizeof(struct otx2_cptlf_wqe), GFP_KERNEL);
1548ec8015aSSrujana Challa 		if (!wqe) {
1558ec8015aSSrujana Challa 			ret = -ENOMEM;
1568ec8015aSSrujana Challa 			goto cleanup_tasklet;
1578ec8015aSSrujana Challa 		}
1588ec8015aSSrujana Challa 
1598ec8015aSSrujana Challa 		tasklet_init(&wqe->work, cptlf_work_handler, (u64) wqe);
1608ec8015aSSrujana Challa 		wqe->lfs = lfs;
1618ec8015aSSrujana Challa 		wqe->lf_num = i;
1628ec8015aSSrujana Challa 		lfs->lf[i].wqe = wqe;
1638ec8015aSSrujana Challa 	}
1648ec8015aSSrujana Challa 	return 0;
1658ec8015aSSrujana Challa 
1668ec8015aSSrujana Challa cleanup_tasklet:
1678ec8015aSSrujana Challa 	cleanup_tasklet_work(lfs);
1688ec8015aSSrujana Challa 	return ret;
1698ec8015aSSrujana Challa }
1708ec8015aSSrujana Challa 
free_pending_queues(struct otx2_cptlfs_info * lfs)1718ec8015aSSrujana Challa static void free_pending_queues(struct otx2_cptlfs_info *lfs)
1728ec8015aSSrujana Challa {
1738ec8015aSSrujana Challa 	int i;
1748ec8015aSSrujana Challa 
1758ec8015aSSrujana Challa 	for (i = 0; i < lfs->lfs_num; i++) {
1768ec8015aSSrujana Challa 		kfree(lfs->lf[i].pqueue.head);
1778ec8015aSSrujana Challa 		lfs->lf[i].pqueue.head = NULL;
1788ec8015aSSrujana Challa 	}
1798ec8015aSSrujana Challa }
1808ec8015aSSrujana Challa 
alloc_pending_queues(struct otx2_cptlfs_info * lfs)1818ec8015aSSrujana Challa static int alloc_pending_queues(struct otx2_cptlfs_info *lfs)
1828ec8015aSSrujana Challa {
1838ec8015aSSrujana Challa 	int size, ret, i;
1848ec8015aSSrujana Challa 
1858ec8015aSSrujana Challa 	if (!lfs->lfs_num)
1868ec8015aSSrujana Challa 		return -EINVAL;
1878ec8015aSSrujana Challa 
1888ec8015aSSrujana Challa 	for (i = 0; i < lfs->lfs_num; i++) {
1898ec8015aSSrujana Challa 		lfs->lf[i].pqueue.qlen = OTX2_CPT_INST_QLEN_MSGS;
1908ec8015aSSrujana Challa 		size = lfs->lf[i].pqueue.qlen *
1918ec8015aSSrujana Challa 		       sizeof(struct otx2_cpt_pending_entry);
1928ec8015aSSrujana Challa 
1938ec8015aSSrujana Challa 		lfs->lf[i].pqueue.head = kzalloc(size, GFP_KERNEL);
1948ec8015aSSrujana Challa 		if (!lfs->lf[i].pqueue.head) {
1958ec8015aSSrujana Challa 			ret = -ENOMEM;
1968ec8015aSSrujana Challa 			goto error;
1978ec8015aSSrujana Challa 		}
1988ec8015aSSrujana Challa 
1998ec8015aSSrujana Challa 		/* Initialize spin lock */
2008ec8015aSSrujana Challa 		spin_lock_init(&lfs->lf[i].pqueue.lock);
2018ec8015aSSrujana Challa 	}
2028ec8015aSSrujana Challa 	return 0;
2038ec8015aSSrujana Challa 
2048ec8015aSSrujana Challa error:
2058ec8015aSSrujana Challa 	free_pending_queues(lfs);
2068ec8015aSSrujana Challa 	return ret;
2078ec8015aSSrujana Challa }
2088ec8015aSSrujana Challa 
lf_sw_cleanup(struct otx2_cptlfs_info * lfs)2098ec8015aSSrujana Challa static void lf_sw_cleanup(struct otx2_cptlfs_info *lfs)
2108ec8015aSSrujana Challa {
2118ec8015aSSrujana Challa 	cleanup_tasklet_work(lfs);
2128ec8015aSSrujana Challa 	free_pending_queues(lfs);
2138ec8015aSSrujana Challa }
2148ec8015aSSrujana Challa 
lf_sw_init(struct otx2_cptlfs_info * lfs)2158ec8015aSSrujana Challa static int lf_sw_init(struct otx2_cptlfs_info *lfs)
2168ec8015aSSrujana Challa {
2178ec8015aSSrujana Challa 	int ret;
2188ec8015aSSrujana Challa 
2198ec8015aSSrujana Challa 	ret = alloc_pending_queues(lfs);
2208ec8015aSSrujana Challa 	if (ret) {
2218ec8015aSSrujana Challa 		dev_err(&lfs->pdev->dev,
2228ec8015aSSrujana Challa 			"Allocating pending queues failed\n");
2238ec8015aSSrujana Challa 		return ret;
2248ec8015aSSrujana Challa 	}
2258ec8015aSSrujana Challa 	ret = init_tasklet_work(lfs);
2268ec8015aSSrujana Challa 	if (ret) {
2278ec8015aSSrujana Challa 		dev_err(&lfs->pdev->dev,
2288ec8015aSSrujana Challa 			"Tasklet work init failed\n");
2298ec8015aSSrujana Challa 		goto pending_queues_free;
2308ec8015aSSrujana Challa 	}
2318ec8015aSSrujana Challa 	return 0;
2328ec8015aSSrujana Challa 
2338ec8015aSSrujana Challa pending_queues_free:
2348ec8015aSSrujana Challa 	free_pending_queues(lfs);
2358ec8015aSSrujana Challa 	return ret;
2368ec8015aSSrujana Challa }
2378ec8015aSSrujana Challa 
cptvf_lf_shutdown(struct otx2_cptlfs_info * lfs)2388ec8015aSSrujana Challa static void cptvf_lf_shutdown(struct otx2_cptlfs_info *lfs)
2398ec8015aSSrujana Challa {
2408ec8015aSSrujana Challa 	atomic_set(&lfs->state, OTX2_CPTLF_IN_RESET);
2418ec8015aSSrujana Challa 
2428ec8015aSSrujana Challa 	/* Remove interrupts affinity */
2438ec8015aSSrujana Challa 	otx2_cptlf_free_irqs_affinity(lfs);
2448ec8015aSSrujana Challa 	/* Disable instruction queue */
2458ec8015aSSrujana Challa 	otx2_cptlf_disable_iqueues(lfs);
2466f03f0e8SSrujana Challa 	/* Unregister crypto algorithms */
2476f03f0e8SSrujana Challa 	otx2_cpt_crypto_exit(lfs->pdev, THIS_MODULE);
2488ec8015aSSrujana Challa 	/* Unregister LFs interrupts */
2498ec8015aSSrujana Challa 	otx2_cptlf_unregister_interrupts(lfs);
2508ec8015aSSrujana Challa 	/* Cleanup LFs software side */
2518ec8015aSSrujana Challa 	lf_sw_cleanup(lfs);
252*8b18d5f5SBharat Bhushan 	/* Free instruction queues */
253*8b18d5f5SBharat Bhushan 	otx2_cpt_free_instruction_queues(lfs);
2548ec8015aSSrujana Challa 	/* Send request to detach LFs */
2558ec8015aSSrujana Challa 	otx2_cpt_detach_rsrcs_msg(lfs);
256*8b18d5f5SBharat Bhushan 	lfs->lfs_num = 0;
2578ec8015aSSrujana Challa }
2588ec8015aSSrujana Challa 
cptvf_lf_init(struct otx2_cptvf_dev * cptvf)2598ec8015aSSrujana Challa static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf)
2608ec8015aSSrujana Challa {
2618ec8015aSSrujana Challa 	struct otx2_cptlfs_info *lfs = &cptvf->lfs;
2628ec8015aSSrujana Challa 	struct device *dev = &cptvf->pdev->dev;
2638ec8015aSSrujana Challa 	int ret, lfs_num;
2648ec8015aSSrujana Challa 	u8 eng_grp_msk;
2658ec8015aSSrujana Challa 
2668ec8015aSSrujana Challa 	/* Get engine group number for symmetric crypto */
2678ec8015aSSrujana Challa 	cptvf->lfs.kcrypto_eng_grp_num = OTX2_CPT_INVALID_CRYPTO_ENG_GRP;
2688ec8015aSSrujana Challa 	ret = otx2_cptvf_send_eng_grp_num_msg(cptvf, OTX2_CPT_SE_TYPES);
2698ec8015aSSrujana Challa 	if (ret)
2708ec8015aSSrujana Challa 		return ret;
2718ec8015aSSrujana Challa 
2728ec8015aSSrujana Challa 	if (cptvf->lfs.kcrypto_eng_grp_num == OTX2_CPT_INVALID_CRYPTO_ENG_GRP) {
2738ec8015aSSrujana Challa 		dev_err(dev, "Engine group for kernel crypto not available\n");
2748ec8015aSSrujana Challa 		ret = -ENOENT;
2758ec8015aSSrujana Challa 		return ret;
2768ec8015aSSrujana Challa 	}
2778ec8015aSSrujana Challa 	eng_grp_msk = 1 << cptvf->lfs.kcrypto_eng_grp_num;
2788ec8015aSSrujana Challa 
2798ec8015aSSrujana Challa 	ret = otx2_cptvf_send_kvf_limits_msg(cptvf);
2808ec8015aSSrujana Challa 	if (ret)
2818ec8015aSSrujana Challa 		return ret;
2828ec8015aSSrujana Challa 
2838ec8015aSSrujana Challa 	lfs_num = cptvf->lfs.kvf_limits ? cptvf->lfs.kvf_limits :
2848ec8015aSSrujana Challa 		  num_online_cpus();
285a4855a8cSSrujana Challa 
286a4855a8cSSrujana Challa 	otx2_cptlf_set_dev_info(lfs, cptvf->pdev, cptvf->reg_base,
287a4855a8cSSrujana Challa 				&cptvf->pfvf_mbox, cptvf->blkaddr);
2888ec8015aSSrujana Challa 	ret = otx2_cptlf_init(lfs, eng_grp_msk, OTX2_CPT_QUEUE_HI_PRIO,
2898ec8015aSSrujana Challa 			      lfs_num);
2908ec8015aSSrujana Challa 	if (ret)
2918ec8015aSSrujana Challa 		return ret;
2928ec8015aSSrujana Challa 
2938ec8015aSSrujana Challa 	/* Get msix offsets for attached LFs */
2948ec8015aSSrujana Challa 	ret = otx2_cpt_msix_offset_msg(lfs);
2958ec8015aSSrujana Challa 	if (ret)
2968ec8015aSSrujana Challa 		goto cleanup_lf;
2978ec8015aSSrujana Challa 
2988ec8015aSSrujana Challa 	/* Initialize LFs software side */
2998ec8015aSSrujana Challa 	ret = lf_sw_init(lfs);
3008ec8015aSSrujana Challa 	if (ret)
3018ec8015aSSrujana Challa 		goto cleanup_lf;
3028ec8015aSSrujana Challa 
3038ec8015aSSrujana Challa 	/* Register LFs interrupts */
3048ec8015aSSrujana Challa 	ret = otx2_cptlf_register_interrupts(lfs);
3058ec8015aSSrujana Challa 	if (ret)
3068ec8015aSSrujana Challa 		goto cleanup_lf_sw;
3078ec8015aSSrujana Challa 
3088ec8015aSSrujana Challa 	/* Set interrupts affinity */
3098ec8015aSSrujana Challa 	ret = otx2_cptlf_set_irqs_affinity(lfs);
3108ec8015aSSrujana Challa 	if (ret)
3118ec8015aSSrujana Challa 		goto unregister_intr;
3128ec8015aSSrujana Challa 
3138ec8015aSSrujana Challa 	atomic_set(&lfs->state, OTX2_CPTLF_STARTED);
3146f03f0e8SSrujana Challa 	/* Register crypto algorithms */
3156f03f0e8SSrujana Challa 	ret = otx2_cpt_crypto_init(lfs->pdev, THIS_MODULE, lfs_num, 1);
3166f03f0e8SSrujana Challa 	if (ret) {
3176f03f0e8SSrujana Challa 		dev_err(&lfs->pdev->dev, "algorithms registration failed\n");
3186f03f0e8SSrujana Challa 		goto disable_irqs;
3196f03f0e8SSrujana Challa 	}
3208ec8015aSSrujana Challa 	return 0;
3218ec8015aSSrujana Challa 
3226f03f0e8SSrujana Challa disable_irqs:
3236f03f0e8SSrujana Challa 	otx2_cptlf_free_irqs_affinity(lfs);
3248ec8015aSSrujana Challa unregister_intr:
3258ec8015aSSrujana Challa 	otx2_cptlf_unregister_interrupts(lfs);
3268ec8015aSSrujana Challa cleanup_lf_sw:
3278ec8015aSSrujana Challa 	lf_sw_cleanup(lfs);
3288ec8015aSSrujana Challa cleanup_lf:
3298ec8015aSSrujana Challa 	otx2_cptlf_shutdown(lfs);
3308ec8015aSSrujana Challa 
3318ec8015aSSrujana Challa 	return ret;
3328ec8015aSSrujana Challa }
3338ec8015aSSrujana Challa 
otx2_cptvf_probe(struct pci_dev * pdev,const struct pci_device_id * ent)33419d8e8c7SSrujana Challa static int otx2_cptvf_probe(struct pci_dev *pdev,
33519d8e8c7SSrujana Challa 			    const struct pci_device_id *ent)
33619d8e8c7SSrujana Challa {
33719d8e8c7SSrujana Challa 	struct device *dev = &pdev->dev;
33819d8e8c7SSrujana Challa 	struct otx2_cptvf_dev *cptvf;
33919d8e8c7SSrujana Challa 	int ret;
34019d8e8c7SSrujana Challa 
34119d8e8c7SSrujana Challa 	cptvf = devm_kzalloc(dev, sizeof(*cptvf), GFP_KERNEL);
34219d8e8c7SSrujana Challa 	if (!cptvf)
34319d8e8c7SSrujana Challa 		return -ENOMEM;
34419d8e8c7SSrujana Challa 
34519d8e8c7SSrujana Challa 	ret = pcim_enable_device(pdev);
34619d8e8c7SSrujana Challa 	if (ret) {
34719d8e8c7SSrujana Challa 		dev_err(dev, "Failed to enable PCI device\n");
34819d8e8c7SSrujana Challa 		goto clear_drvdata;
34919d8e8c7SSrujana Challa 	}
35019d8e8c7SSrujana Challa 
35119d8e8c7SSrujana Challa 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
35219d8e8c7SSrujana Challa 	if (ret) {
35319d8e8c7SSrujana Challa 		dev_err(dev, "Unable to get usable DMA configuration\n");
35419d8e8c7SSrujana Challa 		goto clear_drvdata;
35519d8e8c7SSrujana Challa 	}
35619d8e8c7SSrujana Challa 	/* Map VF's configuration registers */
35719d8e8c7SSrujana Challa 	ret = pcim_iomap_regions_request_all(pdev, 1 << PCI_PF_REG_BAR_NUM,
35819d8e8c7SSrujana Challa 					     OTX2_CPTVF_DRV_NAME);
35919d8e8c7SSrujana Challa 	if (ret) {
36019d8e8c7SSrujana Challa 		dev_err(dev, "Couldn't get PCI resources 0x%x\n", ret);
36119d8e8c7SSrujana Challa 		goto clear_drvdata;
36219d8e8c7SSrujana Challa 	}
36319d8e8c7SSrujana Challa 	pci_set_master(pdev);
36419d8e8c7SSrujana Challa 	pci_set_drvdata(pdev, cptvf);
36519d8e8c7SSrujana Challa 	cptvf->pdev = pdev;
36619d8e8c7SSrujana Challa 
36719d8e8c7SSrujana Challa 	cptvf->reg_base = pcim_iomap_table(pdev)[PCI_PF_REG_BAR_NUM];
36819d8e8c7SSrujana Challa 
3694cd8c315SSrujana Challa 	otx2_cpt_set_hw_caps(pdev, &cptvf->cap_flag);
370eb33cd91SSrujana Challa 
371eb33cd91SSrujana Challa 	ret = cn10k_cptvf_lmtst_init(cptvf);
372eb33cd91SSrujana Challa 	if (ret)
373eb33cd91SSrujana Challa 		goto clear_drvdata;
374eb33cd91SSrujana Challa 
37519d8e8c7SSrujana Challa 	/* Initialize PF<=>VF mailbox */
37619d8e8c7SSrujana Challa 	ret = cptvf_pfvf_mbox_init(cptvf);
37719d8e8c7SSrujana Challa 	if (ret)
37819d8e8c7SSrujana Challa 		goto clear_drvdata;
37919d8e8c7SSrujana Challa 
38019d8e8c7SSrujana Challa 	/* Register interrupts */
38119d8e8c7SSrujana Challa 	ret = cptvf_register_interrupts(cptvf);
38219d8e8c7SSrujana Challa 	if (ret)
38319d8e8c7SSrujana Challa 		goto destroy_pfvf_mbox;
38419d8e8c7SSrujana Challa 
385a4855a8cSSrujana Challa 	cptvf->blkaddr = BLKADDR_CPT0;
3868ec8015aSSrujana Challa 	/* Initialize CPT LFs */
3878ec8015aSSrujana Challa 	ret = cptvf_lf_init(cptvf);
3888ec8015aSSrujana Challa 	if (ret)
3898ec8015aSSrujana Challa 		goto unregister_interrupts;
3908ec8015aSSrujana Challa 
39119d8e8c7SSrujana Challa 	return 0;
39219d8e8c7SSrujana Challa 
3938ec8015aSSrujana Challa unregister_interrupts:
3948ec8015aSSrujana Challa 	cptvf_disable_pfvf_mbox_intrs(cptvf);
39519d8e8c7SSrujana Challa destroy_pfvf_mbox:
39619d8e8c7SSrujana Challa 	cptvf_pfvf_mbox_destroy(cptvf);
39719d8e8c7SSrujana Challa clear_drvdata:
39819d8e8c7SSrujana Challa 	pci_set_drvdata(pdev, NULL);
39919d8e8c7SSrujana Challa 
40019d8e8c7SSrujana Challa 	return ret;
40119d8e8c7SSrujana Challa }
40219d8e8c7SSrujana Challa 
otx2_cptvf_remove(struct pci_dev * pdev)40319d8e8c7SSrujana Challa static void otx2_cptvf_remove(struct pci_dev *pdev)
40419d8e8c7SSrujana Challa {
40519d8e8c7SSrujana Challa 	struct otx2_cptvf_dev *cptvf = pci_get_drvdata(pdev);
40619d8e8c7SSrujana Challa 
40719d8e8c7SSrujana Challa 	if (!cptvf) {
40819d8e8c7SSrujana Challa 		dev_err(&pdev->dev, "Invalid CPT VF device.\n");
40919d8e8c7SSrujana Challa 		return;
41019d8e8c7SSrujana Challa 	}
4118ec8015aSSrujana Challa 	cptvf_lf_shutdown(&cptvf->lfs);
41219d8e8c7SSrujana Challa 	/* Disable PF-VF mailbox interrupt */
41319d8e8c7SSrujana Challa 	cptvf_disable_pfvf_mbox_intrs(cptvf);
41419d8e8c7SSrujana Challa 	/* Destroy PF-VF mbox */
41519d8e8c7SSrujana Challa 	cptvf_pfvf_mbox_destroy(cptvf);
41619d8e8c7SSrujana Challa 	pci_set_drvdata(pdev, NULL);
41719d8e8c7SSrujana Challa }
41819d8e8c7SSrujana Challa 
41919d8e8c7SSrujana Challa /* Supported devices */
42019d8e8c7SSrujana Challa static const struct pci_device_id otx2_cptvf_id_table[] = {
42119d8e8c7SSrujana Challa 	{PCI_VDEVICE(CAVIUM, OTX2_CPT_PCI_VF_DEVICE_ID), 0},
4224cd8c315SSrujana Challa 	{PCI_VDEVICE(CAVIUM, CN10K_CPT_PCI_VF_DEVICE_ID), 0},
42319d8e8c7SSrujana Challa 	{ 0, }  /* end of table */
42419d8e8c7SSrujana Challa };
42519d8e8c7SSrujana Challa 
42619d8e8c7SSrujana Challa static struct pci_driver otx2_cptvf_pci_driver = {
42719d8e8c7SSrujana Challa 	.name = OTX2_CPTVF_DRV_NAME,
42819d8e8c7SSrujana Challa 	.id_table = otx2_cptvf_id_table,
42919d8e8c7SSrujana Challa 	.probe = otx2_cptvf_probe,
43019d8e8c7SSrujana Challa 	.remove = otx2_cptvf_remove,
43119d8e8c7SSrujana Challa };
43219d8e8c7SSrujana Challa 
43319d8e8c7SSrujana Challa module_pci_driver(otx2_cptvf_pci_driver);
43419d8e8c7SSrujana Challa 
43572bc4e71SAlexander Lobakin MODULE_IMPORT_NS(CRYPTO_DEV_OCTEONTX2_CPT);
43672bc4e71SAlexander Lobakin 
43719d8e8c7SSrujana Challa MODULE_AUTHOR("Marvell");
4384cd8c315SSrujana Challa MODULE_DESCRIPTION("Marvell RVU CPT Virtual Function Driver");
43919d8e8c7SSrujana Challa MODULE_LICENSE("GPL v2");
44019d8e8c7SSrujana Challa MODULE_DEVICE_TABLE(pci, otx2_cptvf_id_table);
441