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, ®, 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