162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* Copyright (C) 2020 Marvell. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "otx2_cpt_common.h" 562306a36Sopenharmony_ci#include "otx2_cptvf.h" 662306a36Sopenharmony_ci#include "otx2_cptlf.h" 762306a36Sopenharmony_ci#include "otx2_cptvf_algs.h" 862306a36Sopenharmony_ci#include "cn10k_cpt.h" 962306a36Sopenharmony_ci#include <rvu_reg.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#define OTX2_CPTVF_DRV_NAME "rvu_cptvf" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistatic void cptvf_enable_pfvf_mbox_intrs(struct otx2_cptvf_dev *cptvf) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci /* Clear interrupt if any */ 1662306a36Sopenharmony_ci otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0, OTX2_RVU_VF_INT, 1762306a36Sopenharmony_ci 0x1ULL); 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci /* Enable PF-VF interrupt */ 2062306a36Sopenharmony_ci otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0, 2162306a36Sopenharmony_ci OTX2_RVU_VF_INT_ENA_W1S, 0x1ULL); 2262306a36Sopenharmony_ci} 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic void cptvf_disable_pfvf_mbox_intrs(struct otx2_cptvf_dev *cptvf) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci /* Disable PF-VF interrupt */ 2762306a36Sopenharmony_ci otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0, 2862306a36Sopenharmony_ci OTX2_RVU_VF_INT_ENA_W1C, 0x1ULL); 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci /* Clear interrupt if any */ 3162306a36Sopenharmony_ci otx2_cpt_write64(cptvf->reg_base, BLKADDR_RVUM, 0, OTX2_RVU_VF_INT, 3262306a36Sopenharmony_ci 0x1ULL); 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic int cptvf_register_interrupts(struct otx2_cptvf_dev *cptvf) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci int ret, irq; 3862306a36Sopenharmony_ci int num_vec; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci num_vec = pci_msix_vec_count(cptvf->pdev); 4162306a36Sopenharmony_ci if (num_vec <= 0) 4262306a36Sopenharmony_ci return -EINVAL; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci /* Enable MSI-X */ 4562306a36Sopenharmony_ci ret = pci_alloc_irq_vectors(cptvf->pdev, num_vec, num_vec, 4662306a36Sopenharmony_ci PCI_IRQ_MSIX); 4762306a36Sopenharmony_ci if (ret < 0) { 4862306a36Sopenharmony_ci dev_err(&cptvf->pdev->dev, 4962306a36Sopenharmony_ci "Request for %d msix vectors failed\n", num_vec); 5062306a36Sopenharmony_ci return ret; 5162306a36Sopenharmony_ci } 5262306a36Sopenharmony_ci irq = pci_irq_vector(cptvf->pdev, OTX2_CPT_VF_INT_VEC_E_MBOX); 5362306a36Sopenharmony_ci /* Register VF<=>PF mailbox interrupt handler */ 5462306a36Sopenharmony_ci ret = devm_request_irq(&cptvf->pdev->dev, irq, 5562306a36Sopenharmony_ci otx2_cptvf_pfvf_mbox_intr, 0, 5662306a36Sopenharmony_ci "CPTPFVF Mbox", cptvf); 5762306a36Sopenharmony_ci if (ret) 5862306a36Sopenharmony_ci return ret; 5962306a36Sopenharmony_ci /* Enable PF-VF mailbox interrupts */ 6062306a36Sopenharmony_ci cptvf_enable_pfvf_mbox_intrs(cptvf); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci ret = otx2_cpt_send_ready_msg(&cptvf->pfvf_mbox, cptvf->pdev); 6362306a36Sopenharmony_ci if (ret) { 6462306a36Sopenharmony_ci dev_warn(&cptvf->pdev->dev, 6562306a36Sopenharmony_ci "PF not responding to mailbox, deferring probe\n"); 6662306a36Sopenharmony_ci cptvf_disable_pfvf_mbox_intrs(cptvf); 6762306a36Sopenharmony_ci return -EPROBE_DEFER; 6862306a36Sopenharmony_ci } 6962306a36Sopenharmony_ci return 0; 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic int cptvf_pfvf_mbox_init(struct otx2_cptvf_dev *cptvf) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci struct pci_dev *pdev = cptvf->pdev; 7562306a36Sopenharmony_ci resource_size_t offset, size; 7662306a36Sopenharmony_ci int ret; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci cptvf->pfvf_mbox_wq = 7962306a36Sopenharmony_ci alloc_ordered_workqueue("cpt_pfvf_mailbox", 8062306a36Sopenharmony_ci WQ_HIGHPRI | WQ_MEM_RECLAIM); 8162306a36Sopenharmony_ci if (!cptvf->pfvf_mbox_wq) 8262306a36Sopenharmony_ci return -ENOMEM; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci if (test_bit(CN10K_MBOX, &cptvf->cap_flag)) { 8562306a36Sopenharmony_ci /* For cn10k platform, VF mailbox region is in its BAR2 8662306a36Sopenharmony_ci * register space 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_ci cptvf->pfvf_mbox_base = cptvf->reg_base + 8962306a36Sopenharmony_ci CN10K_CPT_VF_MBOX_REGION; 9062306a36Sopenharmony_ci } else { 9162306a36Sopenharmony_ci offset = pci_resource_start(pdev, PCI_MBOX_BAR_NUM); 9262306a36Sopenharmony_ci size = pci_resource_len(pdev, PCI_MBOX_BAR_NUM); 9362306a36Sopenharmony_ci /* Map PF-VF mailbox memory */ 9462306a36Sopenharmony_ci cptvf->pfvf_mbox_base = devm_ioremap_wc(&pdev->dev, offset, 9562306a36Sopenharmony_ci size); 9662306a36Sopenharmony_ci if (!cptvf->pfvf_mbox_base) { 9762306a36Sopenharmony_ci dev_err(&pdev->dev, "Unable to map BAR4\n"); 9862306a36Sopenharmony_ci ret = -ENOMEM; 9962306a36Sopenharmony_ci goto free_wqe; 10062306a36Sopenharmony_ci } 10162306a36Sopenharmony_ci } 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci ret = otx2_mbox_init(&cptvf->pfvf_mbox, cptvf->pfvf_mbox_base, 10462306a36Sopenharmony_ci pdev, cptvf->reg_base, MBOX_DIR_VFPF, 1); 10562306a36Sopenharmony_ci if (ret) 10662306a36Sopenharmony_ci goto free_wqe; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci ret = otx2_cpt_mbox_bbuf_init(cptvf, pdev); 10962306a36Sopenharmony_ci if (ret) 11062306a36Sopenharmony_ci goto destroy_mbox; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci INIT_WORK(&cptvf->pfvf_mbox_work, otx2_cptvf_pfvf_mbox_handler); 11362306a36Sopenharmony_ci return 0; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cidestroy_mbox: 11662306a36Sopenharmony_ci otx2_mbox_destroy(&cptvf->pfvf_mbox); 11762306a36Sopenharmony_cifree_wqe: 11862306a36Sopenharmony_ci destroy_workqueue(cptvf->pfvf_mbox_wq); 11962306a36Sopenharmony_ci return ret; 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic void cptvf_pfvf_mbox_destroy(struct otx2_cptvf_dev *cptvf) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci destroy_workqueue(cptvf->pfvf_mbox_wq); 12562306a36Sopenharmony_ci otx2_mbox_destroy(&cptvf->pfvf_mbox); 12662306a36Sopenharmony_ci} 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic void cptlf_work_handler(unsigned long data) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci otx2_cpt_post_process((struct otx2_cptlf_wqe *) data); 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic void cleanup_tasklet_work(struct otx2_cptlfs_info *lfs) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci int i; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci for (i = 0; i < lfs->lfs_num; i++) { 13862306a36Sopenharmony_ci if (!lfs->lf[i].wqe) 13962306a36Sopenharmony_ci continue; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci tasklet_kill(&lfs->lf[i].wqe->work); 14262306a36Sopenharmony_ci kfree(lfs->lf[i].wqe); 14362306a36Sopenharmony_ci lfs->lf[i].wqe = NULL; 14462306a36Sopenharmony_ci } 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cistatic int init_tasklet_work(struct otx2_cptlfs_info *lfs) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci struct otx2_cptlf_wqe *wqe; 15062306a36Sopenharmony_ci int i, ret = 0; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci for (i = 0; i < lfs->lfs_num; i++) { 15362306a36Sopenharmony_ci wqe = kzalloc(sizeof(struct otx2_cptlf_wqe), GFP_KERNEL); 15462306a36Sopenharmony_ci if (!wqe) { 15562306a36Sopenharmony_ci ret = -ENOMEM; 15662306a36Sopenharmony_ci goto cleanup_tasklet; 15762306a36Sopenharmony_ci } 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci tasklet_init(&wqe->work, cptlf_work_handler, (u64) wqe); 16062306a36Sopenharmony_ci wqe->lfs = lfs; 16162306a36Sopenharmony_ci wqe->lf_num = i; 16262306a36Sopenharmony_ci lfs->lf[i].wqe = wqe; 16362306a36Sopenharmony_ci } 16462306a36Sopenharmony_ci return 0; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cicleanup_tasklet: 16762306a36Sopenharmony_ci cleanup_tasklet_work(lfs); 16862306a36Sopenharmony_ci return ret; 16962306a36Sopenharmony_ci} 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_cistatic void free_pending_queues(struct otx2_cptlfs_info *lfs) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci int i; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci for (i = 0; i < lfs->lfs_num; i++) { 17662306a36Sopenharmony_ci kfree(lfs->lf[i].pqueue.head); 17762306a36Sopenharmony_ci lfs->lf[i].pqueue.head = NULL; 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistatic int alloc_pending_queues(struct otx2_cptlfs_info *lfs) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci int size, ret, i; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci if (!lfs->lfs_num) 18662306a36Sopenharmony_ci return -EINVAL; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci for (i = 0; i < lfs->lfs_num; i++) { 18962306a36Sopenharmony_ci lfs->lf[i].pqueue.qlen = OTX2_CPT_INST_QLEN_MSGS; 19062306a36Sopenharmony_ci size = lfs->lf[i].pqueue.qlen * 19162306a36Sopenharmony_ci sizeof(struct otx2_cpt_pending_entry); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci lfs->lf[i].pqueue.head = kzalloc(size, GFP_KERNEL); 19462306a36Sopenharmony_ci if (!lfs->lf[i].pqueue.head) { 19562306a36Sopenharmony_ci ret = -ENOMEM; 19662306a36Sopenharmony_ci goto error; 19762306a36Sopenharmony_ci } 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci /* Initialize spin lock */ 20062306a36Sopenharmony_ci spin_lock_init(&lfs->lf[i].pqueue.lock); 20162306a36Sopenharmony_ci } 20262306a36Sopenharmony_ci return 0; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cierror: 20562306a36Sopenharmony_ci free_pending_queues(lfs); 20662306a36Sopenharmony_ci return ret; 20762306a36Sopenharmony_ci} 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_cistatic void lf_sw_cleanup(struct otx2_cptlfs_info *lfs) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci cleanup_tasklet_work(lfs); 21262306a36Sopenharmony_ci free_pending_queues(lfs); 21362306a36Sopenharmony_ci} 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistatic int lf_sw_init(struct otx2_cptlfs_info *lfs) 21662306a36Sopenharmony_ci{ 21762306a36Sopenharmony_ci int ret; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci ret = alloc_pending_queues(lfs); 22062306a36Sopenharmony_ci if (ret) { 22162306a36Sopenharmony_ci dev_err(&lfs->pdev->dev, 22262306a36Sopenharmony_ci "Allocating pending queues failed\n"); 22362306a36Sopenharmony_ci return ret; 22462306a36Sopenharmony_ci } 22562306a36Sopenharmony_ci ret = init_tasklet_work(lfs); 22662306a36Sopenharmony_ci if (ret) { 22762306a36Sopenharmony_ci dev_err(&lfs->pdev->dev, 22862306a36Sopenharmony_ci "Tasklet work init failed\n"); 22962306a36Sopenharmony_ci goto pending_queues_free; 23062306a36Sopenharmony_ci } 23162306a36Sopenharmony_ci return 0; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_cipending_queues_free: 23462306a36Sopenharmony_ci free_pending_queues(lfs); 23562306a36Sopenharmony_ci return ret; 23662306a36Sopenharmony_ci} 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_cistatic void cptvf_lf_shutdown(struct otx2_cptlfs_info *lfs) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci atomic_set(&lfs->state, OTX2_CPTLF_IN_RESET); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci /* Remove interrupts affinity */ 24362306a36Sopenharmony_ci otx2_cptlf_free_irqs_affinity(lfs); 24462306a36Sopenharmony_ci /* Disable instruction queue */ 24562306a36Sopenharmony_ci otx2_cptlf_disable_iqueues(lfs); 24662306a36Sopenharmony_ci /* Unregister crypto algorithms */ 24762306a36Sopenharmony_ci otx2_cpt_crypto_exit(lfs->pdev, THIS_MODULE); 24862306a36Sopenharmony_ci /* Unregister LFs interrupts */ 24962306a36Sopenharmony_ci otx2_cptlf_unregister_interrupts(lfs); 25062306a36Sopenharmony_ci /* Cleanup LFs software side */ 25162306a36Sopenharmony_ci lf_sw_cleanup(lfs); 25262306a36Sopenharmony_ci /* Free instruction queues */ 25362306a36Sopenharmony_ci otx2_cpt_free_instruction_queues(lfs); 25462306a36Sopenharmony_ci /* Send request to detach LFs */ 25562306a36Sopenharmony_ci otx2_cpt_detach_rsrcs_msg(lfs); 25662306a36Sopenharmony_ci lfs->lfs_num = 0; 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_cistatic int cptvf_lf_init(struct otx2_cptvf_dev *cptvf) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci struct otx2_cptlfs_info *lfs = &cptvf->lfs; 26262306a36Sopenharmony_ci struct device *dev = &cptvf->pdev->dev; 26362306a36Sopenharmony_ci int ret, lfs_num; 26462306a36Sopenharmony_ci u8 eng_grp_msk; 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci /* Get engine group number for symmetric crypto */ 26762306a36Sopenharmony_ci cptvf->lfs.kcrypto_eng_grp_num = OTX2_CPT_INVALID_CRYPTO_ENG_GRP; 26862306a36Sopenharmony_ci ret = otx2_cptvf_send_eng_grp_num_msg(cptvf, OTX2_CPT_SE_TYPES); 26962306a36Sopenharmony_ci if (ret) 27062306a36Sopenharmony_ci return ret; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci if (cptvf->lfs.kcrypto_eng_grp_num == OTX2_CPT_INVALID_CRYPTO_ENG_GRP) { 27362306a36Sopenharmony_ci dev_err(dev, "Engine group for kernel crypto not available\n"); 27462306a36Sopenharmony_ci ret = -ENOENT; 27562306a36Sopenharmony_ci return ret; 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci eng_grp_msk = 1 << cptvf->lfs.kcrypto_eng_grp_num; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci ret = otx2_cptvf_send_kvf_limits_msg(cptvf); 28062306a36Sopenharmony_ci if (ret) 28162306a36Sopenharmony_ci return ret; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci lfs_num = cptvf->lfs.kvf_limits ? cptvf->lfs.kvf_limits : 28462306a36Sopenharmony_ci num_online_cpus(); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci otx2_cptlf_set_dev_info(lfs, cptvf->pdev, cptvf->reg_base, 28762306a36Sopenharmony_ci &cptvf->pfvf_mbox, cptvf->blkaddr); 28862306a36Sopenharmony_ci ret = otx2_cptlf_init(lfs, eng_grp_msk, OTX2_CPT_QUEUE_HI_PRIO, 28962306a36Sopenharmony_ci lfs_num); 29062306a36Sopenharmony_ci if (ret) 29162306a36Sopenharmony_ci return ret; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci /* Get msix offsets for attached LFs */ 29462306a36Sopenharmony_ci ret = otx2_cpt_msix_offset_msg(lfs); 29562306a36Sopenharmony_ci if (ret) 29662306a36Sopenharmony_ci goto cleanup_lf; 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci /* Initialize LFs software side */ 29962306a36Sopenharmony_ci ret = lf_sw_init(lfs); 30062306a36Sopenharmony_ci if (ret) 30162306a36Sopenharmony_ci goto cleanup_lf; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci /* Register LFs interrupts */ 30462306a36Sopenharmony_ci ret = otx2_cptlf_register_interrupts(lfs); 30562306a36Sopenharmony_ci if (ret) 30662306a36Sopenharmony_ci goto cleanup_lf_sw; 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci /* Set interrupts affinity */ 30962306a36Sopenharmony_ci ret = otx2_cptlf_set_irqs_affinity(lfs); 31062306a36Sopenharmony_ci if (ret) 31162306a36Sopenharmony_ci goto unregister_intr; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci atomic_set(&lfs->state, OTX2_CPTLF_STARTED); 31462306a36Sopenharmony_ci /* Register crypto algorithms */ 31562306a36Sopenharmony_ci ret = otx2_cpt_crypto_init(lfs->pdev, THIS_MODULE, lfs_num, 1); 31662306a36Sopenharmony_ci if (ret) { 31762306a36Sopenharmony_ci dev_err(&lfs->pdev->dev, "algorithms registration failed\n"); 31862306a36Sopenharmony_ci goto disable_irqs; 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci return 0; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cidisable_irqs: 32362306a36Sopenharmony_ci otx2_cptlf_free_irqs_affinity(lfs); 32462306a36Sopenharmony_ciunregister_intr: 32562306a36Sopenharmony_ci otx2_cptlf_unregister_interrupts(lfs); 32662306a36Sopenharmony_cicleanup_lf_sw: 32762306a36Sopenharmony_ci lf_sw_cleanup(lfs); 32862306a36Sopenharmony_cicleanup_lf: 32962306a36Sopenharmony_ci otx2_cptlf_shutdown(lfs); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci return ret; 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic int otx2_cptvf_probe(struct pci_dev *pdev, 33562306a36Sopenharmony_ci const struct pci_device_id *ent) 33662306a36Sopenharmony_ci{ 33762306a36Sopenharmony_ci struct device *dev = &pdev->dev; 33862306a36Sopenharmony_ci struct otx2_cptvf_dev *cptvf; 33962306a36Sopenharmony_ci int ret; 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci cptvf = devm_kzalloc(dev, sizeof(*cptvf), GFP_KERNEL); 34262306a36Sopenharmony_ci if (!cptvf) 34362306a36Sopenharmony_ci return -ENOMEM; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci ret = pcim_enable_device(pdev); 34662306a36Sopenharmony_ci if (ret) { 34762306a36Sopenharmony_ci dev_err(dev, "Failed to enable PCI device\n"); 34862306a36Sopenharmony_ci goto clear_drvdata; 34962306a36Sopenharmony_ci } 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); 35262306a36Sopenharmony_ci if (ret) { 35362306a36Sopenharmony_ci dev_err(dev, "Unable to get usable DMA configuration\n"); 35462306a36Sopenharmony_ci goto clear_drvdata; 35562306a36Sopenharmony_ci } 35662306a36Sopenharmony_ci /* Map VF's configuration registers */ 35762306a36Sopenharmony_ci ret = pcim_iomap_regions_request_all(pdev, 1 << PCI_PF_REG_BAR_NUM, 35862306a36Sopenharmony_ci OTX2_CPTVF_DRV_NAME); 35962306a36Sopenharmony_ci if (ret) { 36062306a36Sopenharmony_ci dev_err(dev, "Couldn't get PCI resources 0x%x\n", ret); 36162306a36Sopenharmony_ci goto clear_drvdata; 36262306a36Sopenharmony_ci } 36362306a36Sopenharmony_ci pci_set_master(pdev); 36462306a36Sopenharmony_ci pci_set_drvdata(pdev, cptvf); 36562306a36Sopenharmony_ci cptvf->pdev = pdev; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci cptvf->reg_base = pcim_iomap_table(pdev)[PCI_PF_REG_BAR_NUM]; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci otx2_cpt_set_hw_caps(pdev, &cptvf->cap_flag); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci ret = cn10k_cptvf_lmtst_init(cptvf); 37262306a36Sopenharmony_ci if (ret) 37362306a36Sopenharmony_ci goto clear_drvdata; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci /* Initialize PF<=>VF mailbox */ 37662306a36Sopenharmony_ci ret = cptvf_pfvf_mbox_init(cptvf); 37762306a36Sopenharmony_ci if (ret) 37862306a36Sopenharmony_ci goto clear_drvdata; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci /* Register interrupts */ 38162306a36Sopenharmony_ci ret = cptvf_register_interrupts(cptvf); 38262306a36Sopenharmony_ci if (ret) 38362306a36Sopenharmony_ci goto destroy_pfvf_mbox; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci cptvf->blkaddr = BLKADDR_CPT0; 38662306a36Sopenharmony_ci /* Initialize CPT LFs */ 38762306a36Sopenharmony_ci ret = cptvf_lf_init(cptvf); 38862306a36Sopenharmony_ci if (ret) 38962306a36Sopenharmony_ci goto unregister_interrupts; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci return 0; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ciunregister_interrupts: 39462306a36Sopenharmony_ci cptvf_disable_pfvf_mbox_intrs(cptvf); 39562306a36Sopenharmony_cidestroy_pfvf_mbox: 39662306a36Sopenharmony_ci cptvf_pfvf_mbox_destroy(cptvf); 39762306a36Sopenharmony_ciclear_drvdata: 39862306a36Sopenharmony_ci pci_set_drvdata(pdev, NULL); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci return ret; 40162306a36Sopenharmony_ci} 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_cistatic void otx2_cptvf_remove(struct pci_dev *pdev) 40462306a36Sopenharmony_ci{ 40562306a36Sopenharmony_ci struct otx2_cptvf_dev *cptvf = pci_get_drvdata(pdev); 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci if (!cptvf) { 40862306a36Sopenharmony_ci dev_err(&pdev->dev, "Invalid CPT VF device.\n"); 40962306a36Sopenharmony_ci return; 41062306a36Sopenharmony_ci } 41162306a36Sopenharmony_ci cptvf_lf_shutdown(&cptvf->lfs); 41262306a36Sopenharmony_ci /* Disable PF-VF mailbox interrupt */ 41362306a36Sopenharmony_ci cptvf_disable_pfvf_mbox_intrs(cptvf); 41462306a36Sopenharmony_ci /* Destroy PF-VF mbox */ 41562306a36Sopenharmony_ci cptvf_pfvf_mbox_destroy(cptvf); 41662306a36Sopenharmony_ci pci_set_drvdata(pdev, NULL); 41762306a36Sopenharmony_ci} 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci/* Supported devices */ 42062306a36Sopenharmony_cistatic const struct pci_device_id otx2_cptvf_id_table[] = { 42162306a36Sopenharmony_ci {PCI_VDEVICE(CAVIUM, OTX2_CPT_PCI_VF_DEVICE_ID), 0}, 42262306a36Sopenharmony_ci {PCI_VDEVICE(CAVIUM, CN10K_CPT_PCI_VF_DEVICE_ID), 0}, 42362306a36Sopenharmony_ci { 0, } /* end of table */ 42462306a36Sopenharmony_ci}; 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_cistatic struct pci_driver otx2_cptvf_pci_driver = { 42762306a36Sopenharmony_ci .name = OTX2_CPTVF_DRV_NAME, 42862306a36Sopenharmony_ci .id_table = otx2_cptvf_id_table, 42962306a36Sopenharmony_ci .probe = otx2_cptvf_probe, 43062306a36Sopenharmony_ci .remove = otx2_cptvf_remove, 43162306a36Sopenharmony_ci}; 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_cimodule_pci_driver(otx2_cptvf_pci_driver); 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ciMODULE_IMPORT_NS(CRYPTO_DEV_OCTEONTX2_CPT); 43662306a36Sopenharmony_ci 43762306a36Sopenharmony_ciMODULE_AUTHOR("Marvell"); 43862306a36Sopenharmony_ciMODULE_DESCRIPTION("Marvell RVU CPT Virtual Function Driver"); 43962306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 44062306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, otx2_cptvf_id_table); 441