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