162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/pci.h> 362306a36Sopenharmony_ci#include <linux/printk.h> 462306a36Sopenharmony_ci#include <linux/slab.h> 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include "nitrox_dev.h" 762306a36Sopenharmony_ci#include "nitrox_csr.h" 862306a36Sopenharmony_ci#include "nitrox_common.h" 962306a36Sopenharmony_ci#include "nitrox_hal.h" 1062306a36Sopenharmony_ci#include "nitrox_isr.h" 1162306a36Sopenharmony_ci#include "nitrox_mbx.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci/* 1462306a36Sopenharmony_ci * One vector for each type of ring 1562306a36Sopenharmony_ci * - NPS packet ring, AQMQ ring and ZQMQ ring 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci#define NR_RING_VECTORS 3 1862306a36Sopenharmony_ci#define NR_NON_RING_VECTORS 1 1962306a36Sopenharmony_ci/* base entry for packet ring/port */ 2062306a36Sopenharmony_ci#define PKT_RING_MSIX_BASE 0 2162306a36Sopenharmony_ci#define NON_RING_MSIX_BASE 192 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/** 2462306a36Sopenharmony_ci * nps_pkt_slc_isr - IRQ handler for NPS solicit port 2562306a36Sopenharmony_ci * @irq: irq number 2662306a36Sopenharmony_ci * @data: argument 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_cistatic irqreturn_t nps_pkt_slc_isr(int irq, void *data) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci struct nitrox_q_vector *qvec = data; 3162306a36Sopenharmony_ci union nps_pkt_slc_cnts slc_cnts; 3262306a36Sopenharmony_ci struct nitrox_cmdq *cmdq = qvec->cmdq; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci slc_cnts.value = readq(cmdq->compl_cnt_csr_addr); 3562306a36Sopenharmony_ci /* New packet on SLC output port */ 3662306a36Sopenharmony_ci if (slc_cnts.s.slc_int) 3762306a36Sopenharmony_ci tasklet_hi_schedule(&qvec->resp_tasklet); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci return IRQ_HANDLED; 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic void clear_nps_core_err_intr(struct nitrox_device *ndev) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci u64 value; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci /* Write 1 to clear */ 4762306a36Sopenharmony_ci value = nitrox_read_csr(ndev, NPS_CORE_INT); 4862306a36Sopenharmony_ci nitrox_write_csr(ndev, NPS_CORE_INT, value); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), "NSP_CORE_INT 0x%016llx\n", value); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cistatic void clear_nps_pkt_err_intr(struct nitrox_device *ndev) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci union nps_pkt_int pkt_int; 5662306a36Sopenharmony_ci unsigned long value, offset; 5762306a36Sopenharmony_ci int i; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci pkt_int.value = nitrox_read_csr(ndev, NPS_PKT_INT); 6062306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), "NPS_PKT_INT 0x%016llx\n", 6162306a36Sopenharmony_ci pkt_int.value); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci if (pkt_int.s.slc_err) { 6462306a36Sopenharmony_ci offset = NPS_PKT_SLC_ERR_TYPE; 6562306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 6662306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 6762306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), 6862306a36Sopenharmony_ci "NPS_PKT_SLC_ERR_TYPE 0x%016lx\n", value); 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci offset = NPS_PKT_SLC_RERR_LO; 7162306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 7262306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 7362306a36Sopenharmony_ci /* enable the solicit ports */ 7462306a36Sopenharmony_ci for_each_set_bit(i, &value, BITS_PER_LONG) 7562306a36Sopenharmony_ci enable_pkt_solicit_port(ndev, i); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), 7862306a36Sopenharmony_ci "NPS_PKT_SLC_RERR_LO 0x%016lx\n", value); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci offset = NPS_PKT_SLC_RERR_HI; 8162306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 8262306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 8362306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), 8462306a36Sopenharmony_ci "NPS_PKT_SLC_RERR_HI 0x%016lx\n", value); 8562306a36Sopenharmony_ci } 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci if (pkt_int.s.in_err) { 8862306a36Sopenharmony_ci offset = NPS_PKT_IN_ERR_TYPE; 8962306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 9062306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 9162306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), 9262306a36Sopenharmony_ci "NPS_PKT_IN_ERR_TYPE 0x%016lx\n", value); 9362306a36Sopenharmony_ci offset = NPS_PKT_IN_RERR_LO; 9462306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 9562306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 9662306a36Sopenharmony_ci /* enable the input ring */ 9762306a36Sopenharmony_ci for_each_set_bit(i, &value, BITS_PER_LONG) 9862306a36Sopenharmony_ci enable_pkt_input_ring(ndev, i); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), 10162306a36Sopenharmony_ci "NPS_PKT_IN_RERR_LO 0x%016lx\n", value); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci offset = NPS_PKT_IN_RERR_HI; 10462306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 10562306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 10662306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), 10762306a36Sopenharmony_ci "NPS_PKT_IN_RERR_HI 0x%016lx\n", value); 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic void clear_pom_err_intr(struct nitrox_device *ndev) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci u64 value; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci value = nitrox_read_csr(ndev, POM_INT); 11662306a36Sopenharmony_ci nitrox_write_csr(ndev, POM_INT, value); 11762306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), "POM_INT 0x%016llx\n", value); 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistatic void clear_pem_err_intr(struct nitrox_device *ndev) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci u64 value; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci value = nitrox_read_csr(ndev, PEM0_INT); 12562306a36Sopenharmony_ci nitrox_write_csr(ndev, PEM0_INT, value); 12662306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), "PEM(0)_INT 0x%016llx\n", value); 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cistatic void clear_lbc_err_intr(struct nitrox_device *ndev) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci union lbc_int lbc_int; 13262306a36Sopenharmony_ci u64 value, offset; 13362306a36Sopenharmony_ci int i; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci lbc_int.value = nitrox_read_csr(ndev, LBC_INT); 13662306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), "LBC_INT 0x%016llx\n", lbc_int.value); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci if (lbc_int.s.dma_rd_err) { 13962306a36Sopenharmony_ci for (i = 0; i < NR_CLUSTERS; i++) { 14062306a36Sopenharmony_ci offset = EFL_CORE_VF_ERR_INT0X(i); 14162306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 14262306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 14362306a36Sopenharmony_ci offset = EFL_CORE_VF_ERR_INT1X(i); 14462306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 14562306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci if (lbc_int.s.cam_soft_err) { 15062306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), "CAM_SOFT_ERR, invalidating LBC\n"); 15162306a36Sopenharmony_ci invalidate_lbc(ndev); 15262306a36Sopenharmony_ci } 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci if (lbc_int.s.pref_dat_len_mismatch_err) { 15562306a36Sopenharmony_ci offset = LBC_PLM_VF1_64_INT; 15662306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 15762306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 15862306a36Sopenharmony_ci offset = LBC_PLM_VF65_128_INT; 15962306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 16062306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 16162306a36Sopenharmony_ci } 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci if (lbc_int.s.rd_dat_len_mismatch_err) { 16462306a36Sopenharmony_ci offset = LBC_ELM_VF1_64_INT; 16562306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 16662306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 16762306a36Sopenharmony_ci offset = LBC_ELM_VF65_128_INT; 16862306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 16962306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci nitrox_write_csr(ndev, LBC_INT, lbc_int.value); 17262306a36Sopenharmony_ci} 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic void clear_efl_err_intr(struct nitrox_device *ndev) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci int i; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci for (i = 0; i < NR_CLUSTERS; i++) { 17962306a36Sopenharmony_ci union efl_core_int core_int; 18062306a36Sopenharmony_ci u64 value, offset; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci offset = EFL_CORE_INTX(i); 18362306a36Sopenharmony_ci core_int.value = nitrox_read_csr(ndev, offset); 18462306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, core_int.value); 18562306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), "ELF_CORE(%d)_INT 0x%016llx\n", 18662306a36Sopenharmony_ci i, core_int.value); 18762306a36Sopenharmony_ci if (core_int.s.se_err) { 18862306a36Sopenharmony_ci offset = EFL_CORE_SE_ERR_INTX(i); 18962306a36Sopenharmony_ci value = nitrox_read_csr(ndev, offset); 19062306a36Sopenharmony_ci nitrox_write_csr(ndev, offset, value); 19162306a36Sopenharmony_ci } 19262306a36Sopenharmony_ci } 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic void clear_bmi_err_intr(struct nitrox_device *ndev) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci u64 value; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci value = nitrox_read_csr(ndev, BMI_INT); 20062306a36Sopenharmony_ci nitrox_write_csr(ndev, BMI_INT, value); 20162306a36Sopenharmony_ci dev_err_ratelimited(DEV(ndev), "BMI_INT 0x%016llx\n", value); 20262306a36Sopenharmony_ci} 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_cistatic void nps_core_int_tasklet(unsigned long data) 20562306a36Sopenharmony_ci{ 20662306a36Sopenharmony_ci struct nitrox_q_vector *qvec = (void *)(uintptr_t)(data); 20762306a36Sopenharmony_ci struct nitrox_device *ndev = qvec->ndev; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci /* if pf mode do queue recovery */ 21062306a36Sopenharmony_ci if (ndev->mode == __NDEV_MODE_PF) { 21162306a36Sopenharmony_ci } else { 21262306a36Sopenharmony_ci /** 21362306a36Sopenharmony_ci * if VF(s) enabled communicate the error information 21462306a36Sopenharmony_ci * to VF(s) 21562306a36Sopenharmony_ci */ 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci/* 22062306a36Sopenharmony_ci * nps_core_int_isr - interrupt handler for NITROX errors and 22162306a36Sopenharmony_ci * mailbox communication 22262306a36Sopenharmony_ci */ 22362306a36Sopenharmony_cistatic irqreturn_t nps_core_int_isr(int irq, void *data) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci struct nitrox_q_vector *qvec = data; 22662306a36Sopenharmony_ci struct nitrox_device *ndev = qvec->ndev; 22762306a36Sopenharmony_ci union nps_core_int_active core_int; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci core_int.value = nitrox_read_csr(ndev, NPS_CORE_INT_ACTIVE); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci if (core_int.s.nps_core) 23262306a36Sopenharmony_ci clear_nps_core_err_intr(ndev); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci if (core_int.s.nps_pkt) 23562306a36Sopenharmony_ci clear_nps_pkt_err_intr(ndev); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci if (core_int.s.pom) 23862306a36Sopenharmony_ci clear_pom_err_intr(ndev); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci if (core_int.s.pem) 24162306a36Sopenharmony_ci clear_pem_err_intr(ndev); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci if (core_int.s.lbc) 24462306a36Sopenharmony_ci clear_lbc_err_intr(ndev); 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci if (core_int.s.efl) 24762306a36Sopenharmony_ci clear_efl_err_intr(ndev); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci if (core_int.s.bmi) 25062306a36Sopenharmony_ci clear_bmi_err_intr(ndev); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci /* Mailbox interrupt */ 25362306a36Sopenharmony_ci if (core_int.s.mbox) 25462306a36Sopenharmony_ci nitrox_pf2vf_mbox_handler(ndev); 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci /* If more work callback the ISR, set resend */ 25762306a36Sopenharmony_ci core_int.s.resend = 1; 25862306a36Sopenharmony_ci nitrox_write_csr(ndev, NPS_CORE_INT_ACTIVE, core_int.value); 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci return IRQ_HANDLED; 26162306a36Sopenharmony_ci} 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_civoid nitrox_unregister_interrupts(struct nitrox_device *ndev) 26462306a36Sopenharmony_ci{ 26562306a36Sopenharmony_ci struct pci_dev *pdev = ndev->pdev; 26662306a36Sopenharmony_ci int i; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci for (i = 0; i < ndev->num_vecs; i++) { 26962306a36Sopenharmony_ci struct nitrox_q_vector *qvec; 27062306a36Sopenharmony_ci int vec; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci qvec = ndev->qvec + i; 27362306a36Sopenharmony_ci if (!qvec->valid) 27462306a36Sopenharmony_ci continue; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci /* get the vector number */ 27762306a36Sopenharmony_ci vec = pci_irq_vector(pdev, i); 27862306a36Sopenharmony_ci irq_set_affinity_hint(vec, NULL); 27962306a36Sopenharmony_ci free_irq(vec, qvec); 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci tasklet_disable(&qvec->resp_tasklet); 28262306a36Sopenharmony_ci tasklet_kill(&qvec->resp_tasklet); 28362306a36Sopenharmony_ci qvec->valid = false; 28462306a36Sopenharmony_ci } 28562306a36Sopenharmony_ci kfree(ndev->qvec); 28662306a36Sopenharmony_ci ndev->qvec = NULL; 28762306a36Sopenharmony_ci pci_free_irq_vectors(pdev); 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ciint nitrox_register_interrupts(struct nitrox_device *ndev) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci struct pci_dev *pdev = ndev->pdev; 29362306a36Sopenharmony_ci struct nitrox_q_vector *qvec; 29462306a36Sopenharmony_ci int nr_vecs, vec, cpu; 29562306a36Sopenharmony_ci int ret, i; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci /* 29862306a36Sopenharmony_ci * PF MSI-X vectors 29962306a36Sopenharmony_ci * 30062306a36Sopenharmony_ci * Entry 0: NPS PKT ring 0 30162306a36Sopenharmony_ci * Entry 1: AQMQ ring 0 30262306a36Sopenharmony_ci * Entry 2: ZQM ring 0 30362306a36Sopenharmony_ci * Entry 3: NPS PKT ring 1 30462306a36Sopenharmony_ci * Entry 4: AQMQ ring 1 30562306a36Sopenharmony_ci * Entry 5: ZQM ring 1 30662306a36Sopenharmony_ci * .... 30762306a36Sopenharmony_ci * Entry 192: NPS_CORE_INT_ACTIVE 30862306a36Sopenharmony_ci */ 30962306a36Sopenharmony_ci nr_vecs = pci_msix_vec_count(pdev); 31062306a36Sopenharmony_ci if (nr_vecs < 0) { 31162306a36Sopenharmony_ci dev_err(DEV(ndev), "Error in getting vec count %d\n", nr_vecs); 31262306a36Sopenharmony_ci return nr_vecs; 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* Enable MSI-X */ 31662306a36Sopenharmony_ci ret = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX); 31762306a36Sopenharmony_ci if (ret < 0) { 31862306a36Sopenharmony_ci dev_err(DEV(ndev), "msix vectors %d alloc failed\n", nr_vecs); 31962306a36Sopenharmony_ci return ret; 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci ndev->num_vecs = nr_vecs; 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci ndev->qvec = kcalloc(nr_vecs, sizeof(*qvec), GFP_KERNEL); 32462306a36Sopenharmony_ci if (!ndev->qvec) { 32562306a36Sopenharmony_ci pci_free_irq_vectors(pdev); 32662306a36Sopenharmony_ci return -ENOMEM; 32762306a36Sopenharmony_ci } 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci /* request irqs for packet rings/ports */ 33062306a36Sopenharmony_ci for (i = PKT_RING_MSIX_BASE; i < (nr_vecs - 1); i += NR_RING_VECTORS) { 33162306a36Sopenharmony_ci qvec = &ndev->qvec[i]; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci qvec->ring = i / NR_RING_VECTORS; 33462306a36Sopenharmony_ci if (qvec->ring >= ndev->nr_queues) 33562306a36Sopenharmony_ci break; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci qvec->cmdq = &ndev->pkt_inq[qvec->ring]; 33862306a36Sopenharmony_ci snprintf(qvec->name, IRQ_NAMESZ, "nitrox-pkt%d", qvec->ring); 33962306a36Sopenharmony_ci /* get the vector number */ 34062306a36Sopenharmony_ci vec = pci_irq_vector(pdev, i); 34162306a36Sopenharmony_ci ret = request_irq(vec, nps_pkt_slc_isr, 0, qvec->name, qvec); 34262306a36Sopenharmony_ci if (ret) { 34362306a36Sopenharmony_ci dev_err(DEV(ndev), "irq failed for pkt ring/port%d\n", 34462306a36Sopenharmony_ci qvec->ring); 34562306a36Sopenharmony_ci goto irq_fail; 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci cpu = qvec->ring % num_online_cpus(); 34862306a36Sopenharmony_ci irq_set_affinity_hint(vec, get_cpu_mask(cpu)); 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci tasklet_init(&qvec->resp_tasklet, pkt_slc_resp_tasklet, 35162306a36Sopenharmony_ci (unsigned long)qvec); 35262306a36Sopenharmony_ci qvec->valid = true; 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci /* request irqs for non ring vectors */ 35662306a36Sopenharmony_ci i = NON_RING_MSIX_BASE; 35762306a36Sopenharmony_ci qvec = &ndev->qvec[i]; 35862306a36Sopenharmony_ci qvec->ndev = ndev; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d", i); 36162306a36Sopenharmony_ci /* get the vector number */ 36262306a36Sopenharmony_ci vec = pci_irq_vector(pdev, i); 36362306a36Sopenharmony_ci ret = request_irq(vec, nps_core_int_isr, 0, qvec->name, qvec); 36462306a36Sopenharmony_ci if (ret) { 36562306a36Sopenharmony_ci dev_err(DEV(ndev), "irq failed for nitrox-core-int%d\n", i); 36662306a36Sopenharmony_ci goto irq_fail; 36762306a36Sopenharmony_ci } 36862306a36Sopenharmony_ci cpu = num_online_cpus(); 36962306a36Sopenharmony_ci irq_set_affinity_hint(vec, get_cpu_mask(cpu)); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet, 37262306a36Sopenharmony_ci (unsigned long)qvec); 37362306a36Sopenharmony_ci qvec->valid = true; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci return 0; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ciirq_fail: 37862306a36Sopenharmony_ci nitrox_unregister_interrupts(ndev); 37962306a36Sopenharmony_ci return ret; 38062306a36Sopenharmony_ci} 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_civoid nitrox_sriov_unregister_interrupts(struct nitrox_device *ndev) 38362306a36Sopenharmony_ci{ 38462306a36Sopenharmony_ci struct pci_dev *pdev = ndev->pdev; 38562306a36Sopenharmony_ci int i; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci for (i = 0; i < ndev->num_vecs; i++) { 38862306a36Sopenharmony_ci struct nitrox_q_vector *qvec; 38962306a36Sopenharmony_ci int vec; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci qvec = ndev->qvec + i; 39262306a36Sopenharmony_ci if (!qvec->valid) 39362306a36Sopenharmony_ci continue; 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci vec = ndev->iov.msix.vector; 39662306a36Sopenharmony_ci irq_set_affinity_hint(vec, NULL); 39762306a36Sopenharmony_ci free_irq(vec, qvec); 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci tasklet_disable(&qvec->resp_tasklet); 40062306a36Sopenharmony_ci tasklet_kill(&qvec->resp_tasklet); 40162306a36Sopenharmony_ci qvec->valid = false; 40262306a36Sopenharmony_ci } 40362306a36Sopenharmony_ci kfree(ndev->qvec); 40462306a36Sopenharmony_ci ndev->qvec = NULL; 40562306a36Sopenharmony_ci pci_disable_msix(pdev); 40662306a36Sopenharmony_ci} 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ciint nitrox_sriov_register_interupts(struct nitrox_device *ndev) 40962306a36Sopenharmony_ci{ 41062306a36Sopenharmony_ci struct pci_dev *pdev = ndev->pdev; 41162306a36Sopenharmony_ci struct nitrox_q_vector *qvec; 41262306a36Sopenharmony_ci int vec, cpu; 41362306a36Sopenharmony_ci int ret; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci /** 41662306a36Sopenharmony_ci * only non ring vectors i.e Entry 192 is available 41762306a36Sopenharmony_ci * for PF in SR-IOV mode. 41862306a36Sopenharmony_ci */ 41962306a36Sopenharmony_ci ndev->iov.msix.entry = NON_RING_MSIX_BASE; 42062306a36Sopenharmony_ci ret = pci_enable_msix_exact(pdev, &ndev->iov.msix, NR_NON_RING_VECTORS); 42162306a36Sopenharmony_ci if (ret) { 42262306a36Sopenharmony_ci dev_err(DEV(ndev), "failed to allocate nps-core-int%d\n", 42362306a36Sopenharmony_ci NON_RING_MSIX_BASE); 42462306a36Sopenharmony_ci return ret; 42562306a36Sopenharmony_ci } 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci qvec = kcalloc(NR_NON_RING_VECTORS, sizeof(*qvec), GFP_KERNEL); 42862306a36Sopenharmony_ci if (!qvec) { 42962306a36Sopenharmony_ci pci_disable_msix(pdev); 43062306a36Sopenharmony_ci return -ENOMEM; 43162306a36Sopenharmony_ci } 43262306a36Sopenharmony_ci qvec->ndev = ndev; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci ndev->qvec = qvec; 43562306a36Sopenharmony_ci ndev->num_vecs = NR_NON_RING_VECTORS; 43662306a36Sopenharmony_ci snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d", 43762306a36Sopenharmony_ci NON_RING_MSIX_BASE); 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci vec = ndev->iov.msix.vector; 44062306a36Sopenharmony_ci ret = request_irq(vec, nps_core_int_isr, 0, qvec->name, qvec); 44162306a36Sopenharmony_ci if (ret) { 44262306a36Sopenharmony_ci dev_err(DEV(ndev), "irq failed for nitrox-core-int%d\n", 44362306a36Sopenharmony_ci NON_RING_MSIX_BASE); 44462306a36Sopenharmony_ci goto iov_irq_fail; 44562306a36Sopenharmony_ci } 44662306a36Sopenharmony_ci cpu = num_online_cpus(); 44762306a36Sopenharmony_ci irq_set_affinity_hint(vec, get_cpu_mask(cpu)); 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet, 45062306a36Sopenharmony_ci (unsigned long)qvec); 45162306a36Sopenharmony_ci qvec->valid = true; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci return 0; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ciiov_irq_fail: 45662306a36Sopenharmony_ci nitrox_sriov_unregister_interrupts(ndev); 45762306a36Sopenharmony_ci return ret; 45862306a36Sopenharmony_ci} 459