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