octeontx2-pf: CN20K mbox REQ/ACK implementation for NIC PF

This implementation uses separate trigger interrupts for request,
response messages against using trigger message data in CN10K.
This patch adds support for basic mbox implementation for CN20K
from NIC PF side.

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-5-git-send-email-sbhatta@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Sai Krishna 2025-06-11 16:31:54 +05:30 committed by Jakub Kicinski
parent f326d5d86e
commit 370c2374bf
10 changed files with 186 additions and 22 deletions

View File

@ -8,6 +8,21 @@
#ifndef STRUCT_H
#define STRUCT_H
/*
* CN20k RVU PF MBOX Interrupt Vector Enumeration
*
* Vectors 0 - 3 are compatible with pre cn20k and hence
* existing macros are being reused.
*/
enum rvu_mbox_pf_int_vec_e {
RVU_MBOX_PF_INT_VEC_VFPF_MBOX0 = 0x4,
RVU_MBOX_PF_INT_VEC_VFPF_MBOX1 = 0x5,
RVU_MBOX_PF_INT_VEC_VFPF1_MBOX0 = 0x6,
RVU_MBOX_PF_INT_VEC_VFPF1_MBOX1 = 0x7,
RVU_MBOX_PF_INT_VEC_AFPF_MBOX = 0x8,
RVU_MBOX_PF_INT_VEC_CNT = 0x9,
};
/* RVU Admin function Interrupt Vector Enumeration */
enum rvu_af_cn20k_int_vec_e {
RVU_AF_CN20K_INT_VEC_POISON = 0x0,

View File

@ -8,7 +8,7 @@ obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o otx2_ptp.o
obj-$(CONFIG_RVU_ESWITCH) += rvu_rep.o
rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \
otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \
otx2_flows.o otx2_tc.o cn10k.o cn20k.o otx2_dmac_flt.o \
otx2_devlink.o qos_sq.o qos.o otx2_xsk.o
rvu_nicvf-y := otx2_vf.o
rvu_rep-y := rep.o

View File

@ -14,6 +14,7 @@ static struct dev_hw_ops otx2_hw_ops = {
.sqe_flush = otx2_sqe_flush,
.aura_freeptr = otx2_aura_freeptr,
.refill_pool_ptrs = otx2_refill_pool_ptrs,
.pfaf_mbox_intr_handler = otx2_pfaf_mbox_intr_handler,
};
static struct dev_hw_ops cn10k_hw_ops = {
@ -21,8 +22,20 @@ static struct dev_hw_ops cn10k_hw_ops = {
.sqe_flush = cn10k_sqe_flush,
.aura_freeptr = cn10k_aura_freeptr,
.refill_pool_ptrs = cn10k_refill_pool_ptrs,
.pfaf_mbox_intr_handler = otx2_pfaf_mbox_intr_handler,
};
void otx2_init_hw_ops(struct otx2_nic *pfvf)
{
if (!test_bit(CN10K_LMTST, &pfvf->hw.cap_flag)) {
pfvf->hw_ops = &otx2_hw_ops;
return;
}
pfvf->hw_ops = &cn10k_hw_ops;
}
EXPORT_SYMBOL(otx2_init_hw_ops);
int cn10k_lmtst_init(struct otx2_nic *pfvf)
{
@ -30,12 +43,9 @@ int cn10k_lmtst_init(struct otx2_nic *pfvf)
struct otx2_lmt_info *lmt_info;
int err, cpu;
if (!test_bit(CN10K_LMTST, &pfvf->hw.cap_flag)) {
pfvf->hw_ops = &otx2_hw_ops;
if (!test_bit(CN10K_LMTST, &pfvf->hw.cap_flag))
return 0;
}
pfvf->hw_ops = &cn10k_hw_ops;
/* Total LMTLINES = num_online_cpus() * 32 (For Burst flush).*/
pfvf->tot_lmt_lines = (num_online_cpus() * LMT_BURST_SIZE);
pfvf->hw.lmt_info = alloc_percpu(struct otx2_lmt_info);

View File

@ -39,4 +39,5 @@ int cn10k_alloc_leaf_profile(struct otx2_nic *pfvf, u16 *leaf);
int cn10k_set_ipolicer_rate(struct otx2_nic *pfvf, u16 profile,
u32 burst, u64 rate, bool pps);
int cn10k_free_leaf_profile(struct otx2_nic *pfvf, u16 leaf);
void otx2_init_hw_ops(struct otx2_nic *pfvf);
#endif /* CN10K_H */

View File

@ -0,0 +1,63 @@
// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Ethernet driver
*
* Copyright (C) 2024 Marvell.
*
*/
#include "otx2_common.h"
#include "otx2_reg.h"
#include "otx2_struct.h"
#include "cn10k.h"
static struct dev_hw_ops cn20k_hw_ops = {
.pfaf_mbox_intr_handler = cn20k_pfaf_mbox_intr_handler,
};
void cn20k_init(struct otx2_nic *pfvf)
{
pfvf->hw_ops = &cn20k_hw_ops;
}
EXPORT_SYMBOL(cn20k_init);
/* CN20K mbox AF => PFx irq handler */
irqreturn_t cn20k_pfaf_mbox_intr_handler(int irq, void *pf_irq)
{
struct otx2_nic *pf = pf_irq;
struct mbox *mw = &pf->mbox;
struct otx2_mbox_dev *mdev;
struct otx2_mbox *mbox;
struct mbox_hdr *hdr;
u64 pf_trig_val;
pf_trig_val = otx2_read64(pf, RVU_PF_INT) & 0x3ULL;
/* Clear the IRQ */
otx2_write64(pf, RVU_PF_INT, pf_trig_val);
if (pf_trig_val & BIT_ULL(0)) {
mbox = &mw->mbox_up;
mdev = &mbox->dev[0];
otx2_sync_mbox_bbuf(mbox, 0);
hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
if (hdr->num_msgs)
queue_work(pf->mbox_wq, &mw->mbox_up_wrk);
trace_otx2_msg_interrupt(pf->pdev, "UP message from AF to PF",
BIT_ULL(0));
}
if (pf_trig_val & BIT_ULL(1)) {
mbox = &mw->mbox;
mdev = &mbox->dev[0];
otx2_sync_mbox_bbuf(mbox, 0);
hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
if (hdr->num_msgs)
queue_work(pf->mbox_wq, &mw->mbox_wrk);
trace_otx2_msg_interrupt(pf->pdev, "DOWN reply from AF to PF",
BIT_ULL(1));
}
return IRQ_HANDLED;
}

View File

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Marvell RVU Ethernet driver
*
* Copyright (C) 2024 Marvell.
*
*/
#ifndef CN20K_H
#define CN20K_H
#include "otx2_common.h"
void cn20k_init(struct otx2_nic *pfvf);
#endif /* CN20K_H */

View File

@ -33,6 +33,7 @@
#include "qos.h"
#include "rep.h"
#include "cn10k_ipsec.h"
#include "cn20k.h"
/* IPv4 flag more fragment bit */
#define IPV4_FLAG_MORE 0x20
@ -62,6 +63,9 @@
/* Number of segments per SG structure */
#define MAX_SEGS_PER_SG 3
irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq);
irqreturn_t cn20k_pfaf_mbox_intr_handler(int irq, void *pf_irq);
enum arua_mapped_qtypes {
AURA_NIX_RQ,
AURA_NIX_SQ,
@ -367,6 +371,7 @@ struct dev_hw_ops {
int size, int qidx);
int (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq);
void (*aura_freeptr)(void *dev, int aura, u64 buf);
irqreturn_t (*pfaf_mbox_intr_handler)(int irq, void *pf_irq);
};
#define CN10K_MCS_SA_PER_SC 4

View File

@ -1008,7 +1008,7 @@ static void otx2_pfaf_mbox_up_handler(struct work_struct *work)
otx2_mbox_msg_send(mbox, 0);
}
static irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq)
irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq)
{
struct otx2_nic *pf = (struct otx2_nic *)pf_irq;
struct mbox *mw = &pf->mbox;
@ -1066,10 +1066,18 @@ static irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq)
void otx2_disable_mbox_intr(struct otx2_nic *pf)
{
int vector = pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_AFPF_MBOX);
int vector;
/* Disable AF => PF mailbox IRQ */
otx2_write64(pf, RVU_PF_INT_ENA_W1C, BIT_ULL(0));
if (!is_cn20k(pf->pdev)) {
vector = pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_AFPF_MBOX);
otx2_write64(pf, RVU_PF_INT_ENA_W1C, BIT_ULL(0));
} else {
vector = pci_irq_vector(pf->pdev,
RVU_MBOX_PF_INT_VEC_AFPF_MBOX);
otx2_write64(pf, RVU_PF_INT_ENA_W1C,
BIT_ULL(0) | BIT_ULL(1));
}
free_irq(vector, pf);
}
EXPORT_SYMBOL(otx2_disable_mbox_intr);
@ -1082,10 +1090,24 @@ int otx2_register_mbox_intr(struct otx2_nic *pf, bool probe_af)
int err;
/* Register mailbox interrupt handler */
irq_name = &hw->irq_name[RVU_PF_INT_VEC_AFPF_MBOX * NAME_SIZE];
snprintf(irq_name, NAME_SIZE, "RVUPFAF Mbox");
err = request_irq(pci_irq_vector(pf->pdev, RVU_PF_INT_VEC_AFPF_MBOX),
otx2_pfaf_mbox_intr_handler, 0, irq_name, pf);
if (!is_cn20k(pf->pdev)) {
irq_name = &hw->irq_name[RVU_PF_INT_VEC_AFPF_MBOX * NAME_SIZE];
snprintf(irq_name, NAME_SIZE, "RVUPF%d AFPF Mbox",
rvu_get_pf(pf->pdev, pf->pcifunc));
err = request_irq(pci_irq_vector
(pf->pdev, RVU_PF_INT_VEC_AFPF_MBOX),
pf->hw_ops->pfaf_mbox_intr_handler,
0, irq_name, pf);
} else {
irq_name = &hw->irq_name[RVU_MBOX_PF_INT_VEC_AFPF_MBOX *
NAME_SIZE];
snprintf(irq_name, NAME_SIZE, "RVUPF%d AFPF Mbox",
rvu_get_pf(pf->pdev, pf->pcifunc));
err = request_irq(pci_irq_vector
(pf->pdev, RVU_MBOX_PF_INT_VEC_AFPF_MBOX),
pf->hw_ops->pfaf_mbox_intr_handler,
0, irq_name, pf);
}
if (err) {
dev_err(pf->dev,
"RVUPF: IRQ registration failed for PFAF mbox irq\n");
@ -1095,8 +1117,14 @@ int otx2_register_mbox_intr(struct otx2_nic *pf, bool probe_af)
/* Enable mailbox interrupt for msgs coming from AF.
* First clear to avoid spurious interrupts, if any.
*/
otx2_write64(pf, RVU_PF_INT, BIT_ULL(0));
otx2_write64(pf, RVU_PF_INT_ENA_W1S, BIT_ULL(0));
if (!is_cn20k(pf->pdev)) {
otx2_write64(pf, RVU_PF_INT, BIT_ULL(0));
otx2_write64(pf, RVU_PF_INT_ENA_W1S, BIT_ULL(0));
} else {
otx2_write64(pf, RVU_PF_INT, BIT_ULL(0) | BIT_ULL(1));
otx2_write64(pf, RVU_PF_INT_ENA_W1S, BIT_ULL(0) |
BIT_ULL(1));
}
if (!probe_af)
return 0;
@ -1127,7 +1155,7 @@ void otx2_pfaf_mbox_destroy(struct otx2_nic *pf)
pf->mbox_wq = NULL;
}
if (mbox->mbox.hwbase)
if (mbox->mbox.hwbase && !is_cn20k(pf->pdev))
iounmap((void __iomem *)mbox->mbox.hwbase);
otx2_mbox_destroy(&mbox->mbox);
@ -1147,12 +1175,20 @@ int otx2_pfaf_mbox_init(struct otx2_nic *pf)
if (!pf->mbox_wq)
return -ENOMEM;
/* Mailbox is a reserved memory (in RAM) region shared between
* admin function (i.e AF) and this PF, shouldn't be mapped as
* device memory to allow unaligned accesses.
/* For CN20K, AF allocates mbox memory in DRAM and writes PF
* regions/offsets in RVU_MBOX_AF_PFX_ADDR, the RVU_PFX_FUNC_PFAF_MBOX
* gives the aliased address to access AF/PF mailbox regions.
*/
hwbase = ioremap_wc(pci_resource_start(pf->pdev, PCI_MBOX_BAR_NUM),
MBOX_SIZE);
if (is_cn20k(pf->pdev))
hwbase = pf->reg_base + RVU_PFX_FUNC_PFAF_MBOX +
((u64)BLKADDR_MBOX << RVU_FUNC_BLKADDR_SHIFT);
else
/* Mailbox is a reserved memory (in RAM) region shared between
* admin function (i.e AF) and this PF, shouldn't be mapped as
* device memory to allow unaligned accesses.
*/
hwbase = ioremap_wc(pci_resource_start
(pf->pdev, PCI_MBOX_BAR_NUM), MBOX_SIZE);
if (!hwbase) {
dev_err(pf->dev, "Unable to map PFAF mailbox region\n");
err = -ENOMEM;
@ -3000,8 +3036,13 @@ int otx2_init_rsrc(struct pci_dev *pdev, struct otx2_nic *pf)
if (err)
return err;
err = pci_alloc_irq_vectors(hw->pdev, RVU_PF_INT_VEC_CNT,
RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX);
if (!is_cn20k(pf->pdev))
err = pci_alloc_irq_vectors(hw->pdev, RVU_PF_INT_VEC_CNT,
RVU_PF_INT_VEC_CNT, PCI_IRQ_MSIX);
else
err = pci_alloc_irq_vectors(hw->pdev, RVU_MBOX_PF_INT_VEC_CNT,
RVU_MBOX_PF_INT_VEC_CNT,
PCI_IRQ_MSIX);
if (err < 0) {
dev_err(dev, "%s: Failed to alloc %d IRQ vectors\n",
__func__, num_vec);
@ -3010,6 +3051,11 @@ int otx2_init_rsrc(struct pci_dev *pdev, struct otx2_nic *pf)
otx2_setup_dev_hw_settings(pf);
if (is_cn20k(pf->pdev))
cn20k_init(pf);
else
otx2_init_hw_ops(pf);
/* Init PF <=> AF mailbox stuff */
err = otx2_pfaf_mbox_init(pf);
if (err)

View File

@ -58,6 +58,10 @@
#define RVU_VF_MSIX_PBAX(a) (0xF0000 | (a) << 3)
#define RVU_VF_MBOX_REGION (0xC0000)
/* CN20K RVU_MBOX_E: RVU PF/VF MBOX Address Range Enumeration */
#define RVU_MBOX_AF_PFX_ADDR(a) (0x5000 | (a) << 4)
#define RVU_PFX_FUNC_PFAF_MBOX (0x80000)
#define RVU_FUNC_BLKADDR_SHIFT 20
#define RVU_FUNC_BLKADDR_MASK 0x1FULL

View File

@ -616,6 +616,12 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
otx2_setup_dev_hw_settings(vf);
if (is_cn20k(vf->pdev))
cn20k_init(vf);
else
otx2_init_hw_ops(vf);
/* Init VF <=> PF mailbox stuff */
err = otx2vf_vfaf_mbox_init(vf);
if (err)