From: Dariusz Sosnowski <dsosnowski@nvidia.com>
To: Viacheslav Ovsiienko <viacheslavo@nvidia.com>,
Bing Zhao <bingz@nvidia.com>, Ori Kam <orika@nvidia.com>,
Suanming Mou <suanmingm@nvidia.com>,
Matan Azrad <matan@nvidia.com>
Cc: <dev@dpdk.org>
Subject: [PATCH 12/13] net/mlx5: allow associated devices
Date: Mon, 26 Oct 2026 17:27:08 +0100 [thread overview]
Message-ID: <20261026162709.1292958-13-dsosnowski@nvidia.com> (raw)
In-Reply-To: <20261026162709.1292958-1-dsosnowski@nvidia.com>
Allow probing mlx5 networking devices using multiple rte_device's,
which are associated with single mlx5 common device.
This requires a few changes in probing:
- When going through list of IB devices to check for MPESW
or bond setups, use owner IB device from common device,
not the probed device.
- When preparing data for a list of spawned ports,
keep "probed device" and "owner device" separate.
- Use the name of "probed device" when
ethdev port name is constructed.
- Any device related to VIRTUAL devlink port,
which is not an E-Switch owner should be accepted
as a representor port. Representor devarg is not required.
Patch also extends mlx5_nl_check_switch_info() to query
the flavour of related devlink port if phys_port_name is not available.
As of this patch, probing through associated devices
is only allowed for PCI devices.
Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
---
drivers/common/mlx5/linux/mlx5_nl.c | 95 +++++++++++++++++++++++-
drivers/common/mlx5/linux/mlx5_nl.h | 4 +-
drivers/common/mlx5/mlx5_common.h | 5 ++
drivers/net/mlx5/linux/mlx5_os.c | 109 +++++++++++++++++++++-------
drivers/net/mlx5/mlx5.c | 3 +-
drivers/net/mlx5/mlx5.h | 1 +
drivers/net/mlx5/mlx5_ethdev.c | 13 +++-
drivers/net/mlx5/mlx5_mac.c | 6 +-
8 files changed, 199 insertions(+), 37 deletions(-)
diff --git a/drivers/common/mlx5/linux/mlx5_nl.c b/drivers/common/mlx5/linux/mlx5_nl.c
index e57007831c..6a22476a15 100644
--- a/drivers/common/mlx5/linux/mlx5_nl.c
+++ b/drivers/common/mlx5/linux/mlx5_nl.c
@@ -1620,7 +1620,7 @@ mlx5_nl_devlink_port_info_get_cb(struct nlmsghdr *nh, void *arg)
return -rte_errno;
}
-static int __rte_unused
+static int
mlx5_nl_devlink_port_info_get(int nl, int family, struct mlx5_devlink_port_info *info)
{
struct nlmsghdr *nlh;
@@ -1668,6 +1668,8 @@ mlx5_nl_devlink_port_info_get(int nl, int family, struct mlx5_devlink_port_info
* Analyze gathered port parameters via Netlink to recognize master
* and representor devices for E-Switch configuration.
*
+ * @param[in] parent_dev_match
+ * True if underlying netdev's parent device is the same as for IB device.
* @param[in] num_vf_set
* flag of presence of number of VFs port attribute.
* @param[inout] switch_info
@@ -1679,7 +1681,8 @@ mlx5_nl_devlink_port_info_get(int nl, int family, struct mlx5_devlink_port_info
* recognized parameters (if any).
*/
static void
-mlx5_nl_check_switch_info(bool num_vf_set,
+mlx5_nl_check_switch_info(bool parent_dev_match,
+ bool num_vf_set,
struct mlx5_switch_info *switch_info)
{
switch (switch_info->name_type) {
@@ -1714,12 +1717,67 @@ mlx5_nl_check_switch_info(bool num_vf_set,
/* New representors naming schema. */
switch_info->representor = 1;
break;
+ case MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL:
+ switch_info->master = parent_dev_match;
+ switch_info->representor = !parent_dev_match;
+ break;
}
}
+static void
+check_virtual_port(struct mlx5_netdev_info *netdev_info,
+ struct mlx5_switch_info *switch_info)
+{
+ struct mlx5_devlink_port_info devlink_port_info = {
+ .bus_name = netdev_info->devlink_port_bus_name,
+ .dev_name = netdev_info->devlink_port_dev_name,
+ .index = netdev_info->devlink_port_index,
+ };
+ int nl;
+ int family;
+ int ret = 0;
+
+ nl = mlx5_nl_init(NETLINK_GENERIC, 0);
+ if (nl < 0) {
+ DRV_LOG(DEBUG, "Unable to open NETLINK_GENERIC socket");
+ return;
+ }
+
+ family = mlx5_nl_devlink_family_id_get(nl);
+ if (family < 0) {
+ DRV_LOG(DEBUG, "Unable to query devlink genetlink family ID");
+ goto exit_end;
+ }
+
+ if (mlx5_netdev_info_has_devlink_port(netdev_info)) {
+ ret = mlx5_nl_devlink_port_info_get(nl, family, &devlink_port_info);
+ } else {
+ /*
+ * TODO: Kernel too old. Devlink port must be found by dumping all ports
+ * and matching by netdev_ifindex. Until this is done, log unsupported.
+ */
+ DRV_LOG(DEBUG, "Kernel does not expose IFLA_DEVLINK_PORT");
+ ret = -ENOTSUP;
+ }
+
+ if (ret < 0) {
+ DRV_LOG(DEBUG, "Unable to query devlink port flavour");
+ goto exit_end;
+ }
+
+ if ((devlink_port_info.flags & MLX5_DEVLINK_PORT_INFO_FLAG_FLAVOUR) &&
+ devlink_port_info.flavour == MLX5_DEVLINK_PORT_FLAVOUR_VIRTUAL)
+ switch_info->name_type = MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL;
+
+exit_end:
+ close(nl);
+}
+
/**
* Get switch information associated with network interface.
*
+ * @param cdev
+ * Pointer to common device.
* @param nl
* Netlink socket of the ROUTE kind (NETLINK_ROUTE).
* @param ifindex
@@ -1732,12 +1790,15 @@ mlx5_nl_check_switch_info(bool num_vf_set,
*/
RTE_EXPORT_INTERNAL_SYMBOL(mlx5_nl_switch_info)
int
-mlx5_nl_switch_info(int nl, unsigned int ifindex,
+mlx5_nl_switch_info(struct mlx5_common_device *cdev,
+ int nl,
+ unsigned int ifindex,
struct mlx5_switch_info *info)
{
struct mlx5_netdev_info netdev_info = {
.ifindex = ifindex,
};
+ bool parent_dev_match;
bool num_vf_set;
int ret;
@@ -1756,7 +1817,33 @@ mlx5_nl_switch_info(int nl, unsigned int ifindex,
if (netdev_info.flags & MLX5_NETDEV_INFO_FLAG_PHYS_SWITCH_ID) {
info->switch_id = netdev_info.phys_switch_id;
- mlx5_nl_check_switch_info(num_vf_set, info);
+
+ if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_NOTSET)
+ check_virtual_port(&netdev_info, info);
+
+ /* Port type could be updated to virtual. Recheck. */
+ if (info->name_type == MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL) {
+ if (!(netdev_info.flags & MLX5_NETDEV_INFO_FLAG_PARENT_DEV_NAME) ||
+ !(netdev_info.flags & MLX5_NETDEV_INFO_FLAG_PARENT_DEV_BUS_NAME)) {
+ DRV_LOG(ERR, "ifindex %u cannot get parent dev", ifindex);
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
+
+ strlcpy(info->parent_dev_bus_name, netdev_info.parent_dev_bus_name,
+ sizeof(info->parent_dev_bus_name));
+ strlcpy(info->parent_dev_name, netdev_info.parent_dev_name,
+ sizeof(info->parent_dev_name));
+
+ parent_dev_match = mlx5_dev_matches(cdev->dev,
+ netdev_info.parent_dev_bus_name,
+ netdev_info.parent_dev_name);
+ } else {
+ /* Irrelevant for other port flavours. */
+ parent_dev_match = false;
+ }
+
+ mlx5_nl_check_switch_info(parent_dev_match, num_vf_set, info);
}
if (info->master && info->representor) {
diff --git a/drivers/common/mlx5/linux/mlx5_nl.h b/drivers/common/mlx5/linux/mlx5_nl.h
index 0a9aab6610..7663864e56 100644
--- a/drivers/common/mlx5/linux/mlx5_nl.h
+++ b/drivers/common/mlx5/linux/mlx5_nl.h
@@ -144,7 +144,9 @@ __rte_internal
int mlx5_nl_vf_mac_addr_modify(int nlsk_fd, unsigned int iface_idx,
struct rte_ether_addr *mac, int vf_index);
__rte_internal
-int mlx5_nl_switch_info(int nl, unsigned int ifindex,
+int mlx5_nl_switch_info(struct mlx5_common_device *cdev,
+ int nl,
+ unsigned int ifindex,
struct mlx5_switch_info *info);
__rte_internal
diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h
index 548f0c887b..fb73b3a038 100644
--- a/drivers/common/mlx5/mlx5_common.h
+++ b/drivers/common/mlx5/mlx5_common.h
@@ -152,6 +152,7 @@ enum mlx5_nl_phys_port_name_type {
MLX5_PHYS_PORT_NAME_TYPE_PFVF, /* pf0vf0, kernel ver >= 5.0 */
MLX5_PHYS_PORT_NAME_TYPE_PFHPF, /* pf0, kernel ver >= 5.7, HPF rep */
MLX5_PHYS_PORT_NAME_TYPE_PFSF, /* pf0sf0, kernel ver >= 5.0 */
+ MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL, /* Virtual devlink port. */
MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN, /* Unrecognized. */
};
@@ -169,6 +170,8 @@ struct mlx5_dev_info {
struct mlx5_port_nl_info *port_info;
};
+#define MLX5_SWITCH_INFO_PARENT_DEV_NAME_MAX (128)
+
/** Switch information returned by mlx5_nl_switch_info(). */
struct mlx5_switch_info {
uint32_t master:1; /**< Master device. */
@@ -179,6 +182,8 @@ struct mlx5_switch_info {
int32_t port_name; /**< Representor port name. */
int32_t mpesw_owner; /**< MPESW owner port number. */
uint64_t switch_id; /**< Switch identifier. */
+ char parent_dev_bus_name[MLX5_SWITCH_INFO_PARENT_DEV_NAME_MAX];
+ char parent_dev_name[MLX5_SWITCH_INFO_PARENT_DEV_NAME_MAX];
};
/* CQE status. */
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 1b1b1bb013..83c9774443 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1122,6 +1122,9 @@ build_port_name(struct rte_device *dpdk_dev,
written += ret;
if (written >= (int)name_sz)
return written;
+ } else if (spawn->info.name_type == MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL) {
+ /* All relevant information was put in the name. Finish here. */
+ goto end;
} else if (spawn->info.representor) {
/*
* If port is a representor, then switchdev has been enabled.
@@ -1249,6 +1252,13 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
bool ignore_ctrl_num = eth_da->nb_mh_controllers == 0 ||
switch_info->name_type == MLX5_PHYS_PORT_NAME_TYPE_UPLINK;
+ /*
+ * Representor on virtual devlink port always match.
+ * Probing logic filters out unwanted ports before mlx5_dev_spawn() is reached.
+ */
+ if (switch_info->name_type == MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL)
+ return true;
+
switch (eth_da->type) {
case RTE_ETH_REPRESENTOR_PF:
if (switch_info->name_type != MLX5_PHYS_PORT_NAME_TYPE_UPLINK) {
@@ -1299,8 +1309,6 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
/**
* Spawn an Ethernet device from Verbs information.
*
- * @param dpdk_dev
- * Backing DPDK device.
* @param spawn
* Verbs device parameters (name, port, switch_info) to spawn.
* @param eth_da
@@ -1316,11 +1324,11 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
* EEXIST: device is already spawned
*/
static struct rte_eth_dev *
-mlx5_dev_spawn(struct rte_device *dpdk_dev,
- struct mlx5_dev_spawn_data *spawn,
+mlx5_dev_spawn(struct mlx5_dev_spawn_data *spawn,
struct rte_eth_devargs *eth_da,
struct mlx5_kvargs_ctrl *mkvlist)
{
+ struct rte_device *dpdk_dev = spawn->dpdk_dev;
const struct mlx5_switch_info *switch_info = &spawn->info;
struct mlx5_dev_ctx_shared *sh = NULL;
struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP };
@@ -2477,6 +2485,7 @@ calc_nb_uplinks_hpfs(struct ibv_device **ibv_match,
*/
static int
mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
+ struct rte_device *dev,
struct rte_eth_devargs *req_eth_da,
uint16_t owner_id, struct mlx5_kvargs_ctrl *mkvlist)
{
@@ -2511,13 +2520,22 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
* >= 0 - MPESW device. Value is the port index of the MPESW owner.
*/
int mpesw = MLX5_MPESW_PORT_INVALID;
- struct rte_pci_device *pci_dev = RTE_BUS_DEVICE(cdev->dev, *pci_dev);
+ struct rte_pci_device *owner_pci_dev;
struct mlx5_dev_spawn_data *list = NULL;
struct rte_eth_devargs eth_da = *req_eth_da;
- struct rte_pci_addr owner_pci = pci_dev->addr; /* Owner PF. */
+ struct rte_pci_addr owner_pci; /* Owner PF. */
struct mlx5_bond_info bond_info;
int ret = -1;
+ if (!mlx5_dev_is_pci(cdev->dev)) {
+ DRV_LOG(ERR, "Owner device is not PCI: dev %s owner %s",
+ dev->name, cdev->dev->name);
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
+ owner_pci_dev = RTE_BUS_DEVICE(cdev->dev, *owner_pci_dev);
+ owner_pci = owner_pci_dev->addr;
+
errno = 0;
ibv_list = mlx5_glue->get_device_list(&ret);
if (!ibv_list) {
@@ -2699,8 +2717,9 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
list[ns].phys_port = i;
list[ns].phys_dev_name = ibv_match[0]->name;
list[ns].eth_dev = NULL;
- list[ns].pci_dev = pci_dev;
+ list[ns].pci_dev = owner_pci_dev;
list[ns].cdev = cdev;
+ list[ns].dpdk_dev = dev;
list[ns].pf_bond = bd;
list[ns].mpesw_port = MLX5_MPESW_PORT_INVALID;
list[ns].ifindex = mlx5_nl_ifindex(nl_rdma,
@@ -2718,7 +2737,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
}
ret = -1;
if (nl_route >= 0)
- ret = mlx5_nl_switch_info(nl_route,
+ ret = mlx5_nl_switch_info(cdev, nl_route,
list[ns].ifindex,
&list[ns].info);
if (ret || (!list[ns].info.representor &&
@@ -2731,6 +2750,11 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
ret = mlx5_sysfs_switch_info(list[ns].ifindex,
&list[ns].info);
}
+ /* Allow usage of associated devices only for VIRTUAL devlink ports. */
+ if (!ret &&
+ list[ns].info.name_type != MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL &&
+ cdev->dev != dev)
+ continue;
if (!ret && bd >= 0) {
switch (list[ns].info.name_type) {
case MLX5_PHYS_PORT_NAME_TYPE_UPLINK:
@@ -2790,13 +2814,26 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
list[ns].info.mpesw_owner = mpesw;
ns++;
break;
+ case MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL:
+ list[ns].mpesw_port = mpesw;
+ list[ns].info.mpesw_owner = mpesw;
+ /* Spawn the device if and only if it matches. */
+ if (mlx5_dev_matches(list[ns].dpdk_dev,
+ list[ns].info.parent_dev_bus_name,
+ list[ns].info.parent_dev_name))
+ ns++;
+ break;
default:
break;
}
continue;
}
- if (!ret && (list[ns].info.representor ^
- list[ns].info.master))
+ if (!ret && list[ns].info.name_type == MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL) {
+ if (mlx5_dev_matches(list[ns].dpdk_dev,
+ list[ns].info.parent_dev_bus_name,
+ list[ns].info.parent_dev_name))
+ ns++;
+ } else if (!ret && (list[ns].info.representor ^ list[ns].info.master))
ns++;
}
} else {
@@ -2824,8 +2861,9 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
list[ns].phys_port = 1;
list[ns].phys_dev_name = ibv_match[i]->name;
list[ns].eth_dev = NULL;
- list[ns].pci_dev = pci_dev;
+ list[ns].pci_dev = owner_pci_dev;
list[ns].cdev = cdev;
+ list[ns].dpdk_dev = dev;
list[ns].pf_bond = -1;
list[ns].mpesw_port = MLX5_MPESW_PORT_INVALID;
list[ns].ifindex = 0;
@@ -2872,7 +2910,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
}
ret = -1;
if (nl_route >= 0)
- ret = mlx5_nl_switch_info(nl_route,
+ ret = mlx5_nl_switch_info(cdev, nl_route,
list[ns].ifindex,
&list[ns].info);
if (ret || (!list[ns].info.representor &&
@@ -2885,6 +2923,11 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
ret = mlx5_sysfs_switch_info(list[ns].ifindex,
&list[ns].info);
}
+ /* Allow usage of associated devices only for VIRTUAL devlink ports. */
+ if (!ret &&
+ list[ns].info.name_type != MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL &&
+ cdev->dev != dev)
+ continue;
if (!ret && (list[ns].info.representor ^
list[ns].info.master)) {
ns++;
@@ -2921,7 +2964,12 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
list[0].info.representor = 0;
}
}
- MLX5_ASSERT(ns);
+ if (ns == 0) {
+ DRV_LOG(ERR, "Unable to match any IB port to probed device");
+ rte_errno = ENOENT;
+ ret = -rte_errno;
+ goto exit;
+ }
/* Calculate number of uplinks and host PFs for each matched IB device. */
calc_nb_uplinks_hpfs(ibv_match, nd, list, ns);
/*
@@ -2934,7 +2982,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
if (eth_da.nb_ports == 0 && ns > 0) {
if (list[0].pf_bond >= 0 && list[0].info.representor)
DRV_LOG(WARNING, "Representor on Bonding device should use pf#vf# syntax: %s",
- pci_dev->device.devargs->args);
+ dev->devargs->args);
eth_da.nb_ports = 1;
eth_da.ports[0] = list[0].info.port_name;
}
@@ -2946,8 +2994,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
for (i = 0; i != ns; ++i) {
uint32_t restore;
- list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], ð_da,
- mkvlist);
+ list[i].eth_dev = mlx5_dev_spawn(&list[i], ð_da, mkvlist);
if (!list[i].eth_dev) {
if (rte_errno != EBUSY && rte_errno != EEXIST)
break;
@@ -2955,7 +3002,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
continue;
}
restore = list[i].eth_dev->data->dev_flags;
- rte_eth_copy_pci_info(list[i].eth_dev, pci_dev);
+ rte_eth_copy_pci_info(list[i].eth_dev, list[i].pci_dev);
/**
* Each representor has a dedicated interrupts vector.
* rte_eth_copy_pci_info() assigns PF interrupts handle to
@@ -3070,21 +3117,22 @@ mlx5_os_parse_eth_devargs(struct rte_device *dev,
*/
static int
mlx5_os_pci_probe(struct mlx5_common_device *cdev,
+ struct rte_device *dev,
struct mlx5_kvargs_ctrl *mkvlist)
{
- struct rte_pci_device *pci_dev = RTE_BUS_DEVICE(cdev->dev, *pci_dev);
+ struct rte_pci_device *pci_dev = RTE_BUS_DEVICE(dev, *pci_dev);
struct rte_eth_devargs eth_da = { .nb_ports = 0 };
int ret = 0;
uint16_t p;
- ret = mlx5_os_parse_eth_devargs(cdev->dev, ð_da);
+ ret = mlx5_os_parse_eth_devargs(dev, ð_da);
if (ret != 0)
return ret;
if (eth_da.nb_ports > 0) {
/* Iterate all port if devargs pf is range: "pf[0-1]vf[...]". */
for (p = 0; p < eth_da.nb_ports; p++) {
- ret = mlx5_os_pci_probe_pf(cdev, ð_da,
+ ret = mlx5_os_pci_probe_pf(cdev, dev, ð_da,
eth_da.ports[p], mkvlist);
if (ret) {
DRV_LOG(INFO, "Probe of PCI device " PCI_PRI_FMT " "
@@ -3098,7 +3146,7 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev,
}
}
} else {
- ret = mlx5_os_pci_probe_pf(cdev, ð_da, 0, mkvlist);
+ ret = mlx5_os_pci_probe_pf(cdev, dev, ð_da, 0, mkvlist);
}
return ret;
}
@@ -3106,6 +3154,7 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev,
/* Probe a single SF device on auxiliary bus, no representor support. */
static int
mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev,
+ struct rte_device *dev,
struct mlx5_kvargs_ctrl *mkvlist)
{
struct rte_eth_devargs eth_da = { .nb_ports = 0 };
@@ -3113,11 +3162,16 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev,
.pf_bond = -1,
.mpesw_port = MLX5_MPESW_PORT_INVALID,
};
- struct rte_device *dev = cdev->dev;
struct rte_auxiliary_device *adev = RTE_BUS_DEVICE(dev, *adev);
struct rte_eth_dev *eth_dev;
int ret = 0;
+ if (cdev->dev != dev) {
+ DRV_LOG(ERR, "Invalid device %s used to probe common device %s",
+ dev->name, cdev->dev->name);
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
/* Parse ethdev devargs. */
ret = mlx5_os_parse_eth_devargs(dev, ð_da);
if (ret != 0)
@@ -3133,8 +3187,9 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev,
}
spawn.ifindex = ret;
spawn.cdev = cdev;
+ spawn.dpdk_dev = dev;
/* Spawn device. */
- eth_dev = mlx5_dev_spawn(dev, &spawn, ð_da, mkvlist);
+ eth_dev = mlx5_dev_spawn(&spawn, ð_da, mkvlist);
if (eth_dev == NULL)
return -rte_errno;
/* Post create. */
@@ -3165,7 +3220,7 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev,
*/
int
mlx5_os_net_probe(struct mlx5_common_device *cdev,
- struct rte_device *dev __rte_unused,
+ struct rte_device *dev,
struct mlx5_kvargs_ctrl *mkvlist)
{
int ret;
@@ -3184,10 +3239,10 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev,
strerror(rte_errno));
return -rte_errno;
}
- if (mlx5_dev_is_pci(cdev->dev))
- return mlx5_os_pci_probe(cdev, mkvlist);
+ if (mlx5_dev_is_pci(dev))
+ return mlx5_os_pci_probe(cdev, dev, mkvlist);
else
- return mlx5_os_auxiliary_probe(cdev, mkvlist);
+ return mlx5_os_auxiliary_probe(cdev, dev, mkvlist);
}
/**
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 615b2ff943..9dc3402e22 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -3881,7 +3881,7 @@ mlx5_net_remove(struct mlx5_common_device *cdev)
uint16_t port_id;
int ret = 0;
- RTE_ETH_FOREACH_DEV_OF(port_id, cdev->dev) {
+ MLX5_ETH_FOREACH_SIBLING(port_id, cdev) {
/*
* mlx5_dev_close() is not registered to secondary process,
* call the close function explicitly for secondary process.
@@ -3999,6 +3999,7 @@ static struct mlx5_class_driver mlx5_net_driver = {
.probe = mlx5_os_net_probe,
.remove = mlx5_net_remove,
.probe_again = 1,
+ .probe_associated = 1,
.intr_lsc = 1,
.intr_rmv = 1,
};
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index e4ebdd4c2f..de969c0b2e 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -234,6 +234,7 @@ struct mlx5_dev_spawn_data {
const char *phys_dev_name; /**< Name of physical device. */
struct rte_eth_dev *eth_dev; /**< Associated Ethernet device. */
struct rte_pci_device *pci_dev; /**< Backend PCI device. */
+ struct rte_device *dpdk_dev; /**< Backend DPDK device. */
struct mlx5_common_device *cdev; /**< Backend common device. */
struct mlx5_bond_info *bond_info;
};
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index f41724725c..115b67ffdf 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -472,6 +472,8 @@ mlx5_representor_id_encode(const struct mlx5_switch_info *info,
type = RTE_ETH_REPRESENTOR_PF;
pf = info->mpesw_owner;
break;
+ case MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL:
+ return UINT16_MAX;
case MLX5_PHYS_PORT_NAME_TYPE_PFSF:
type = RTE_ETH_REPRESENTOR_SF;
break;
@@ -507,10 +509,13 @@ mlx5_representor_info_count_one(struct mlx5_priv *priv)
case MLX5_PHYS_PORT_NAME_TYPE_PFSF:
/* FALLTHROUGH */
case MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN:
- /* FALLTHROUGH */
- default:
return 1;
+ case MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL:
+ return 0;
}
+
+ /* Suppress "control reaches end of non-void function" warning without adding "default". */
+ return 0;
}
static unsigned int
@@ -606,6 +611,10 @@ mlx5_representor_info_fill_one(struct mlx5_priv *priv,
range->id_end = range->id_base;
snprintf(range->name, sizeof(range->name), "pf%dvf", range->pf);
break;
+ case MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL:
+ /* Rejected by mlx5_representor_info_count_one() */
+ MLX5_ASSERT(false);
+ break;
}
info->nb_ranges += count;
diff --git a/drivers/net/mlx5/mlx5_mac.c b/drivers/net/mlx5/mlx5_mac.c
index 8cbaaf67dd..2ee8580f14 100644
--- a/drivers/net/mlx5/mlx5_mac.c
+++ b/drivers/net/mlx5/mlx5_mac.c
@@ -177,10 +177,12 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
* need to skip the special cases:
* - HPF on BlueField,
* - SF representors,
- * - uplink ports when running in MPESW mode.
+ * - uplink ports when running in MPESW mode,
+ * - VIRTUAL switch ports (nested E-Switch).
*/
if (priv->representor && !mlx5_is_hpf(dev) && !mlx5_is_sf_repr(dev) &&
- !priv->mpesw_uplink) {
+ !priv->mpesw_uplink &&
+ priv->port_info.type != MLX5_PHYS_PORT_NAME_TYPE_VIRTUAL) {
DRV_LOG(DEBUG, "VF represented by port %u setting primary MAC address",
dev->data->port_id);
if (priv->pf_bond >= 0) {
--
2.43.0
next prev parent reply other threads:[~2026-10-26 16:29 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 16:26 [PATCH 00/13] net/mlx5: support nested E-Switch Dariusz Sosnowski
2026-10-26 16:26 ` [PATCH 01/13] common/mlx5: rework IB port number query Dariusz Sosnowski
2026-10-26 16:26 ` [PATCH 02/13] common/mlx5: allow ifindex query without cache Dariusz Sosnowski
2026-10-26 16:26 ` [PATCH 03/13] common/mlx5: separate netdev info from switch info Dariusz Sosnowski
2026-10-26 16:27 ` [PATCH 04/13] common/mlx5: query parent device over Netlink Dariusz Sosnowski
2026-10-26 16:27 ` [PATCH 05/13] common/mlx5: add check for auxiliary device Dariusz Sosnowski
2026-10-26 16:27 ` [PATCH 06/13] common/mlx5: gather associated devices Dariusz Sosnowski
2026-10-26 16:27 ` [PATCH 07/13] common/mlx5: always use EAL device for probing Dariusz Sosnowski
2026-10-26 16:27 ` [PATCH 08/13] common/mlx5: query devlink port for netdevs Dariusz Sosnowski
2026-10-26 16:27 ` [PATCH 09/13] common/mlx5: get devlink port by port index Dariusz Sosnowski
2026-10-26 16:27 ` [PATCH 10/13] common/mlx5: add check for managed device Dariusz Sosnowski
2026-10-26 16:27 ` [PATCH 11/13] net/mlx5: add sibling device iteration macro Dariusz Sosnowski
2026-10-26 16:27 ` Dariusz Sosnowski [this message]
2026-10-26 16:27 ` [PATCH 13/13] net/mlx5: allow multiport auxiliary device probe Dariusz Sosnowski
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=20261026162709.1292958-13-dsosnowski@nvidia.com \
--to=dsosnowski@nvidia.com \
--cc=bingz@nvidia.com \
--cc=dev@dpdk.org \
--cc=matan@nvidia.com \
--cc=orika@nvidia.com \
--cc=suanmingm@nvidia.com \
--cc=viacheslavo@nvidia.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