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_cptlf.h" 662306a36Sopenharmony_ci#include "rvu_reg.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#define CPT_TIMER_HOLD 0x03F 962306a36Sopenharmony_ci#define CPT_COUNT_HOLD 32 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_cistatic void cptlf_do_set_done_time_wait(struct otx2_cptlf_info *lf, 1262306a36Sopenharmony_ci int time_wait) 1362306a36Sopenharmony_ci{ 1462306a36Sopenharmony_ci union otx2_cptx_lf_done_wait done_wait; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci done_wait.u = otx2_cpt_read64(lf->lfs->reg_base, lf->lfs->blkaddr, 1762306a36Sopenharmony_ci lf->slot, OTX2_CPT_LF_DONE_WAIT); 1862306a36Sopenharmony_ci done_wait.s.time_wait = time_wait; 1962306a36Sopenharmony_ci otx2_cpt_write64(lf->lfs->reg_base, lf->lfs->blkaddr, lf->slot, 2062306a36Sopenharmony_ci OTX2_CPT_LF_DONE_WAIT, done_wait.u); 2162306a36Sopenharmony_ci} 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic void cptlf_do_set_done_num_wait(struct otx2_cptlf_info *lf, int num_wait) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci union otx2_cptx_lf_done_wait done_wait; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci done_wait.u = otx2_cpt_read64(lf->lfs->reg_base, lf->lfs->blkaddr, 2862306a36Sopenharmony_ci lf->slot, OTX2_CPT_LF_DONE_WAIT); 2962306a36Sopenharmony_ci done_wait.s.num_wait = num_wait; 3062306a36Sopenharmony_ci otx2_cpt_write64(lf->lfs->reg_base, lf->lfs->blkaddr, lf->slot, 3162306a36Sopenharmony_ci OTX2_CPT_LF_DONE_WAIT, done_wait.u); 3262306a36Sopenharmony_ci} 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistatic void cptlf_set_done_time_wait(struct otx2_cptlfs_info *lfs, 3562306a36Sopenharmony_ci int time_wait) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci int slot; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) 4062306a36Sopenharmony_ci cptlf_do_set_done_time_wait(&lfs->lf[slot], time_wait); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistatic void cptlf_set_done_num_wait(struct otx2_cptlfs_info *lfs, int num_wait) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci int slot; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) 4862306a36Sopenharmony_ci cptlf_do_set_done_num_wait(&lfs->lf[slot], num_wait); 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic int cptlf_set_pri(struct otx2_cptlf_info *lf, int pri) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci struct otx2_cptlfs_info *lfs = lf->lfs; 5462306a36Sopenharmony_ci union otx2_cptx_af_lf_ctrl lf_ctrl; 5562306a36Sopenharmony_ci int ret; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci ret = otx2_cpt_read_af_reg(lfs->mbox, lfs->pdev, 5862306a36Sopenharmony_ci CPT_AF_LFX_CTL(lf->slot), 5962306a36Sopenharmony_ci &lf_ctrl.u, lfs->blkaddr); 6062306a36Sopenharmony_ci if (ret) 6162306a36Sopenharmony_ci return ret; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci lf_ctrl.s.pri = pri ? 1 : 0; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci ret = otx2_cpt_write_af_reg(lfs->mbox, lfs->pdev, 6662306a36Sopenharmony_ci CPT_AF_LFX_CTL(lf->slot), 6762306a36Sopenharmony_ci lf_ctrl.u, lfs->blkaddr); 6862306a36Sopenharmony_ci return ret; 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic int cptlf_set_eng_grps_mask(struct otx2_cptlf_info *lf, 7262306a36Sopenharmony_ci int eng_grps_mask) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci struct otx2_cptlfs_info *lfs = lf->lfs; 7562306a36Sopenharmony_ci union otx2_cptx_af_lf_ctrl lf_ctrl; 7662306a36Sopenharmony_ci int ret; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci ret = otx2_cpt_read_af_reg(lfs->mbox, lfs->pdev, 7962306a36Sopenharmony_ci CPT_AF_LFX_CTL(lf->slot), 8062306a36Sopenharmony_ci &lf_ctrl.u, lfs->blkaddr); 8162306a36Sopenharmony_ci if (ret) 8262306a36Sopenharmony_ci return ret; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci lf_ctrl.s.grp = eng_grps_mask; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci ret = otx2_cpt_write_af_reg(lfs->mbox, lfs->pdev, 8762306a36Sopenharmony_ci CPT_AF_LFX_CTL(lf->slot), 8862306a36Sopenharmony_ci lf_ctrl.u, lfs->blkaddr); 8962306a36Sopenharmony_ci return ret; 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic int cptlf_set_grp_and_pri(struct otx2_cptlfs_info *lfs, 9362306a36Sopenharmony_ci int eng_grp_mask, int pri) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci int slot, ret = 0; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) { 9862306a36Sopenharmony_ci ret = cptlf_set_pri(&lfs->lf[slot], pri); 9962306a36Sopenharmony_ci if (ret) 10062306a36Sopenharmony_ci return ret; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci ret = cptlf_set_eng_grps_mask(&lfs->lf[slot], eng_grp_mask); 10362306a36Sopenharmony_ci if (ret) 10462306a36Sopenharmony_ci return ret; 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci return ret; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic void cptlf_hw_init(struct otx2_cptlfs_info *lfs) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci /* Disable instruction queues */ 11262306a36Sopenharmony_ci otx2_cptlf_disable_iqueues(lfs); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci /* Set instruction queues base addresses */ 11562306a36Sopenharmony_ci otx2_cptlf_set_iqueues_base_addr(lfs); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci /* Set instruction queues sizes */ 11862306a36Sopenharmony_ci otx2_cptlf_set_iqueues_size(lfs); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci /* Set done interrupts time wait */ 12162306a36Sopenharmony_ci cptlf_set_done_time_wait(lfs, CPT_TIMER_HOLD); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci /* Set done interrupts num wait */ 12462306a36Sopenharmony_ci cptlf_set_done_num_wait(lfs, CPT_COUNT_HOLD); 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci /* Enable instruction queues */ 12762306a36Sopenharmony_ci otx2_cptlf_enable_iqueues(lfs); 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_cistatic void cptlf_hw_cleanup(struct otx2_cptlfs_info *lfs) 13162306a36Sopenharmony_ci{ 13262306a36Sopenharmony_ci /* Disable instruction queues */ 13362306a36Sopenharmony_ci otx2_cptlf_disable_iqueues(lfs); 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic void cptlf_set_misc_intrs(struct otx2_cptlfs_info *lfs, u8 enable) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci union otx2_cptx_lf_misc_int_ena_w1s irq_misc = { .u = 0x0 }; 13962306a36Sopenharmony_ci u64 reg = enable ? OTX2_CPT_LF_MISC_INT_ENA_W1S : 14062306a36Sopenharmony_ci OTX2_CPT_LF_MISC_INT_ENA_W1C; 14162306a36Sopenharmony_ci int slot; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci irq_misc.s.fault = 0x1; 14462306a36Sopenharmony_ci irq_misc.s.hwerr = 0x1; 14562306a36Sopenharmony_ci irq_misc.s.irde = 0x1; 14662306a36Sopenharmony_ci irq_misc.s.nqerr = 0x1; 14762306a36Sopenharmony_ci irq_misc.s.nwrp = 0x1; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) 15062306a36Sopenharmony_ci otx2_cpt_write64(lfs->reg_base, lfs->blkaddr, slot, reg, 15162306a36Sopenharmony_ci irq_misc.u); 15262306a36Sopenharmony_ci} 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_cistatic void cptlf_enable_intrs(struct otx2_cptlfs_info *lfs) 15562306a36Sopenharmony_ci{ 15662306a36Sopenharmony_ci int slot; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* Enable done interrupts */ 15962306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) 16062306a36Sopenharmony_ci otx2_cpt_write64(lfs->reg_base, lfs->blkaddr, slot, 16162306a36Sopenharmony_ci OTX2_CPT_LF_DONE_INT_ENA_W1S, 0x1); 16262306a36Sopenharmony_ci /* Enable Misc interrupts */ 16362306a36Sopenharmony_ci cptlf_set_misc_intrs(lfs, true); 16462306a36Sopenharmony_ci} 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistatic void cptlf_disable_intrs(struct otx2_cptlfs_info *lfs) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci int slot; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) 17162306a36Sopenharmony_ci otx2_cpt_write64(lfs->reg_base, lfs->blkaddr, slot, 17262306a36Sopenharmony_ci OTX2_CPT_LF_DONE_INT_ENA_W1C, 0x1); 17362306a36Sopenharmony_ci cptlf_set_misc_intrs(lfs, false); 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic inline int cptlf_read_done_cnt(struct otx2_cptlf_info *lf) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci union otx2_cptx_lf_done irq_cnt; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci irq_cnt.u = otx2_cpt_read64(lf->lfs->reg_base, lf->lfs->blkaddr, lf->slot, 18162306a36Sopenharmony_ci OTX2_CPT_LF_DONE); 18262306a36Sopenharmony_ci return irq_cnt.s.done; 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic irqreturn_t cptlf_misc_intr_handler(int __always_unused irq, void *arg) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci union otx2_cptx_lf_misc_int irq_misc, irq_misc_ack; 18862306a36Sopenharmony_ci struct otx2_cptlf_info *lf = arg; 18962306a36Sopenharmony_ci struct device *dev; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci dev = &lf->lfs->pdev->dev; 19262306a36Sopenharmony_ci irq_misc.u = otx2_cpt_read64(lf->lfs->reg_base, lf->lfs->blkaddr, 19362306a36Sopenharmony_ci lf->slot, OTX2_CPT_LF_MISC_INT); 19462306a36Sopenharmony_ci irq_misc_ack.u = 0x0; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci if (irq_misc.s.fault) { 19762306a36Sopenharmony_ci dev_err(dev, "Memory error detected while executing CPT_INST_S, LF %d.\n", 19862306a36Sopenharmony_ci lf->slot); 19962306a36Sopenharmony_ci irq_misc_ack.s.fault = 0x1; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci } else if (irq_misc.s.hwerr) { 20262306a36Sopenharmony_ci dev_err(dev, "HW error from an engine executing CPT_INST_S, LF %d.", 20362306a36Sopenharmony_ci lf->slot); 20462306a36Sopenharmony_ci irq_misc_ack.s.hwerr = 0x1; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci } else if (irq_misc.s.nwrp) { 20762306a36Sopenharmony_ci dev_err(dev, "SMMU fault while writing CPT_RES_S to CPT_INST_S[RES_ADDR], LF %d.\n", 20862306a36Sopenharmony_ci lf->slot); 20962306a36Sopenharmony_ci irq_misc_ack.s.nwrp = 0x1; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci } else if (irq_misc.s.irde) { 21262306a36Sopenharmony_ci dev_err(dev, "Memory error when accessing instruction memory queue CPT_LF_Q_BASE[ADDR].\n"); 21362306a36Sopenharmony_ci irq_misc_ack.s.irde = 0x1; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci } else if (irq_misc.s.nqerr) { 21662306a36Sopenharmony_ci dev_err(dev, "Error enqueuing an instruction received at CPT_LF_NQ.\n"); 21762306a36Sopenharmony_ci irq_misc_ack.s.nqerr = 0x1; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci } else { 22062306a36Sopenharmony_ci dev_err(dev, "Unhandled interrupt in CPT LF %d\n", lf->slot); 22162306a36Sopenharmony_ci return IRQ_NONE; 22262306a36Sopenharmony_ci } 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci /* Acknowledge interrupts */ 22562306a36Sopenharmony_ci otx2_cpt_write64(lf->lfs->reg_base, lf->lfs->blkaddr, lf->slot, 22662306a36Sopenharmony_ci OTX2_CPT_LF_MISC_INT, irq_misc_ack.u); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci return IRQ_HANDLED; 22962306a36Sopenharmony_ci} 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_cistatic irqreturn_t cptlf_done_intr_handler(int irq, void *arg) 23262306a36Sopenharmony_ci{ 23362306a36Sopenharmony_ci union otx2_cptx_lf_done_wait done_wait; 23462306a36Sopenharmony_ci struct otx2_cptlf_info *lf = arg; 23562306a36Sopenharmony_ci int irq_cnt; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci /* Read the number of completed requests */ 23862306a36Sopenharmony_ci irq_cnt = cptlf_read_done_cnt(lf); 23962306a36Sopenharmony_ci if (irq_cnt) { 24062306a36Sopenharmony_ci done_wait.u = otx2_cpt_read64(lf->lfs->reg_base, lf->lfs->blkaddr, 24162306a36Sopenharmony_ci lf->slot, OTX2_CPT_LF_DONE_WAIT); 24262306a36Sopenharmony_ci /* Acknowledge the number of completed requests */ 24362306a36Sopenharmony_ci otx2_cpt_write64(lf->lfs->reg_base, lf->lfs->blkaddr, lf->slot, 24462306a36Sopenharmony_ci OTX2_CPT_LF_DONE_ACK, irq_cnt); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci otx2_cpt_write64(lf->lfs->reg_base, lf->lfs->blkaddr, lf->slot, 24762306a36Sopenharmony_ci OTX2_CPT_LF_DONE_WAIT, done_wait.u); 24862306a36Sopenharmony_ci if (unlikely(!lf->wqe)) { 24962306a36Sopenharmony_ci dev_err(&lf->lfs->pdev->dev, "No work for LF %d\n", 25062306a36Sopenharmony_ci lf->slot); 25162306a36Sopenharmony_ci return IRQ_NONE; 25262306a36Sopenharmony_ci } 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci /* Schedule processing of completed requests */ 25562306a36Sopenharmony_ci tasklet_hi_schedule(&lf->wqe->work); 25662306a36Sopenharmony_ci } 25762306a36Sopenharmony_ci return IRQ_HANDLED; 25862306a36Sopenharmony_ci} 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_civoid otx2_cptlf_unregister_interrupts(struct otx2_cptlfs_info *lfs) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci int i, offs, vector; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci for (i = 0; i < lfs->lfs_num; i++) { 26562306a36Sopenharmony_ci for (offs = 0; offs < OTX2_CPT_LF_MSIX_VECTORS; offs++) { 26662306a36Sopenharmony_ci if (!lfs->lf[i].is_irq_reg[offs]) 26762306a36Sopenharmony_ci continue; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci vector = pci_irq_vector(lfs->pdev, 27062306a36Sopenharmony_ci lfs->lf[i].msix_offset + offs); 27162306a36Sopenharmony_ci free_irq(vector, &lfs->lf[i]); 27262306a36Sopenharmony_ci lfs->lf[i].is_irq_reg[offs] = false; 27362306a36Sopenharmony_ci } 27462306a36Sopenharmony_ci } 27562306a36Sopenharmony_ci cptlf_disable_intrs(lfs); 27662306a36Sopenharmony_ci} 27762306a36Sopenharmony_ciEXPORT_SYMBOL_NS_GPL(otx2_cptlf_unregister_interrupts, 27862306a36Sopenharmony_ci CRYPTO_DEV_OCTEONTX2_CPT); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_cistatic int cptlf_do_register_interrrupts(struct otx2_cptlfs_info *lfs, 28162306a36Sopenharmony_ci int lf_num, int irq_offset, 28262306a36Sopenharmony_ci irq_handler_t handler) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci int ret, vector; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci vector = pci_irq_vector(lfs->pdev, lfs->lf[lf_num].msix_offset + 28762306a36Sopenharmony_ci irq_offset); 28862306a36Sopenharmony_ci ret = request_irq(vector, handler, 0, 28962306a36Sopenharmony_ci lfs->lf[lf_num].irq_name[irq_offset], 29062306a36Sopenharmony_ci &lfs->lf[lf_num]); 29162306a36Sopenharmony_ci if (ret) 29262306a36Sopenharmony_ci return ret; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci lfs->lf[lf_num].is_irq_reg[irq_offset] = true; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci return ret; 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ciint otx2_cptlf_register_interrupts(struct otx2_cptlfs_info *lfs) 30062306a36Sopenharmony_ci{ 30162306a36Sopenharmony_ci int irq_offs, ret, i; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci for (i = 0; i < lfs->lfs_num; i++) { 30462306a36Sopenharmony_ci irq_offs = OTX2_CPT_LF_INT_VEC_E_MISC; 30562306a36Sopenharmony_ci snprintf(lfs->lf[i].irq_name[irq_offs], 32, "CPTLF Misc%d", i); 30662306a36Sopenharmony_ci ret = cptlf_do_register_interrrupts(lfs, i, irq_offs, 30762306a36Sopenharmony_ci cptlf_misc_intr_handler); 30862306a36Sopenharmony_ci if (ret) 30962306a36Sopenharmony_ci goto free_irq; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci irq_offs = OTX2_CPT_LF_INT_VEC_E_DONE; 31262306a36Sopenharmony_ci snprintf(lfs->lf[i].irq_name[irq_offs], 32, "OTX2_CPTLF Done%d", 31362306a36Sopenharmony_ci i); 31462306a36Sopenharmony_ci ret = cptlf_do_register_interrrupts(lfs, i, irq_offs, 31562306a36Sopenharmony_ci cptlf_done_intr_handler); 31662306a36Sopenharmony_ci if (ret) 31762306a36Sopenharmony_ci goto free_irq; 31862306a36Sopenharmony_ci } 31962306a36Sopenharmony_ci cptlf_enable_intrs(lfs); 32062306a36Sopenharmony_ci return 0; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cifree_irq: 32362306a36Sopenharmony_ci otx2_cptlf_unregister_interrupts(lfs); 32462306a36Sopenharmony_ci return ret; 32562306a36Sopenharmony_ci} 32662306a36Sopenharmony_ciEXPORT_SYMBOL_NS_GPL(otx2_cptlf_register_interrupts, CRYPTO_DEV_OCTEONTX2_CPT); 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_civoid otx2_cptlf_free_irqs_affinity(struct otx2_cptlfs_info *lfs) 32962306a36Sopenharmony_ci{ 33062306a36Sopenharmony_ci int slot, offs; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) { 33362306a36Sopenharmony_ci for (offs = 0; offs < OTX2_CPT_LF_MSIX_VECTORS; offs++) 33462306a36Sopenharmony_ci irq_set_affinity_hint(pci_irq_vector(lfs->pdev, 33562306a36Sopenharmony_ci lfs->lf[slot].msix_offset + 33662306a36Sopenharmony_ci offs), NULL); 33762306a36Sopenharmony_ci free_cpumask_var(lfs->lf[slot].affinity_mask); 33862306a36Sopenharmony_ci } 33962306a36Sopenharmony_ci} 34062306a36Sopenharmony_ciEXPORT_SYMBOL_NS_GPL(otx2_cptlf_free_irqs_affinity, CRYPTO_DEV_OCTEONTX2_CPT); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ciint otx2_cptlf_set_irqs_affinity(struct otx2_cptlfs_info *lfs) 34362306a36Sopenharmony_ci{ 34462306a36Sopenharmony_ci struct otx2_cptlf_info *lf = lfs->lf; 34562306a36Sopenharmony_ci int slot, offs, ret; 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) { 34862306a36Sopenharmony_ci if (!zalloc_cpumask_var(&lf[slot].affinity_mask, GFP_KERNEL)) { 34962306a36Sopenharmony_ci dev_err(&lfs->pdev->dev, 35062306a36Sopenharmony_ci "cpumask allocation failed for LF %d", slot); 35162306a36Sopenharmony_ci ret = -ENOMEM; 35262306a36Sopenharmony_ci goto free_affinity_mask; 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci cpumask_set_cpu(cpumask_local_spread(slot, 35662306a36Sopenharmony_ci dev_to_node(&lfs->pdev->dev)), 35762306a36Sopenharmony_ci lf[slot].affinity_mask); 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci for (offs = 0; offs < OTX2_CPT_LF_MSIX_VECTORS; offs++) { 36062306a36Sopenharmony_ci ret = irq_set_affinity_hint(pci_irq_vector(lfs->pdev, 36162306a36Sopenharmony_ci lf[slot].msix_offset + offs), 36262306a36Sopenharmony_ci lf[slot].affinity_mask); 36362306a36Sopenharmony_ci if (ret) 36462306a36Sopenharmony_ci goto free_affinity_mask; 36562306a36Sopenharmony_ci } 36662306a36Sopenharmony_ci } 36762306a36Sopenharmony_ci return 0; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_cifree_affinity_mask: 37062306a36Sopenharmony_ci otx2_cptlf_free_irqs_affinity(lfs); 37162306a36Sopenharmony_ci return ret; 37262306a36Sopenharmony_ci} 37362306a36Sopenharmony_ciEXPORT_SYMBOL_NS_GPL(otx2_cptlf_set_irqs_affinity, CRYPTO_DEV_OCTEONTX2_CPT); 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ciint otx2_cptlf_init(struct otx2_cptlfs_info *lfs, u8 eng_grp_mask, int pri, 37662306a36Sopenharmony_ci int lfs_num) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci int slot, ret; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci if (!lfs->pdev || !lfs->reg_base) 38162306a36Sopenharmony_ci return -EINVAL; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci lfs->lfs_num = lfs_num; 38462306a36Sopenharmony_ci for (slot = 0; slot < lfs->lfs_num; slot++) { 38562306a36Sopenharmony_ci lfs->lf[slot].lfs = lfs; 38662306a36Sopenharmony_ci lfs->lf[slot].slot = slot; 38762306a36Sopenharmony_ci if (lfs->lmt_base) 38862306a36Sopenharmony_ci lfs->lf[slot].lmtline = lfs->lmt_base + 38962306a36Sopenharmony_ci (slot * LMTLINE_SIZE); 39062306a36Sopenharmony_ci else 39162306a36Sopenharmony_ci lfs->lf[slot].lmtline = lfs->reg_base + 39262306a36Sopenharmony_ci OTX2_CPT_RVU_FUNC_ADDR_S(BLKADDR_LMT, slot, 39362306a36Sopenharmony_ci OTX2_CPT_LMT_LF_LMTLINEX(0)); 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci lfs->lf[slot].ioreg = lfs->reg_base + 39662306a36Sopenharmony_ci OTX2_CPT_RVU_FUNC_ADDR_S(lfs->blkaddr, slot, 39762306a36Sopenharmony_ci OTX2_CPT_LF_NQX(0)); 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci /* Send request to attach LFs */ 40062306a36Sopenharmony_ci ret = otx2_cpt_attach_rscrs_msg(lfs); 40162306a36Sopenharmony_ci if (ret) 40262306a36Sopenharmony_ci goto clear_lfs_num; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci ret = otx2_cpt_alloc_instruction_queues(lfs); 40562306a36Sopenharmony_ci if (ret) { 40662306a36Sopenharmony_ci dev_err(&lfs->pdev->dev, 40762306a36Sopenharmony_ci "Allocating instruction queues failed\n"); 40862306a36Sopenharmony_ci goto detach_rsrcs; 40962306a36Sopenharmony_ci } 41062306a36Sopenharmony_ci cptlf_hw_init(lfs); 41162306a36Sopenharmony_ci /* 41262306a36Sopenharmony_ci * Allow each LF to execute requests destined to any of 8 engine 41362306a36Sopenharmony_ci * groups and set queue priority of each LF to high 41462306a36Sopenharmony_ci */ 41562306a36Sopenharmony_ci ret = cptlf_set_grp_and_pri(lfs, eng_grp_mask, pri); 41662306a36Sopenharmony_ci if (ret) 41762306a36Sopenharmony_ci goto free_iq; 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci return 0; 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_cifree_iq: 42262306a36Sopenharmony_ci cptlf_hw_cleanup(lfs); 42362306a36Sopenharmony_ci otx2_cpt_free_instruction_queues(lfs); 42462306a36Sopenharmony_cidetach_rsrcs: 42562306a36Sopenharmony_ci otx2_cpt_detach_rsrcs_msg(lfs); 42662306a36Sopenharmony_ciclear_lfs_num: 42762306a36Sopenharmony_ci lfs->lfs_num = 0; 42862306a36Sopenharmony_ci return ret; 42962306a36Sopenharmony_ci} 43062306a36Sopenharmony_ciEXPORT_SYMBOL_NS_GPL(otx2_cptlf_init, CRYPTO_DEV_OCTEONTX2_CPT); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_civoid otx2_cptlf_shutdown(struct otx2_cptlfs_info *lfs) 43362306a36Sopenharmony_ci{ 43462306a36Sopenharmony_ci /* Cleanup LFs hardware side */ 43562306a36Sopenharmony_ci cptlf_hw_cleanup(lfs); 43662306a36Sopenharmony_ci /* Free instruction queues */ 43762306a36Sopenharmony_ci otx2_cpt_free_instruction_queues(lfs); 43862306a36Sopenharmony_ci /* Send request to detach LFs */ 43962306a36Sopenharmony_ci otx2_cpt_detach_rsrcs_msg(lfs); 44062306a36Sopenharmony_ci lfs->lfs_num = 0; 44162306a36Sopenharmony_ci} 44262306a36Sopenharmony_ciEXPORT_SYMBOL_NS_GPL(otx2_cptlf_shutdown, CRYPTO_DEV_OCTEONTX2_CPT); 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ciMODULE_AUTHOR("Marvell"); 44562306a36Sopenharmony_ciMODULE_DESCRIPTION("Marvell RVU CPT Common module"); 44662306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 447