[PATCH v8 net-next 4/9] octeontx2-af: switch: Representor for switch port
From: Ratheesh Kannoth
Date: Tue Aug 11 2026 - 04:59:29 EST
Extends esw_cfg with a devlink-derived switch id, copies it into
rvu->rswitch on the AF, adds rvu_sw_port_id(), exports
rvu_rep_get_vlan_id().
Signed-off-by: Ratheesh Kannoth <rkannoth@xxxxxxxxxxx>
---
.../net/ethernet/marvell/octeontx2/af/mbox.h | 1 +
.../net/ethernet/marvell/octeontx2/af/rvu.h | 5 +++
.../ethernet/marvell/octeontx2/af/rvu_rep.c | 33 ++++++++++++++++++-
.../marvell/octeontx2/af/switch/rvu_sw.c | 26 +++++++++++++++
.../marvell/octeontx2/af/switch/rvu_sw.h | 5 +++
.../net/ethernet/marvell/octeontx2/nic/rep.c | 4 +++
6 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index 1fbe9cac5eb8..c391043173b0 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -1839,6 +1839,7 @@ struct esw_cfg_req {
struct mbox_msghdr hdr;
u8 ena;
u64 rsvd;
+ unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN];
};
struct rep_evt_data {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index 2876c76ae61b..9174b879850a 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -576,6 +576,10 @@ struct rvu_switch {
u16 *entry2pcifunc;
u16 mode;
u16 start_entry;
+ unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN];
+#define RVU_SWITCH_FLAG_FW_READY BIT_ULL(0)
+ u64 flags;
+ u16 pcifunc;
};
struct rep_evtq_ent {
@@ -1199,4 +1203,5 @@ int rvu_rep_install_mcam_rules(struct rvu *rvu);
void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena);
int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable);
int npc_mcam_verify_entry(struct npc_mcam *mcam, u16 pcifunc, int entry);
+u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc);
#endif /* RVU_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
index a2781e0f504e..672d54847c7b 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
@@ -6,6 +6,7 @@
*/
#include <linux/bitfield.h>
+#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/module.h>
@@ -189,7 +190,7 @@ int rvu_mbox_handler_nix_lf_stats(struct rvu *rvu,
return 0;
}
-static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
+u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
{
int id;
@@ -429,6 +430,30 @@ int rvu_rep_pf_init(struct rvu *rvu)
return 0;
}
+/* ESW_CFG is always the sole message in a mailbox transaction.
+ *
+ * The otx2 mailbox API does not batch multiple messages per sync: the
+ * representor driver allocates only ESW_CFG before calling
+ * otx2_sync_mbox_msg() (see rvu_eswitch_config()), and the AF processes
+ * one message per dispatch. next_msgoff is therefore the end offset of this
+ * message, not a cumulative offset across batched messages, so the length
+ * check below is safe. Batching is not supported; do not flag this path.
+ */
+static bool esw_cfg_req_has_switch_id(const struct esw_cfg_req *req)
+{
+ u16 hdr_len = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
+ u16 next_off = req->hdr.next_msgoff;
+ u16 msg_len;
+
+ if (next_off < hdr_len)
+ return false;
+
+ msg_len = next_off - hdr_len;
+
+ return msg_len >= offsetof(struct esw_cfg_req, switch_id) +
+ MAX_PHYS_ITEM_ID_LEN;
+}
+
int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
struct msg_rsp *rsp)
{
@@ -436,6 +461,9 @@ int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
return 0;
rvu->rep_mode = req->ena;
+ if (esw_cfg_req_has_switch_id(req))
+ memcpy(rvu->rswitch.switch_id, req->switch_id,
+ MAX_PHYS_ITEM_ID_LEN);
if (!rvu->rep_mode)
rvu_npc_free_mcam_entries(rvu, req->hdr.pcifunc, -1);
@@ -449,6 +477,9 @@ int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
int pf, vf, numvfs, hwvf, rep = 0;
u16 pcifunc;
+ /* Called once from representor driver probe during devlink eswitch
+ * SWITCHDEV bring-up; not re-run during switch device operation.
+ */
rvu->rep_pcifunc = req->hdr.pcifunc;
rsp->rep_cnt = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
rvu->rep_cnt = rsp->rep_cnt;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c
index fe143ad3f944..2451eb57ec4c 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.c
@@ -5,7 +5,33 @@
*
*/
+#include <linux/bitfield.h>
+
#include "rvu.h"
+#include "rvu_sw.h"
+
+/*
+ * rep_cnt and rep2pfvf_map are populated once when the representor driver
+ * probes via GET_REP_CNT (see rvu_get_rep_cnt() in rep.c), as part of
+ * devlink eswitch SWITCHDEV bring-up. They are not updated during switch
+ * device mailbox handling, so this lockless lookup cannot race with a
+ * concurrent rep2pfvf_map resize.
+ */
+u32 rvu_sw_port_id(struct rvu *rvu, u16 pcifunc)
+{
+ u16 rep_id;
+
+ if (!rvu->rep2pfvf_map || !rvu->rep_cnt)
+ return RVU_SW_INVALID_PORT_ID;
+
+ rep_id = rvu_rep_get_vlan_id(rvu, pcifunc);
+ if (rep_id >= rvu->rep_cnt ||
+ rvu->rep2pfvf_map[rep_id] != pcifunc)
+ return RVU_SW_INVALID_PORT_ID;
+
+ return FIELD_PREP(GENMASK_ULL(31, 16), rep_id) |
+ FIELD_PREP(GENMASK_ULL(15, 0), pcifunc);
+}
int rvu_mbox_handler_swdev2af_notify(struct rvu *rvu,
struct swdev2af_notify_req *req,
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h
index f28dba556d80..e9ad32c84576 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/switch/rvu_sw.h
@@ -8,4 +8,9 @@
#ifndef RVU_SWITCH_H
#define RVU_SWITCH_H
+/* RVU Switch */
+#define RVU_SW_INVALID_PORT_ID ((u32)~0U)
+
+u32 rvu_sw_port_id(struct rvu *rvu, u16 pcifunc);
+
#endif
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
index 0f5d5642d3f7..257a2ae6a53e 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
@@ -399,8 +399,11 @@ static void rvu_rep_get_stats64(struct net_device *dev,
static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena)
{
+ struct devlink_port_attrs attrs = {};
struct esw_cfg_req *req;
+ rvu_rep_devlink_set_switch_id(priv, &attrs.switch_id);
+
mutex_lock(&priv->mbox.lock);
req = otx2_mbox_alloc_msg_esw_cfg(&priv->mbox);
if (!req) {
@@ -408,6 +411,7 @@ static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena)
return -ENOMEM;
}
req->ena = ena;
+ memcpy(req->switch_id, attrs.switch_id.id, attrs.switch_id.id_len);
otx2_sync_mbox_msg(&priv->mbox);
mutex_unlock(&priv->mbox.lock);
return 0;
--
2.43.0