mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 net-next] octeontx2-af: pass devlink switch id and cache representor map
@ 2026-09-23  4:58 Ratheesh Kannoth
  2026-09-24  7:18 ` kernel test robot
  0 siblings, 1 reply; 2+ messages in thread
From: Ratheesh Kannoth @ 2026-09-23  4:58 UTC (permalink / raw)
  To: linux-kernel, netdev
  Cc: andrew+netdev, davem, edumazet, kuba, pabeni, sgoutham, Ratheesh Kannoth

Extend MBOX_MSG_ESW_CFG with the representor devlink switch_id and
store it in the AF. Build rep2pfvf_map once on GET_REP_CNT, always
refresh rep_pcifunc, and protect map access with rsrc_lock. Reset the
cache on eswitch disable and representor FLR. Add rvu_sw_port_id()
and share the representor index lookup with rvu_rep_get_vlan_id().

Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>

---

v1 -> v2:
- Always refresh rep_pcifunc on GET_REP_CNT instead of pinning it to
  the first caller.
- Replace the READ_ONCE/WRITE_ONCE rep2pfvf_map fast path with
  rvu_rep_lookup_id() lookups under rsrc_lock.
- Add rvu_rep_cache_reset() and call it on eswitch disable and
  representor FLR so the cached map and switch_id are torn down.
- Ignore redundant ESW_CFG enable/disable requests when the mode is
  already in the requested state.
- Validate switch_id length before allocating the ESW_CFG mailbox
  message.
- Build the representor map from rvu_rep_create() via rvu_get_rep_cnt().
- Drop the ESW_CFG wire-format comment block; the layout change is
  carried only by the struct fields.
- Factor rvu_rep_get_vlan_id() and rvu_sw_port_id() through a shared
  rvu_rep_lookup_id() helper.
  https://lore.kernel.org/netdev/20260918050021.1359606-1-rkannoth@marvell.com/
---
 .../net/ethernet/marvell/octeontx2/af/mbox.h  |   2 +
 .../net/ethernet/marvell/octeontx2/af/rvu.c   |   3 +
 .../net/ethernet/marvell/octeontx2/af/rvu.h   |   9 ++
 .../ethernet/marvell/octeontx2/af/rvu_rep.c   | 117 +++++++++++++++---
 .../net/ethernet/marvell/octeontx2/nic/rep.c  |  11 ++
 5 files changed, 125 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index cece197d1074..45c03f9294a5 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -1788,6 +1788,8 @@ struct esw_cfg_req {
 	struct mbox_msghdr hdr;
 	u8 ena;
 	u64 rsvd;
+	unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN];
+	u8 switch_id_len;
 };
 
 struct rep_evt_data {
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index 30e148291581..aeb6b4917f45 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -2924,6 +2924,9 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc)
 	if (rvu->mcs_blk_cnt)
 		rvu_mcs_flr_handler(rvu, pcifunc);
 
+	if (is_rep_dev(rvu, pcifunc))
+		rvu_rep_cache_reset(rvu);
+
 	mutex_unlock(&rvu->flr_lock);
 }
 
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index fb4870cd18e9..d5f69cba6d41 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -570,6 +570,7 @@ struct npc_kpu_profile_adapter {
 };
 
 #define RVU_SWITCH_LBK_CHAN	63
+#define RVU_SW_INVALID_PORT_ID	((u32)~0U)
 
 struct rvu_switch {
 	struct mutex switch_lock; /* Serialize flow installation */
@@ -577,6 +578,11 @@ struct rvu_switch {
 	u16 *entry2pcifunc;
 	u16 mode;
 	u16 start_entry;
+	unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN];
+	u8 switch_id_len;
+#define RVU_SWITCH_FLAG_FW_READY BIT_ULL(0)
+	u64 flags;
+	u16 pcifunc;
 };
 
 struct rep_evtq_ent {
@@ -1194,9 +1200,12 @@ void rvu_mcs_ptp_cfg(struct rvu *rvu, u8 rpm_id, u8 lmac_id, bool ena);
 void rvu_mcs_exit(struct rvu *rvu);
 
 /* Representor APIs */
+void rvu_rep_cache_reset(struct rvu *rvu);
 int rvu_rep_pf_init(struct rvu *rvu);
 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);
+u32 rvu_sw_port_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..a3ad45f46742 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,14 +190,47 @@ int rvu_mbox_handler_nix_lf_stats(struct rvu *rvu,
 	return 0;
 }
 
-static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
+static bool rvu_rep_lookup_id(struct rvu *rvu, u16 pcifunc, u16 *rep_id)
 {
-	int id;
+	u16 *map;
+	int id, cnt;
+	bool found = false;
+
+	mutex_lock(&rvu->rsrc_lock);
+	map = rvu->rep2pfvf_map;
+	cnt = rvu->rep_cnt;
+	if (map && cnt) {
+		for (id = 0; id < cnt; id++) {
+			if (map[id] == pcifunc) {
+				*rep_id = id;
+				found = true;
+				break;
+			}
+		}
+	}
+	mutex_unlock(&rvu->rsrc_lock);
 
-	for (id = 0; id < rvu->rep_cnt; id++)
-		if (rvu->rep2pfvf_map[id] == pcifunc)
-			return id;
-	return 0;
+	return found;
+}
+
+u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc)
+{
+	u16 rep_id;
+
+	if (!rvu_rep_lookup_id(rvu, pcifunc, &rep_id))
+		return 0;
+	return rep_id;
+}
+
+u32 rvu_sw_port_id(struct rvu *rvu, u16 pcifunc)
+{
+	u16 rep_id;
+
+	if (!rvu_rep_lookup_id(rvu, pcifunc, &rep_id))
+		return RVU_SW_INVALID_PORT_ID;
+
+	return FIELD_PREP(GENMASK_ULL(31, 16), rep_id) |
+	       FIELD_PREP(GENMASK_ULL(15, 0), pcifunc);
 }
 
 static int rvu_rep_tx_vlan_cfg(struct rvu *rvu,  u16 pcifunc,
@@ -429,16 +463,48 @@ int rvu_rep_pf_init(struct rvu *rvu)
 	return 0;
 }
 
+void rvu_rep_cache_reset(struct rvu *rvu)
+{
+	u16 *map;
+
+	mutex_lock(&rvu->rsrc_lock);
+	rvu->rep_mode = 0;
+	rvu->rep_pcifunc = 0;
+	map = rvu->rep2pfvf_map;
+	rvu->rep_cnt = 0;
+	rvu->rep2pfvf_map = NULL;
+	memset(rvu->rswitch.switch_id, 0, sizeof(rvu->rswitch.switch_id));
+	rvu->rswitch.switch_id_len = 0;
+	mutex_unlock(&rvu->rsrc_lock);
+
+	devm_kfree(rvu->dev, map);
+}
+
 int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req,
 			     struct msg_rsp *rsp)
 {
 	if (req->hdr.pcifunc != rvu->rep_pcifunc)
 		return 0;
 
+	if (rvu->rep_mode && req->ena)
+		return 0;
+
+	if (!rvu->rep_mode && !req->ena)
+		return 0;
+
 	rvu->rep_mode = req->ena;
+	memset(rvu->rswitch.switch_id, 0, sizeof(rvu->rswitch.switch_id));
+	rvu->rswitch.switch_id_len = 0;
+	if (req->switch_id_len && req->switch_id_len <= MAX_PHYS_ITEM_ID_LEN) {
+		memcpy(rvu->rswitch.switch_id, req->switch_id,
+		       req->switch_id_len);
+		rvu->rswitch.switch_id_len = req->switch_id_len;
+	}
 
-	if (!rvu->rep_mode)
+	if (!rvu->rep_mode) {
 		rvu_npc_free_mcam_entries(rvu, req->hdr.pcifunc, -1);
+		rvu_rep_cache_reset(rvu);
+	}
 
 	return 0;
 }
@@ -447,31 +513,48 @@ int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req,
 				 struct get_rep_cnt_rsp *rsp)
 {
 	int pf, vf, numvfs, hwvf, rep = 0;
-	u16 pcifunc;
+	u16 pcifunc, rep_cnt;
+	u16 *map;
+
+	mutex_lock(&rvu->rsrc_lock);
 
 	rvu->rep_pcifunc = req->hdr.pcifunc;
-	rsp->rep_cnt = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
-	rvu->rep_cnt = rsp->rep_cnt;
 
-	rvu->rep2pfvf_map = devm_kzalloc(rvu->dev, rvu->rep_cnt *
-					 sizeof(u16), GFP_KERNEL);
-	if (!rvu->rep2pfvf_map)
+	if (rvu->rep2pfvf_map) {
+		rsp->rep_cnt = rvu->rep_cnt;
+		for (rep = 0; rep < rvu->rep_cnt; rep++)
+			rsp->rep_pf_map[rep] = rvu->rep2pfvf_map[rep];
+		mutex_unlock(&rvu->rsrc_lock);
+		return 0;
+	}
+
+	rep_cnt = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs;
+	map = devm_kzalloc(rvu->dev, rep_cnt * sizeof(u16), GFP_KERNEL);
+	if (!map) {
+		mutex_unlock(&rvu->rsrc_lock);
 		return -ENOMEM;
+	}
 
 	for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
 		if (!is_pf_cgxmapped(rvu, pf))
 			continue;
 		pcifunc = rvu_make_pcifunc(rvu->pdev, pf, 0);
-		rvu->rep2pfvf_map[rep] = pcifunc;
+		map[rep] = pcifunc;
 		rsp->rep_pf_map[rep] = pcifunc;
 		rep++;
 		rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvf);
 		for (vf = 0; vf < numvfs; vf++) {
-			rvu->rep2pfvf_map[rep] = pcifunc |
-				((vf + 1) & RVU_PFVF_FUNC_MASK);
-			rsp->rep_pf_map[rep] = rvu->rep2pfvf_map[rep];
+			map[rep] = pcifunc | ((vf + 1) & RVU_PFVF_FUNC_MASK);
+			rsp->rep_pf_map[rep] = map[rep];
 			rep++;
 		}
 	}
+
+	rvu->rep_cnt = rep_cnt;
+	rvu->rep2pfvf_map = map;
+	rsp->rep_cnt = rep_cnt;
+
+	mutex_unlock(&rvu->rsrc_lock);
+
 	return 0;
 }
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
index 0f5d5642d3f7..049aef800739 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c
@@ -399,8 +399,13 @@ 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);
+	if (attrs.switch_id.id_len > MAX_PHYS_ITEM_ID_LEN)
+		return -EINVAL;
+
 	mutex_lock(&priv->mbox.lock);
 	req = otx2_mbox_alloc_msg_esw_cfg(&priv->mbox);
 	if (!req) {
@@ -408,6 +413,8 @@ static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena)
 		return -ENOMEM;
 	}
 	req->ena = ena;
+	req->switch_id_len = attrs.switch_id.id_len;
+	memcpy(req->switch_id, attrs.switch_id.id, req->switch_id_len);
 	otx2_sync_mbox_msg(&priv->mbox);
 	mutex_unlock(&priv->mbox.lock);
 	return 0;
@@ -653,6 +660,10 @@ int rvu_rep_create(struct otx2_nic *priv, struct netlink_ext_ack *extack)
 	int rep_id, err;
 	u16 pcifunc;
 
+	err = rvu_get_rep_cnt(priv);
+	if (err)
+		return err;
+
 	err = rvu_rep_rsrc_init(priv);
 	if (err)
 		return -ENOMEM;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH v2 net-next] octeontx2-af: pass devlink switch id and cache representor map
  2026-09-23  4:58 [PATCH v2 net-next] octeontx2-af: pass devlink switch id and cache representor map Ratheesh Kannoth
@ 2026-09-24  7:18 ` kernel test robot
  0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2026-09-24  7:18 UTC (permalink / raw)
  To: Ratheesh Kannoth, linux-kernel, netdev
  Cc: llvm, oe-kbuild-all, andrew+netdev, davem, edumazet, kuba,
	pabeni, sgoutham, Ratheesh Kannoth

Hi Ratheesh,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]
[also build test ERROR on linus/master v7.3-rc4 next-20260922]
[cannot apply to linux-review/Ratheesh-Kannoth/octeontx2-af-Representor-devlink-id-and-port-mapping/20260918-103021 horms-ipvs/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ratheesh-Kannoth/octeontx2-af-pass-devlink-switch-id-and-cache-representor-map/20260923-102826
base:   net-next/main
patch link:    https://lore.kernel.org/r/20260923045826.1774338-1-rkannoth%40marvell.com
patch subject: [PATCH v2 net-next] octeontx2-af: pass devlink switch id and cache representor map
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20260924/202609241557.82GuIoAK-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260924/202609241557.82GuIoAK-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202609241557.82GuIoAK-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

>> drivers/net/ethernet/marvell/octeontx2/nic/rep.c:663:8: error: call to undeclared function 'rvu_get_rep_cnt'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
     663 |         err = rvu_get_rep_cnt(priv);
         |               ^
>> drivers/net/ethernet/marvell/octeontx2/nic/rep.c:744:12: warning: no previous prototype for function 'rvu_get_rep_cnt' [-Wmissing-prototypes]
     744 | static int rvu_get_rep_cnt(struct otx2_nic *priv)
         |            ^
   drivers/net/ethernet/marvell/octeontx2/nic/rep.c:744:8: note: declare 'static' if the function is not intended to be used outside of this translation unit
     744 | static int rvu_get_rep_cnt(struct otx2_nic *priv)
         |        ^
   1 warning and 1 error generated.


vim +/rvu_get_rep_cnt +663 drivers/net/ethernet/marvell/octeontx2/nic/rep.c

   654	
   655	int rvu_rep_create(struct otx2_nic *priv, struct netlink_ext_ack *extack)
   656	{
   657		int rep_cnt = priv->rep_cnt;
   658		struct net_device *ndev;
   659		struct rep_dev *rep;
   660		int rep_id, err;
   661		u16 pcifunc;
   662	
 > 663		err = rvu_get_rep_cnt(priv);
   664		if (err)
   665			return err;
   666	
   667		err = rvu_rep_rsrc_init(priv);
   668		if (err)
   669			return -ENOMEM;
   670	
   671		priv->reps = kzalloc_objs(struct rep_dev *, rep_cnt);
   672		if (!priv->reps)
   673			return -ENOMEM;
   674	
   675		for (rep_id = 0; rep_id < rep_cnt; rep_id++) {
   676			ndev = alloc_etherdev(sizeof(*rep));
   677			if (!ndev) {
   678				NL_SET_ERR_MSG_FMT_MOD(extack,
   679						       "PFVF representor:%d creation failed",
   680						       rep_id);
   681				err = -ENOMEM;
   682				goto exit;
   683			}
   684	
   685			rep = netdev_priv(ndev);
   686			priv->reps[rep_id] = rep;
   687			rep->mdev = priv;
   688			rep->netdev = ndev;
   689			rep->rep_id = rep_id;
   690	
   691			ndev->min_mtu = OTX2_MIN_MTU;
   692			ndev->max_mtu = priv->hw.max_mtu;
   693			ndev->netdev_ops = &rvu_rep_netdev_ops;
   694			pcifunc = priv->rep_pf_map[rep_id];
   695			rep->pcifunc = pcifunc;
   696	
   697			snprintf(ndev->name, sizeof(ndev->name), "Rpf%dvf%d",
   698				 rvu_get_pf(priv->pdev, pcifunc),
   699				 (pcifunc & RVU_PFVF_FUNC_MASK));
   700	
   701			ndev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
   702				       NETIF_F_IPV6_CSUM | NETIF_F_RXHASH |
   703				       NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6);
   704	
   705			ndev->hw_features |= NETIF_F_HW_TC;
   706			ndev->features |= ndev->hw_features;
   707			eth_hw_addr_random(ndev);
   708			err = rvu_rep_devlink_port_register(rep);
   709			if (err) {
   710				free_netdev(ndev);
   711				goto exit;
   712			}
   713	
   714			SET_NETDEV_DEVLINK_PORT(ndev, &rep->dl_port);
   715			err = register_netdev(ndev);
   716			if (err) {
   717				NL_SET_ERR_MSG_MOD(extack,
   718						   "PFVF representor registration failed");
   719				rvu_rep_devlink_port_unregister(rep);
   720				free_netdev(ndev);
   721				goto exit;
   722			}
   723	
   724			INIT_DELAYED_WORK(&rep->stats_wrk, rvu_rep_get_stats);
   725		}
   726		err = rvu_rep_napi_init(priv, extack);
   727		if (err)
   728			goto exit;
   729	
   730		rvu_eswitch_config(priv, true);
   731		return 0;
   732	exit:
   733		while (--rep_id >= 0) {
   734			rep = priv->reps[rep_id];
   735			unregister_netdev(rep->netdev);
   736			rvu_rep_devlink_port_unregister(rep);
   737			free_netdev(rep->netdev);
   738		}
   739		kfree(priv->reps);
   740		rvu_rep_rsrc_free(priv);
   741		return err;
   742	}
   743	
 > 744	static int rvu_get_rep_cnt(struct otx2_nic *priv)
   745	{
   746		struct get_rep_cnt_rsp *rsp;
   747		struct mbox_msghdr *msghdr;
   748		struct msg_req *req;
   749		int err, rep;
   750	
   751		mutex_lock(&priv->mbox.lock);
   752		req = otx2_mbox_alloc_msg_get_rep_cnt(&priv->mbox);
   753		if (!req) {
   754			mutex_unlock(&priv->mbox.lock);
   755			return -ENOMEM;
   756		}
   757		err = otx2_sync_mbox_msg(&priv->mbox);
   758		if (err)
   759			goto exit;
   760	
   761		msghdr = otx2_mbox_get_rsp(&priv->mbox.mbox, 0, &req->hdr);
   762		if (IS_ERR(msghdr)) {
   763			err = PTR_ERR(msghdr);
   764			goto exit;
   765		}
   766	
   767		rsp = (struct get_rep_cnt_rsp *)msghdr;
   768		priv->hw.tx_queues = rsp->rep_cnt;
   769		priv->hw.rx_queues = rsp->rep_cnt;
   770		priv->rep_cnt = rsp->rep_cnt;
   771		for (rep = 0; rep < priv->rep_cnt; rep++)
   772			priv->rep_pf_map[rep] = rsp->rep_pf_map[rep];
   773	
   774	exit:
   775		mutex_unlock(&priv->mbox.lock);
   776		return err;
   777	}
   778	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-24  7:18 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-23  4:58 [PATCH v2 net-next] octeontx2-af: pass devlink switch id and cache representor map Ratheesh Kannoth
2026-09-24  7:18 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®