From: Ratheesh Kannoth <rkannoth@marvell.com>
To: <linux-kernel@vger.kernel.org>, <netdev@vger.kernel.org>
Cc: <andrew+netdev@lunn.ch>, <davem@davemloft.net>,
<edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>,
<sgoutham@marvell.com>, "Ratheesh Kannoth" <rkannoth@marvell.com>
Subject: [PATCH v8 net-next 2/9] octeontx2-af: switch: Add switch dev to AF mboxes
Date: Tue, 11 Aug 2026 14:23:59 +0530 [thread overview]
Message-ID: <20260811085406.3227312-3-rkannoth@marvell.com> (raw)
In-Reply-To: <20260811085406.3227312-1-rkannoth@marvell.com>
The Marvell switch hardware runs on a Linux OS. Switch
needs various information from AF driver. These mboxes are defined
to query those from AF driver.
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
---
.../ethernet/marvell/octeontx2/af/Makefile | 2 +-
.../net/ethernet/marvell/octeontx2/af/mbox.h | 130 ++++++++++++++++++
.../net/ethernet/marvell/octeontx2/af/rvu.c | 127 +++++++++++++++++
.../net/ethernet/marvell/octeontx2/af/rvu.h | 1 +
.../ethernet/marvell/octeontx2/af/rvu_nix.c | 82 ++++++++---
.../ethernet/marvell/octeontx2/af/rvu_npc.c | 115 ++++++++++++++++
.../marvell/octeontx2/af/rvu_npc_fs.c | 11 ++
.../marvell/octeontx2/af/switch/rvu_sw.c | 15 ++
.../marvell/octeontx2/af/switch/rvu_sw.h | 11 ++
9 files changed, 472 insertions(+), 22 deletions(-)
create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c
create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/Makefile b/drivers/net/ethernet/marvell/octeontx2/af/Makefile
index 82dd387308c9..73f20a44f1a0 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/Makefile
+++ b/drivers/net/ethernet/marvell/octeontx2/af/Makefile
@@ -12,6 +12,6 @@ rvu_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \
rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \
rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o \
rvu_sdp.o rvu_npc_hash.o mcs.o mcs_rvu_if.o mcs_cnf10kb.o \
- switch/rvu_sw_l2.o switch/rvu_sw_l3.o switch/rvu_sw_fl.o\
+ switch/rvu_sw.o switch/rvu_sw_l2.o switch/rvu_sw_l3.o switch/rvu_sw_fl.o \
rvu_rep.o cn20k/mbox_init.o cn20k/nix.o cn20k/debugfs.o \
cn20k/npa.o cn20k/npc.o
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index 80c01b686448..1fbe9cac5eb8 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -172,6 +172,10 @@ M(FL_NOTIFY, 0x012, fl_notify, \
fl_notify_req, msg_rsp) \
M(FL_GET_STATS, 0x013, fl_get_stats, \
fl_get_stats_req, fl_get_stats_rsp) \
+M(IFACE_GET_INFO, 0x014, iface_get_info, msg_req, \
+ iface_get_info_rsp) \
+M(SWDEV2AF_NOTIFY, 0x015, swdev2af_notify, \
+ swdev2af_notify_req, msg_rsp) \
/* CGX mbox IDs (range 0x200 - 0x3FF) */ \
M(CGX_START_RXTX, 0x200, cgx_start_rxtx, msg_req, msg_rsp) \
M(CGX_STOP_RXTX, 0x201, cgx_stop_rxtx, msg_req, msg_rsp) \
@@ -317,6 +321,14 @@ M(NPC_MCAM_GET_DFT_RL_IDXS, 0x601e, npc_get_dft_rl_idxs, \
M(NPC_MCAM_GET_NPC_PFL_INFO, 0x601f, npc_get_pfl_info, \
msg_req, \
npc_get_pfl_info_rsp) \
+M(NPC_MCAM_FLOW_DEL_N_FREE, 0x6020, npc_flow_del_n_free, \
+ npc_flow_del_n_free_req, msg_rsp) \
+M(NPC_MCAM_GET_MUL_STATS, 0x6022, npc_mcam_mul_stats, \
+ npc_mcam_get_mul_stats_req, \
+ npc_mcam_get_mul_stats_rsp) \
+M(NPC_MCAM_GET_FEATURES, 0x6023, npc_mcam_get_features, \
+ msg_req, \
+ npc_mcam_get_features_rsp) \
/* NIX mbox IDs (range 0x8000 - 0xFFFF) */ \
M(NIX_LF_ALLOC, 0x8000, nix_lf_alloc, \
nix_lf_alloc_req, nix_lf_alloc_rsp) \
@@ -447,6 +459,12 @@ M(MCS_INTR_NOTIFY, 0xE00, mcs_intr_notify, mcs_intr_info, msg_rsp)
#define MBOX_UP_REP_MESSAGES \
M(REP_EVENT_UP_NOTIFY, 0xEF0, rep_event_up_notify, rep_event, msg_rsp) \
+#define MBOX_UP_AF2SWDEV_MESSAGES \
+M(AF2SWDEV, 0xEF1, af2swdev_notify, af2swdev_notify_req, msg_rsp)
+
+#define MBOX_UP_AF2PF_FDB_REFRESH_MESSAGES \
+M(AF2PF_FDB_REFRESH, 0xEF2, af2pf_fdb_refresh, af2pf_fdb_refresh_req, msg_rsp)
+
enum {
#define M(_name, _id, _1, _2, _3) MBOX_MSG_ ## _name = _id,
MBOX_MESSAGES
@@ -454,6 +472,8 @@ MBOX_UP_CGX_MESSAGES
MBOX_UP_CPT_MESSAGES
MBOX_UP_MCS_MESSAGES
MBOX_UP_REP_MESSAGES
+MBOX_UP_AF2SWDEV_MESSAGES
+MBOX_UP_AF2PF_FDB_REFRESH_MESSAGES
#undef M
};
@@ -1592,6 +1612,31 @@ struct npc_mcam_alloc_entry_rsp {
u16 entry_list[NPC_MAX_NONCONTIG_ENTRIES];
};
+struct npc_flow_del_n_free_req {
+ struct mbox_msghdr hdr;
+ u16 cnt;
+ u16 entry[256]; /* Entry index to be freed */
+};
+
+struct npc_mcam_get_features_rsp {
+ struct mbox_msghdr hdr;
+ u64 rx_features;
+ u64 tx_features;
+};
+
+struct npc_mcam_get_mul_stats_req {
+ struct mbox_msghdr hdr;
+ u16 cnt;
+ u16 entry[256]; /* mcam entry */
+};
+
+struct npc_mcam_get_mul_stats_rsp {
+ struct mbox_msghdr hdr;
+ u16 cnt;
+ u16 rsvd[3]; /* explicit padding for stat[] 8-byte alignment */
+ u64 stat[256]; /* counter stats */
+};
+
struct npc_mcam_free_entry_req {
struct mbox_msghdr hdr;
u16 entry; /* Entry index to be freed */
@@ -1927,6 +1972,91 @@ struct fl_get_stats_rsp {
u64 pkts_diff;
};
+struct af2swdev_notify_req {
+ struct mbox_msghdr hdr;
+ u64 flags;
+ u32 port_id;
+ u32 switch_id;
+ union {
+ struct {
+ u8 mac[6];
+ u8 rsvd_mac[2]; /* explicit padding to 8 bytes */
+ };
+ struct {
+ u8 cnt;
+ u8 rsvd[7]; /* explicit padding before fib_entry[] */
+ struct fib_entry entry[12];
+ };
+
+ struct {
+ u64 cookie;
+ u64 features;
+ struct fl_tuple tuple;
+ };
+ };
+};
+
+struct af2pf_fdb_refresh_req {
+ struct mbox_msghdr hdr;
+ u16 pcifunc;
+ u8 mac[6];
+};
+
+struct iface_info {
+ u8 is_vf : 1;
+ u8 is_sdp : 1;
+ u8 rsvd : 6;
+ u16 pcifunc;
+ u16 rx_chan_base;
+ u16 tx_chan_base;
+ u16 sq_cnt;
+ u16 cq_cnt;
+ u16 rq_cnt;
+ u8 rx_chan_cnt;
+ u8 tx_chan_cnt;
+ u8 tx_link;
+ u8 nix;
+};
+
+/* Max supported */
+#define IFACE_MAX (256 + 32) /* 32 PFs + 256 VFs */
+
+struct iface_get_info_rsp {
+ struct mbox_msghdr hdr;
+ u16 cnt;
+ u8 truncated;
+ u8 rsvd[5];
+ struct iface_info info[IFACE_MAX];
+};
+
+struct fl_info {
+ u64 cookie;
+ u16 mcam_idx[2];
+ u8 dis : 1;
+ u8 uni_di : 1;
+};
+
+struct swdev2af_notify_req {
+ struct mbox_msghdr hdr;
+ u64 msg_type;
+#define SWDEV2AF_MSG_TYPE_FW_STATUS BIT_ULL(0)
+#define SWDEV2AF_MSG_TYPE_REFRESH_FDB BIT_ULL(1)
+#define SWDEV2AF_MSG_TYPE_REFRESH_FL BIT_ULL(2)
+ u16 pcifunc;
+ u16 rsvd1[3]; /* explicit padding before union for 8-byte alignment */
+ union {
+ bool fw_up; // FW_STATUS message
+
+ u8 mac[ETH_ALEN]; // fdb refresh message
+
+ struct { // fl refresh message
+ u8 cnt;
+ u8 rsvd2[7];
+ struct fl_info fl[64];
+ };
+ };
+};
+
struct flow_msg {
unsigned char dmac[6];
unsigned char smac[6];
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index ffba56ee8a60..2a5070c56bdb 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -1990,6 +1990,133 @@ int rvu_mbox_handler_msix_offset(struct rvu *rvu, struct msg_req *req,
return 0;
}
+static void rvu_iface_get_qcnts(struct rvu *rvu, struct rvu_pfvf *pfvf,
+ struct iface_info *info)
+{
+ mutex_lock(&rvu->rsrc_lock);
+
+ info->sq_cnt = 0;
+ info->cq_cnt = 0;
+ info->rq_cnt = 0;
+
+ /* Use each LF queue context size; bitmaps are sized to qsize longs. */
+ if (pfvf->sq_ctx && pfvf->sq_bmap)
+ info->sq_cnt = bitmap_weight(pfvf->sq_bmap, pfvf->sq_ctx->qsize);
+ if (pfvf->cq_ctx && pfvf->cq_bmap)
+ info->cq_cnt = bitmap_weight(pfvf->cq_bmap, pfvf->cq_ctx->qsize);
+ if (pfvf->rq_ctx && pfvf->rq_bmap)
+ info->rq_cnt = bitmap_weight(pfvf->rq_bmap, pfvf->rq_ctx->qsize);
+
+ mutex_unlock(&rvu->rsrc_lock);
+}
+
+int rvu_mbox_handler_iface_get_info(struct rvu *rvu, struct msg_req *req,
+ struct iface_get_info_rsp *rsp)
+{
+ struct iface_info *info;
+ bool truncated = false;
+ struct rvu_pfvf *pfvf;
+ int pf, vf, numvfs;
+ int tot = 0;
+ u16 pcifunc;
+ u64 cfg;
+
+ /* Read-only topology snapshot for switch software; any PF/VF may
+ * request it. Only channel and queue counts already visible to the
+ * requester through AF are reported.
+ */
+ rsp->cnt = 0;
+ rsp->truncated = 0;
+ memset(rsp->rsvd, 0, sizeof(rsp->rsvd));
+ /* Preserve mbox_msghdr fields pre-filled by the mbox framework. */
+ memset(rsp->info, 0, sizeof(rsp->info));
+ info = rsp->info;
+ for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
+ if (tot >= IFACE_MAX) {
+ truncated = true;
+ goto done;
+ }
+
+ cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf));
+ numvfs = (cfg >> 12) & 0xFF;
+
+ /* Skip not enabled PFs */
+ if (!(cfg & BIT_ULL(20)))
+ goto chk_vfs;
+
+ /* If Admin function, check on VFs */
+ if (cfg & BIT_ULL(21))
+ goto chk_vfs;
+
+ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+ /* Populate iff at least one Tx channel */
+ if (!pfvf->tx_chan_cnt)
+ goto chk_vfs;
+
+ info->is_vf = 0;
+ info->pcifunc = pcifunc;
+ info->rx_chan_base = pfvf->rx_chan_base;
+ info->rx_chan_cnt = pfvf->rx_chan_cnt;
+ info->tx_chan_base = pfvf->tx_chan_base;
+ info->tx_chan_cnt = pfvf->tx_chan_cnt;
+ info->tx_link = nix_get_tx_link(rvu, pcifunc);
+ if (is_sdp_pfvf(rvu, pcifunc))
+ info->is_sdp = 1;
+
+ rvu_iface_get_qcnts(rvu, pfvf, info);
+
+ if (pfvf->nix_blkaddr == BLKADDR_NIX0)
+ info->nix = 0;
+ else
+ info->nix = 1;
+
+ info++;
+ tot++;
+
+chk_vfs:
+ for (vf = 0; vf < numvfs; vf++) {
+ if (tot >= IFACE_MAX) {
+ truncated = true;
+ goto done;
+ }
+
+ pcifunc = rvu_make_pcifunc(rvu->pdev, pf, vf + 1);
+ pfvf = rvu_get_pfvf(rvu, pcifunc);
+
+ if (!pfvf->tx_chan_cnt)
+ continue;
+
+ info->is_vf = 1;
+ info->pcifunc = pcifunc;
+ info->rx_chan_base = pfvf->rx_chan_base;
+ info->rx_chan_cnt = pfvf->rx_chan_cnt;
+ info->tx_chan_base = pfvf->tx_chan_base;
+ info->tx_chan_cnt = pfvf->tx_chan_cnt;
+ info->tx_link = nix_get_tx_link(rvu, pcifunc);
+ if (is_sdp_pfvf(rvu, pcifunc))
+ info->is_sdp = 1;
+
+ rvu_iface_get_qcnts(rvu, pfvf, info);
+
+ if (pfvf->nix_blkaddr == BLKADDR_NIX0)
+ info->nix = 0;
+ else
+ info->nix = 1;
+
+ info++;
+
+ tot++;
+ }
+ }
+done:
+ rsp->cnt = tot;
+ rsp->truncated = truncated;
+
+ return 0;
+}
+
int rvu_mbox_handler_free_rsrc_cnt(struct rvu *rvu, struct msg_req *req,
struct free_rsrcs_rsp *rsp)
{
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 094227404ef9..2876c76ae61b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -1160,6 +1160,7 @@ void rvu_program_channels(struct rvu *rvu);
/* CN10K NIX */
void rvu_nix_block_cn10k_init(struct rvu *rvu, struct nix_hw *nix_hw);
+int nix_get_tx_link(struct rvu *rvu, u16 pcifunc);
/* CN10K RVU - LMT*/
void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc);
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index b81c47ea023b..9bc86fc949f3 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -32,7 +32,6 @@ static int nix_free_all_bandprof(struct rvu *rvu, u16 pcifunc);
static void nix_clear_ratelimit_aggr(struct rvu *rvu, struct nix_hw *nix_hw,
u32 leaf_prof);
static const char *nix_get_ctx_name(int ctype);
-static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc);
enum mc_tbl_sz {
MC_TBL_SZ_256,
@@ -912,8 +911,28 @@ static void nix_setup_lso(struct rvu *rvu, struct nix_hw *nix_hw, int blkaddr)
nix_hw->lso.in_use++;
}
+static void nix_qctx_assign(struct rvu *rvu, struct qmem **ctx,
+ unsigned long **bmap, struct qmem *new_ctx,
+ unsigned long *new_bmap)
+{
+ mutex_lock(&rvu->rsrc_lock);
+ *ctx = new_ctx;
+ *bmap = new_bmap;
+ mutex_unlock(&rvu->rsrc_lock);
+}
+
+static void nix_ctx_assign(struct rvu *rvu, struct qmem **ctx,
+ struct qmem *new_ctx)
+{
+ mutex_lock(&rvu->rsrc_lock);
+ *ctx = new_ctx;
+ mutex_unlock(&rvu->rsrc_lock);
+}
+
static void nix_ctx_free(struct rvu *rvu, struct rvu_pfvf *pfvf)
{
+ mutex_lock(&rvu->rsrc_lock);
+
kfree(pfvf->rq_bmap);
kfree(pfvf->sq_bmap);
kfree(pfvf->cq_bmap);
@@ -939,6 +958,8 @@ static void nix_ctx_free(struct rvu *rvu, struct rvu_pfvf *pfvf)
pfvf->rss_ctx = NULL;
pfvf->nix_qints_ctx = NULL;
pfvf->cq_ints_ctx = NULL;
+
+ mutex_unlock(&rvu->rsrc_lock);
}
static int nixlf_rss_ctx_init(struct rvu *rvu, int blkaddr,
@@ -946,6 +967,7 @@ static int nixlf_rss_ctx_init(struct rvu *rvu, int blkaddr,
int rss_sz, int rss_grps, int hwctx_size,
u64 way_mask, bool tag_lsb_as_adder)
{
+ struct qmem *rss_ctx;
int err, grp, num_indices;
u64 val;
@@ -955,12 +977,12 @@ static int nixlf_rss_ctx_init(struct rvu *rvu, int blkaddr,
num_indices = rss_sz * rss_grps;
/* Alloc NIX RSS HW context memory and config the base */
- err = qmem_alloc(rvu->dev, &pfvf->rss_ctx, num_indices, hwctx_size);
+ err = qmem_alloc(rvu->dev, &rss_ctx, num_indices, hwctx_size);
if (err)
return err;
rvu_write64(rvu, blkaddr, NIX_AF_LFX_RSS_BASE(nixlf),
- (u64)pfvf->rss_ctx->iova);
+ (u64)rss_ctx->iova);
/* Config full RSS table size, enable RSS and caching */
val = BIT_ULL(36) | BIT_ULL(4) | way_mask << 20 |
@@ -974,6 +996,8 @@ static int nixlf_rss_ctx_init(struct rvu *rvu, int blkaddr,
for (grp = 0; grp < rss_grps; grp++)
rvu_write64(rvu, blkaddr, NIX_AF_LFX_RSS_GRPX(nixlf, grp),
((ilog2(rss_sz) - 1) << 16) | (rss_sz * grp));
+
+ nix_ctx_assign(rvu, &pfvf->rss_ctx, rss_ctx);
return 0;
}
@@ -1514,6 +1538,9 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
struct nix_lf_alloc_rsp *rsp)
{
int nixlf, qints, hwctx_size, intf, rc = 0, pf;
+ unsigned long *rq_bmap, *sq_bmap, *cq_bmap;
+ struct qmem *cq_ints_ctx, *nix_qints_ctx;
+ struct qmem *rq_ctx, *sq_ctx, *cq_ctx;
u16 bcast, mcast, promisc, ucast;
struct rvu_hwinfo *hw = rvu->hw;
u16 pcifunc = req->hdr.pcifunc;
@@ -1584,59 +1611,68 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
/* Alloc NIX RQ HW context memory and config the base */
hwctx_size = 1UL << ((ctx_cfg >> 4) & 0xF);
- rc = qmem_alloc(rvu->dev, &pfvf->rq_ctx, req->rq_cnt, hwctx_size);
+ rc = qmem_alloc(rvu->dev, &rq_ctx, req->rq_cnt, hwctx_size);
if (rc)
goto free_mem;
- pfvf->rq_bmap = kcalloc(req->rq_cnt, sizeof(long), GFP_KERNEL);
- if (!pfvf->rq_bmap) {
+ rq_bmap = kcalloc(req->rq_cnt, sizeof(long), GFP_KERNEL);
+ if (!rq_bmap) {
+ qmem_free(rvu->dev, rq_ctx);
rc = -ENOMEM;
goto free_mem;
}
rvu_write64(rvu, blkaddr, NIX_AF_LFX_RQS_BASE(nixlf),
- (u64)pfvf->rq_ctx->iova);
+ (u64)rq_ctx->iova);
/* Set caching and queue count in HW */
cfg = BIT_ULL(36) | (req->rq_cnt - 1) | req->way_mask << 20;
rvu_write64(rvu, blkaddr, NIX_AF_LFX_RQS_CFG(nixlf), cfg);
+ nix_qctx_assign(rvu, &pfvf->rq_ctx, &pfvf->rq_bmap, rq_ctx, rq_bmap);
+
/* Alloc NIX SQ HW context memory and config the base */
hwctx_size = 1UL << (ctx_cfg & 0xF);
- rc = qmem_alloc(rvu->dev, &pfvf->sq_ctx, req->sq_cnt, hwctx_size);
+ rc = qmem_alloc(rvu->dev, &sq_ctx, req->sq_cnt, hwctx_size);
if (rc)
goto free_mem;
- pfvf->sq_bmap = kcalloc(req->sq_cnt, sizeof(long), GFP_KERNEL);
- if (!pfvf->sq_bmap) {
+ sq_bmap = kcalloc(req->sq_cnt, sizeof(long), GFP_KERNEL);
+ if (!sq_bmap) {
+ qmem_free(rvu->dev, sq_ctx);
rc = -ENOMEM;
goto free_mem;
}
rvu_write64(rvu, blkaddr, NIX_AF_LFX_SQS_BASE(nixlf),
- (u64)pfvf->sq_ctx->iova);
+ (u64)sq_ctx->iova);
cfg = BIT_ULL(36) | (req->sq_cnt - 1) | req->way_mask << 20;
rvu_write64(rvu, blkaddr, NIX_AF_LFX_SQS_CFG(nixlf), cfg);
+ nix_qctx_assign(rvu, &pfvf->sq_ctx, &pfvf->sq_bmap, sq_ctx, sq_bmap);
+
/* Alloc NIX CQ HW context memory and config the base */
hwctx_size = 1UL << ((ctx_cfg >> 8) & 0xF);
- rc = qmem_alloc(rvu->dev, &pfvf->cq_ctx, req->cq_cnt, hwctx_size);
+ rc = qmem_alloc(rvu->dev, &cq_ctx, req->cq_cnt, hwctx_size);
if (rc)
goto free_mem;
- pfvf->cq_bmap = kcalloc(req->cq_cnt, sizeof(long), GFP_KERNEL);
- if (!pfvf->cq_bmap) {
+ cq_bmap = kcalloc(req->cq_cnt, sizeof(long), GFP_KERNEL);
+ if (!cq_bmap) {
+ qmem_free(rvu->dev, cq_ctx);
rc = -ENOMEM;
goto free_mem;
}
rvu_write64(rvu, blkaddr, NIX_AF_LFX_CQS_BASE(nixlf),
- (u64)pfvf->cq_ctx->iova);
+ (u64)cq_ctx->iova);
cfg = BIT_ULL(36) | (req->cq_cnt - 1) | req->way_mask << 20;
rvu_write64(rvu, blkaddr, NIX_AF_LFX_CQS_CFG(nixlf), cfg);
+ nix_qctx_assign(rvu, &pfvf->cq_ctx, &pfvf->cq_bmap, cq_ctx, cq_bmap);
+
/* Initialize receive side scaling (RSS) */
hwctx_size = 1UL << ((ctx_cfg >> 12) & 0xF);
rc = nixlf_rss_ctx_init(rvu, blkaddr, pfvf, nixlf, req->rss_sz,
@@ -1649,29 +1685,33 @@ int rvu_mbox_handler_nix_lf_alloc(struct rvu *rvu,
cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
qints = (cfg >> 24) & 0xFFF;
hwctx_size = 1UL << ((ctx_cfg >> 24) & 0xF);
- rc = qmem_alloc(rvu->dev, &pfvf->cq_ints_ctx, qints, hwctx_size);
+ rc = qmem_alloc(rvu->dev, &cq_ints_ctx, qints, hwctx_size);
if (rc)
goto free_mem;
rvu_write64(rvu, blkaddr, NIX_AF_LFX_CINTS_BASE(nixlf),
- (u64)pfvf->cq_ints_ctx->iova);
+ (u64)cq_ints_ctx->iova);
rvu_write64(rvu, blkaddr, NIX_AF_LFX_CINTS_CFG(nixlf),
BIT_ULL(36) | req->way_mask << 20);
+ nix_ctx_assign(rvu, &pfvf->cq_ints_ctx, cq_ints_ctx);
+
/* Alloc memory for QINT's HW contexts */
cfg = rvu_read64(rvu, blkaddr, NIX_AF_CONST2);
qints = (cfg >> 12) & 0xFFF;
hwctx_size = 1UL << ((ctx_cfg >> 20) & 0xF);
- rc = qmem_alloc(rvu->dev, &pfvf->nix_qints_ctx, qints, hwctx_size);
+ rc = qmem_alloc(rvu->dev, &nix_qints_ctx, qints, hwctx_size);
if (rc)
goto free_mem;
rvu_write64(rvu, blkaddr, NIX_AF_LFX_QINTS_BASE(nixlf),
- (u64)pfvf->nix_qints_ctx->iova);
+ (u64)nix_qints_ctx->iova);
rvu_write64(rvu, blkaddr, NIX_AF_LFX_QINTS_CFG(nixlf),
BIT_ULL(36) | req->way_mask << 20);
+ nix_ctx_assign(rvu, &pfvf->nix_qints_ctx, nix_qints_ctx);
+
/* Setup VLANX TPID's.
* Use VLAN1 for 802.1Q
* and VLAN0 for 802.1AD.
@@ -2109,10 +2149,10 @@ static void nix_clear_tx_xoff(struct rvu *rvu, int blkaddr,
rvu_write64(rvu, blkaddr, reg, 0x0);
}
-static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc)
+int nix_get_tx_link(struct rvu *rvu, u16 pcifunc)
{
- struct rvu_hwinfo *hw = rvu->hw;
int pf = rvu_get_pf(rvu->pdev, pcifunc);
+ struct rvu_hwinfo *hw = rvu->hw;
u8 cgx_id = 0, lmac_id = 0;
if (is_lbk_vf(rvu, pcifunc)) {/* LBK links */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index db27ea622f35..2317f34b474c 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -3545,6 +3545,46 @@ int rvu_mbox_handler_npc_mcam_free_entry(struct rvu *rvu,
return rc;
}
+int rvu_mbox_handler_npc_flow_del_n_free(struct rvu *rvu,
+ struct npc_flow_del_n_free_req *mreq,
+ struct msg_rsp *rsp)
+{
+ struct npc_mcam_free_entry_req sreq = { 0 };
+ struct npc_delete_flow_req dreq = { 0 };
+ struct npc_delete_flow_rsp drsp = { 0 };
+ u16 entry[256];
+ int ret = 0, i;
+ bool err = false;
+ u16 cnt;
+
+ sreq.hdr.pcifunc = mreq->hdr.pcifunc;
+ dreq.hdr.pcifunc = mreq->hdr.pcifunc;
+
+ cnt = mreq->cnt;
+ if (!cnt || cnt > 256) {
+ dev_err_ratelimited(rvu->dev, "Invalid cnt=%u\n", cnt);
+ return -EINVAL;
+ }
+
+ /* Snapshot shared mailbox memory before processing the request. */
+ memcpy(entry, mreq->entry, cnt * sizeof(entry[0]));
+
+ for (i = 0; i < cnt; i++) {
+ dreq.entry = entry[i];
+ rvu_mbox_handler_npc_delete_flow(rvu, &dreq, &drsp);
+
+ sreq.entry = entry[i];
+ ret = rvu_mbox_handler_npc_mcam_free_entry(rvu, &sreq, rsp);
+ if (ret) {
+ dev_err(rvu->dev, "free entry error for i=%d entry=%d\n",
+ i, entry[i]);
+ err = true;
+ }
+ }
+
+ return err ? -EINVAL : 0;
+}
+
int rvu_mbox_handler_npc_mcam_read_entry(struct rvu *rvu,
struct npc_mcam_read_entry_req *req,
struct npc_mcam_read_entry_rsp *rsp)
@@ -4407,6 +4447,81 @@ int rvu_mbox_handler_npc_mcam_entry_stats(struct rvu *rvu,
return 0;
}
+int rvu_mbox_handler_npc_mcam_mul_stats(struct rvu *rvu,
+ struct npc_mcam_get_mul_stats_req *req,
+ struct npc_mcam_get_mul_stats_rsp *rsp)
+{
+ struct npc_mcam *mcam = &rvu->hw->mcam;
+ u16 req_cnt, index, cntr, mcam_entry;
+ u16 pcifunc = req->hdr.pcifunc;
+ int blkaddr, cnt = 0, i;
+ u16 entry[256];
+ u64 regval;
+ u32 bank;
+
+ rsp->cnt = 0;
+ memset(rsp->rsvd, 0, sizeof(rsp->rsvd));
+ memset(rsp->stat, 0, sizeof(rsp->stat));
+
+ req_cnt = req->cnt;
+ if (!req_cnt || req_cnt > 256) {
+ dev_err_ratelimited(rvu->dev, "%s invalid request cnt=%u\n",
+ __func__, req_cnt);
+ return -EINVAL;
+ }
+
+ /* Snapshot shared mailbox memory before processing the request. */
+ memcpy(entry, req->entry, req_cnt * sizeof(entry[0]));
+
+ blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
+ if (blkaddr < 0)
+ return NPC_MCAM_INVALID_REQ;
+
+ mutex_lock(&mcam->lock);
+
+ for (i = 0; i < req_cnt; i++) {
+ mcam_entry = npc_cn20k_vidx2idx(entry[i]);
+
+ if (npc_mcam_verify_entry(mcam, pcifunc, mcam_entry)) {
+ mutex_unlock(&mcam->lock);
+ dev_err(rvu->dev, "%s invalid mcam index=%d\n",
+ __func__, entry[i]);
+ return -EINVAL;
+ }
+
+ index = mcam_entry & (mcam->banksize - 1);
+ bank = npc_get_bank(mcam, mcam_entry);
+
+ if (is_cn20k(rvu->pdev)) {
+ regval = rvu_read64(rvu, blkaddr,
+ NPC_AF_CN20K_MCAMEX_BANKX_STAT_EXT(index,
+ bank));
+ rsp->stat[cnt] = regval;
+ cnt++;
+ continue;
+ }
+
+ /* read MCAM entry STAT_ACT register */
+ regval = rvu_read64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_STAT_ACT(index, bank));
+
+ if (!(regval & rvu->hw->npc_stat_ena)) {
+ rsp->stat[cnt] = 0;
+ cnt++;
+ continue;
+ }
+
+ cntr = regval & 0x1FF;
+
+ rsp->stat[cnt] = rvu_read64(rvu, blkaddr, NPC_AF_MATCH_STATX(cntr));
+ rsp->stat[cnt] &= BIT_ULL(48) - 1;
+ cnt++;
+ }
+
+ rsp->cnt = cnt;
+ mutex_unlock(&mcam->lock);
+ return 0;
+}
+
void rvu_npc_clear_ucast_entry(struct rvu *rvu, int pcifunc, int nixlf)
{
struct npc_mcam *mcam = &rvu->hw->mcam;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
index d422bdd5e8f8..e36c68ee5d84 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
@@ -1931,6 +1931,17 @@ static int npc_delete_flow(struct rvu *rvu, struct rvu_npc_mcam_rule *rule,
return rvu_mbox_handler_npc_mcam_dis_entry(rvu, &dis_req, &dis_rsp);
}
+int rvu_mbox_handler_npc_mcam_get_features(struct rvu *rvu,
+ struct msg_req *req,
+ struct npc_mcam_get_features_rsp *rsp)
+{
+ struct npc_mcam *mcam = &rvu->hw->mcam;
+
+ rsp->rx_features = mcam->rx_features;
+ rsp->tx_features = mcam->tx_features;
+ return 0;
+}
+
int rvu_mbox_handler_npc_delete_flow(struct rvu *rvu,
struct npc_delete_flow_req *req,
struct npc_delete_flow_rsp *rsp)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c
new file mode 100644
index 000000000000..fe143ad3f944
--- /dev/null
+++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell RVU Admin Function driver
+ *
+ * Copyright (C) 2026 Marvell.
+ *
+ */
+
+#include "rvu.h"
+
+int rvu_mbox_handler_swdev2af_notify(struct rvu *rvu,
+ struct swdev2af_notify_req *req,
+ struct msg_rsp *rsp)
+{
+ return 0;
+}
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h
new file mode 100644
index 000000000000..f28dba556d80
--- /dev/null
+++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Marvell RVU Admin Function driver
+ *
+ * Copyright (C) 2026 Marvell.
+ *
+ */
+
+#ifndef RVU_SWITCH_H
+#define RVU_SWITCH_H
+
+#endif
--
2.43.0
next prev parent reply other threads:[~2026-08-11 8:54 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-11 8:53 [PATCH v8 net-next 0/9] Switch support Ratheesh Kannoth
2026-08-11 8:53 ` [PATCH v8 net-next 1/9] octeontx2-af: switch: Add AF to switch mbox and skeleton files Ratheesh Kannoth
2026-08-11 8:53 ` Ratheesh Kannoth [this message]
2026-08-11 8:54 ` [PATCH v8 net-next 3/9] octeontx2-pf: switch: Add pf files hierarchy Ratheesh Kannoth
2026-08-11 8:54 ` [PATCH v8 net-next 4/9] octeontx2-af: switch: Representor for switch port Ratheesh Kannoth
2026-08-11 8:54 ` [PATCH v8 net-next 5/9] octeontx2-af: switch: TL1 scheduling and NPC channel control Ratheesh Kannoth
2026-08-11 8:54 ` [PATCH v8 net-next 6/9] octeontx2-pf: switch: Register notifiers for switch offload Ratheesh Kannoth
2026-08-11 8:54 ` [PATCH v8 net-next 7/9] octeontx2: switch: plumb bridge FDB updates through AF and switchdev Ratheesh Kannoth
2026-08-11 8:54 ` [PATCH v8 net-next 8/9] octeontx2: switch: offload host FIB updates to switch via AF mailbox Ratheesh Kannoth
2026-08-11 8:54 ` [PATCH v8 net-next 9/9] octeontx2: switch: add TC flow offload path for switch flows Ratheesh Kannoth
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260811085406.3227312-3-rkannoth@marvell.com \
--to=rkannoth@marvell.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sgoutham@marvell.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox