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"
10cd078cb6SHerbert Xu #include "nitrox_isr.h"
11cf718eaaSSrikanth, Jampala #include "nitrox_mbx.h"
1214fa93cdSSrikanth Jampala 
135b0ef799SLee Jones /*
145155e118SSrikanth Jampala  * One vector for each type of ring
155155e118SSrikanth Jampala  *  - NPS packet ring, AQMQ ring and ZQMQ ring
165155e118SSrikanth Jampala  */
1714fa93cdSSrikanth Jampala #define NR_RING_VECTORS 3
187a027b57SSrikanth, Jampala #define NR_NON_RING_VECTORS 1
195155e118SSrikanth Jampala /* base entry for packet ring/port */
205155e118SSrikanth Jampala #define PKT_RING_MSIX_BASE 0
215155e118SSrikanth Jampala #define NON_RING_MSIX_BASE 192
2214fa93cdSSrikanth Jampala 
2314fa93cdSSrikanth Jampala /**
2414fa93cdSSrikanth Jampala  * nps_pkt_slc_isr - IRQ handler for NPS solicit port
2514fa93cdSSrikanth Jampala  * @irq: irq number
2614fa93cdSSrikanth Jampala  * @data: argument
2714fa93cdSSrikanth Jampala  */
nps_pkt_slc_isr(int irq,void * data)2814fa93cdSSrikanth Jampala static irqreturn_t nps_pkt_slc_isr(int irq, void *data)
2914fa93cdSSrikanth Jampala {
305155e118SSrikanth Jampala 	struct nitrox_q_vector *qvec = data;
315155e118SSrikanth Jampala 	union nps_pkt_slc_cnts slc_cnts;
325155e118SSrikanth Jampala 	struct nitrox_cmdq *cmdq = qvec->cmdq;
3314fa93cdSSrikanth Jampala 
345155e118SSrikanth Jampala 	slc_cnts.value = readq(cmdq->compl_cnt_csr_addr);
3514fa93cdSSrikanth Jampala 	/* New packet on SLC output port */
365155e118SSrikanth Jampala 	if (slc_cnts.s.slc_int)
375155e118SSrikanth Jampala 		tasklet_hi_schedule(&qvec->resp_tasklet);
3814fa93cdSSrikanth Jampala 
3914fa93cdSSrikanth Jampala 	return IRQ_HANDLED;
4014fa93cdSSrikanth Jampala }
4114fa93cdSSrikanth Jampala 
clear_nps_core_err_intr(struct nitrox_device * ndev)4214fa93cdSSrikanth Jampala static void clear_nps_core_err_intr(struct nitrox_device *ndev)
4314fa93cdSSrikanth Jampala {
4414fa93cdSSrikanth Jampala 	u64 value;
4514fa93cdSSrikanth Jampala 
4614fa93cdSSrikanth Jampala 	/* Write 1 to clear */
4714fa93cdSSrikanth Jampala 	value = nitrox_read_csr(ndev, NPS_CORE_INT);
4814fa93cdSSrikanth Jampala 	nitrox_write_csr(ndev, NPS_CORE_INT, value);
4914fa93cdSSrikanth Jampala 
5014fa93cdSSrikanth Jampala 	dev_err_ratelimited(DEV(ndev), "NSP_CORE_INT  0x%016llx\n", value);
5114fa93cdSSrikanth Jampala }
5214fa93cdSSrikanth Jampala 
clear_nps_pkt_err_intr(struct nitrox_device * ndev)5314fa93cdSSrikanth Jampala static void clear_nps_pkt_err_intr(struct nitrox_device *ndev)
5414fa93cdSSrikanth Jampala {
5514fa93cdSSrikanth Jampala 	union nps_pkt_int pkt_int;
5614fa93cdSSrikanth Jampala 	unsigned long value, offset;
5714fa93cdSSrikanth Jampala 	int i;
5814fa93cdSSrikanth Jampala 
5914fa93cdSSrikanth Jampala 	pkt_int.value = nitrox_read_csr(ndev, NPS_PKT_INT);
6014fa93cdSSrikanth Jampala 	dev_err_ratelimited(DEV(ndev), "NPS_PKT_INT  0x%016llx\n",
6114fa93cdSSrikanth Jampala 			    pkt_int.value);
6214fa93cdSSrikanth Jampala 
6314fa93cdSSrikanth Jampala 	if (pkt_int.s.slc_err) {
6414fa93cdSSrikanth Jampala 		offset = NPS_PKT_SLC_ERR_TYPE;
6514fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
6614fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
6714fa93cdSSrikanth Jampala 		dev_err_ratelimited(DEV(ndev),
6814fa93cdSSrikanth Jampala 				    "NPS_PKT_SLC_ERR_TYPE  0x%016lx\n", value);
6914fa93cdSSrikanth Jampala 
7014fa93cdSSrikanth Jampala 		offset = NPS_PKT_SLC_RERR_LO;
7114fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
7214fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
7314fa93cdSSrikanth Jampala 		/* enable the solicit ports */
7414fa93cdSSrikanth Jampala 		for_each_set_bit(i, &value, BITS_PER_LONG)
7514fa93cdSSrikanth Jampala 			enable_pkt_solicit_port(ndev, i);
7614fa93cdSSrikanth Jampala 
7714fa93cdSSrikanth Jampala 		dev_err_ratelimited(DEV(ndev),
7814fa93cdSSrikanth Jampala 				    "NPS_PKT_SLC_RERR_LO  0x%016lx\n", value);
7914fa93cdSSrikanth Jampala 
8014fa93cdSSrikanth Jampala 		offset = NPS_PKT_SLC_RERR_HI;
8114fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
8214fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
8314fa93cdSSrikanth Jampala 		dev_err_ratelimited(DEV(ndev),
8414fa93cdSSrikanth Jampala 				    "NPS_PKT_SLC_RERR_HI  0x%016lx\n", value);
8514fa93cdSSrikanth Jampala 	}
8614fa93cdSSrikanth Jampala 
8714fa93cdSSrikanth Jampala 	if (pkt_int.s.in_err) {
8814fa93cdSSrikanth Jampala 		offset = NPS_PKT_IN_ERR_TYPE;
8914fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
9014fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
9114fa93cdSSrikanth Jampala 		dev_err_ratelimited(DEV(ndev),
9214fa93cdSSrikanth Jampala 				    "NPS_PKT_IN_ERR_TYPE  0x%016lx\n", value);
9314fa93cdSSrikanth Jampala 		offset = NPS_PKT_IN_RERR_LO;
9414fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
9514fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
9614fa93cdSSrikanth Jampala 		/* enable the input ring */
9714fa93cdSSrikanth Jampala 		for_each_set_bit(i, &value, BITS_PER_LONG)
9814fa93cdSSrikanth Jampala 			enable_pkt_input_ring(ndev, i);
9914fa93cdSSrikanth Jampala 
10014fa93cdSSrikanth Jampala 		dev_err_ratelimited(DEV(ndev),
10114fa93cdSSrikanth Jampala 				    "NPS_PKT_IN_RERR_LO  0x%016lx\n", value);
10214fa93cdSSrikanth Jampala 
10314fa93cdSSrikanth Jampala 		offset = NPS_PKT_IN_RERR_HI;
10414fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
10514fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
10614fa93cdSSrikanth Jampala 		dev_err_ratelimited(DEV(ndev),
10714fa93cdSSrikanth Jampala 				    "NPS_PKT_IN_RERR_HI  0x%016lx\n", value);
10814fa93cdSSrikanth Jampala 	}
10914fa93cdSSrikanth Jampala }
11014fa93cdSSrikanth Jampala 
clear_pom_err_intr(struct nitrox_device * ndev)11114fa93cdSSrikanth Jampala static void clear_pom_err_intr(struct nitrox_device *ndev)
11214fa93cdSSrikanth Jampala {
11314fa93cdSSrikanth Jampala 	u64 value;
11414fa93cdSSrikanth Jampala 
11514fa93cdSSrikanth Jampala 	value = nitrox_read_csr(ndev, POM_INT);
11614fa93cdSSrikanth Jampala 	nitrox_write_csr(ndev, POM_INT, value);
11714fa93cdSSrikanth Jampala 	dev_err_ratelimited(DEV(ndev), "POM_INT  0x%016llx\n", value);
11814fa93cdSSrikanth Jampala }
11914fa93cdSSrikanth Jampala 
clear_pem_err_intr(struct nitrox_device * ndev)12014fa93cdSSrikanth Jampala static void clear_pem_err_intr(struct nitrox_device *ndev)
12114fa93cdSSrikanth Jampala {
12214fa93cdSSrikanth Jampala 	u64 value;
12314fa93cdSSrikanth Jampala 
12414fa93cdSSrikanth Jampala 	value = nitrox_read_csr(ndev, PEM0_INT);
12514fa93cdSSrikanth Jampala 	nitrox_write_csr(ndev, PEM0_INT, value);
12614fa93cdSSrikanth Jampala 	dev_err_ratelimited(DEV(ndev), "PEM(0)_INT  0x%016llx\n", value);
12714fa93cdSSrikanth Jampala }
12814fa93cdSSrikanth Jampala 
clear_lbc_err_intr(struct nitrox_device * ndev)12914fa93cdSSrikanth Jampala static void clear_lbc_err_intr(struct nitrox_device *ndev)
13014fa93cdSSrikanth Jampala {
13114fa93cdSSrikanth Jampala 	union lbc_int lbc_int;
13214fa93cdSSrikanth Jampala 	u64 value, offset;
13314fa93cdSSrikanth Jampala 	int i;
13414fa93cdSSrikanth Jampala 
13514fa93cdSSrikanth Jampala 	lbc_int.value = nitrox_read_csr(ndev, LBC_INT);
13614fa93cdSSrikanth Jampala 	dev_err_ratelimited(DEV(ndev), "LBC_INT  0x%016llx\n", lbc_int.value);
13714fa93cdSSrikanth Jampala 
13814fa93cdSSrikanth Jampala 	if (lbc_int.s.dma_rd_err) {
13914fa93cdSSrikanth Jampala 		for (i = 0; i < NR_CLUSTERS; i++) {
14014fa93cdSSrikanth Jampala 			offset = EFL_CORE_VF_ERR_INT0X(i);
14114fa93cdSSrikanth Jampala 			value = nitrox_read_csr(ndev, offset);
14214fa93cdSSrikanth Jampala 			nitrox_write_csr(ndev, offset, value);
14314fa93cdSSrikanth Jampala 			offset = EFL_CORE_VF_ERR_INT1X(i);
14414fa93cdSSrikanth Jampala 			value = nitrox_read_csr(ndev, offset);
14514fa93cdSSrikanth Jampala 			nitrox_write_csr(ndev, offset, value);
14614fa93cdSSrikanth Jampala 		}
14714fa93cdSSrikanth Jampala 	}
14814fa93cdSSrikanth Jampala 
14914fa93cdSSrikanth Jampala 	if (lbc_int.s.cam_soft_err) {
15014fa93cdSSrikanth Jampala 		dev_err_ratelimited(DEV(ndev), "CAM_SOFT_ERR, invalidating LBC\n");
15114fa93cdSSrikanth Jampala 		invalidate_lbc(ndev);
15214fa93cdSSrikanth Jampala 	}
15314fa93cdSSrikanth Jampala 
15414fa93cdSSrikanth Jampala 	if (lbc_int.s.pref_dat_len_mismatch_err) {
15514fa93cdSSrikanth Jampala 		offset = LBC_PLM_VF1_64_INT;
15614fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
15714fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
15814fa93cdSSrikanth Jampala 		offset = LBC_PLM_VF65_128_INT;
15914fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
16014fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
16114fa93cdSSrikanth Jampala 	}
16214fa93cdSSrikanth Jampala 
16314fa93cdSSrikanth Jampala 	if (lbc_int.s.rd_dat_len_mismatch_err) {
16414fa93cdSSrikanth Jampala 		offset = LBC_ELM_VF1_64_INT;
16514fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
16614fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
16714fa93cdSSrikanth Jampala 		offset = LBC_ELM_VF65_128_INT;
16814fa93cdSSrikanth Jampala 		value = nitrox_read_csr(ndev, offset);
16914fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, value);
17014fa93cdSSrikanth Jampala 	}
17114fa93cdSSrikanth Jampala 	nitrox_write_csr(ndev, LBC_INT, lbc_int.value);
17214fa93cdSSrikanth Jampala }
17314fa93cdSSrikanth Jampala 
clear_efl_err_intr(struct nitrox_device * ndev)17414fa93cdSSrikanth Jampala static void clear_efl_err_intr(struct nitrox_device *ndev)
17514fa93cdSSrikanth Jampala {
17614fa93cdSSrikanth Jampala 	int i;
17714fa93cdSSrikanth Jampala 
17814fa93cdSSrikanth Jampala 	for (i = 0; i < NR_CLUSTERS; i++) {
17914fa93cdSSrikanth Jampala 		union efl_core_int core_int;
18014fa93cdSSrikanth Jampala 		u64 value, offset;
18114fa93cdSSrikanth Jampala 
18214fa93cdSSrikanth Jampala 		offset = EFL_CORE_INTX(i);
18314fa93cdSSrikanth Jampala 		core_int.value = nitrox_read_csr(ndev, offset);
18414fa93cdSSrikanth Jampala 		nitrox_write_csr(ndev, offset, core_int.value);
18514fa93cdSSrikanth Jampala 		dev_err_ratelimited(DEV(ndev), "ELF_CORE(%d)_INT  0x%016llx\n",
18614fa93cdSSrikanth Jampala 				    i, core_int.value);
18714fa93cdSSrikanth Jampala 		if (core_int.s.se_err) {
18814fa93cdSSrikanth Jampala 			offset = EFL_CORE_SE_ERR_INTX(i);
18914fa93cdSSrikanth Jampala 			value = nitrox_read_csr(ndev, offset);
19014fa93cdSSrikanth Jampala 			nitrox_write_csr(ndev, offset, value);
19114fa93cdSSrikanth Jampala 		}
19214fa93cdSSrikanth Jampala 	}
19314fa93cdSSrikanth Jampala }
19414fa93cdSSrikanth Jampala 
clear_bmi_err_intr(struct nitrox_device * ndev)19514fa93cdSSrikanth Jampala static void clear_bmi_err_intr(struct nitrox_device *ndev)
19614fa93cdSSrikanth Jampala {
19714fa93cdSSrikanth Jampala 	u64 value;
19814fa93cdSSrikanth Jampala 
19914fa93cdSSrikanth Jampala 	value = nitrox_read_csr(ndev, BMI_INT);
20014fa93cdSSrikanth Jampala 	nitrox_write_csr(ndev, BMI_INT, value);
20114fa93cdSSrikanth Jampala 	dev_err_ratelimited(DEV(ndev), "BMI_INT  0x%016llx\n", value);
20214fa93cdSSrikanth Jampala }
20314fa93cdSSrikanth Jampala 
nps_core_int_tasklet(unsigned long data)2045155e118SSrikanth Jampala static void nps_core_int_tasklet(unsigned long data)
20514fa93cdSSrikanth Jampala {
2065155e118SSrikanth Jampala 	struct nitrox_q_vector *qvec = (void *)(uintptr_t)(data);
2075155e118SSrikanth Jampala 	struct nitrox_device *ndev = qvec->ndev;
20814fa93cdSSrikanth Jampala 
2095155e118SSrikanth Jampala 	/* if pf mode do queue recovery */
2105155e118SSrikanth Jampala 	if (ndev->mode == __NDEV_MODE_PF) {
2115155e118SSrikanth Jampala 	} else {
2125155e118SSrikanth Jampala 		/**
2135155e118SSrikanth Jampala 		 * if VF(s) enabled communicate the error information
2145155e118SSrikanth Jampala 		 * to VF(s)
2155155e118SSrikanth Jampala 		 */
2165155e118SSrikanth Jampala 	}
21714fa93cdSSrikanth Jampala }
21814fa93cdSSrikanth Jampala 
2195b0ef799SLee Jones /*
2205155e118SSrikanth Jampala  * nps_core_int_isr - interrupt handler for NITROX errors and
2215155e118SSrikanth Jampala  *   mailbox communication
2225155e118SSrikanth Jampala  */
nps_core_int_isr(int irq,void * data)22314fa93cdSSrikanth Jampala static irqreturn_t nps_core_int_isr(int irq, void *data)
22414fa93cdSSrikanth Jampala {
225cf718eaaSSrikanth, Jampala 	struct nitrox_q_vector *qvec = data;
226cf718eaaSSrikanth, Jampala 	struct nitrox_device *ndev = qvec->ndev;
2275155e118SSrikanth Jampala 	union nps_core_int_active core_int;
22814fa93cdSSrikanth Jampala 
2295155e118SSrikanth Jampala 	core_int.value = nitrox_read_csr(ndev, NPS_CORE_INT_ACTIVE);
2305155e118SSrikanth Jampala 
2315155e118SSrikanth Jampala 	if (core_int.s.nps_core)
2325155e118SSrikanth Jampala 		clear_nps_core_err_intr(ndev);
2335155e118SSrikanth Jampala 
2345155e118SSrikanth Jampala 	if (core_int.s.nps_pkt)
2355155e118SSrikanth Jampala 		clear_nps_pkt_err_intr(ndev);
2365155e118SSrikanth Jampala 
2375155e118SSrikanth Jampala 	if (core_int.s.pom)
2385155e118SSrikanth Jampala 		clear_pom_err_intr(ndev);
2395155e118SSrikanth Jampala 
2405155e118SSrikanth Jampala 	if (core_int.s.pem)
2415155e118SSrikanth Jampala 		clear_pem_err_intr(ndev);
2425155e118SSrikanth Jampala 
2435155e118SSrikanth Jampala 	if (core_int.s.lbc)
2445155e118SSrikanth Jampala 		clear_lbc_err_intr(ndev);
2455155e118SSrikanth Jampala 
2465155e118SSrikanth Jampala 	if (core_int.s.efl)
2475155e118SSrikanth Jampala 		clear_efl_err_intr(ndev);
2485155e118SSrikanth Jampala 
2495155e118SSrikanth Jampala 	if (core_int.s.bmi)
2505155e118SSrikanth Jampala 		clear_bmi_err_intr(ndev);
2515155e118SSrikanth Jampala 
252cf718eaaSSrikanth, Jampala 	/* Mailbox interrupt */
253cf718eaaSSrikanth, Jampala 	if (core_int.s.mbox)
254cf718eaaSSrikanth, Jampala 		nitrox_pf2vf_mbox_handler(ndev);
255cf718eaaSSrikanth, Jampala 
2565155e118SSrikanth Jampala 	/* If more work callback the ISR, set resend */
2575155e118SSrikanth Jampala 	core_int.s.resend = 1;
2585155e118SSrikanth Jampala 	nitrox_write_csr(ndev, NPS_CORE_INT_ACTIVE, core_int.value);
25914fa93cdSSrikanth Jampala 
26014fa93cdSSrikanth Jampala 	return IRQ_HANDLED;
26114fa93cdSSrikanth Jampala }
26214fa93cdSSrikanth Jampala 
nitrox_unregister_interrupts(struct nitrox_device * ndev)2635155e118SSrikanth Jampala void nitrox_unregister_interrupts(struct nitrox_device *ndev)
26414fa93cdSSrikanth Jampala {
2655155e118SSrikanth Jampala 	struct pci_dev *pdev = ndev->pdev;
2665155e118SSrikanth Jampala 	int i;
2675155e118SSrikanth Jampala 
2685155e118SSrikanth Jampala 	for (i = 0; i < ndev->num_vecs; i++) {
2695155e118SSrikanth Jampala 		struct nitrox_q_vector *qvec;
2705155e118SSrikanth Jampala 		int vec;
2715155e118SSrikanth Jampala 
2725155e118SSrikanth Jampala 		qvec = ndev->qvec + i;
2735155e118SSrikanth Jampala 		if (!qvec->valid)
2745155e118SSrikanth Jampala 			continue;
2755155e118SSrikanth Jampala 
2765155e118SSrikanth Jampala 		/* get the vector number */
2775155e118SSrikanth Jampala 		vec = pci_irq_vector(pdev, i);
2785155e118SSrikanth Jampala 		irq_set_affinity_hint(vec, NULL);
2795155e118SSrikanth Jampala 		free_irq(vec, qvec);
2805155e118SSrikanth Jampala 
2815155e118SSrikanth Jampala 		tasklet_disable(&qvec->resp_tasklet);
2825155e118SSrikanth Jampala 		tasklet_kill(&qvec->resp_tasklet);
2835155e118SSrikanth Jampala 		qvec->valid = false;
2845155e118SSrikanth Jampala 	}
2855155e118SSrikanth Jampala 	kfree(ndev->qvec);
2867a027b57SSrikanth, Jampala 	ndev->qvec = NULL;
2875155e118SSrikanth Jampala 	pci_free_irq_vectors(pdev);
2885155e118SSrikanth Jampala }
2895155e118SSrikanth Jampala 
nitrox_register_interrupts(struct nitrox_device * ndev)2905155e118SSrikanth Jampala int nitrox_register_interrupts(struct nitrox_device *ndev)
2915155e118SSrikanth Jampala {
2925155e118SSrikanth Jampala 	struct pci_dev *pdev = ndev->pdev;
2935155e118SSrikanth Jampala 	struct nitrox_q_vector *qvec;
2945155e118SSrikanth Jampala 	int nr_vecs, vec, cpu;
2955155e118SSrikanth Jampala 	int ret, i;
29614fa93cdSSrikanth Jampala 
29714fa93cdSSrikanth Jampala 	/*
29814fa93cdSSrikanth Jampala 	 * PF MSI-X vectors
29914fa93cdSSrikanth Jampala 	 *
30014fa93cdSSrikanth Jampala 	 * Entry 0: NPS PKT ring 0
30114fa93cdSSrikanth Jampala 	 * Entry 1: AQMQ ring 0
30214fa93cdSSrikanth Jampala 	 * Entry 2: ZQM ring 0
30314fa93cdSSrikanth Jampala 	 * Entry 3: NPS PKT ring 1
30414fa93cdSSrikanth Jampala 	 * Entry 4: AQMQ ring 1
30514fa93cdSSrikanth Jampala 	 * Entry 5: ZQM ring 1
30614fa93cdSSrikanth Jampala 	 * ....
30714fa93cdSSrikanth Jampala 	 * Entry 192: NPS_CORE_INT_ACTIVE
30814fa93cdSSrikanth Jampala 	 */
3095155e118SSrikanth Jampala 	nr_vecs = pci_msix_vec_count(pdev);
310*57c12666STong Tiangen 	if (nr_vecs < 0) {
311*57c12666STong Tiangen 		dev_err(DEV(ndev), "Error in getting vec count %d\n", nr_vecs);
312*57c12666STong Tiangen 		return nr_vecs;
313*57c12666STong Tiangen 	}
31414fa93cdSSrikanth Jampala 
3155155e118SSrikanth Jampala 	/* Enable MSI-X */
3165155e118SSrikanth Jampala 	ret = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX);
3175155e118SSrikanth Jampala 	if (ret < 0) {
3185155e118SSrikanth Jampala 		dev_err(DEV(ndev), "msix vectors %d alloc failed\n", nr_vecs);
3195155e118SSrikanth Jampala 		return ret;
3205155e118SSrikanth Jampala 	}
3215155e118SSrikanth Jampala 	ndev->num_vecs = nr_vecs;
3225155e118SSrikanth Jampala 
3235155e118SSrikanth Jampala 	ndev->qvec = kcalloc(nr_vecs, sizeof(*qvec), GFP_KERNEL);
3245155e118SSrikanth Jampala 	if (!ndev->qvec) {
3255155e118SSrikanth Jampala 		pci_free_irq_vectors(pdev);
32614fa93cdSSrikanth Jampala 		return -ENOMEM;
32714fa93cdSSrikanth Jampala 	}
32814fa93cdSSrikanth Jampala 
3295155e118SSrikanth Jampala 	/* request irqs for packet rings/ports */
3305155e118SSrikanth Jampala 	for (i = PKT_RING_MSIX_BASE; i < (nr_vecs - 1); i += NR_RING_VECTORS) {
3315155e118SSrikanth Jampala 		qvec = &ndev->qvec[i];
33214fa93cdSSrikanth Jampala 
3335155e118SSrikanth Jampala 		qvec->ring = i / NR_RING_VECTORS;
3345155e118SSrikanth Jampala 		if (qvec->ring >= ndev->nr_queues)
3355155e118SSrikanth Jampala 			break;
33614fa93cdSSrikanth Jampala 
3377a027b57SSrikanth, Jampala 		qvec->cmdq = &ndev->pkt_inq[qvec->ring];
3385155e118SSrikanth Jampala 		snprintf(qvec->name, IRQ_NAMESZ, "nitrox-pkt%d", qvec->ring);
3395155e118SSrikanth Jampala 		/* get the vector number */
3405155e118SSrikanth Jampala 		vec = pci_irq_vector(pdev, i);
3415155e118SSrikanth Jampala 		ret = request_irq(vec, nps_pkt_slc_isr, 0, qvec->name, qvec);
34214fa93cdSSrikanth Jampala 		if (ret) {
3435155e118SSrikanth Jampala 			dev_err(DEV(ndev), "irq failed for pkt ring/port%d\n",
3445155e118SSrikanth Jampala 				qvec->ring);
34514fa93cdSSrikanth Jampala 			goto irq_fail;
3465155e118SSrikanth Jampala 		}
3475155e118SSrikanth Jampala 		cpu = qvec->ring % num_online_cpus();
3485155e118SSrikanth Jampala 		irq_set_affinity_hint(vec, get_cpu_mask(cpu));
3495155e118SSrikanth Jampala 
3505155e118SSrikanth Jampala 		tasklet_init(&qvec->resp_tasklet, pkt_slc_resp_tasklet,
3515155e118SSrikanth Jampala 			     (unsigned long)qvec);
3525155e118SSrikanth Jampala 		qvec->valid = true;
3535155e118SSrikanth Jampala 	}
3545155e118SSrikanth Jampala 
3555155e118SSrikanth Jampala 	/* request irqs for non ring vectors */
3565155e118SSrikanth Jampala 	i = NON_RING_MSIX_BASE;
3575155e118SSrikanth Jampala 	qvec = &ndev->qvec[i];
3587a027b57SSrikanth, Jampala 	qvec->ndev = ndev;
3595155e118SSrikanth Jampala 
3605155e118SSrikanth Jampala 	snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d", i);
3615155e118SSrikanth Jampala 	/* get the vector number */
3625155e118SSrikanth Jampala 	vec = pci_irq_vector(pdev, i);
3635155e118SSrikanth Jampala 	ret = request_irq(vec, nps_core_int_isr, 0, qvec->name, qvec);
3645155e118SSrikanth Jampala 	if (ret) {
3655155e118SSrikanth Jampala 		dev_err(DEV(ndev), "irq failed for nitrox-core-int%d\n", i);
3665155e118SSrikanth Jampala 		goto irq_fail;
3675155e118SSrikanth Jampala 	}
3685155e118SSrikanth Jampala 	cpu = num_online_cpus();
3695155e118SSrikanth Jampala 	irq_set_affinity_hint(vec, get_cpu_mask(cpu));
3705155e118SSrikanth Jampala 
3715155e118SSrikanth Jampala 	tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet,
3725155e118SSrikanth Jampala 		     (unsigned long)qvec);
3735155e118SSrikanth Jampala 	qvec->valid = true;
37414fa93cdSSrikanth Jampala 
37514fa93cdSSrikanth Jampala 	return 0;
37614fa93cdSSrikanth Jampala 
37714fa93cdSSrikanth Jampala irq_fail:
3785155e118SSrikanth Jampala 	nitrox_unregister_interrupts(ndev);
3795155e118SSrikanth Jampala 	return ret;
38014fa93cdSSrikanth Jampala }
3817a027b57SSrikanth, Jampala 
nitrox_sriov_unregister_interrupts(struct nitrox_device * ndev)3827a027b57SSrikanth, Jampala void nitrox_sriov_unregister_interrupts(struct nitrox_device *ndev)
3837a027b57SSrikanth, Jampala {
3847a027b57SSrikanth, Jampala 	struct pci_dev *pdev = ndev->pdev;
3857a027b57SSrikanth, Jampala 	int i;
3867a027b57SSrikanth, Jampala 
3877a027b57SSrikanth, Jampala 	for (i = 0; i < ndev->num_vecs; i++) {
3887a027b57SSrikanth, Jampala 		struct nitrox_q_vector *qvec;
3897a027b57SSrikanth, Jampala 		int vec;
3907a027b57SSrikanth, Jampala 
3917a027b57SSrikanth, Jampala 		qvec = ndev->qvec + i;
3927a027b57SSrikanth, Jampala 		if (!qvec->valid)
3937a027b57SSrikanth, Jampala 			continue;
3947a027b57SSrikanth, Jampala 
3957a027b57SSrikanth, Jampala 		vec = ndev->iov.msix.vector;
3967a027b57SSrikanth, Jampala 		irq_set_affinity_hint(vec, NULL);
3977a027b57SSrikanth, Jampala 		free_irq(vec, qvec);
3987a027b57SSrikanth, Jampala 
3997a027b57SSrikanth, Jampala 		tasklet_disable(&qvec->resp_tasklet);
4007a027b57SSrikanth, Jampala 		tasklet_kill(&qvec->resp_tasklet);
4017a027b57SSrikanth, Jampala 		qvec->valid = false;
4027a027b57SSrikanth, Jampala 	}
4037a027b57SSrikanth, Jampala 	kfree(ndev->qvec);
4047a027b57SSrikanth, Jampala 	ndev->qvec = NULL;
4057a027b57SSrikanth, Jampala 	pci_disable_msix(pdev);
4067a027b57SSrikanth, Jampala }
4077a027b57SSrikanth, Jampala 
nitrox_sriov_register_interupts(struct nitrox_device * ndev)4087a027b57SSrikanth, Jampala int nitrox_sriov_register_interupts(struct nitrox_device *ndev)
4097a027b57SSrikanth, Jampala {
4107a027b57SSrikanth, Jampala 	struct pci_dev *pdev = ndev->pdev;
4117a027b57SSrikanth, Jampala 	struct nitrox_q_vector *qvec;
4127a027b57SSrikanth, Jampala 	int vec, cpu;
4137a027b57SSrikanth, Jampala 	int ret;
4147a027b57SSrikanth, Jampala 
4157a027b57SSrikanth, Jampala 	/**
4167a027b57SSrikanth, Jampala 	 * only non ring vectors i.e Entry 192 is available
4177a027b57SSrikanth, Jampala 	 * for PF in SR-IOV mode.
4187a027b57SSrikanth, Jampala 	 */
4197a027b57SSrikanth, Jampala 	ndev->iov.msix.entry = NON_RING_MSIX_BASE;
4207a027b57SSrikanth, Jampala 	ret = pci_enable_msix_exact(pdev, &ndev->iov.msix, NR_NON_RING_VECTORS);
4217a027b57SSrikanth, Jampala 	if (ret) {
4227a027b57SSrikanth, Jampala 		dev_err(DEV(ndev), "failed to allocate nps-core-int%d\n",
4237a027b57SSrikanth, Jampala 			NON_RING_MSIX_BASE);
4247a027b57SSrikanth, Jampala 		return ret;
4257a027b57SSrikanth, Jampala 	}
4267a027b57SSrikanth, Jampala 
4277a027b57SSrikanth, Jampala 	qvec = kcalloc(NR_NON_RING_VECTORS, sizeof(*qvec), GFP_KERNEL);
4287a027b57SSrikanth, Jampala 	if (!qvec) {
4297a027b57SSrikanth, Jampala 		pci_disable_msix(pdev);
4307a027b57SSrikanth, Jampala 		return -ENOMEM;
4317a027b57SSrikanth, Jampala 	}
4327a027b57SSrikanth, Jampala 	qvec->ndev = ndev;
4337a027b57SSrikanth, Jampala 
4347a027b57SSrikanth, Jampala 	ndev->qvec = qvec;
4357a027b57SSrikanth, Jampala 	ndev->num_vecs = NR_NON_RING_VECTORS;
4367a027b57SSrikanth, Jampala 	snprintf(qvec->name, IRQ_NAMESZ, "nitrox-core-int%d",
4377a027b57SSrikanth, Jampala 		 NON_RING_MSIX_BASE);
4387a027b57SSrikanth, Jampala 
4397a027b57SSrikanth, Jampala 	vec = ndev->iov.msix.vector;
4407a027b57SSrikanth, Jampala 	ret = request_irq(vec, nps_core_int_isr, 0, qvec->name, qvec);
4417a027b57SSrikanth, Jampala 	if (ret) {
4427a027b57SSrikanth, Jampala 		dev_err(DEV(ndev), "irq failed for nitrox-core-int%d\n",
4437a027b57SSrikanth, Jampala 			NON_RING_MSIX_BASE);
4447a027b57SSrikanth, Jampala 		goto iov_irq_fail;
4457a027b57SSrikanth, Jampala 	}
4467a027b57SSrikanth, Jampala 	cpu = num_online_cpus();
4477a027b57SSrikanth, Jampala 	irq_set_affinity_hint(vec, get_cpu_mask(cpu));
4487a027b57SSrikanth, Jampala 
4497a027b57SSrikanth, Jampala 	tasklet_init(&qvec->resp_tasklet, nps_core_int_tasklet,
4507a027b57SSrikanth, Jampala 		     (unsigned long)qvec);
4517a027b57SSrikanth, Jampala 	qvec->valid = true;
4527a027b57SSrikanth, Jampala 
4537a027b57SSrikanth, Jampala 	return 0;
4547a027b57SSrikanth, Jampala 
4557a027b57SSrikanth, Jampala iov_irq_fail:
4567a027b57SSrikanth, Jampala 	nitrox_sriov_unregister_interrupts(ndev);
4577a027b57SSrikanth, Jampala 	return ret;
4587a027b57SSrikanth, Jampala }
459