Skip to content

Commit 70f8986

Browse files
Sai Krishnakuba-moo
authored andcommitted
octeontx2-pf: CN20K mbox implementation between PF-VF
This patch implements the CN20k MBOX communication between PF and it's VFs. CN20K silicon got extra interrupt of MBOX response for trigger interrupt. Also few of the CSR offsets got changed in CN20K against prior series of silicons. Signed-off-by: Sai Krishna <[email protected]> Signed-off-by: Sunil Kovvuri Goutham <[email protected]> Signed-off-by: Subbaraya Sundeep <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f8909d3 commit 70f8986

File tree

5 files changed

+194
-14
lines changed

5 files changed

+194
-14
lines changed

drivers/net/ethernet/marvell/octeontx2/af/common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct qmem {
3939
void *base;
4040
dma_addr_t iova;
4141
int alloc_sz;
42-
u16 entry_sz;
42+
u32 entry_sz;
4343
u8 align;
4444
u32 qsize;
4545
};

drivers/net/ethernet/marvell/octeontx2/nic/cn20k.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
static struct dev_hw_ops cn20k_hw_ops = {
1414
.pfaf_mbox_intr_handler = cn20k_pfaf_mbox_intr_handler,
1515
.vfaf_mbox_intr_handler = cn20k_vfaf_mbox_intr_handler,
16+
.pfvf_mbox_intr_handler = cn20k_pfvf_mbox_intr_handler,
1617
};
1718

1819
void cn20k_init(struct otx2_nic *pfvf)
@@ -108,3 +109,144 @@ irqreturn_t cn20k_vfaf_mbox_intr_handler(int irq, void *vf_irq)
108109

109110
return IRQ_HANDLED;
110111
}
112+
113+
void cn20k_enable_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
114+
{
115+
/* Clear PF <=> VF mailbox IRQ */
116+
otx2_write64(pf, RVU_MBOX_PF_VFPF_INTX(0), ~0ull);
117+
otx2_write64(pf, RVU_MBOX_PF_VFPF_INTX(1), ~0ull);
118+
otx2_write64(pf, RVU_MBOX_PF_VFPF1_INTX(0), ~0ull);
119+
otx2_write64(pf, RVU_MBOX_PF_VFPF1_INTX(1), ~0ull);
120+
121+
/* Enable PF <=> VF mailbox IRQ */
122+
otx2_write64(pf, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(0), INTR_MASK(numvfs));
123+
otx2_write64(pf, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(0), INTR_MASK(numvfs));
124+
if (numvfs > 64) {
125+
numvfs -= 64;
126+
otx2_write64(pf, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(1),
127+
INTR_MASK(numvfs));
128+
otx2_write64(pf, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(1),
129+
INTR_MASK(numvfs));
130+
}
131+
}
132+
133+
void cn20k_disable_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
134+
{
135+
int vector, intr_vec, vec = 0;
136+
137+
/* Disable PF <=> VF mailbox IRQ */
138+
otx2_write64(pf, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(0), ~0ull);
139+
otx2_write64(pf, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(1), ~0ull);
140+
otx2_write64(pf, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(0), ~0ull);
141+
otx2_write64(pf, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(1), ~0ull);
142+
143+
otx2_write64(pf, RVU_MBOX_PF_VFPF_INTX(0), ~0ull);
144+
otx2_write64(pf, RVU_MBOX_PF_VFPF1_INTX(0), ~0ull);
145+
146+
if (numvfs > 64) {
147+
otx2_write64(pf, RVU_MBOX_PF_VFPF_INTX(1), ~0ull);
148+
otx2_write64(pf, RVU_MBOX_PF_VFPF1_INTX(1), ~0ull);
149+
}
150+
151+
for (intr_vec = RVU_MBOX_PF_INT_VEC_VFPF_MBOX0; intr_vec <=
152+
RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1; intr_vec++, vec++) {
153+
vector = pci_irq_vector(pf->pdev, intr_vec);
154+
free_irq(vector, pf->hw.pfvf_irq_devid[vec]);
155+
}
156+
}
157+
158+
irqreturn_t cn20k_pfvf_mbox_intr_handler(int irq, void *pf_irq)
159+
{
160+
struct pf_irq_data *irq_data = pf_irq;
161+
struct otx2_nic *pf = irq_data->pf;
162+
struct mbox *mbox;
163+
u64 intr;
164+
165+
/* Sync with mbox memory region */
166+
rmb();
167+
168+
/* Clear interrupts */
169+
intr = otx2_read64(pf, irq_data->intr_status);
170+
otx2_write64(pf, irq_data->intr_status, intr);
171+
mbox = pf->mbox_pfvf;
172+
173+
if (intr)
174+
trace_otx2_msg_interrupt(pf->pdev, "VF(s) to PF", intr);
175+
176+
irq_data->pf_queue_work_hdlr(mbox, pf->mbox_pfvf_wq, irq_data->start,
177+
irq_data->mdevs, intr);
178+
179+
return IRQ_HANDLED;
180+
}
181+
182+
int cn20k_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
183+
{
184+
struct otx2_hw *hw = &pf->hw;
185+
struct pf_irq_data *irq_data;
186+
int intr_vec, ret, vec = 0;
187+
char *irq_name;
188+
189+
/* irq data for 4 PF intr vectors */
190+
irq_data = devm_kcalloc(pf->dev, 4,
191+
sizeof(struct pf_irq_data), GFP_KERNEL);
192+
if (!irq_data)
193+
return -ENOMEM;
194+
195+
for (intr_vec = RVU_MBOX_PF_INT_VEC_VFPF_MBOX0; intr_vec <=
196+
RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1; intr_vec++, vec++) {
197+
switch (intr_vec) {
198+
case RVU_MBOX_PF_INT_VEC_VFPF_MBOX0:
199+
irq_data[vec].intr_status =
200+
RVU_MBOX_PF_VFPF_INTX(0);
201+
irq_data[vec].start = 0;
202+
irq_data[vec].mdevs = 64;
203+
break;
204+
case RVU_MBOX_PF_INT_VEC_VFPF_MBOX1:
205+
irq_data[vec].intr_status =
206+
RVU_MBOX_PF_VFPF_INTX(1);
207+
irq_data[vec].start = 64;
208+
irq_data[vec].mdevs = 96;
209+
break;
210+
case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX0:
211+
irq_data[vec].intr_status =
212+
RVU_MBOX_PF_VFPF1_INTX(0);
213+
irq_data[vec].start = 0;
214+
irq_data[vec].mdevs = 64;
215+
break;
216+
case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1:
217+
irq_data[vec].intr_status =
218+
RVU_MBOX_PF_VFPF1_INTX(1);
219+
irq_data[vec].start = 64;
220+
irq_data[vec].mdevs = 96;
221+
break;
222+
}
223+
irq_data[vec].pf_queue_work_hdlr = otx2_queue_vf_work;
224+
irq_data[vec].vec_num = intr_vec;
225+
irq_data[vec].pf = pf;
226+
227+
/* Register mailbox interrupt handler */
228+
irq_name = &hw->irq_name[intr_vec * NAME_SIZE];
229+
if (pf->pcifunc)
230+
snprintf(irq_name, NAME_SIZE,
231+
"RVUPF%d_VF%d Mbox%d", rvu_get_pf(pf->pdev,
232+
pf->pcifunc), vec / 2, vec % 2);
233+
else
234+
snprintf(irq_name, NAME_SIZE, "RVUPF_VF%d Mbox%d",
235+
vec / 2, vec % 2);
236+
237+
hw->pfvf_irq_devid[vec] = &irq_data[vec];
238+
ret = request_irq(pci_irq_vector(pf->pdev, intr_vec),
239+
pf->hw_ops->pfvf_mbox_intr_handler, 0,
240+
irq_name,
241+
&irq_data[vec]);
242+
if (ret) {
243+
dev_err(pf->dev,
244+
"RVUPF: IRQ registration failed for PFVF mbox0 irq\n");
245+
return ret;
246+
}
247+
}
248+
249+
cn20k_enable_pfvf_mbox_intr(pf, numvfs);
250+
251+
return 0;
252+
}

drivers/net/ethernet/marvell/octeontx2/nic/cn20k.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@
1111
#include "otx2_common.h"
1212

1313
void cn20k_init(struct otx2_nic *pfvf);
14+
int cn20k_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs);
15+
void cn20k_disable_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs);
16+
void cn20k_enable_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs);
1417
#endif /* CN20K_H */

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq);
6767
irqreturn_t cn20k_pfaf_mbox_intr_handler(int irq, void *pf_irq);
6868
irqreturn_t cn20k_vfaf_mbox_intr_handler(int irq, void *vf_irq);
69+
irqreturn_t cn20k_pfvf_mbox_intr_handler(int irq, void *pf_irq);
6970
irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq);
7071

7172
enum arua_mapped_qtypes {
@@ -376,6 +377,7 @@ struct dev_hw_ops {
376377
void (*aura_freeptr)(void *dev, int aura, u64 buf);
377378
irqreturn_t (*pfaf_mbox_intr_handler)(int irq, void *pf_irq);
378379
irqreturn_t (*vfaf_mbox_intr_handler)(int irq, void *pf_irq);
380+
irqreturn_t (*pfvf_mbox_intr_handler)(int irq, void *pf_irq);
379381
};
380382

381383
#define CN10K_MCS_SA_PER_SC 4

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,23 @@ irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq)
576576
return IRQ_HANDLED;
577577
}
578578

579+
static void *cn20k_pfvf_mbox_alloc(struct otx2_nic *pf, int numvfs)
580+
{
581+
struct qmem *mbox_addr;
582+
int err;
583+
584+
err = qmem_alloc(&pf->pdev->dev, &mbox_addr, numvfs, MBOX_SIZE);
585+
if (err) {
586+
dev_err(pf->dev, "qmem alloc fail\n");
587+
return ERR_PTR(-ENOMEM);
588+
}
589+
590+
otx2_write64(pf, RVU_PF_VF_MBOX_ADDR, (u64)mbox_addr->iova);
591+
pf->pfvf_mbox_addr = mbox_addr;
592+
593+
return mbox_addr->base;
594+
}
595+
579596
static int otx2_pfvf_mbox_init(struct otx2_nic *pf, int numvfs)
580597
{
581598
void __iomem *hwbase;
@@ -597,19 +614,27 @@ static int otx2_pfvf_mbox_init(struct otx2_nic *pf, int numvfs)
597614
if (!pf->mbox_pfvf_wq)
598615
return -ENOMEM;
599616

600-
/* On CN10K platform, PF <-> VF mailbox region follows after
601-
* PF <-> AF mailbox region.
617+
/* For CN20K, PF allocates mbox memory in DRAM and writes PF/VF
618+
* regions/offsets in RVU_PF_VF_MBOX_ADDR, the RVU_PFX_FUNC_PFAF_MBOX
619+
* gives the aliased address to access PF/VF mailbox regions.
602620
*/
603-
if (test_bit(CN10K_MBOX, &pf->hw.cap_flag))
604-
base = pci_resource_start(pf->pdev, PCI_MBOX_BAR_NUM) +
605-
MBOX_SIZE;
606-
else
607-
base = readq(pf->reg_base + RVU_PF_VF_BAR4_ADDR);
621+
if (is_cn20k(pf->pdev)) {
622+
hwbase = (void __iomem *)cn20k_pfvf_mbox_alloc(pf, numvfs);
623+
} else {
624+
/* On CN10K platform, PF <-> VF mailbox region follows after
625+
* PF <-> AF mailbox region.
626+
*/
627+
if (test_bit(CN10K_MBOX, &pf->hw.cap_flag))
628+
base = pci_resource_start(pf->pdev, PCI_MBOX_BAR_NUM) +
629+
MBOX_SIZE;
630+
else
631+
base = readq(pf->reg_base + RVU_PF_VF_BAR4_ADDR);
608632

609-
hwbase = ioremap_wc(base, MBOX_SIZE * pf->total_vfs);
610-
if (!hwbase) {
611-
err = -ENOMEM;
612-
goto free_wq;
633+
hwbase = ioremap_wc(base, MBOX_SIZE * pf->total_vfs);
634+
if (!hwbase) {
635+
err = -ENOMEM;
636+
goto free_wq;
637+
}
613638
}
614639

615640
mbox = &pf->mbox_pfvf[0];
@@ -633,7 +658,7 @@ static int otx2_pfvf_mbox_init(struct otx2_nic *pf, int numvfs)
633658
return 0;
634659

635660
free_iomem:
636-
if (hwbase)
661+
if (hwbase && !(is_cn20k(pf->pdev)))
637662
iounmap(hwbase);
638663
free_wq:
639664
destroy_workqueue(pf->mbox_pfvf_wq);
@@ -652,8 +677,10 @@ static void otx2_pfvf_mbox_destroy(struct otx2_nic *pf)
652677
pf->mbox_pfvf_wq = NULL;
653678
}
654679

655-
if (mbox->mbox.hwbase)
680+
if (mbox->mbox.hwbase && !is_cn20k(pf->pdev))
656681
iounmap(mbox->mbox.hwbase);
682+
else
683+
qmem_free(&pf->pdev->dev, pf->pfvf_mbox_addr);
657684

658685
otx2_mbox_destroy(&mbox->mbox);
659686
}
@@ -677,6 +704,9 @@ static void otx2_disable_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
677704
{
678705
int vector;
679706

707+
if (is_cn20k(pf->pdev))
708+
return cn20k_disable_pfvf_mbox_intr(pf, numvfs);
709+
680710
/* Disable PF <=> VF mailbox IRQ */
681711
otx2_write64(pf, RVU_PF_VFPF_MBOX_INT_ENA_W1CX(0), ~0ull);
682712
otx2_write64(pf, RVU_PF_VFPF_MBOX_INT_ENA_W1CX(1), ~0ull);
@@ -698,6 +728,9 @@ static int otx2_register_pfvf_mbox_intr(struct otx2_nic *pf, int numvfs)
698728
char *irq_name;
699729
int err;
700730

731+
if (is_cn20k(pf->pdev))
732+
return cn20k_register_pfvf_mbox_intr(pf, numvfs);
733+
701734
/* Register MBOX0 interrupt handler */
702735
irq_name = &hw->irq_name[RVU_PF_INT_VEC_VFPF_MBOX0 * NAME_SIZE];
703736
if (pf->pcifunc)

0 commit comments

Comments
 (0)