xref: /openbmc/linux/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
15e8ce833SSrujana Challa // SPDX-License-Identifier: GPL-2.0-only
25e8ce833SSrujana Challa /* Copyright (C) 2020 Marvell. */
35e8ce833SSrujana Challa 
45e8ce833SSrujana Challa #include <linux/firmware.h>
55e8ce833SSrujana Challa #include "otx2_cpt_hw_types.h"
65e8ce833SSrujana Challa #include "otx2_cpt_common.h"
7fed8f4d5SSrujana Challa #include "otx2_cpt_devlink.h"
843ac0b82SSrujana Challa #include "otx2_cptpf_ucode.h"
95e8ce833SSrujana Challa #include "otx2_cptpf.h"
10eb33cd91SSrujana Challa #include "cn10k_cpt.h"
115e8ce833SSrujana Challa #include "rvu_reg.h"
125e8ce833SSrujana Challa 
134cd8c315SSrujana Challa #define OTX2_CPT_DRV_NAME    "rvu_cptpf"
144cd8c315SSrujana Challa #define OTX2_CPT_DRV_STRING  "Marvell RVU CPT Physical Function Driver"
155e8ce833SSrujana Challa 
16a4855a8cSSrujana Challa #define CPT_UC_RID_CN9K_B0   1
17a4855a8cSSrujana Challa 
cptpf_enable_vfpf_mbox_intr(struct otx2_cptpf_dev * cptpf,int num_vfs)18fe16eceaSSrujana Challa static void cptpf_enable_vfpf_mbox_intr(struct otx2_cptpf_dev *cptpf,
19fe16eceaSSrujana Challa 					int num_vfs)
20fe16eceaSSrujana Challa {
21fe16eceaSSrujana Challa 	int ena_bits;
22fe16eceaSSrujana Challa 
23fe16eceaSSrujana Challa 	/* Clear any pending interrupts */
24fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
25fe16eceaSSrujana Challa 			 RVU_PF_VFPF_MBOX_INTX(0), ~0x0ULL);
26fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
27fe16eceaSSrujana Challa 			 RVU_PF_VFPF_MBOX_INTX(1), ~0x0ULL);
28fe16eceaSSrujana Challa 
29fe16eceaSSrujana Challa 	/* Enable VF interrupts for VFs from 0 to 63 */
30fe16eceaSSrujana Challa 	ena_bits = ((num_vfs - 1) % 64);
31fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
32fe16eceaSSrujana Challa 			 RVU_PF_VFPF_MBOX_INT_ENA_W1SX(0),
33fe16eceaSSrujana Challa 			 GENMASK_ULL(ena_bits, 0));
34fe16eceaSSrujana Challa 
35fe16eceaSSrujana Challa 	if (num_vfs > 64) {
36fe16eceaSSrujana Challa 		/* Enable VF interrupts for VFs from 64 to 127 */
37fe16eceaSSrujana Challa 		ena_bits = num_vfs - 64 - 1;
38fe16eceaSSrujana Challa 		otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
39fe16eceaSSrujana Challa 				RVU_PF_VFPF_MBOX_INT_ENA_W1SX(1),
40fe16eceaSSrujana Challa 				GENMASK_ULL(ena_bits, 0));
41fe16eceaSSrujana Challa 	}
42fe16eceaSSrujana Challa }
43fe16eceaSSrujana Challa 
cptpf_disable_vfpf_mbox_intr(struct otx2_cptpf_dev * cptpf,int num_vfs)44fe16eceaSSrujana Challa static void cptpf_disable_vfpf_mbox_intr(struct otx2_cptpf_dev *cptpf,
45fe16eceaSSrujana Challa 					 int num_vfs)
46fe16eceaSSrujana Challa {
47fe16eceaSSrujana Challa 	int vector;
48fe16eceaSSrujana Challa 
49fe16eceaSSrujana Challa 	/* Disable VF-PF interrupts */
50fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
51fe16eceaSSrujana Challa 			 RVU_PF_VFPF_MBOX_INT_ENA_W1CX(0), ~0ULL);
52fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
53fe16eceaSSrujana Challa 			 RVU_PF_VFPF_MBOX_INT_ENA_W1CX(1), ~0ULL);
54fe16eceaSSrujana Challa 	/* Clear any pending interrupts */
55fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
56fe16eceaSSrujana Challa 			 RVU_PF_VFPF_MBOX_INTX(0), ~0ULL);
57fe16eceaSSrujana Challa 
58fe16eceaSSrujana Challa 	vector = pci_irq_vector(cptpf->pdev, RVU_PF_INT_VEC_VFPF_MBOX0);
59fe16eceaSSrujana Challa 	free_irq(vector, cptpf);
60fe16eceaSSrujana Challa 
61fe16eceaSSrujana Challa 	if (num_vfs > 64) {
62fe16eceaSSrujana Challa 		otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
63fe16eceaSSrujana Challa 				 RVU_PF_VFPF_MBOX_INTX(1), ~0ULL);
64fe16eceaSSrujana Challa 		vector = pci_irq_vector(cptpf->pdev, RVU_PF_INT_VEC_VFPF_MBOX1);
65fe16eceaSSrujana Challa 		free_irq(vector, cptpf);
66fe16eceaSSrujana Challa 	}
67fe16eceaSSrujana Challa }
68fe16eceaSSrujana Challa 
cptpf_enable_vf_flr_me_intrs(struct otx2_cptpf_dev * cptpf,int num_vfs)6976c1f4e0SSrujana Challa static void cptpf_enable_vf_flr_me_intrs(struct otx2_cptpf_dev *cptpf,
7076c1f4e0SSrujana Challa 					 int num_vfs)
71fe16eceaSSrujana Challa {
7276c1f4e0SSrujana Challa 	/* Clear FLR interrupt if any */
73fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_VFFLR_INTX(0),
7476c1f4e0SSrujana Challa 			 INTR_MASK(num_vfs));
75fe16eceaSSrujana Challa 
76fe16eceaSSrujana Challa 	/* Enable VF FLR interrupts */
77fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
7876c1f4e0SSrujana Challa 			 RVU_PF_VFFLR_INT_ENA_W1SX(0), INTR_MASK(num_vfs));
7976c1f4e0SSrujana Challa 	/* Clear ME interrupt if any */
8076c1f4e0SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_VFME_INTX(0),
8176c1f4e0SSrujana Challa 			 INTR_MASK(num_vfs));
8276c1f4e0SSrujana Challa 	/* Enable VF ME interrupts */
83fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
8476c1f4e0SSrujana Challa 			 RVU_PF_VFME_INT_ENA_W1SX(0), INTR_MASK(num_vfs));
8576c1f4e0SSrujana Challa 
8676c1f4e0SSrujana Challa 	if (num_vfs <= 64)
8776c1f4e0SSrujana Challa 		return;
8876c1f4e0SSrujana Challa 
8976c1f4e0SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_VFFLR_INTX(1),
9076c1f4e0SSrujana Challa 			 INTR_MASK(num_vfs - 64));
9176c1f4e0SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
9276c1f4e0SSrujana Challa 			 RVU_PF_VFFLR_INT_ENA_W1SX(1), INTR_MASK(num_vfs - 64));
9376c1f4e0SSrujana Challa 
9476c1f4e0SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_VFME_INTX(1),
9576c1f4e0SSrujana Challa 			 INTR_MASK(num_vfs - 64));
9676c1f4e0SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
9776c1f4e0SSrujana Challa 			 RVU_PF_VFME_INT_ENA_W1SX(1), INTR_MASK(num_vfs - 64));
98fe16eceaSSrujana Challa }
99fe16eceaSSrujana Challa 
cptpf_disable_vf_flr_me_intrs(struct otx2_cptpf_dev * cptpf,int num_vfs)10076c1f4e0SSrujana Challa static void cptpf_disable_vf_flr_me_intrs(struct otx2_cptpf_dev *cptpf,
101fe16eceaSSrujana Challa 				       int num_vfs)
102fe16eceaSSrujana Challa {
103fe16eceaSSrujana Challa 	int vector;
104fe16eceaSSrujana Challa 
105fe16eceaSSrujana Challa 	/* Disable VF FLR interrupts */
106fe16eceaSSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
10776c1f4e0SSrujana Challa 			 RVU_PF_VFFLR_INT_ENA_W1CX(0), INTR_MASK(num_vfs));
108fe16eceaSSrujana Challa 	vector = pci_irq_vector(cptpf->pdev, RVU_PF_INT_VEC_VFFLR0);
109fe16eceaSSrujana Challa 	free_irq(vector, cptpf);
110fe16eceaSSrujana Challa 
11176c1f4e0SSrujana Challa 	/* Disable VF ME interrupts */
11276c1f4e0SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
11376c1f4e0SSrujana Challa 			 RVU_PF_VFME_INT_ENA_W1CX(0), INTR_MASK(num_vfs));
11476c1f4e0SSrujana Challa 	vector = pci_irq_vector(cptpf->pdev, RVU_PF_INT_VEC_VFME0);
11576c1f4e0SSrujana Challa 	free_irq(vector, cptpf);
11676c1f4e0SSrujana Challa 
11776c1f4e0SSrujana Challa 	if (num_vfs <= 64)
11876c1f4e0SSrujana Challa 		return;
11976c1f4e0SSrujana Challa 
12076c1f4e0SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
12176c1f4e0SSrujana Challa 			 RVU_PF_VFFLR_INT_ENA_W1CX(1), INTR_MASK(num_vfs - 64));
122fe16eceaSSrujana Challa 	vector = pci_irq_vector(cptpf->pdev, RVU_PF_INT_VEC_VFFLR1);
123fe16eceaSSrujana Challa 	free_irq(vector, cptpf);
12476c1f4e0SSrujana Challa 
12576c1f4e0SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
12676c1f4e0SSrujana Challa 			 RVU_PF_VFME_INT_ENA_W1CX(1), INTR_MASK(num_vfs - 64));
12776c1f4e0SSrujana Challa 	vector = pci_irq_vector(cptpf->pdev, RVU_PF_INT_VEC_VFME1);
12876c1f4e0SSrujana Challa 	free_irq(vector, cptpf);
129fe16eceaSSrujana Challa }
130fe16eceaSSrujana Challa 
cptpf_flr_wq_handler(struct work_struct * work)131fe16eceaSSrujana Challa static void cptpf_flr_wq_handler(struct work_struct *work)
132fe16eceaSSrujana Challa {
133fe16eceaSSrujana Challa 	struct cptpf_flr_work *flr_work;
134fe16eceaSSrujana Challa 	struct otx2_cptpf_dev *pf;
135fe16eceaSSrujana Challa 	struct mbox_msghdr *req;
136fe16eceaSSrujana Challa 	struct otx2_mbox *mbox;
137fe16eceaSSrujana Challa 	int vf, reg = 0;
138fe16eceaSSrujana Challa 
139fe16eceaSSrujana Challa 	flr_work = container_of(work, struct cptpf_flr_work, work);
140fe16eceaSSrujana Challa 	pf = flr_work->pf;
141fe16eceaSSrujana Challa 	mbox = &pf->afpf_mbox;
142fe16eceaSSrujana Challa 
143fe16eceaSSrujana Challa 	vf = flr_work - pf->flr_work;
144fe16eceaSSrujana Challa 
1454363f3d3SHarman Kalra 	mutex_lock(&pf->lock);
146fe16eceaSSrujana Challa 	req = otx2_mbox_alloc_msg_rsp(mbox, 0, sizeof(*req),
147fe16eceaSSrujana Challa 				      sizeof(struct msg_rsp));
148280ee3c3SYang Yingliang 	if (!req) {
149280ee3c3SYang Yingliang 		mutex_unlock(&pf->lock);
150fe16eceaSSrujana Challa 		return;
151280ee3c3SYang Yingliang 	}
152fe16eceaSSrujana Challa 
153fe16eceaSSrujana Challa 	req->sig = OTX2_MBOX_REQ_SIG;
154fe16eceaSSrujana Challa 	req->id = MBOX_MSG_VF_FLR;
155fe16eceaSSrujana Challa 	req->pcifunc &= RVU_PFVF_FUNC_MASK;
156fe16eceaSSrujana Challa 	req->pcifunc |= (vf + 1) & RVU_PFVF_FUNC_MASK;
157fe16eceaSSrujana Challa 
158fe16eceaSSrujana Challa 	otx2_cpt_send_mbox_msg(mbox, pf->pdev);
1594363f3d3SHarman Kalra 	if (!otx2_cpt_sync_mbox_msg(&pf->afpf_mbox)) {
160fe16eceaSSrujana Challa 
161fe16eceaSSrujana Challa 		if (vf >= 64) {
162fe16eceaSSrujana Challa 			reg = 1;
163fe16eceaSSrujana Challa 			vf = vf - 64;
164fe16eceaSSrujana Challa 		}
165fe16eceaSSrujana Challa 		/* Clear transaction pending register */
166fe16eceaSSrujana Challa 		otx2_cpt_write64(pf->reg_base, BLKADDR_RVUM, 0,
167fe16eceaSSrujana Challa 				 RVU_PF_VFTRPENDX(reg), BIT_ULL(vf));
168fe16eceaSSrujana Challa 		otx2_cpt_write64(pf->reg_base, BLKADDR_RVUM, 0,
169fe16eceaSSrujana Challa 				 RVU_PF_VFFLR_INT_ENA_W1SX(reg), BIT_ULL(vf));
170fe16eceaSSrujana Challa 	}
1714363f3d3SHarman Kalra 	mutex_unlock(&pf->lock);
1724363f3d3SHarman Kalra }
173fe16eceaSSrujana Challa 
cptpf_vf_flr_intr(int __always_unused irq,void * arg)174fe16eceaSSrujana Challa static irqreturn_t cptpf_vf_flr_intr(int __always_unused irq, void *arg)
175fe16eceaSSrujana Challa {
176fe16eceaSSrujana Challa 	int reg, dev, vf, start_vf, num_reg = 1;
177fe16eceaSSrujana Challa 	struct otx2_cptpf_dev *cptpf = arg;
178fe16eceaSSrujana Challa 	u64 intr;
179fe16eceaSSrujana Challa 
180fe16eceaSSrujana Challa 	if (cptpf->max_vfs > 64)
181fe16eceaSSrujana Challa 		num_reg = 2;
182fe16eceaSSrujana Challa 
183fe16eceaSSrujana Challa 	for (reg = 0; reg < num_reg; reg++) {
184fe16eceaSSrujana Challa 		intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0,
185fe16eceaSSrujana Challa 				       RVU_PF_VFFLR_INTX(reg));
186fe16eceaSSrujana Challa 		if (!intr)
187fe16eceaSSrujana Challa 			continue;
188fe16eceaSSrujana Challa 		start_vf = 64 * reg;
189fe16eceaSSrujana Challa 		for (vf = 0; vf < 64; vf++) {
190fe16eceaSSrujana Challa 			if (!(intr & BIT_ULL(vf)))
191fe16eceaSSrujana Challa 				continue;
192fe16eceaSSrujana Challa 			dev = vf + start_vf;
193fe16eceaSSrujana Challa 			queue_work(cptpf->flr_wq, &cptpf->flr_work[dev].work);
194fe16eceaSSrujana Challa 			/* Clear interrupt */
195fe16eceaSSrujana Challa 			otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
196fe16eceaSSrujana Challa 					 RVU_PF_VFFLR_INTX(reg), BIT_ULL(vf));
197fe16eceaSSrujana Challa 			/* Disable the interrupt */
198fe16eceaSSrujana Challa 			otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
199fe16eceaSSrujana Challa 					 RVU_PF_VFFLR_INT_ENA_W1CX(reg),
200fe16eceaSSrujana Challa 					 BIT_ULL(vf));
201fe16eceaSSrujana Challa 		}
202fe16eceaSSrujana Challa 	}
203fe16eceaSSrujana Challa 	return IRQ_HANDLED;
204fe16eceaSSrujana Challa }
205fe16eceaSSrujana Challa 
cptpf_vf_me_intr(int __always_unused irq,void * arg)20676c1f4e0SSrujana Challa static irqreturn_t cptpf_vf_me_intr(int __always_unused irq, void *arg)
20776c1f4e0SSrujana Challa {
20876c1f4e0SSrujana Challa 	struct otx2_cptpf_dev *cptpf = arg;
20976c1f4e0SSrujana Challa 	int reg, vf, num_reg = 1;
21076c1f4e0SSrujana Challa 	u64 intr;
21176c1f4e0SSrujana Challa 
21276c1f4e0SSrujana Challa 	if (cptpf->max_vfs > 64)
21376c1f4e0SSrujana Challa 		num_reg = 2;
21476c1f4e0SSrujana Challa 
21576c1f4e0SSrujana Challa 	for (reg = 0; reg < num_reg; reg++) {
21676c1f4e0SSrujana Challa 		intr = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0,
21776c1f4e0SSrujana Challa 				       RVU_PF_VFME_INTX(reg));
21876c1f4e0SSrujana Challa 		if (!intr)
21976c1f4e0SSrujana Challa 			continue;
22076c1f4e0SSrujana Challa 		for (vf = 0; vf < 64; vf++) {
22176c1f4e0SSrujana Challa 			if (!(intr & BIT_ULL(vf)))
22276c1f4e0SSrujana Challa 				continue;
22376c1f4e0SSrujana Challa 			otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
22476c1f4e0SSrujana Challa 					 RVU_PF_VFTRPENDX(reg), BIT_ULL(vf));
22576c1f4e0SSrujana Challa 			/* Clear interrupt */
22676c1f4e0SSrujana Challa 			otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0,
22776c1f4e0SSrujana Challa 					 RVU_PF_VFME_INTX(reg), BIT_ULL(vf));
22876c1f4e0SSrujana Challa 		}
22976c1f4e0SSrujana Challa 	}
23076c1f4e0SSrujana Challa 	return IRQ_HANDLED;
23176c1f4e0SSrujana Challa }
23276c1f4e0SSrujana Challa 
cptpf_unregister_vfpf_intr(struct otx2_cptpf_dev * cptpf,int num_vfs)233fe16eceaSSrujana Challa static void cptpf_unregister_vfpf_intr(struct otx2_cptpf_dev *cptpf,
234fe16eceaSSrujana Challa 				       int num_vfs)
235fe16eceaSSrujana Challa {
236fe16eceaSSrujana Challa 	cptpf_disable_vfpf_mbox_intr(cptpf, num_vfs);
23776c1f4e0SSrujana Challa 	cptpf_disable_vf_flr_me_intrs(cptpf, num_vfs);
238fe16eceaSSrujana Challa }
239fe16eceaSSrujana Challa 
cptpf_register_vfpf_intr(struct otx2_cptpf_dev * cptpf,int num_vfs)240fe16eceaSSrujana Challa static int cptpf_register_vfpf_intr(struct otx2_cptpf_dev *cptpf, int num_vfs)
241fe16eceaSSrujana Challa {
242fe16eceaSSrujana Challa 	struct pci_dev *pdev = cptpf->pdev;
243fe16eceaSSrujana Challa 	struct device *dev = &pdev->dev;
244fe16eceaSSrujana Challa 	int ret, vector;
245fe16eceaSSrujana Challa 
246fe16eceaSSrujana Challa 	vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFPF_MBOX0);
247fe16eceaSSrujana Challa 	/* Register VF-PF mailbox interrupt handler */
248fe16eceaSSrujana Challa 	ret = request_irq(vector, otx2_cptpf_vfpf_mbox_intr, 0, "CPTVFPF Mbox0",
249fe16eceaSSrujana Challa 			  cptpf);
250fe16eceaSSrujana Challa 	if (ret) {
251fe16eceaSSrujana Challa 		dev_err(dev,
252fe16eceaSSrujana Challa 			"IRQ registration failed for PFVF mbox0 irq\n");
253fe16eceaSSrujana Challa 		return ret;
254fe16eceaSSrujana Challa 	}
255fe16eceaSSrujana Challa 	vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFFLR0);
256fe16eceaSSrujana Challa 	/* Register VF FLR interrupt handler */
257fe16eceaSSrujana Challa 	ret = request_irq(vector, cptpf_vf_flr_intr, 0, "CPTPF FLR0", cptpf);
258fe16eceaSSrujana Challa 	if (ret) {
259fe16eceaSSrujana Challa 		dev_err(dev,
260fe16eceaSSrujana Challa 			"IRQ registration failed for VFFLR0 irq\n");
261fe16eceaSSrujana Challa 		goto free_mbox0_irq;
262fe16eceaSSrujana Challa 	}
26376c1f4e0SSrujana Challa 	vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFME0);
26476c1f4e0SSrujana Challa 	/* Register VF ME interrupt handler */
26576c1f4e0SSrujana Challa 	ret = request_irq(vector, cptpf_vf_me_intr, 0, "CPTPF ME0", cptpf);
26676c1f4e0SSrujana Challa 	if (ret) {
26776c1f4e0SSrujana Challa 		dev_err(dev,
26876c1f4e0SSrujana Challa 			"IRQ registration failed for PFVF mbox0 irq\n");
26976c1f4e0SSrujana Challa 		goto free_flr0_irq;
27076c1f4e0SSrujana Challa 	}
27176c1f4e0SSrujana Challa 
272fe16eceaSSrujana Challa 	if (num_vfs > 64) {
273fe16eceaSSrujana Challa 		vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFPF_MBOX1);
274fe16eceaSSrujana Challa 		ret = request_irq(vector, otx2_cptpf_vfpf_mbox_intr, 0,
275fe16eceaSSrujana Challa 				  "CPTVFPF Mbox1", cptpf);
276fe16eceaSSrujana Challa 		if (ret) {
277fe16eceaSSrujana Challa 			dev_err(dev,
278fe16eceaSSrujana Challa 				"IRQ registration failed for PFVF mbox1 irq\n");
27976c1f4e0SSrujana Challa 			goto free_me0_irq;
280fe16eceaSSrujana Challa 		}
281fe16eceaSSrujana Challa 		vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFFLR1);
282fe16eceaSSrujana Challa 		/* Register VF FLR interrupt handler */
283fe16eceaSSrujana Challa 		ret = request_irq(vector, cptpf_vf_flr_intr, 0, "CPTPF FLR1",
284fe16eceaSSrujana Challa 				  cptpf);
285fe16eceaSSrujana Challa 		if (ret) {
286fe16eceaSSrujana Challa 			dev_err(dev,
287fe16eceaSSrujana Challa 				"IRQ registration failed for VFFLR1 irq\n");
288fe16eceaSSrujana Challa 			goto free_mbox1_irq;
289fe16eceaSSrujana Challa 		}
29076c1f4e0SSrujana Challa 		vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFME1);
29176c1f4e0SSrujana Challa 		/* Register VF FLR interrupt handler */
29276c1f4e0SSrujana Challa 		ret = request_irq(vector, cptpf_vf_me_intr, 0, "CPTPF ME1",
29376c1f4e0SSrujana Challa 				  cptpf);
29476c1f4e0SSrujana Challa 		if (ret) {
29576c1f4e0SSrujana Challa 			dev_err(dev,
29676c1f4e0SSrujana Challa 				"IRQ registration failed for VFFLR1 irq\n");
29776c1f4e0SSrujana Challa 			goto free_flr1_irq;
29876c1f4e0SSrujana Challa 		}
299fe16eceaSSrujana Challa 	}
300fe16eceaSSrujana Challa 	cptpf_enable_vfpf_mbox_intr(cptpf, num_vfs);
30176c1f4e0SSrujana Challa 	cptpf_enable_vf_flr_me_intrs(cptpf, num_vfs);
302fe16eceaSSrujana Challa 
303fe16eceaSSrujana Challa 	return 0;
304fe16eceaSSrujana Challa 
30576c1f4e0SSrujana Challa free_flr1_irq:
30676c1f4e0SSrujana Challa 	vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFFLR1);
30776c1f4e0SSrujana Challa 	free_irq(vector, cptpf);
308fe16eceaSSrujana Challa free_mbox1_irq:
309fe16eceaSSrujana Challa 	vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFPF_MBOX1);
310fe16eceaSSrujana Challa 	free_irq(vector, cptpf);
31176c1f4e0SSrujana Challa free_me0_irq:
31276c1f4e0SSrujana Challa 	vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFME0);
31376c1f4e0SSrujana Challa 	free_irq(vector, cptpf);
314fe16eceaSSrujana Challa free_flr0_irq:
315fe16eceaSSrujana Challa 	vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFFLR0);
316fe16eceaSSrujana Challa 	free_irq(vector, cptpf);
317fe16eceaSSrujana Challa free_mbox0_irq:
318fe16eceaSSrujana Challa 	vector = pci_irq_vector(pdev, RVU_PF_INT_VEC_VFPF_MBOX0);
319fe16eceaSSrujana Challa 	free_irq(vector, cptpf);
320fe16eceaSSrujana Challa 	return ret;
321fe16eceaSSrujana Challa }
322fe16eceaSSrujana Challa 
cptpf_flr_wq_destroy(struct otx2_cptpf_dev * pf)323fe16eceaSSrujana Challa static void cptpf_flr_wq_destroy(struct otx2_cptpf_dev *pf)
324fe16eceaSSrujana Challa {
325fe16eceaSSrujana Challa 	if (!pf->flr_wq)
326fe16eceaSSrujana Challa 		return;
327fe16eceaSSrujana Challa 	destroy_workqueue(pf->flr_wq);
328fe16eceaSSrujana Challa 	pf->flr_wq = NULL;
329fe16eceaSSrujana Challa 	kfree(pf->flr_work);
330fe16eceaSSrujana Challa }
331fe16eceaSSrujana Challa 
cptpf_flr_wq_init(struct otx2_cptpf_dev * cptpf,int num_vfs)332fe16eceaSSrujana Challa static int cptpf_flr_wq_init(struct otx2_cptpf_dev *cptpf, int num_vfs)
333fe16eceaSSrujana Challa {
334fe16eceaSSrujana Challa 	int vf;
335fe16eceaSSrujana Challa 
336fe16eceaSSrujana Challa 	cptpf->flr_wq = alloc_ordered_workqueue("cptpf_flr_wq", 0);
337fe16eceaSSrujana Challa 	if (!cptpf->flr_wq)
338fe16eceaSSrujana Challa 		return -ENOMEM;
339fe16eceaSSrujana Challa 
340fe16eceaSSrujana Challa 	cptpf->flr_work = kcalloc(num_vfs, sizeof(struct cptpf_flr_work),
341fe16eceaSSrujana Challa 				  GFP_KERNEL);
342fe16eceaSSrujana Challa 	if (!cptpf->flr_work)
343fe16eceaSSrujana Challa 		goto destroy_wq;
344fe16eceaSSrujana Challa 
345fe16eceaSSrujana Challa 	for (vf = 0; vf < num_vfs; vf++) {
346fe16eceaSSrujana Challa 		cptpf->flr_work[vf].pf = cptpf;
347fe16eceaSSrujana Challa 		INIT_WORK(&cptpf->flr_work[vf].work, cptpf_flr_wq_handler);
348fe16eceaSSrujana Challa 	}
349fe16eceaSSrujana Challa 	return 0;
350fe16eceaSSrujana Challa 
351fe16eceaSSrujana Challa destroy_wq:
352fe16eceaSSrujana Challa 	destroy_workqueue(cptpf->flr_wq);
353fe16eceaSSrujana Challa 	return -ENOMEM;
354fe16eceaSSrujana Challa }
355fe16eceaSSrujana Challa 
cptpf_vfpf_mbox_init(struct otx2_cptpf_dev * cptpf,int num_vfs)356fe16eceaSSrujana Challa static int cptpf_vfpf_mbox_init(struct otx2_cptpf_dev *cptpf, int num_vfs)
357fe16eceaSSrujana Challa {
358fe16eceaSSrujana Challa 	struct device *dev = &cptpf->pdev->dev;
359fe16eceaSSrujana Challa 	u64 vfpf_mbox_base;
360fe16eceaSSrujana Challa 	int err, i;
361fe16eceaSSrujana Challa 
362*8ae5c4d1STejun Heo 	cptpf->vfpf_mbox_wq =
363*8ae5c4d1STejun Heo 		alloc_ordered_workqueue("cpt_vfpf_mailbox",
364*8ae5c4d1STejun Heo 					WQ_HIGHPRI | WQ_MEM_RECLAIM);
365fe16eceaSSrujana Challa 	if (!cptpf->vfpf_mbox_wq)
366fe16eceaSSrujana Challa 		return -ENOMEM;
367fe16eceaSSrujana Challa 
368fe16eceaSSrujana Challa 	/* Map VF-PF mailbox memory */
3694cd8c315SSrujana Challa 	if (test_bit(CN10K_MBOX, &cptpf->cap_flag))
3704cd8c315SSrujana Challa 		vfpf_mbox_base = readq(cptpf->reg_base + RVU_PF_VF_MBOX_ADDR);
3714cd8c315SSrujana Challa 	else
372fe16eceaSSrujana Challa 		vfpf_mbox_base = readq(cptpf->reg_base + RVU_PF_VF_BAR4_ADDR);
3734cd8c315SSrujana Challa 
374fe16eceaSSrujana Challa 	if (!vfpf_mbox_base) {
375fe16eceaSSrujana Challa 		dev_err(dev, "VF-PF mailbox address not configured\n");
376fe16eceaSSrujana Challa 		err = -ENOMEM;
377fe16eceaSSrujana Challa 		goto free_wqe;
378fe16eceaSSrujana Challa 	}
379fe16eceaSSrujana Challa 	cptpf->vfpf_mbox_base = devm_ioremap_wc(dev, vfpf_mbox_base,
380fe16eceaSSrujana Challa 						MBOX_SIZE * cptpf->max_vfs);
381fe16eceaSSrujana Challa 	if (!cptpf->vfpf_mbox_base) {
382fe16eceaSSrujana Challa 		dev_err(dev, "Mapping of VF-PF mailbox address failed\n");
383fe16eceaSSrujana Challa 		err = -ENOMEM;
384fe16eceaSSrujana Challa 		goto free_wqe;
385fe16eceaSSrujana Challa 	}
386fe16eceaSSrujana Challa 	err = otx2_mbox_init(&cptpf->vfpf_mbox, cptpf->vfpf_mbox_base,
387fe16eceaSSrujana Challa 			     cptpf->pdev, cptpf->reg_base, MBOX_DIR_PFVF,
388fe16eceaSSrujana Challa 			     num_vfs);
389fe16eceaSSrujana Challa 	if (err)
390fe16eceaSSrujana Challa 		goto free_wqe;
391fe16eceaSSrujana Challa 
392fe16eceaSSrujana Challa 	for (i = 0; i < num_vfs; i++) {
393fe16eceaSSrujana Challa 		cptpf->vf[i].vf_id = i;
394fe16eceaSSrujana Challa 		cptpf->vf[i].cptpf = cptpf;
395fe16eceaSSrujana Challa 		cptpf->vf[i].intr_idx = i % 64;
396fe16eceaSSrujana Challa 		INIT_WORK(&cptpf->vf[i].vfpf_mbox_work,
397fe16eceaSSrujana Challa 			  otx2_cptpf_vfpf_mbox_handler);
398fe16eceaSSrujana Challa 	}
399fe16eceaSSrujana Challa 	return 0;
400fe16eceaSSrujana Challa 
401fe16eceaSSrujana Challa free_wqe:
402fe16eceaSSrujana Challa 	destroy_workqueue(cptpf->vfpf_mbox_wq);
403fe16eceaSSrujana Challa 	return err;
404fe16eceaSSrujana Challa }
405fe16eceaSSrujana Challa 
cptpf_vfpf_mbox_destroy(struct otx2_cptpf_dev * cptpf)406fe16eceaSSrujana Challa static void cptpf_vfpf_mbox_destroy(struct otx2_cptpf_dev *cptpf)
407fe16eceaSSrujana Challa {
408fe16eceaSSrujana Challa 	destroy_workqueue(cptpf->vfpf_mbox_wq);
409fe16eceaSSrujana Challa 	otx2_mbox_destroy(&cptpf->vfpf_mbox);
410fe16eceaSSrujana Challa }
411fe16eceaSSrujana Challa 
cptpf_disable_afpf_mbox_intr(struct otx2_cptpf_dev * cptpf)41283ffcf78SSrujana Challa static void cptpf_disable_afpf_mbox_intr(struct otx2_cptpf_dev *cptpf)
41383ffcf78SSrujana Challa {
41483ffcf78SSrujana Challa 	/* Disable AF-PF interrupt */
41583ffcf78SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT_ENA_W1C,
41683ffcf78SSrujana Challa 			 0x1ULL);
41783ffcf78SSrujana Challa 	/* Clear interrupt if any */
41883ffcf78SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT, 0x1ULL);
41983ffcf78SSrujana Challa }
42083ffcf78SSrujana Challa 
cptpf_register_afpf_mbox_intr(struct otx2_cptpf_dev * cptpf)42183ffcf78SSrujana Challa static int cptpf_register_afpf_mbox_intr(struct otx2_cptpf_dev *cptpf)
42283ffcf78SSrujana Challa {
42383ffcf78SSrujana Challa 	struct pci_dev *pdev = cptpf->pdev;
42483ffcf78SSrujana Challa 	struct device *dev = &pdev->dev;
42583ffcf78SSrujana Challa 	int ret, irq;
42683ffcf78SSrujana Challa 
42783ffcf78SSrujana Challa 	irq = pci_irq_vector(pdev, RVU_PF_INT_VEC_AFPF_MBOX);
42883ffcf78SSrujana Challa 	/* Register AF-PF mailbox interrupt handler */
42983ffcf78SSrujana Challa 	ret = devm_request_irq(dev, irq, otx2_cptpf_afpf_mbox_intr, 0,
43083ffcf78SSrujana Challa 			       "CPTAFPF Mbox", cptpf);
43183ffcf78SSrujana Challa 	if (ret) {
43283ffcf78SSrujana Challa 		dev_err(dev,
43383ffcf78SSrujana Challa 			"IRQ registration failed for PFAF mbox irq\n");
43483ffcf78SSrujana Challa 		return ret;
43583ffcf78SSrujana Challa 	}
43683ffcf78SSrujana Challa 	/* Clear interrupt if any, to avoid spurious interrupts */
43783ffcf78SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT, 0x1ULL);
43883ffcf78SSrujana Challa 	/* Enable AF-PF interrupt */
43983ffcf78SSrujana Challa 	otx2_cpt_write64(cptpf->reg_base, BLKADDR_RVUM, 0, RVU_PF_INT_ENA_W1S,
44083ffcf78SSrujana Challa 			 0x1ULL);
44183ffcf78SSrujana Challa 
44283ffcf78SSrujana Challa 	ret = otx2_cpt_send_ready_msg(&cptpf->afpf_mbox, cptpf->pdev);
44383ffcf78SSrujana Challa 	if (ret) {
44483ffcf78SSrujana Challa 		dev_warn(dev,
44583ffcf78SSrujana Challa 			 "AF not responding to mailbox, deferring probe\n");
44683ffcf78SSrujana Challa 		cptpf_disable_afpf_mbox_intr(cptpf);
44783ffcf78SSrujana Challa 		return -EPROBE_DEFER;
44883ffcf78SSrujana Challa 	}
44983ffcf78SSrujana Challa 	return 0;
45083ffcf78SSrujana Challa }
45183ffcf78SSrujana Challa 
cptpf_afpf_mbox_init(struct otx2_cptpf_dev * cptpf)45283ffcf78SSrujana Challa static int cptpf_afpf_mbox_init(struct otx2_cptpf_dev *cptpf)
45383ffcf78SSrujana Challa {
4544cd8c315SSrujana Challa 	struct pci_dev *pdev = cptpf->pdev;
4554cd8c315SSrujana Challa 	resource_size_t offset;
45683ffcf78SSrujana Challa 	int err;
45783ffcf78SSrujana Challa 
458*8ae5c4d1STejun Heo 	cptpf->afpf_mbox_wq =
459*8ae5c4d1STejun Heo 		alloc_ordered_workqueue("cpt_afpf_mailbox",
460*8ae5c4d1STejun Heo 					WQ_HIGHPRI | WQ_MEM_RECLAIM);
46183ffcf78SSrujana Challa 	if (!cptpf->afpf_mbox_wq)
46283ffcf78SSrujana Challa 		return -ENOMEM;
46383ffcf78SSrujana Challa 
4644cd8c315SSrujana Challa 	offset = pci_resource_start(pdev, PCI_MBOX_BAR_NUM);
4654cd8c315SSrujana Challa 	/* Map AF-PF mailbox memory */
4664cd8c315SSrujana Challa 	cptpf->afpf_mbox_base = devm_ioremap_wc(&pdev->dev, offset, MBOX_SIZE);
4674cd8c315SSrujana Challa 	if (!cptpf->afpf_mbox_base) {
4684cd8c315SSrujana Challa 		dev_err(&pdev->dev, "Unable to map BAR4\n");
4694cd8c315SSrujana Challa 		err = -ENOMEM;
4704cd8c315SSrujana Challa 		goto error;
4714cd8c315SSrujana Challa 	}
4724cd8c315SSrujana Challa 
47383ffcf78SSrujana Challa 	err = otx2_mbox_init(&cptpf->afpf_mbox, cptpf->afpf_mbox_base,
4744cd8c315SSrujana Challa 			     pdev, cptpf->reg_base, MBOX_DIR_PFAF, 1);
47583ffcf78SSrujana Challa 	if (err)
47683ffcf78SSrujana Challa 		goto error;
47783ffcf78SSrujana Challa 
4785c553114SSrujana Challa 	err = otx2_mbox_init(&cptpf->afpf_mbox_up, cptpf->afpf_mbox_base,
4795c553114SSrujana Challa 			     pdev, cptpf->reg_base, MBOX_DIR_PFAF_UP, 1);
4805c553114SSrujana Challa 	if (err)
4815c553114SSrujana Challa 		goto mbox_cleanup;
4825c553114SSrujana Challa 
48383ffcf78SSrujana Challa 	INIT_WORK(&cptpf->afpf_mbox_work, otx2_cptpf_afpf_mbox_handler);
4845c553114SSrujana Challa 	INIT_WORK(&cptpf->afpf_mbox_up_work, otx2_cptpf_afpf_mbox_up_handler);
4854363f3d3SHarman Kalra 	mutex_init(&cptpf->lock);
4865c553114SSrujana Challa 
48783ffcf78SSrujana Challa 	return 0;
48883ffcf78SSrujana Challa 
4895c553114SSrujana Challa mbox_cleanup:
4905c553114SSrujana Challa 	otx2_mbox_destroy(&cptpf->afpf_mbox);
49183ffcf78SSrujana Challa error:
49283ffcf78SSrujana Challa 	destroy_workqueue(cptpf->afpf_mbox_wq);
49383ffcf78SSrujana Challa 	return err;
49483ffcf78SSrujana Challa }
49583ffcf78SSrujana Challa 
cptpf_afpf_mbox_destroy(struct otx2_cptpf_dev * cptpf)49683ffcf78SSrujana Challa static void cptpf_afpf_mbox_destroy(struct otx2_cptpf_dev *cptpf)
49783ffcf78SSrujana Challa {
49883ffcf78SSrujana Challa 	destroy_workqueue(cptpf->afpf_mbox_wq);
49983ffcf78SSrujana Challa 	otx2_mbox_destroy(&cptpf->afpf_mbox);
5005c553114SSrujana Challa 	otx2_mbox_destroy(&cptpf->afpf_mbox_up);
50183ffcf78SSrujana Challa }
50283ffcf78SSrujana Challa 
sso_pf_func_ovrd_show(struct device * dev,struct device_attribute * attr,char * buf)503a4855a8cSSrujana Challa static ssize_t sso_pf_func_ovrd_show(struct device *dev,
504a4855a8cSSrujana Challa 				     struct device_attribute *attr, char *buf)
505a4855a8cSSrujana Challa {
506a4855a8cSSrujana Challa 	struct otx2_cptpf_dev *cptpf = dev_get_drvdata(dev);
507a4855a8cSSrujana Challa 
508a4855a8cSSrujana Challa 	return sprintf(buf, "%d\n", cptpf->sso_pf_func_ovrd);
509a4855a8cSSrujana Challa }
510a4855a8cSSrujana Challa 
sso_pf_func_ovrd_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)511a4855a8cSSrujana Challa static ssize_t sso_pf_func_ovrd_store(struct device *dev,
512a4855a8cSSrujana Challa 				      struct device_attribute *attr,
513a4855a8cSSrujana Challa 				      const char *buf, size_t count)
514a4855a8cSSrujana Challa {
515a4855a8cSSrujana Challa 	struct otx2_cptpf_dev *cptpf = dev_get_drvdata(dev);
516a4855a8cSSrujana Challa 	u8 sso_pf_func_ovrd;
517a4855a8cSSrujana Challa 
518a4855a8cSSrujana Challa 	if (!(cptpf->pdev->revision == CPT_UC_RID_CN9K_B0))
519a4855a8cSSrujana Challa 		return count;
520a4855a8cSSrujana Challa 
521a4855a8cSSrujana Challa 	if (kstrtou8(buf, 0, &sso_pf_func_ovrd))
522a4855a8cSSrujana Challa 		return -EINVAL;
523a4855a8cSSrujana Challa 
524a4855a8cSSrujana Challa 	cptpf->sso_pf_func_ovrd = sso_pf_func_ovrd;
525a4855a8cSSrujana Challa 
526a4855a8cSSrujana Challa 	return count;
5275e8ce833SSrujana Challa }
5285e8ce833SSrujana Challa 
kvf_limits_show(struct device * dev,struct device_attribute * attr,char * buf)5298ec8015aSSrujana Challa static ssize_t kvf_limits_show(struct device *dev,
5308ec8015aSSrujana Challa 			       struct device_attribute *attr, char *buf)
5318ec8015aSSrujana Challa {
5328ec8015aSSrujana Challa 	struct otx2_cptpf_dev *cptpf = dev_get_drvdata(dev);
5338ec8015aSSrujana Challa 
5348ec8015aSSrujana Challa 	return sprintf(buf, "%d\n", cptpf->kvf_limits);
5358ec8015aSSrujana Challa }
5368ec8015aSSrujana Challa 
kvf_limits_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)5378ec8015aSSrujana Challa static ssize_t kvf_limits_store(struct device *dev,
5388ec8015aSSrujana Challa 				struct device_attribute *attr,
5398ec8015aSSrujana Challa 				const char *buf, size_t count)
5408ec8015aSSrujana Challa {
5418ec8015aSSrujana Challa 	struct otx2_cptpf_dev *cptpf = dev_get_drvdata(dev);
5428ec8015aSSrujana Challa 	int lfs_num;
5430ea275dfSDan Carpenter 	int ret;
5448ec8015aSSrujana Challa 
5450ea275dfSDan Carpenter 	ret = kstrtoint(buf, 0, &lfs_num);
5460ea275dfSDan Carpenter 	if (ret)
5470ea275dfSDan Carpenter 		return ret;
5488ec8015aSSrujana Challa 	if (lfs_num < 1 || lfs_num > num_online_cpus()) {
5498ec8015aSSrujana Challa 		dev_err(dev, "lfs count %d must be in range [1 - %d]\n",
5508ec8015aSSrujana Challa 			lfs_num, num_online_cpus());
5518ec8015aSSrujana Challa 		return -EINVAL;
5528ec8015aSSrujana Challa 	}
5538ec8015aSSrujana Challa 	cptpf->kvf_limits = lfs_num;
5548ec8015aSSrujana Challa 
5558ec8015aSSrujana Challa 	return count;
5568ec8015aSSrujana Challa }
5578ec8015aSSrujana Challa 
5588ec8015aSSrujana Challa static DEVICE_ATTR_RW(kvf_limits);
559a4855a8cSSrujana Challa static DEVICE_ATTR_RW(sso_pf_func_ovrd);
560a4855a8cSSrujana Challa 
5618ec8015aSSrujana Challa static struct attribute *cptpf_attrs[] = {
5628ec8015aSSrujana Challa 	&dev_attr_kvf_limits.attr,
563a4855a8cSSrujana Challa 	&dev_attr_sso_pf_func_ovrd.attr,
5648ec8015aSSrujana Challa 	NULL
5658ec8015aSSrujana Challa };
5668ec8015aSSrujana Challa 
5678ec8015aSSrujana Challa static const struct attribute_group cptpf_sysfs_group = {
5688ec8015aSSrujana Challa 	.attrs = cptpf_attrs,
5698ec8015aSSrujana Challa };
5708ec8015aSSrujana Challa 
cpt_is_pf_usable(struct otx2_cptpf_dev * cptpf)5715e8ce833SSrujana Challa static int cpt_is_pf_usable(struct otx2_cptpf_dev *cptpf)
5725e8ce833SSrujana Challa {
5735e8ce833SSrujana Challa 	u64 rev;
5745e8ce833SSrujana Challa 
5755e8ce833SSrujana Challa 	rev = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0,
5765e8ce833SSrujana Challa 			      RVU_PF_BLOCK_ADDRX_DISC(BLKADDR_RVUM));
5775e8ce833SSrujana Challa 	rev = (rev >> 12) & 0xFF;
5785e8ce833SSrujana Challa 	/*
5795e8ce833SSrujana Challa 	 * Check if AF has setup revision for RVUM block, otherwise
5805e8ce833SSrujana Challa 	 * driver probe should be deferred until AF driver comes up
5815e8ce833SSrujana Challa 	 */
5825e8ce833SSrujana Challa 	if (!rev) {
5835e8ce833SSrujana Challa 		dev_warn(&cptpf->pdev->dev,
5845e8ce833SSrujana Challa 			 "AF is not initialized, deferring probe\n");
5855e8ce833SSrujana Challa 		return -EPROBE_DEFER;
5865e8ce833SSrujana Challa 	}
5875e8ce833SSrujana Challa 	return 0;
5885e8ce833SSrujana Challa }
5895e8ce833SSrujana Challa 
cptx_device_reset(struct otx2_cptpf_dev * cptpf,int blkaddr)590b2d17df3SSrujana Challa static int cptx_device_reset(struct otx2_cptpf_dev *cptpf, int blkaddr)
59143ac0b82SSrujana Challa {
59243ac0b82SSrujana Challa 	int timeout = 10, ret;
59343ac0b82SSrujana Challa 	u64 reg = 0;
59443ac0b82SSrujana Challa 
59543ac0b82SSrujana Challa 	ret = otx2_cpt_write_af_reg(&cptpf->afpf_mbox, cptpf->pdev,
596b2d17df3SSrujana Challa 				    CPT_AF_BLK_RST, 0x1, blkaddr);
59743ac0b82SSrujana Challa 	if (ret)
59843ac0b82SSrujana Challa 		return ret;
59943ac0b82SSrujana Challa 
60043ac0b82SSrujana Challa 	do {
60143ac0b82SSrujana Challa 		ret = otx2_cpt_read_af_reg(&cptpf->afpf_mbox, cptpf->pdev,
602b2d17df3SSrujana Challa 					   CPT_AF_BLK_RST, &reg, blkaddr);
60343ac0b82SSrujana Challa 		if (ret)
60443ac0b82SSrujana Challa 			return ret;
60543ac0b82SSrujana Challa 
60643ac0b82SSrujana Challa 		if (!((reg >> 63) & 0x1))
60743ac0b82SSrujana Challa 			break;
60843ac0b82SSrujana Challa 
60943ac0b82SSrujana Challa 		usleep_range(10000, 20000);
61043ac0b82SSrujana Challa 		if (timeout-- < 0)
61143ac0b82SSrujana Challa 			return -EBUSY;
61243ac0b82SSrujana Challa 	} while (1);
61343ac0b82SSrujana Challa 
61443ac0b82SSrujana Challa 	return ret;
61543ac0b82SSrujana Challa }
61643ac0b82SSrujana Challa 
cptpf_device_reset(struct otx2_cptpf_dev * cptpf)617b2d17df3SSrujana Challa static int cptpf_device_reset(struct otx2_cptpf_dev *cptpf)
618b2d17df3SSrujana Challa {
619b2d17df3SSrujana Challa 	int ret = 0;
620b2d17df3SSrujana Challa 
621b2d17df3SSrujana Challa 	if (cptpf->has_cpt1) {
622b2d17df3SSrujana Challa 		ret = cptx_device_reset(cptpf, BLKADDR_CPT1);
623b2d17df3SSrujana Challa 		if (ret)
624b2d17df3SSrujana Challa 			return ret;
625b2d17df3SSrujana Challa 	}
626b2d17df3SSrujana Challa 	return cptx_device_reset(cptpf, BLKADDR_CPT0);
627b2d17df3SSrujana Challa }
628b2d17df3SSrujana Challa 
cptpf_check_block_implemented(struct otx2_cptpf_dev * cptpf)629b2d17df3SSrujana Challa static void cptpf_check_block_implemented(struct otx2_cptpf_dev *cptpf)
630b2d17df3SSrujana Challa {
631b2d17df3SSrujana Challa 	u64 cfg;
632b2d17df3SSrujana Challa 
633b2d17df3SSrujana Challa 	cfg = otx2_cpt_read64(cptpf->reg_base, BLKADDR_RVUM, 0,
634b2d17df3SSrujana Challa 			      RVU_PF_BLOCK_ADDRX_DISC(BLKADDR_CPT1));
635b2d17df3SSrujana Challa 	if (cfg & BIT_ULL(11))
636b2d17df3SSrujana Challa 		cptpf->has_cpt1 = true;
637b2d17df3SSrujana Challa }
638b2d17df3SSrujana Challa 
cptpf_device_init(struct otx2_cptpf_dev * cptpf)63943ac0b82SSrujana Challa static int cptpf_device_init(struct otx2_cptpf_dev *cptpf)
64043ac0b82SSrujana Challa {
64143ac0b82SSrujana Challa 	union otx2_cptx_af_constants1 af_cnsts1 = {0};
64243ac0b82SSrujana Challa 	int ret = 0;
64343ac0b82SSrujana Challa 
644b2d17df3SSrujana Challa 	/* check if 'implemented' bit is set for block BLKADDR_CPT1 */
645b2d17df3SSrujana Challa 	cptpf_check_block_implemented(cptpf);
64643ac0b82SSrujana Challa 	/* Reset the CPT PF device */
64743ac0b82SSrujana Challa 	ret = cptpf_device_reset(cptpf);
64843ac0b82SSrujana Challa 	if (ret)
64943ac0b82SSrujana Challa 		return ret;
65043ac0b82SSrujana Challa 
65143ac0b82SSrujana Challa 	/* Get number of SE, IE and AE engines */
65243ac0b82SSrujana Challa 	ret = otx2_cpt_read_af_reg(&cptpf->afpf_mbox, cptpf->pdev,
653b2d17df3SSrujana Challa 				   CPT_AF_CONSTANTS1, &af_cnsts1.u,
654b2d17df3SSrujana Challa 				   BLKADDR_CPT0);
65543ac0b82SSrujana Challa 	if (ret)
65643ac0b82SSrujana Challa 		return ret;
65743ac0b82SSrujana Challa 
65843ac0b82SSrujana Challa 	cptpf->eng_grps.avail.max_se_cnt = af_cnsts1.s.se;
65943ac0b82SSrujana Challa 	cptpf->eng_grps.avail.max_ie_cnt = af_cnsts1.s.ie;
66043ac0b82SSrujana Challa 	cptpf->eng_grps.avail.max_ae_cnt = af_cnsts1.s.ae;
66143ac0b82SSrujana Challa 
66243ac0b82SSrujana Challa 	/* Disable all cores */
66343ac0b82SSrujana Challa 	ret = otx2_cpt_disable_all_cores(cptpf);
66443ac0b82SSrujana Challa 
66543ac0b82SSrujana Challa 	return ret;
66643ac0b82SSrujana Challa }
66743ac0b82SSrujana Challa 
cptpf_sriov_disable(struct pci_dev * pdev)668fe16eceaSSrujana Challa static int cptpf_sriov_disable(struct pci_dev *pdev)
669fe16eceaSSrujana Challa {
670fe16eceaSSrujana Challa 	struct otx2_cptpf_dev *cptpf = pci_get_drvdata(pdev);
671fe16eceaSSrujana Challa 	int num_vfs = pci_num_vf(pdev);
672fe16eceaSSrujana Challa 
673fe16eceaSSrujana Challa 	if (!num_vfs)
674fe16eceaSSrujana Challa 		return 0;
675fe16eceaSSrujana Challa 
676fe16eceaSSrujana Challa 	pci_disable_sriov(pdev);
677fe16eceaSSrujana Challa 	cptpf_unregister_vfpf_intr(cptpf, num_vfs);
678fe16eceaSSrujana Challa 	cptpf_flr_wq_destroy(cptpf);
679fe16eceaSSrujana Challa 	cptpf_vfpf_mbox_destroy(cptpf);
680fe16eceaSSrujana Challa 	module_put(THIS_MODULE);
681fe16eceaSSrujana Challa 	cptpf->enabled_vfs = 0;
682fe16eceaSSrujana Challa 
683fe16eceaSSrujana Challa 	return 0;
684fe16eceaSSrujana Challa }
685fe16eceaSSrujana Challa 
cptpf_sriov_enable(struct pci_dev * pdev,int num_vfs)686fe16eceaSSrujana Challa static int cptpf_sriov_enable(struct pci_dev *pdev, int num_vfs)
687fe16eceaSSrujana Challa {
688fe16eceaSSrujana Challa 	struct otx2_cptpf_dev *cptpf = pci_get_drvdata(pdev);
689fe16eceaSSrujana Challa 	int ret;
690fe16eceaSSrujana Challa 
691fe16eceaSSrujana Challa 	/* Initialize VF<=>PF mailbox */
692fe16eceaSSrujana Challa 	ret = cptpf_vfpf_mbox_init(cptpf, num_vfs);
693fe16eceaSSrujana Challa 	if (ret)
694fe16eceaSSrujana Challa 		return ret;
695fe16eceaSSrujana Challa 
696fe16eceaSSrujana Challa 	ret = cptpf_flr_wq_init(cptpf, num_vfs);
697fe16eceaSSrujana Challa 	if (ret)
698fe16eceaSSrujana Challa 		goto destroy_mbox;
699fe16eceaSSrujana Challa 	/* Register VF<=>PF mailbox interrupt */
700fe16eceaSSrujana Challa 	ret = cptpf_register_vfpf_intr(cptpf, num_vfs);
701fe16eceaSSrujana Challa 	if (ret)
702fe16eceaSSrujana Challa 		goto destroy_flr;
703fe16eceaSSrujana Challa 
70478506c2aSSrujana Challa 	/* Get CPT HW capabilities using LOAD_FVC operation. */
70578506c2aSSrujana Challa 	ret = otx2_cpt_discover_eng_capabilities(cptpf);
70678506c2aSSrujana Challa 	if (ret)
70778506c2aSSrujana Challa 		goto disable_intr;
70878506c2aSSrujana Challa 
70940a645f7SSrujana Challa 	ret = otx2_cpt_create_eng_grps(cptpf, &cptpf->eng_grps);
71043ac0b82SSrujana Challa 	if (ret)
71143ac0b82SSrujana Challa 		goto disable_intr;
71243ac0b82SSrujana Challa 
713fe16eceaSSrujana Challa 	cptpf->enabled_vfs = num_vfs;
714fe16eceaSSrujana Challa 	ret = pci_enable_sriov(pdev, num_vfs);
715fe16eceaSSrujana Challa 	if (ret)
716fe16eceaSSrujana Challa 		goto disable_intr;
717fe16eceaSSrujana Challa 
718fe16eceaSSrujana Challa 	dev_notice(&cptpf->pdev->dev, "VFs enabled: %d\n", num_vfs);
719fe16eceaSSrujana Challa 
720fe16eceaSSrujana Challa 	try_module_get(THIS_MODULE);
721fe16eceaSSrujana Challa 	return num_vfs;
722fe16eceaSSrujana Challa 
723fe16eceaSSrujana Challa disable_intr:
724fe16eceaSSrujana Challa 	cptpf_unregister_vfpf_intr(cptpf, num_vfs);
725fe16eceaSSrujana Challa 	cptpf->enabled_vfs = 0;
726fe16eceaSSrujana Challa destroy_flr:
727fe16eceaSSrujana Challa 	cptpf_flr_wq_destroy(cptpf);
728fe16eceaSSrujana Challa destroy_mbox:
729fe16eceaSSrujana Challa 	cptpf_vfpf_mbox_destroy(cptpf);
730fe16eceaSSrujana Challa 	return ret;
731fe16eceaSSrujana Challa }
732fe16eceaSSrujana Challa 
otx2_cptpf_sriov_configure(struct pci_dev * pdev,int num_vfs)733fe16eceaSSrujana Challa static int otx2_cptpf_sriov_configure(struct pci_dev *pdev, int num_vfs)
734fe16eceaSSrujana Challa {
735fe16eceaSSrujana Challa 	if (num_vfs > 0) {
736fe16eceaSSrujana Challa 		return cptpf_sriov_enable(pdev, num_vfs);
737fe16eceaSSrujana Challa 	} else {
738fe16eceaSSrujana Challa 		return cptpf_sriov_disable(pdev);
739fe16eceaSSrujana Challa 	}
740fe16eceaSSrujana Challa }
741fe16eceaSSrujana Challa 
otx2_cptpf_probe(struct pci_dev * pdev,const struct pci_device_id * ent)7425e8ce833SSrujana Challa static int otx2_cptpf_probe(struct pci_dev *pdev,
7435e8ce833SSrujana Challa 			    const struct pci_device_id *ent)
7445e8ce833SSrujana Challa {
7455e8ce833SSrujana Challa 	struct device *dev = &pdev->dev;
7465e8ce833SSrujana Challa 	struct otx2_cptpf_dev *cptpf;
7475e8ce833SSrujana Challa 	int err;
7485e8ce833SSrujana Challa 
7495e8ce833SSrujana Challa 	cptpf = devm_kzalloc(dev, sizeof(*cptpf), GFP_KERNEL);
7505e8ce833SSrujana Challa 	if (!cptpf)
7515e8ce833SSrujana Challa 		return -ENOMEM;
7525e8ce833SSrujana Challa 
7535e8ce833SSrujana Challa 	err = pcim_enable_device(pdev);
7545e8ce833SSrujana Challa 	if (err) {
7555e8ce833SSrujana Challa 		dev_err(dev, "Failed to enable PCI device\n");
7565e8ce833SSrujana Challa 		goto clear_drvdata;
7575e8ce833SSrujana Challa 	}
7585e8ce833SSrujana Challa 
7595e8ce833SSrujana Challa 	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
7605e8ce833SSrujana Challa 	if (err) {
7615e8ce833SSrujana Challa 		dev_err(dev, "Unable to get usable DMA configuration\n");
7625e8ce833SSrujana Challa 		goto clear_drvdata;
7635e8ce833SSrujana Challa 	}
7645e8ce833SSrujana Challa 	/* Map PF's configuration registers */
7655e8ce833SSrujana Challa 	err = pcim_iomap_regions_request_all(pdev, 1 << PCI_PF_REG_BAR_NUM,
7665e8ce833SSrujana Challa 					     OTX2_CPT_DRV_NAME);
7675e8ce833SSrujana Challa 	if (err) {
7685e8ce833SSrujana Challa 		dev_err(dev, "Couldn't get PCI resources 0x%x\n", err);
7695e8ce833SSrujana Challa 		goto clear_drvdata;
7705e8ce833SSrujana Challa 	}
7715e8ce833SSrujana Challa 	pci_set_master(pdev);
7725e8ce833SSrujana Challa 	pci_set_drvdata(pdev, cptpf);
7735e8ce833SSrujana Challa 	cptpf->pdev = pdev;
7745e8ce833SSrujana Challa 
7755e8ce833SSrujana Challa 	cptpf->reg_base = pcim_iomap_table(pdev)[PCI_PF_REG_BAR_NUM];
7765e8ce833SSrujana Challa 
7775e8ce833SSrujana Challa 	/* Check if AF driver is up, otherwise defer probe */
7785e8ce833SSrujana Challa 	err = cpt_is_pf_usable(cptpf);
7795e8ce833SSrujana Challa 	if (err)
7805e8ce833SSrujana Challa 		goto clear_drvdata;
7815e8ce833SSrujana Challa 
78283ffcf78SSrujana Challa 	err = pci_alloc_irq_vectors(pdev, RVU_PF_INT_VEC_CNT,
78383ffcf78SSrujana Challa 				    RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX);
78483ffcf78SSrujana Challa 	if (err < 0) {
78583ffcf78SSrujana Challa 		dev_err(dev, "Request for %d msix vectors failed\n",
78683ffcf78SSrujana Challa 			RVU_PF_INT_VEC_CNT);
78783ffcf78SSrujana Challa 		goto clear_drvdata;
78883ffcf78SSrujana Challa 	}
7894cd8c315SSrujana Challa 	otx2_cpt_set_hw_caps(pdev, &cptpf->cap_flag);
79083ffcf78SSrujana Challa 	/* Initialize AF-PF mailbox */
79183ffcf78SSrujana Challa 	err = cptpf_afpf_mbox_init(cptpf);
79283ffcf78SSrujana Challa 	if (err)
79383ffcf78SSrujana Challa 		goto clear_drvdata;
79483ffcf78SSrujana Challa 	/* Register mailbox interrupt */
79583ffcf78SSrujana Challa 	err = cptpf_register_afpf_mbox_intr(cptpf);
79683ffcf78SSrujana Challa 	if (err)
79783ffcf78SSrujana Challa 		goto destroy_afpf_mbox;
79883ffcf78SSrujana Challa 
799fe16eceaSSrujana Challa 	cptpf->max_vfs = pci_sriov_get_totalvfs(pdev);
800fe16eceaSSrujana Challa 
801eb33cd91SSrujana Challa 	err = cn10k_cptpf_lmtst_init(cptpf);
802eb33cd91SSrujana Challa 	if (err)
803eb33cd91SSrujana Challa 		goto unregister_intr;
804eb33cd91SSrujana Challa 
80543ac0b82SSrujana Challa 	/* Initialize CPT PF device */
80643ac0b82SSrujana Challa 	err = cptpf_device_init(cptpf);
80743ac0b82SSrujana Challa 	if (err)
80843ac0b82SSrujana Challa 		goto unregister_intr;
80943ac0b82SSrujana Challa 
81043ac0b82SSrujana Challa 	/* Initialize engine groups */
81143ac0b82SSrujana Challa 	err = otx2_cpt_init_eng_grps(pdev, &cptpf->eng_grps);
81243ac0b82SSrujana Challa 	if (err)
81343ac0b82SSrujana Challa 		goto unregister_intr;
81443ac0b82SSrujana Challa 
8158ec8015aSSrujana Challa 	err = sysfs_create_group(&dev->kobj, &cptpf_sysfs_group);
8168ec8015aSSrujana Challa 	if (err)
8178ec8015aSSrujana Challa 		goto cleanup_eng_grps;
818fed8f4d5SSrujana Challa 
819fed8f4d5SSrujana Challa 	err = otx2_cpt_register_dl(cptpf);
820fed8f4d5SSrujana Challa 	if (err)
821fed8f4d5SSrujana Challa 		goto sysfs_grp_del;
822fed8f4d5SSrujana Challa 
8235e8ce833SSrujana Challa 	return 0;
8245e8ce833SSrujana Challa 
825fed8f4d5SSrujana Challa sysfs_grp_del:
826fed8f4d5SSrujana Challa 	sysfs_remove_group(&dev->kobj, &cptpf_sysfs_group);
8278ec8015aSSrujana Challa cleanup_eng_grps:
8288ec8015aSSrujana Challa 	otx2_cpt_cleanup_eng_grps(pdev, &cptpf->eng_grps);
82943ac0b82SSrujana Challa unregister_intr:
83043ac0b82SSrujana Challa 	cptpf_disable_afpf_mbox_intr(cptpf);
83183ffcf78SSrujana Challa destroy_afpf_mbox:
83283ffcf78SSrujana Challa 	cptpf_afpf_mbox_destroy(cptpf);
8335e8ce833SSrujana Challa clear_drvdata:
8345e8ce833SSrujana Challa 	pci_set_drvdata(pdev, NULL);
8355e8ce833SSrujana Challa 	return err;
8365e8ce833SSrujana Challa }
8375e8ce833SSrujana Challa 
otx2_cptpf_remove(struct pci_dev * pdev)8385e8ce833SSrujana Challa static void otx2_cptpf_remove(struct pci_dev *pdev)
8395e8ce833SSrujana Challa {
8405e8ce833SSrujana Challa 	struct otx2_cptpf_dev *cptpf = pci_get_drvdata(pdev);
8415e8ce833SSrujana Challa 
8425e8ce833SSrujana Challa 	if (!cptpf)
8435e8ce833SSrujana Challa 		return;
844fe16eceaSSrujana Challa 
845fe16eceaSSrujana Challa 	cptpf_sriov_disable(pdev);
846fed8f4d5SSrujana Challa 	otx2_cpt_unregister_dl(cptpf);
8478ec8015aSSrujana Challa 	/* Delete sysfs entry created for kernel VF limits */
8488ec8015aSSrujana Challa 	sysfs_remove_group(&pdev->dev.kobj, &cptpf_sysfs_group);
84943ac0b82SSrujana Challa 	/* Cleanup engine groups */
85043ac0b82SSrujana Challa 	otx2_cpt_cleanup_eng_grps(pdev, &cptpf->eng_grps);
85183ffcf78SSrujana Challa 	/* Disable AF-PF mailbox interrupt */
85283ffcf78SSrujana Challa 	cptpf_disable_afpf_mbox_intr(cptpf);
85383ffcf78SSrujana Challa 	/* Destroy AF-PF mbox */
85483ffcf78SSrujana Challa 	cptpf_afpf_mbox_destroy(cptpf);
8555e8ce833SSrujana Challa 	pci_set_drvdata(pdev, NULL);
8565e8ce833SSrujana Challa }
8575e8ce833SSrujana Challa 
8585e8ce833SSrujana Challa /* Supported devices */
8595e8ce833SSrujana Challa static const struct pci_device_id otx2_cpt_id_table[] = {
8605e8ce833SSrujana Challa 	{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, OTX2_CPT_PCI_PF_DEVICE_ID) },
8614cd8c315SSrujana Challa 	{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, CN10K_CPT_PCI_PF_DEVICE_ID) },
8625e8ce833SSrujana Challa 	{ 0, }  /* end of table */
8635e8ce833SSrujana Challa };
8645e8ce833SSrujana Challa 
8655e8ce833SSrujana Challa static struct pci_driver otx2_cpt_pci_driver = {
8665e8ce833SSrujana Challa 	.name = OTX2_CPT_DRV_NAME,
8675e8ce833SSrujana Challa 	.id_table = otx2_cpt_id_table,
8685e8ce833SSrujana Challa 	.probe = otx2_cptpf_probe,
8695e8ce833SSrujana Challa 	.remove = otx2_cptpf_remove,
870fe16eceaSSrujana Challa 	.sriov_configure = otx2_cptpf_sriov_configure
8715e8ce833SSrujana Challa };
8725e8ce833SSrujana Challa 
8735e8ce833SSrujana Challa module_pci_driver(otx2_cpt_pci_driver);
8745e8ce833SSrujana Challa 
87572bc4e71SAlexander Lobakin MODULE_IMPORT_NS(CRYPTO_DEV_OCTEONTX2_CPT);
87672bc4e71SAlexander Lobakin 
8775e8ce833SSrujana Challa MODULE_AUTHOR("Marvell");
8785e8ce833SSrujana Challa MODULE_DESCRIPTION(OTX2_CPT_DRV_STRING);
8795e8ce833SSrujana Challa MODULE_LICENSE("GPL v2");
8805e8ce833SSrujana Challa MODULE_DEVICE_TABLE(pci, otx2_cpt_id_table);
881