1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 214fa93cdSSrikanth Jampala #include <linux/pci.h> 314fa93cdSSrikanth Jampala #include <linux/printk.h> 414fa93cdSSrikanth Jampala #include <linux/slab.h> 514fa93cdSSrikanth Jampala 614fa93cdSSrikanth Jampala #include "nitrox_dev.h" 714fa93cdSSrikanth Jampala #include "nitrox_csr.h" 814fa93cdSSrikanth Jampala #include "nitrox_common.h" 941a9aca6SSrikanth Jampala #include "nitrox_hal.h" 1014fa93cdSSrikanth Jampala 1114fa93cdSSrikanth Jampala #define NR_RING_VECTORS 3 1214fa93cdSSrikanth Jampala #define NPS_CORE_INT_ACTIVE_ENTRY 192 1314fa93cdSSrikanth Jampala 1414fa93cdSSrikanth Jampala /** 1514fa93cdSSrikanth Jampala * nps_pkt_slc_isr - IRQ handler for NPS solicit port 1614fa93cdSSrikanth Jampala * @irq: irq number 1714fa93cdSSrikanth Jampala * @data: argument 1814fa93cdSSrikanth Jampala */ 1914fa93cdSSrikanth Jampala static irqreturn_t nps_pkt_slc_isr(int irq, void *data) 2014fa93cdSSrikanth Jampala { 2114fa93cdSSrikanth Jampala struct bh_data *slc = data; 2214fa93cdSSrikanth Jampala union nps_pkt_slc_cnts pkt_slc_cnts; 2314fa93cdSSrikanth Jampala 2414fa93cdSSrikanth Jampala pkt_slc_cnts.value = readq(slc->completion_cnt_csr_addr); 2514fa93cdSSrikanth Jampala /* New packet on SLC output port */ 2614fa93cdSSrikanth Jampala if (pkt_slc_cnts.s.slc_int) 2714fa93cdSSrikanth Jampala tasklet_hi_schedule(&slc->resp_handler); 2814fa93cdSSrikanth Jampala 2914fa93cdSSrikanth Jampala return IRQ_HANDLED; 3014fa93cdSSrikanth Jampala } 3114fa93cdSSrikanth Jampala 3214fa93cdSSrikanth Jampala static void clear_nps_core_err_intr(struct nitrox_device *ndev) 3314fa93cdSSrikanth Jampala { 3414fa93cdSSrikanth Jampala u64 value; 3514fa93cdSSrikanth Jampala 3614fa93cdSSrikanth Jampala /* Write 1 to clear */ 3714fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, NPS_CORE_INT); 3814fa93cdSSrikanth Jampala nitrox_write_csr(ndev, NPS_CORE_INT, value); 3914fa93cdSSrikanth Jampala 4014fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), "NSP_CORE_INT 0x%016llx\n", value); 4114fa93cdSSrikanth Jampala } 4214fa93cdSSrikanth Jampala 4314fa93cdSSrikanth Jampala static void clear_nps_pkt_err_intr(struct nitrox_device *ndev) 4414fa93cdSSrikanth Jampala { 4514fa93cdSSrikanth Jampala union nps_pkt_int pkt_int; 4614fa93cdSSrikanth Jampala unsigned long value, offset; 4714fa93cdSSrikanth Jampala int i; 4814fa93cdSSrikanth Jampala 4914fa93cdSSrikanth Jampala pkt_int.value = nitrox_read_csr(ndev, NPS_PKT_INT); 5014fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), "NPS_PKT_INT 0x%016llx\n", 5114fa93cdSSrikanth Jampala pkt_int.value); 5214fa93cdSSrikanth Jampala 5314fa93cdSSrikanth Jampala if (pkt_int.s.slc_err) { 5414fa93cdSSrikanth Jampala offset = NPS_PKT_SLC_ERR_TYPE; 5514fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 5614fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 5714fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), 5814fa93cdSSrikanth Jampala "NPS_PKT_SLC_ERR_TYPE 0x%016lx\n", value); 5914fa93cdSSrikanth Jampala 6014fa93cdSSrikanth Jampala offset = NPS_PKT_SLC_RERR_LO; 6114fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 6214fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 6314fa93cdSSrikanth Jampala /* enable the solicit ports */ 6414fa93cdSSrikanth Jampala for_each_set_bit(i, &value, BITS_PER_LONG) 6514fa93cdSSrikanth Jampala enable_pkt_solicit_port(ndev, i); 6614fa93cdSSrikanth Jampala 6714fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), 6814fa93cdSSrikanth Jampala "NPS_PKT_SLC_RERR_LO 0x%016lx\n", value); 6914fa93cdSSrikanth Jampala 7014fa93cdSSrikanth Jampala offset = NPS_PKT_SLC_RERR_HI; 7114fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 7214fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 7314fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), 7414fa93cdSSrikanth Jampala "NPS_PKT_SLC_RERR_HI 0x%016lx\n", value); 7514fa93cdSSrikanth Jampala } 7614fa93cdSSrikanth Jampala 7714fa93cdSSrikanth Jampala if (pkt_int.s.in_err) { 7814fa93cdSSrikanth Jampala offset = NPS_PKT_IN_ERR_TYPE; 7914fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 8014fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 8114fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), 8214fa93cdSSrikanth Jampala "NPS_PKT_IN_ERR_TYPE 0x%016lx\n", value); 8314fa93cdSSrikanth Jampala offset = NPS_PKT_IN_RERR_LO; 8414fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 8514fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 8614fa93cdSSrikanth Jampala /* enable the input ring */ 8714fa93cdSSrikanth Jampala for_each_set_bit(i, &value, BITS_PER_LONG) 8814fa93cdSSrikanth Jampala enable_pkt_input_ring(ndev, i); 8914fa93cdSSrikanth Jampala 9014fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), 9114fa93cdSSrikanth Jampala "NPS_PKT_IN_RERR_LO 0x%016lx\n", value); 9214fa93cdSSrikanth Jampala 9314fa93cdSSrikanth Jampala offset = NPS_PKT_IN_RERR_HI; 9414fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 9514fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 9614fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), 9714fa93cdSSrikanth Jampala "NPS_PKT_IN_RERR_HI 0x%016lx\n", value); 9814fa93cdSSrikanth Jampala } 9914fa93cdSSrikanth Jampala } 10014fa93cdSSrikanth Jampala 10114fa93cdSSrikanth Jampala static void clear_pom_err_intr(struct nitrox_device *ndev) 10214fa93cdSSrikanth Jampala { 10314fa93cdSSrikanth Jampala u64 value; 10414fa93cdSSrikanth Jampala 10514fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, POM_INT); 10614fa93cdSSrikanth Jampala nitrox_write_csr(ndev, POM_INT, value); 10714fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), "POM_INT 0x%016llx\n", value); 10814fa93cdSSrikanth Jampala } 10914fa93cdSSrikanth Jampala 11014fa93cdSSrikanth Jampala static void clear_pem_err_intr(struct nitrox_device *ndev) 11114fa93cdSSrikanth Jampala { 11214fa93cdSSrikanth Jampala u64 value; 11314fa93cdSSrikanth Jampala 11414fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, PEM0_INT); 11514fa93cdSSrikanth Jampala nitrox_write_csr(ndev, PEM0_INT, value); 11614fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), "PEM(0)_INT 0x%016llx\n", value); 11714fa93cdSSrikanth Jampala } 11814fa93cdSSrikanth Jampala 11914fa93cdSSrikanth Jampala static void clear_lbc_err_intr(struct nitrox_device *ndev) 12014fa93cdSSrikanth Jampala { 12114fa93cdSSrikanth Jampala union lbc_int lbc_int; 12214fa93cdSSrikanth Jampala u64 value, offset; 12314fa93cdSSrikanth Jampala int i; 12414fa93cdSSrikanth Jampala 12514fa93cdSSrikanth Jampala lbc_int.value = nitrox_read_csr(ndev, LBC_INT); 12614fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), "LBC_INT 0x%016llx\n", lbc_int.value); 12714fa93cdSSrikanth Jampala 12814fa93cdSSrikanth Jampala if (lbc_int.s.dma_rd_err) { 12914fa93cdSSrikanth Jampala for (i = 0; i < NR_CLUSTERS; i++) { 13014fa93cdSSrikanth Jampala offset = EFL_CORE_VF_ERR_INT0X(i); 13114fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 13214fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 13314fa93cdSSrikanth Jampala offset = EFL_CORE_VF_ERR_INT1X(i); 13414fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 13514fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 13614fa93cdSSrikanth Jampala } 13714fa93cdSSrikanth Jampala } 13814fa93cdSSrikanth Jampala 13914fa93cdSSrikanth Jampala if (lbc_int.s.cam_soft_err) { 14014fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), "CAM_SOFT_ERR, invalidating LBC\n"); 14114fa93cdSSrikanth Jampala invalidate_lbc(ndev); 14214fa93cdSSrikanth Jampala } 14314fa93cdSSrikanth Jampala 14414fa93cdSSrikanth Jampala if (lbc_int.s.pref_dat_len_mismatch_err) { 14514fa93cdSSrikanth Jampala offset = LBC_PLM_VF1_64_INT; 14614fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 14714fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 14814fa93cdSSrikanth Jampala offset = LBC_PLM_VF65_128_INT; 14914fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 15014fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 15114fa93cdSSrikanth Jampala } 15214fa93cdSSrikanth Jampala 15314fa93cdSSrikanth Jampala if (lbc_int.s.rd_dat_len_mismatch_err) { 15414fa93cdSSrikanth Jampala offset = LBC_ELM_VF1_64_INT; 15514fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 15614fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 15714fa93cdSSrikanth Jampala offset = LBC_ELM_VF65_128_INT; 15814fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 15914fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 16014fa93cdSSrikanth Jampala } 16114fa93cdSSrikanth Jampala nitrox_write_csr(ndev, LBC_INT, lbc_int.value); 16214fa93cdSSrikanth Jampala } 16314fa93cdSSrikanth Jampala 16414fa93cdSSrikanth Jampala static void clear_efl_err_intr(struct nitrox_device *ndev) 16514fa93cdSSrikanth Jampala { 16614fa93cdSSrikanth Jampala int i; 16714fa93cdSSrikanth Jampala 16814fa93cdSSrikanth Jampala for (i = 0; i < NR_CLUSTERS; i++) { 16914fa93cdSSrikanth Jampala union efl_core_int core_int; 17014fa93cdSSrikanth Jampala u64 value, offset; 17114fa93cdSSrikanth Jampala 17214fa93cdSSrikanth Jampala offset = EFL_CORE_INTX(i); 17314fa93cdSSrikanth Jampala core_int.value = nitrox_read_csr(ndev, offset); 17414fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, core_int.value); 17514fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), "ELF_CORE(%d)_INT 0x%016llx\n", 17614fa93cdSSrikanth Jampala i, core_int.value); 17714fa93cdSSrikanth Jampala if (core_int.s.se_err) { 17814fa93cdSSrikanth Jampala offset = EFL_CORE_SE_ERR_INTX(i); 17914fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, offset); 18014fa93cdSSrikanth Jampala nitrox_write_csr(ndev, offset, value); 18114fa93cdSSrikanth Jampala } 18214fa93cdSSrikanth Jampala } 18314fa93cdSSrikanth Jampala } 18414fa93cdSSrikanth Jampala 18514fa93cdSSrikanth Jampala static void clear_bmi_err_intr(struct nitrox_device *ndev) 18614fa93cdSSrikanth Jampala { 18714fa93cdSSrikanth Jampala u64 value; 18814fa93cdSSrikanth Jampala 18914fa93cdSSrikanth Jampala value = nitrox_read_csr(ndev, BMI_INT); 19014fa93cdSSrikanth Jampala nitrox_write_csr(ndev, BMI_INT, value); 19114fa93cdSSrikanth Jampala dev_err_ratelimited(DEV(ndev), "BMI_INT 0x%016llx\n", value); 19214fa93cdSSrikanth Jampala } 19314fa93cdSSrikanth Jampala 19414fa93cdSSrikanth Jampala /** 19514fa93cdSSrikanth Jampala * clear_nps_core_int_active - clear NPS_CORE_INT_ACTIVE interrupts 19614fa93cdSSrikanth Jampala * @ndev: NITROX device 19714fa93cdSSrikanth Jampala */ 19814fa93cdSSrikanth Jampala static void clear_nps_core_int_active(struct nitrox_device *ndev) 19914fa93cdSSrikanth Jampala { 20014fa93cdSSrikanth Jampala union nps_core_int_active core_int_active; 20114fa93cdSSrikanth Jampala 20214fa93cdSSrikanth Jampala core_int_active.value = nitrox_read_csr(ndev, NPS_CORE_INT_ACTIVE); 20314fa93cdSSrikanth Jampala 20414fa93cdSSrikanth Jampala if (core_int_active.s.nps_core) 20514fa93cdSSrikanth Jampala clear_nps_core_err_intr(ndev); 20614fa93cdSSrikanth Jampala 20714fa93cdSSrikanth Jampala if (core_int_active.s.nps_pkt) 20814fa93cdSSrikanth Jampala clear_nps_pkt_err_intr(ndev); 20914fa93cdSSrikanth Jampala 21014fa93cdSSrikanth Jampala if (core_int_active.s.pom) 21114fa93cdSSrikanth Jampala clear_pom_err_intr(ndev); 21214fa93cdSSrikanth Jampala 21314fa93cdSSrikanth Jampala if (core_int_active.s.pem) 21414fa93cdSSrikanth Jampala clear_pem_err_intr(ndev); 21514fa93cdSSrikanth Jampala 21614fa93cdSSrikanth Jampala if (core_int_active.s.lbc) 21714fa93cdSSrikanth Jampala clear_lbc_err_intr(ndev); 21814fa93cdSSrikanth Jampala 21914fa93cdSSrikanth Jampala if (core_int_active.s.efl) 22014fa93cdSSrikanth Jampala clear_efl_err_intr(ndev); 22114fa93cdSSrikanth Jampala 22214fa93cdSSrikanth Jampala if (core_int_active.s.bmi) 22314fa93cdSSrikanth Jampala clear_bmi_err_intr(ndev); 22414fa93cdSSrikanth Jampala 22514fa93cdSSrikanth Jampala /* If more work callback the ISR, set resend */ 22614fa93cdSSrikanth Jampala core_int_active.s.resend = 1; 22714fa93cdSSrikanth Jampala nitrox_write_csr(ndev, NPS_CORE_INT_ACTIVE, core_int_active.value); 22814fa93cdSSrikanth Jampala } 22914fa93cdSSrikanth Jampala 23014fa93cdSSrikanth Jampala static irqreturn_t nps_core_int_isr(int irq, void *data) 23114fa93cdSSrikanth Jampala { 23214fa93cdSSrikanth Jampala struct nitrox_device *ndev = data; 23314fa93cdSSrikanth Jampala 23414fa93cdSSrikanth Jampala clear_nps_core_int_active(ndev); 23514fa93cdSSrikanth Jampala 23614fa93cdSSrikanth Jampala return IRQ_HANDLED; 23714fa93cdSSrikanth Jampala } 23814fa93cdSSrikanth Jampala 23914fa93cdSSrikanth Jampala static int nitrox_enable_msix(struct nitrox_device *ndev) 24014fa93cdSSrikanth Jampala { 24114fa93cdSSrikanth Jampala struct msix_entry *entries; 24214fa93cdSSrikanth Jampala char **names; 24314fa93cdSSrikanth Jampala int i, nr_entries, ret; 24414fa93cdSSrikanth Jampala 24514fa93cdSSrikanth Jampala /* 24614fa93cdSSrikanth Jampala * PF MSI-X vectors 24714fa93cdSSrikanth Jampala * 24814fa93cdSSrikanth Jampala * Entry 0: NPS PKT ring 0 24914fa93cdSSrikanth Jampala * Entry 1: AQMQ ring 0 25014fa93cdSSrikanth Jampala * Entry 2: ZQM ring 0 25114fa93cdSSrikanth Jampala * Entry 3: NPS PKT ring 1 25214fa93cdSSrikanth Jampala * Entry 4: AQMQ ring 1 25314fa93cdSSrikanth Jampala * Entry 5: ZQM ring 1 25414fa93cdSSrikanth Jampala * .... 25514fa93cdSSrikanth Jampala * Entry 192: NPS_CORE_INT_ACTIVE 25614fa93cdSSrikanth Jampala */ 25714fa93cdSSrikanth Jampala nr_entries = (ndev->nr_queues * NR_RING_VECTORS) + 1; 258590b5b7dSKees Cook entries = kcalloc_node(nr_entries, sizeof(struct msix_entry), 25914fa93cdSSrikanth Jampala GFP_KERNEL, ndev->node); 26014fa93cdSSrikanth Jampala if (!entries) 26114fa93cdSSrikanth Jampala return -ENOMEM; 26214fa93cdSSrikanth Jampala 26314fa93cdSSrikanth Jampala names = kcalloc(nr_entries, sizeof(char *), GFP_KERNEL); 26414fa93cdSSrikanth Jampala if (!names) { 26514fa93cdSSrikanth Jampala kfree(entries); 26614fa93cdSSrikanth Jampala return -ENOMEM; 26714fa93cdSSrikanth Jampala } 26814fa93cdSSrikanth Jampala 26914fa93cdSSrikanth Jampala /* fill entires */ 27014fa93cdSSrikanth Jampala for (i = 0; i < (nr_entries - 1); i++) 27114fa93cdSSrikanth Jampala entries[i].entry = i; 27214fa93cdSSrikanth Jampala 27314fa93cdSSrikanth Jampala entries[i].entry = NPS_CORE_INT_ACTIVE_ENTRY; 27414fa93cdSSrikanth Jampala 27514fa93cdSSrikanth Jampala for (i = 0; i < nr_entries; i++) { 27614fa93cdSSrikanth Jampala *(names + i) = kzalloc(MAX_MSIX_VECTOR_NAME, GFP_KERNEL); 27714fa93cdSSrikanth Jampala if (!(*(names + i))) { 27814fa93cdSSrikanth Jampala ret = -ENOMEM; 27914fa93cdSSrikanth Jampala goto msix_fail; 28014fa93cdSSrikanth Jampala } 28114fa93cdSSrikanth Jampala } 28214fa93cdSSrikanth Jampala ndev->msix.entries = entries; 28314fa93cdSSrikanth Jampala ndev->msix.names = names; 28414fa93cdSSrikanth Jampala ndev->msix.nr_entries = nr_entries; 28514fa93cdSSrikanth Jampala 28614fa93cdSSrikanth Jampala ret = pci_enable_msix_exact(ndev->pdev, ndev->msix.entries, 28714fa93cdSSrikanth Jampala ndev->msix.nr_entries); 28814fa93cdSSrikanth Jampala if (ret) { 28914fa93cdSSrikanth Jampala dev_err(&ndev->pdev->dev, "Failed to enable MSI-X IRQ(s) %d\n", 29014fa93cdSSrikanth Jampala ret); 29114fa93cdSSrikanth Jampala goto msix_fail; 29214fa93cdSSrikanth Jampala } 29314fa93cdSSrikanth Jampala return 0; 29414fa93cdSSrikanth Jampala 29514fa93cdSSrikanth Jampala msix_fail: 29614fa93cdSSrikanth Jampala for (i = 0; i < nr_entries; i++) 29714fa93cdSSrikanth Jampala kfree(*(names + i)); 29814fa93cdSSrikanth Jampala 29914fa93cdSSrikanth Jampala kfree(entries); 30014fa93cdSSrikanth Jampala kfree(names); 30114fa93cdSSrikanth Jampala return ret; 30214fa93cdSSrikanth Jampala } 30314fa93cdSSrikanth Jampala 30414fa93cdSSrikanth Jampala static void nitrox_cleanup_pkt_slc_bh(struct nitrox_device *ndev) 30514fa93cdSSrikanth Jampala { 30614fa93cdSSrikanth Jampala int i; 30714fa93cdSSrikanth Jampala 30814fa93cdSSrikanth Jampala if (!ndev->bh.slc) 30914fa93cdSSrikanth Jampala return; 31014fa93cdSSrikanth Jampala 31114fa93cdSSrikanth Jampala for (i = 0; i < ndev->nr_queues; i++) { 31214fa93cdSSrikanth Jampala struct bh_data *bh = &ndev->bh.slc[i]; 31314fa93cdSSrikanth Jampala 31414fa93cdSSrikanth Jampala tasklet_disable(&bh->resp_handler); 31514fa93cdSSrikanth Jampala tasklet_kill(&bh->resp_handler); 31614fa93cdSSrikanth Jampala } 31714fa93cdSSrikanth Jampala kfree(ndev->bh.slc); 31814fa93cdSSrikanth Jampala ndev->bh.slc = NULL; 31914fa93cdSSrikanth Jampala } 32014fa93cdSSrikanth Jampala 32114fa93cdSSrikanth Jampala static int nitrox_setup_pkt_slc_bh(struct nitrox_device *ndev) 32214fa93cdSSrikanth Jampala { 32314fa93cdSSrikanth Jampala u32 size; 32414fa93cdSSrikanth Jampala int i; 32514fa93cdSSrikanth Jampala 32614fa93cdSSrikanth Jampala size = ndev->nr_queues * sizeof(struct bh_data); 32714fa93cdSSrikanth Jampala ndev->bh.slc = kzalloc(size, GFP_KERNEL); 32814fa93cdSSrikanth Jampala if (!ndev->bh.slc) 32914fa93cdSSrikanth Jampala return -ENOMEM; 33014fa93cdSSrikanth Jampala 33114fa93cdSSrikanth Jampala for (i = 0; i < ndev->nr_queues; i++) { 33214fa93cdSSrikanth Jampala struct bh_data *bh = &ndev->bh.slc[i]; 33314fa93cdSSrikanth Jampala u64 offset; 33414fa93cdSSrikanth Jampala 33514fa93cdSSrikanth Jampala offset = NPS_PKT_SLC_CNTSX(i); 33614fa93cdSSrikanth Jampala /* pre calculate completion count address */ 33714fa93cdSSrikanth Jampala bh->completion_cnt_csr_addr = NITROX_CSR_ADDR(ndev, offset); 33814fa93cdSSrikanth Jampala bh->cmdq = &ndev->pkt_cmdqs[i]; 33914fa93cdSSrikanth Jampala 34014fa93cdSSrikanth Jampala tasklet_init(&bh->resp_handler, pkt_slc_resp_handler, 34114fa93cdSSrikanth Jampala (unsigned long)bh); 34214fa93cdSSrikanth Jampala } 34314fa93cdSSrikanth Jampala 34414fa93cdSSrikanth Jampala return 0; 34514fa93cdSSrikanth Jampala } 34614fa93cdSSrikanth Jampala 34714fa93cdSSrikanth Jampala static int nitrox_request_irqs(struct nitrox_device *ndev) 34814fa93cdSSrikanth Jampala { 34914fa93cdSSrikanth Jampala struct pci_dev *pdev = ndev->pdev; 35014fa93cdSSrikanth Jampala struct msix_entry *msix_ent = ndev->msix.entries; 35114fa93cdSSrikanth Jampala int nr_ring_vectors, i = 0, ring, cpu, ret; 35214fa93cdSSrikanth Jampala char *name; 35314fa93cdSSrikanth Jampala 35414fa93cdSSrikanth Jampala /* 35514fa93cdSSrikanth Jampala * PF MSI-X vectors 35614fa93cdSSrikanth Jampala * 35714fa93cdSSrikanth Jampala * Entry 0: NPS PKT ring 0 35814fa93cdSSrikanth Jampala * Entry 1: AQMQ ring 0 35914fa93cdSSrikanth Jampala * Entry 2: ZQM ring 0 36014fa93cdSSrikanth Jampala * Entry 3: NPS PKT ring 1 36114fa93cdSSrikanth Jampala * .... 36214fa93cdSSrikanth Jampala * Entry 192: NPS_CORE_INT_ACTIVE 36314fa93cdSSrikanth Jampala */ 36414fa93cdSSrikanth Jampala nr_ring_vectors = ndev->nr_queues * NR_RING_VECTORS; 36514fa93cdSSrikanth Jampala 36614fa93cdSSrikanth Jampala /* request irq for pkt ring/ports only */ 36714fa93cdSSrikanth Jampala while (i < nr_ring_vectors) { 36814fa93cdSSrikanth Jampala name = *(ndev->msix.names + i); 36914fa93cdSSrikanth Jampala ring = (i / NR_RING_VECTORS); 37014fa93cdSSrikanth Jampala snprintf(name, MAX_MSIX_VECTOR_NAME, "n5(%d)-slc-ring%d", 37114fa93cdSSrikanth Jampala ndev->idx, ring); 37214fa93cdSSrikanth Jampala 37314fa93cdSSrikanth Jampala ret = request_irq(msix_ent[i].vector, nps_pkt_slc_isr, 0, 37414fa93cdSSrikanth Jampala name, &ndev->bh.slc[ring]); 37514fa93cdSSrikanth Jampala if (ret) { 37614fa93cdSSrikanth Jampala dev_err(&pdev->dev, "failed to get irq %d for %s\n", 37714fa93cdSSrikanth Jampala msix_ent[i].vector, name); 37814fa93cdSSrikanth Jampala return ret; 37914fa93cdSSrikanth Jampala } 38014fa93cdSSrikanth Jampala cpu = ring % num_online_cpus(); 38114fa93cdSSrikanth Jampala irq_set_affinity_hint(msix_ent[i].vector, get_cpu_mask(cpu)); 38214fa93cdSSrikanth Jampala 38314fa93cdSSrikanth Jampala set_bit(i, ndev->msix.irqs); 38414fa93cdSSrikanth Jampala i += NR_RING_VECTORS; 38514fa93cdSSrikanth Jampala } 38614fa93cdSSrikanth Jampala 38714fa93cdSSrikanth Jampala /* Request IRQ for NPS_CORE_INT_ACTIVE */ 38814fa93cdSSrikanth Jampala name = *(ndev->msix.names + i); 38914fa93cdSSrikanth Jampala snprintf(name, MAX_MSIX_VECTOR_NAME, "n5(%d)-nps-core-int", ndev->idx); 39014fa93cdSSrikanth Jampala ret = request_irq(msix_ent[i].vector, nps_core_int_isr, 0, name, ndev); 39114fa93cdSSrikanth Jampala if (ret) { 39214fa93cdSSrikanth Jampala dev_err(&pdev->dev, "failed to get irq %d for %s\n", 39314fa93cdSSrikanth Jampala msix_ent[i].vector, name); 39414fa93cdSSrikanth Jampala return ret; 39514fa93cdSSrikanth Jampala } 39614fa93cdSSrikanth Jampala set_bit(i, ndev->msix.irqs); 39714fa93cdSSrikanth Jampala 39814fa93cdSSrikanth Jampala return 0; 39914fa93cdSSrikanth Jampala } 40014fa93cdSSrikanth Jampala 40114fa93cdSSrikanth Jampala static void nitrox_disable_msix(struct nitrox_device *ndev) 40214fa93cdSSrikanth Jampala { 40314fa93cdSSrikanth Jampala struct msix_entry *msix_ent = ndev->msix.entries; 40414fa93cdSSrikanth Jampala char **names = ndev->msix.names; 40514fa93cdSSrikanth Jampala int i = 0, ring, nr_ring_vectors; 40614fa93cdSSrikanth Jampala 40714fa93cdSSrikanth Jampala nr_ring_vectors = ndev->msix.nr_entries - 1; 40814fa93cdSSrikanth Jampala 40914fa93cdSSrikanth Jampala /* clear pkt ring irqs */ 41014fa93cdSSrikanth Jampala while (i < nr_ring_vectors) { 41114fa93cdSSrikanth Jampala if (test_and_clear_bit(i, ndev->msix.irqs)) { 41214fa93cdSSrikanth Jampala ring = (i / NR_RING_VECTORS); 41314fa93cdSSrikanth Jampala irq_set_affinity_hint(msix_ent[i].vector, NULL); 41414fa93cdSSrikanth Jampala free_irq(msix_ent[i].vector, &ndev->bh.slc[ring]); 41514fa93cdSSrikanth Jampala } 41614fa93cdSSrikanth Jampala i += NR_RING_VECTORS; 41714fa93cdSSrikanth Jampala } 41814fa93cdSSrikanth Jampala irq_set_affinity_hint(msix_ent[i].vector, NULL); 41914fa93cdSSrikanth Jampala free_irq(msix_ent[i].vector, ndev); 42014fa93cdSSrikanth Jampala clear_bit(i, ndev->msix.irqs); 42114fa93cdSSrikanth Jampala 42214fa93cdSSrikanth Jampala kfree(ndev->msix.entries); 42314fa93cdSSrikanth Jampala for (i = 0; i < ndev->msix.nr_entries; i++) 42414fa93cdSSrikanth Jampala kfree(*(names + i)); 42514fa93cdSSrikanth Jampala 42614fa93cdSSrikanth Jampala kfree(names); 42714fa93cdSSrikanth Jampala pci_disable_msix(ndev->pdev); 42814fa93cdSSrikanth Jampala } 42914fa93cdSSrikanth Jampala 43014fa93cdSSrikanth Jampala /** 43114fa93cdSSrikanth Jampala * nitrox_pf_cleanup_isr: Cleanup PF MSI-X and IRQ 43214fa93cdSSrikanth Jampala * @ndev: NITROX device 43314fa93cdSSrikanth Jampala */ 43414fa93cdSSrikanth Jampala void nitrox_pf_cleanup_isr(struct nitrox_device *ndev) 43514fa93cdSSrikanth Jampala { 43614fa93cdSSrikanth Jampala nitrox_disable_msix(ndev); 43714fa93cdSSrikanth Jampala nitrox_cleanup_pkt_slc_bh(ndev); 43814fa93cdSSrikanth Jampala } 43914fa93cdSSrikanth Jampala 44014fa93cdSSrikanth Jampala /** 44114fa93cdSSrikanth Jampala * nitrox_init_isr - Initialize PF MSI-X vectors and IRQ 44214fa93cdSSrikanth Jampala * @ndev: NITROX device 44314fa93cdSSrikanth Jampala * 44414fa93cdSSrikanth Jampala * Return: 0 on success, a negative value on failure. 44514fa93cdSSrikanth Jampala */ 44614fa93cdSSrikanth Jampala int nitrox_pf_init_isr(struct nitrox_device *ndev) 44714fa93cdSSrikanth Jampala { 44814fa93cdSSrikanth Jampala int err; 44914fa93cdSSrikanth Jampala 45014fa93cdSSrikanth Jampala err = nitrox_setup_pkt_slc_bh(ndev); 45114fa93cdSSrikanth Jampala if (err) 45214fa93cdSSrikanth Jampala return err; 45314fa93cdSSrikanth Jampala 45414fa93cdSSrikanth Jampala err = nitrox_enable_msix(ndev); 45514fa93cdSSrikanth Jampala if (err) 45614fa93cdSSrikanth Jampala goto msix_fail; 45714fa93cdSSrikanth Jampala 45814fa93cdSSrikanth Jampala err = nitrox_request_irqs(ndev); 45914fa93cdSSrikanth Jampala if (err) 46014fa93cdSSrikanth Jampala goto irq_fail; 46114fa93cdSSrikanth Jampala 46214fa93cdSSrikanth Jampala return 0; 46314fa93cdSSrikanth Jampala 46414fa93cdSSrikanth Jampala irq_fail: 46514fa93cdSSrikanth Jampala nitrox_disable_msix(ndev); 46614fa93cdSSrikanth Jampala msix_fail: 46714fa93cdSSrikanth Jampala nitrox_cleanup_pkt_slc_bh(ndev); 46814fa93cdSSrikanth Jampala return err; 46914fa93cdSSrikanth Jampala } 470