Skip to content

Commit f8909d3

Browse files
Sai Krishnakuba-moo
authored andcommitted
octeontx2-af: CN20K mbox implementation for AF's VF
This patch implements the CN20k MBOX communication between AF and AF's VFs. This implementation uses separate trigger interrupts for request, response messages against using trigger message data in CN10K. Signed-off-by: Sai Krishna <saikrishnag@marvell.com> Signed-off-by: Sunil Kovvuri Goutham <sgoutham@marvell.com> Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com> Link: https://patch.msgid.link/1749639716-13868-6-git-send-email-sbhatta@marvell.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 370c237 commit f8909d3

File tree

11 files changed

+380
-37
lines changed

11 files changed

+380
-37
lines changed

drivers/net/ethernet/marvell/octeontx2/af/cn20k/api.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
struct ng_rvu {
1414
struct mbox_ops *rvu_mbox_ops;
1515
struct qmem *pf_mbox_addr;
16+
struct qmem *vf_mbox_addr;
1617
};
1718

1819
/* Mbox related APIs */
@@ -21,8 +22,11 @@ int cn20k_rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
2122
int num, int type, unsigned long *pf_bmap);
2223
void cn20k_free_mbox_memory(struct rvu *rvu);
2324
int cn20k_register_afpf_mbox_intr(struct rvu *rvu);
25+
int cn20k_register_afvf_mbox_intr(struct rvu *rvu, int pf_vec_start);
2426
void cn20k_rvu_enable_mbox_intr(struct rvu *rvu);
2527
void cn20k_rvu_unregister_interrupts(struct rvu *rvu);
2628
int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev,
2729
void *reg_base, int direction, int ndevs);
30+
void cn20k_rvu_enable_afvf_intr(struct rvu *rvu, int vfs);
31+
void cn20k_rvu_disable_afvf_intr(struct rvu *rvu, int vfs);
2832
#endif /* CN20K_API_H */

drivers/net/ethernet/marvell/octeontx2/af/cn20k/mbox_init.c

Lines changed: 160 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,91 @@
1313
#include "reg.h"
1414
#include "api.h"
1515

16+
static irqreturn_t cn20k_afvf_mbox_intr_handler(int irq, void *rvu_irq)
17+
{
18+
struct rvu_irq_data *rvu_irq_data = rvu_irq;
19+
struct rvu *rvu = rvu_irq_data->rvu;
20+
u64 intr;
21+
22+
/* Sync with mbox memory region */
23+
rmb();
24+
25+
/* Clear interrupts */
26+
intr = rvupf_read64(rvu, rvu_irq_data->intr_status);
27+
rvupf_write64(rvu, rvu_irq_data->intr_status, intr);
28+
29+
if (intr)
30+
trace_otx2_msg_interrupt(rvu->pdev, "VF(s) to AF", intr);
31+
32+
rvu_irq_data->afvf_queue_work_hdlr(&rvu->afvf_wq_info, rvu_irq_data->start,
33+
rvu_irq_data->mdevs, intr);
34+
35+
return IRQ_HANDLED;
36+
}
37+
38+
int cn20k_register_afvf_mbox_intr(struct rvu *rvu, int pf_vec_start)
39+
{
40+
struct rvu_irq_data *irq_data;
41+
int intr_vec, offset, vec = 0;
42+
int err;
43+
44+
/* irq data for 4 VFPF intr vectors */
45+
irq_data = devm_kcalloc(rvu->dev, 4,
46+
sizeof(struct rvu_irq_data), GFP_KERNEL);
47+
if (!irq_data)
48+
return -ENOMEM;
49+
50+
for (intr_vec = RVU_MBOX_PF_INT_VEC_VFPF_MBOX0; intr_vec <=
51+
RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1;
52+
intr_vec++, vec++) {
53+
switch (intr_vec) {
54+
case RVU_MBOX_PF_INT_VEC_VFPF_MBOX0:
55+
irq_data[vec].intr_status =
56+
RVU_MBOX_PF_VFPF_INTX(0);
57+
irq_data[vec].start = 0;
58+
irq_data[vec].mdevs = 64;
59+
break;
60+
case RVU_MBOX_PF_INT_VEC_VFPF_MBOX1:
61+
irq_data[vec].intr_status =
62+
RVU_MBOX_PF_VFPF_INTX(1);
63+
irq_data[vec].start = 64;
64+
irq_data[vec].mdevs = 64;
65+
break;
66+
case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX0:
67+
irq_data[vec].intr_status =
68+
RVU_MBOX_PF_VFPF1_INTX(0);
69+
irq_data[vec].start = 0;
70+
irq_data[vec].mdevs = 64;
71+
break;
72+
case RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1:
73+
irq_data[vec].intr_status = RVU_MBOX_PF_VFPF1_INTX(1);
74+
irq_data[vec].start = 64;
75+
irq_data[vec].mdevs = 64;
76+
break;
77+
}
78+
irq_data[vec].afvf_queue_work_hdlr =
79+
rvu_queue_work;
80+
offset = pf_vec_start + intr_vec;
81+
irq_data[vec].vec_num = offset;
82+
irq_data[vec].rvu = rvu;
83+
84+
sprintf(&rvu->irq_name[offset * NAME_SIZE], "RVUAF VFAF%d Mbox%d",
85+
vec / 2, vec % 2);
86+
err = request_irq(pci_irq_vector(rvu->pdev, offset),
87+
rvu->ng_rvu->rvu_mbox_ops->afvf_intr_handler, 0,
88+
&rvu->irq_name[offset * NAME_SIZE],
89+
&irq_data[vec]);
90+
if (err) {
91+
dev_err(rvu->dev,
92+
"RVUAF: IRQ registration failed for AFVF mbox irq\n");
93+
return err;
94+
}
95+
rvu->irq_allocated[offset] = true;
96+
}
97+
98+
return 0;
99+
}
100+
16101
/* CN20K mbox PFx => AF irq handler */
17102
static irqreturn_t cn20k_mbox_pf_common_intr_handler(int irq, void *rvu_irq)
18103
{
@@ -150,6 +235,21 @@ int cn20k_rvu_get_mbox_regions(struct rvu *rvu, void **mbox_addr,
150235
int region;
151236
u64 bar;
152237

238+
if (type == TYPE_AFVF) {
239+
for (region = 0; region < num; region++) {
240+
if (!test_bit(region, pf_bmap))
241+
continue;
242+
243+
bar = (u64)phys_to_virt((u64)rvu->ng_rvu->vf_mbox_addr->base);
244+
bar += region * MBOX_SIZE;
245+
mbox_addr[region] = (void *)bar;
246+
247+
if (!mbox_addr[region])
248+
return -ENOMEM;
249+
}
250+
return 0;
251+
}
252+
153253
for (region = 0; region < num; region++) {
154254
if (!test_bit(region, pf_bmap))
155255
continue;
@@ -180,6 +280,9 @@ static int rvu_alloc_mbox_memory(struct rvu *rvu, int type,
180280
*
181281
* AF will access mbox memory using direct physical addresses
182282
* and PFs will access the same shared memory from BAR2.
283+
*
284+
* PF <=> VF mbox memory also works in the same fashion.
285+
* AFPF, PFVF requires IOVA to be used to maintain the mailbox msgs
183286
*/
184287

185288
err = qmem_alloc(rvu->dev, &mbox_addr, ndevs, mbox_size);
@@ -196,6 +299,10 @@ static int rvu_alloc_mbox_memory(struct rvu *rvu, int type,
196299
iova += mbox_size;
197300
}
198301
break;
302+
case TYPE_AFVF:
303+
rvu->ng_rvu->vf_mbox_addr = mbox_addr;
304+
rvupf_write64(rvu, RVU_PF_VF_MBOX_ADDR, (u64)mbox_addr->iova);
305+
break;
199306
default:
200307
return 0;
201308
}
@@ -205,6 +312,7 @@ static int rvu_alloc_mbox_memory(struct rvu *rvu, int type,
205312

206313
static struct mbox_ops cn20k_mbox_ops = {
207314
.pf_intr_handler = cn20k_mbox_pf_common_intr_handler,
315+
.afvf_intr_handler = cn20k_afvf_mbox_intr_handler,
208316
};
209317

210318
int cn20k_rvu_mbox_init(struct rvu *rvu, int type, int ndevs)
@@ -216,9 +324,13 @@ int cn20k_rvu_mbox_init(struct rvu *rvu, int type, int ndevs)
216324

217325
rvu->ng_rvu->rvu_mbox_ops = &cn20k_mbox_ops;
218326

219-
for (dev = 0; dev < ndevs; dev++)
220-
rvu_write64(rvu, BLKADDR_RVUM,
221-
RVU_MBOX_AF_PFX_CFG(dev), ilog2(MBOX_SIZE));
327+
if (type == TYPE_AFVF) {
328+
rvu_write64(rvu, BLKADDR_RVUM, RVU_MBOX_PF_VF_CFG, ilog2(MBOX_SIZE));
329+
} else {
330+
for (dev = 0; dev < ndevs; dev++)
331+
rvu_write64(rvu, BLKADDR_RVUM,
332+
RVU_MBOX_AF_PFX_CFG(dev), ilog2(MBOX_SIZE));
333+
}
222334

223335
return rvu_alloc_mbox_memory(rvu, type, ndevs, MBOX_SIZE);
224336
}
@@ -229,6 +341,51 @@ void cn20k_free_mbox_memory(struct rvu *rvu)
229341
return;
230342

231343
qmem_free(rvu->dev, rvu->ng_rvu->pf_mbox_addr);
344+
qmem_free(rvu->dev, rvu->ng_rvu->vf_mbox_addr);
345+
}
346+
347+
void cn20k_rvu_disable_afvf_intr(struct rvu *rvu, int vfs)
348+
{
349+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(0), INTR_MASK(vfs));
350+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(0), INTR_MASK(vfs));
351+
rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(0), INTR_MASK(vfs));
352+
rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(0), INTR_MASK(vfs));
353+
354+
if (vfs <= 64)
355+
return;
356+
357+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1CX(1), INTR_MASK(vfs - 64));
358+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(1), INTR_MASK(vfs - 64));
359+
rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1CX(1), INTR_MASK(vfs - 64));
360+
rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1CX(1), INTR_MASK(vfs - 64));
361+
}
362+
363+
void cn20k_rvu_enable_afvf_intr(struct rvu *rvu, int vfs)
364+
{
365+
/* Clear any pending interrupts and enable AF VF interrupts for
366+
* the first 64 VFs.
367+
*/
368+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INTX(0), INTR_MASK(vfs));
369+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(0), INTR_MASK(vfs));
370+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INTX(0), INTR_MASK(vfs));
371+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(0), INTR_MASK(vfs));
372+
373+
/* FLR */
374+
rvupf_write64(rvu, RVU_PF_VFFLR_INTX(0), INTR_MASK(vfs));
375+
rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1SX(0), INTR_MASK(vfs));
376+
377+
/* Same for remaining VFs, if any. */
378+
if (vfs <= 64)
379+
return;
380+
381+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INTX(1), INTR_MASK(vfs - 64));
382+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF_INT_ENA_W1SX(1), INTR_MASK(vfs - 64));
383+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INTX(1), INTR_MASK(vfs - 64));
384+
rvupf_write64(rvu, RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(1), INTR_MASK(vfs - 64));
385+
386+
rvupf_write64(rvu, RVU_PF_VFFLR_INTX(1), INTR_MASK(vfs - 64));
387+
rvupf_write64(rvu, RVU_PF_VFFLR_INT_ENA_W1SX(1), INTR_MASK(vfs - 64));
388+
rvupf_write64(rvu, RVU_PF_VFME_INT_ENA_W1SX(1), INTR_MASK(vfs - 64));
232389
}
233390

234391
int rvu_alloc_cint_qint_mem(struct rvu *rvu, struct rvu_pfvf *pfvf,

drivers/net/ethernet/marvell/octeontx2/af/cn20k/reg.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,41 @@
4141
#define NIX_CINTX_INT_W1S(a) (0xd30 | (a) << 12)
4242
#define NIX_QINTX_CNT(a) (0xc00 | (a) << 12)
4343

44+
#define RVU_MBOX_AF_VFAF_INT(a) (0x3000 | (a) << 6)
45+
#define RVU_MBOX_AF_VFAF_INT_W1S(a) (0x3008 | (a) << 6)
46+
#define RVU_MBOX_AF_VFAF_INT_ENA_W1S(a) (0x3010 | (a) << 6)
47+
#define RVU_MBOX_AF_VFAF_INT_ENA_W1C(a) (0x3018 | (a) << 6)
48+
#define RVU_MBOX_AF_VFAF_INT_ENA_W1C(a) (0x3018 | (a) << 6)
49+
#define RVU_MBOX_AF_VFAF1_INT(a) (0x3020 | (a) << 6)
50+
#define RVU_MBOX_AF_VFAF1_INT_W1S(a) (0x3028 | (a) << 6)
51+
#define RVU_MBOX_AF_VFAF1_IN_ENA_W1S(a) (0x3030 | (a) << 6)
52+
#define RVU_MBOX_AF_VFAF1_IN_ENA_W1C(a) (0x3038 | (a) << 6)
53+
54+
#define RVU_MBOX_AF_AFVFX_TRIG(a, b) (0x10000 | (a) << 4 | (b) << 3)
55+
#define RVU_MBOX_AF_VFX_ADDR(a) (0x20000 | (a) << 4)
56+
#define RVU_MBOX_AF_VFX_CFG(a) (0x28000 | (a) << 4)
57+
58+
#define RVU_MBOX_PF_VFX_PFVF_TRIGX(a) (0x2000 | (a) << 3)
59+
60+
#define RVU_MBOX_PF_VFPF_INTX(a) (0x1000 | (a) << 3)
61+
#define RVU_MBOX_PF_VFPF_INT_W1SX(a) (0x1020 | (a) << 3)
62+
#define RVU_MBOX_PF_VFPF_INT_ENA_W1SX(a) (0x1040 | (a) << 3)
63+
#define RVU_MBOX_PF_VFPF_INT_ENA_W1CX(a) (0x1060 | (a) << 3)
64+
65+
#define RVU_MBOX_PF_VFPF1_INTX(a) (0x1080 | (a) << 3)
66+
#define RVU_MBOX_PF_VFPF1_INT_W1SX(a) (0x10a0 | (a) << 3)
67+
#define RVU_MBOX_PF_VFPF1_INT_ENA_W1SX(a) (0x10c0 | (a) << 3)
68+
#define RVU_MBOX_PF_VFPF1_INT_ENA_W1CX(a) (0x10e0 | (a) << 3)
69+
70+
#define RVU_MBOX_PF_VF_ADDR (0xC40)
71+
#define RVU_MBOX_PF_LMTLINE_ADDR (0xC48)
72+
#define RVU_MBOX_PF_VF_CFG (0xC60)
73+
74+
#define RVU_MBOX_VF_VFPF_TRIGX(a) (0x3000 | (a) << 3)
75+
#define RVU_MBOX_VF_INT (0x20)
76+
#define RVU_MBOX_VF_INT_W1S (0x28)
77+
#define RVU_MBOX_VF_INT_ENA_W1S (0x30)
78+
#define RVU_MBOX_VF_INT_ENA_W1C (0x38)
79+
80+
#define RVU_MBOX_VF_VFAF_TRIGX(a) (0x2000 | (a) << 3)
4481
#endif /* RVU_MBOX_REG_H */

drivers/net/ethernet/marvell/octeontx2/af/mbox.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,24 +63,28 @@ int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev,
6363
{
6464
switch (direction) {
6565
case MBOX_DIR_AFPF:
66+
case MBOX_DIR_PFVF:
6667
mbox->tx_start = MBOX_DOWN_TX_START;
6768
mbox->rx_start = MBOX_DOWN_RX_START;
6869
mbox->tx_size = MBOX_DOWN_TX_SIZE;
6970
mbox->rx_size = MBOX_DOWN_RX_SIZE;
7071
break;
7172
case MBOX_DIR_PFAF:
73+
case MBOX_DIR_VFPF:
7274
mbox->tx_start = MBOX_DOWN_RX_START;
7375
mbox->rx_start = MBOX_DOWN_TX_START;
7476
mbox->tx_size = MBOX_DOWN_RX_SIZE;
7577
mbox->rx_size = MBOX_DOWN_TX_SIZE;
7678
break;
7779
case MBOX_DIR_AFPF_UP:
80+
case MBOX_DIR_PFVF_UP:
7881
mbox->tx_start = MBOX_UP_TX_START;
7982
mbox->rx_start = MBOX_UP_RX_START;
8083
mbox->tx_size = MBOX_UP_TX_SIZE;
8184
mbox->rx_size = MBOX_UP_RX_SIZE;
8285
break;
8386
case MBOX_DIR_PFAF_UP:
87+
case MBOX_DIR_VFPF_UP:
8488
mbox->tx_start = MBOX_UP_RX_START;
8589
mbox->rx_start = MBOX_UP_TX_START;
8690
mbox->tx_size = MBOX_UP_RX_SIZE;
@@ -107,6 +111,22 @@ int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev,
107111
mbox->trigger = RVU_MBOX_PF_PFAF_TRIGX(1);
108112
mbox->tr_shift = 0;
109113
break;
114+
case MBOX_DIR_PFVF:
115+
mbox->trigger = RVU_MBOX_PF_VFX_PFVF_TRIGX(1);
116+
mbox->tr_shift = 4;
117+
break;
118+
case MBOX_DIR_PFVF_UP:
119+
mbox->trigger = RVU_MBOX_PF_VFX_PFVF_TRIGX(0);
120+
mbox->tr_shift = 4;
121+
break;
122+
case MBOX_DIR_VFPF:
123+
mbox->trigger = RVU_MBOX_VF_VFPF_TRIGX(0);
124+
mbox->tr_shift = 0;
125+
break;
126+
case MBOX_DIR_VFPF_UP:
127+
mbox->trigger = RVU_MBOX_VF_VFPF_TRIGX(1);
128+
mbox->tr_shift = 0;
129+
break;
110130
default:
111131
return -ENODEV;
112132
}

0 commit comments

Comments
 (0)