@@ -881,11 +881,15 @@ Driver options
For instance, to probe VF port representors 0 through 2::
- representor=vf[0-2]
+ <PCI_BDF>,representor=vf[0-2]
To probe SF port representors 0 through 2::
- representor=sf[0-2]
+ <PCI_BDF>,representor=sf[0-2]
+
+ To probe VF port representors 0 through 2 on both PFs of bonding device::
+
+ <Primary_PCI_BDF>,representor=pf[0,1]vf[0-2]
- ``max_dump_files_num`` parameter [int]
@@ -676,6 +676,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
struct mlx5dv_context dv_attr = { .comp_mask = 0 };
struct rte_eth_dev *eth_dev = NULL;
struct mlx5_priv *priv = NULL;
+ uint16_t repr_id = -1;
int err = 0;
unsigned int hw_padding = 0;
unsigned int mps;
@@ -693,11 +694,19 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
char name[RTE_ETH_NAME_MAX_LEN];
int own_domain_id = 0;
uint16_t port_id;
- unsigned int i;
+ unsigned int c = 0, p = 0, f = 0;
#ifdef HAVE_MLX5DV_DR_DEVX_PORT
struct mlx5dv_devx_port devx_port = { .comp_mask = 0 };
#endif
+ if (switch_info->representor)
+ repr_id = rte_eth_representor_id_encode(
+ switch_info->ctrl_num,
+ spawn->pf_bond >= 0 ? switch_info->pf_num : 0,
+ switch_info->name_type ==
+ MLX5_PHYS_PORT_NAME_TYPE_PFSF ?
+ RTE_ETH_REPRESENTOR_SF : RTE_ETH_REPRESENTOR_VF,
+ switch_info->port_name);
/* Determine if this port representor is supposed to be spawned. */
if (switch_info->representor && dpdk_dev->devargs) {
switch (eth_da->type) {
@@ -729,51 +738,27 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
dpdk_dev->devargs->args);
return NULL;
}
- /* Check controller ID: */
- for (i = 0; i < eth_da->nb_mh_controllers; ++i)
- if (eth_da->mh_controllers[i] ==
- (uint16_t)switch_info->ctrl_num)
- break;
- if (eth_da->nb_mh_controllers &&
- i == eth_da->nb_mh_controllers) {
- rte_errno = EBUSY;
- return NULL;
- }
- /* Check SF/VF ID: */
- for (i = 0; i < eth_da->nb_representor_ports; ++i)
- if (eth_da->representor_ports[i] ==
- (uint16_t)switch_info->port_name)
- break;
- if (eth_da->type != RTE_ETH_REPRESENTOR_PF &&
- i == eth_da->nb_representor_ports) {
- rte_errno = EBUSY;
- return NULL;
- }
- /* Check PF ID. Check after repr port to avoid warning flood. */
- if (spawn->pf_bond >= 0) {
- for (i = 0; i < eth_da->nb_ports; ++i)
- if (eth_da->ports[i] ==
- (uint16_t)switch_info->pf_num)
- break;
- if (eth_da->nb_ports && i == eth_da->nb_ports) {
- /* For backward compatibility, bonding
- * representor syntax supported with limitation,
- * device iterator won't find it:
- * <PF1_BDF>,representor=#
- */
- if (switch_info->pf_num > 0 &&
- eth_da->ports[0] == 0) {
- DRV_LOG(WARNING, "Representor on Bonding PF should use pf#vf# format: %s",
- dpdk_dev->devargs->args);
- } else {
- rte_errno = EBUSY;
- return NULL;
+ /* Check representor ID: */
+ for (c = 0; c < eth_da->nb_mh_controllers; ++c) {
+ for (p = 0; p < eth_da->nb_ports; ++p) {
+ for (f = 0; f < eth_da->nb_representor_ports;
+ ++f) {
+ uint16_t repr;
+
+ repr = rte_eth_representor_id_encode(
+ eth_da->mh_controllers[c],
+ eth_da->ports[p],
+ eth_da->type,
+ eth_da->representor_ports[f]);
+
+ if (repr_id == repr)
+ break;
}
}
- } else if (eth_da->nb_ports > 1 || eth_da->ports[0]) {
- rte_errno = EINVAL;
- DRV_LOG(ERR, "PF id not supported by non-bond device: %s",
- dpdk_dev->devargs->args);
+ }
+ if (c == eth_da->nb_mh_controllers && p == eth_da->nb_ports &&
+ f == eth_da->nb_representor_ports) {
+ rte_errno = EBUSY;
return NULL;
}
}
@@ -790,17 +775,23 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
switch_info->port_name);
} else {
/* Bonding device. */
- if (!switch_info->representor)
+ if (!switch_info->representor) {
snprintf(name, sizeof(name), "%s_%s",
dpdk_dev->name,
mlx5_os_get_dev_device_name(spawn->phys_dev));
- else
- snprintf(name, sizeof(name), "%s_%s_representor_%s%u",
- dpdk_dev->name,
- mlx5_os_get_dev_device_name(spawn->phys_dev),
- switch_info->name_type ==
- MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf",
- switch_info->port_name);
+ } else {
+ err = snprintf(name, sizeof(name), "%s_%s_representor_c%dpf%d%s%u",
+ dpdk_dev->name,
+ mlx5_os_get_dev_device_name(spawn->phys_dev),
+ switch_info->ctrl_num,
+ switch_info->pf_num,
+ switch_info->name_type ==
+ MLX5_PHYS_PORT_NAME_TYPE_PFSF ? "sf" : "vf",
+ switch_info->port_name);
+ if (err >= (int)sizeof(name))
+ DRV_LOG(WARNING, "representor name overflow %s",
+ name);
+ }
}
/* check if the device is already spawned */
if (rte_eth_dev_get_port_by_name(name, &port_id) == 0) {
@@ -1079,11 +1070,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
priv->vport_id = switch_info->representor ?
switch_info->port_name + 1 : -1;
#endif
- /* representor_id field keeps the unmodified VF index. */
- priv->representor_id = switch_info->representor ?
- rte_eth_representor_id_encode(0, 0, RTE_ETH_REPRESENTOR_VF,
- switch_info->port_name) :
- -1;
+ priv->representor_id = repr_id;
/*
* Look for sibling devices in order to reuse their switch domain
* if any, otherwise allocate one.
@@ -1704,9 +1691,11 @@ mlx5_dev_spawn_data_cmp(const void *a, const void *b)
* @param[in] ibv_dev
* Pointer to Infiniband device structure.
* @param[in] pci_dev
- * Pointer to PCI device structure to match PCI address.
+ * Pointer to master PCI Address structure to match PCI address.
* @param[in] nl_rdma
* Netlink RDMA group socket handle.
+ * @param[in] owner
+ * Rerepsentor owner PF index.
*
* @return
* negative value if no bonding device found, otherwise
@@ -1714,8 +1703,8 @@ mlx5_dev_spawn_data_cmp(const void *a, const void *b)
*/
static int
mlx5_device_bond_pci_match(const struct ibv_device *ibv_dev,
- const struct rte_pci_device *pci_dev,
- int nl_rdma)
+ const struct rte_pci_addr *pci_dev,
+ int nl_rdma, uint16_t owner)
{
char ifname[IF_NAMESIZE + 1];
unsigned int ifindex;
@@ -1772,10 +1761,10 @@ mlx5_device_bond_pci_match(const struct ibv_device *ibv_dev,
" for netdev \"%s\"", ifname);
continue;
}
- if (pci_dev->addr.domain != pci_addr.domain ||
- pci_dev->addr.bus != pci_addr.bus ||
- pci_dev->addr.devid != pci_addr.devid ||
- pci_dev->addr.function != pci_addr.function)
+ if (pci_dev->domain != pci_addr.domain ||
+ pci_dev->bus != pci_addr.bus ||
+ pci_dev->devid != pci_addr.devid ||
+ pci_dev->function + owner != pci_addr.function)
continue;
/* Slave interface PCI address match found. */
fclose(file);
@@ -1843,7 +1832,8 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct mlx5_dev_config dev_config;
unsigned int dev_config_vf;
struct rte_eth_devargs eth_da = { .type = RTE_ETH_REPRESENTOR_NONE };
- int ret;
+ struct rte_pci_addr probe_addr = pci_dev->addr;
+ int ret = -1;
if (rte_eal_process_type() == RTE_PROC_PRIMARY)
mlx5_pmd_socket_init();
@@ -1895,7 +1885,8 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
DRV_LOG(DEBUG, "checking device \"%s\"", ibv_list[ret]->name);
bd = mlx5_device_bond_pci_match
- (ibv_list[ret], pci_dev, nl_rdma);
+ (ibv_list[ret], &probe_addr, nl_rdma,
+ eth_da.ports[0]);
if (bd >= 0) {
/*
* Bonding device detected. Only one match is allowed,
@@ -1912,6 +1903,9 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
ret = -rte_errno;
goto exit;
}
+ /* Amend master pci address if owner PF specified. */
+ if (eth_da.nb_representor_ports)
+ probe_addr.function += eth_da.ports[0];
DRV_LOG(INFO, "PCI information matches for"
" slave %d bonding device \"%s\"",
bd, ibv_list[ret]->name);
@@ -1921,10 +1915,10 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
if (mlx5_dev_to_pci_addr
(ibv_list[ret]->ibdev_path, &pci_addr))
continue;
- if (pci_dev->addr.domain != pci_addr.domain ||
- pci_dev->addr.bus != pci_addr.bus ||
- pci_dev->addr.devid != pci_addr.devid ||
- pci_dev->addr.function != pci_addr.function)
+ if (probe_addr.domain != pci_addr.domain ||
+ probe_addr.bus != pci_addr.bus ||
+ probe_addr.devid != pci_addr.devid ||
+ probe_addr.function != pci_addr.function)
continue;
DRV_LOG(INFO, "PCI information matches for device \"%s\"",
ibv_list[ret]->name);
@@ -1936,8 +1930,8 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
DRV_LOG(WARNING,
"no Verbs device matches PCI device " PCI_PRI_FMT ","
" are kernel drivers loaded?",
- pci_dev->addr.domain, pci_dev->addr.bus,
- pci_dev->addr.devid, pci_dev->addr.function);
+ probe_addr.domain, probe_addr.bus,
+ probe_addr.devid, probe_addr.function);
rte_errno = ENOENT;
ret = -rte_errno;
goto exit;
@@ -2202,6 +2196,24 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
dev_config_vf = 0;
break;
}
+ if (pci_dev->device.devargs) {
+ /* Set devargs default values. */
+ if (eth_da.nb_mh_controllers == 0) {
+ eth_da.nb_mh_controllers = 1;
+ eth_da.mh_controllers[0] = 0;
+ }
+ 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);
+ eth_da.nb_ports = 1;
+ eth_da.ports[0] = list[0].info.pf_num;
+ }
+ if (eth_da.nb_representor_ports == 0) {
+ eth_da.nb_representor_ports = 1;
+ eth_da.representor_ports[0] = 0;
+ }
+ }
for (i = 0; i != ns; ++i) {
uint32_t restore;
@@ -2243,8 +2255,8 @@ mlx5_os_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
DRV_LOG(ERR,
"probe of PCI device " PCI_PRI_FMT " aborted after"
" encountering an error: %s",
- pci_dev->addr.domain, pci_dev->addr.bus,
- pci_dev->addr.devid, pci_dev->addr.function,
+ probe_addr.domain, probe_addr.bus,
+ probe_addr.devid, probe_addr.function,
strerror(rte_errno));
ret = -rte_errno;
/* Roll back. */
@@ -358,6 +358,28 @@ static const struct mlx5_indexed_pool_config mlx5_ipool_cfg[] = {
#define MLX5_FLOW_TABLE_HLIST_ARRAY_SIZE 4096
+/**
+ * Decide whether representor ID is a HPF(host PF) port on BF2.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ *
+ * @return
+ * Non-zero if HPF, otherwise 0.
+ */
+int
+mlx5_is_hpf(struct rte_eth_dev *dev)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ enum rte_eth_representor_type type;
+ uint16_t port;
+
+ port = rte_eth_representor_id_parse(priv->representor_id,
+ NULL, NULL, &type);
+ return priv->representor && type == RTE_ETH_REPRESENTOR_VF &&
+ port == rte_eth_representor_id_parse(-1, NULL, NULL, NULL);
+}
+
/**
* Initialize the ASO aging management structure.
*
@@ -945,7 +945,7 @@ struct mlx5_priv {
uint16_t vport_id; /* Associated VF vport index (if any). */
uint32_t vport_meta_tag; /* Used for vport index match ove VF LAG. */
uint32_t vport_meta_mask; /* Used for vport index field match mask. */
- int32_t representor_id; /* Port representor identifier. */
+ int32_t representor_id; /* RTE_ETH_REPR(), -1 if not a representor. */
int32_t pf_bond; /* >=0 means PF index in bonding configuration. */
unsigned int if_index; /* Associated kernel network device index. */
uint32_t bond_ifindex; /**< Bond interface index. */
@@ -1019,6 +1019,7 @@ int mlx5_udp_tunnel_port_add(struct rte_eth_dev *dev,
struct rte_eth_udp_tunnel *udp_tunnel);
uint16_t mlx5_eth_find_next(uint16_t port_id, struct rte_pci_device *pci_dev);
int mlx5_dev_close(struct rte_eth_dev *dev);
+int mlx5_is_hpf(struct rte_eth_dev *dev);
void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
/* Macro to iterate over all valid ports for mlx5 driver. */
@@ -48,10 +48,6 @@
#define MLX5_PMD_SOFT_COUNTERS 1
#endif
-/* Switch port ID parameters for bonding configurations. */
-#define MLX5_PORT_ID_BONDING_PF_MASK 0xf
-#define MLX5_PORT_ID_BONDING_PF_SHIFT 12
-
/* Alarm timeout. */
#define MLX5_ALARM_TIMEOUT_US 100000
@@ -330,33 +330,6 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
if (priv->representor) {
uint16_t port_id;
- if (priv->pf_bond >= 0) {
- /*
- * Switch port ID is opaque value with driver defined
- * format. Push the PF index in bonding configurations
- * in upper four bits of port ID. If we get too many
- * representors (more than 4K) or PFs (more than 15)
- * this approach must be reconsidered.
- */
- /* Switch port ID for VF representors: 0 - 0xFFE */
- if ((info->switch_info.port_id != 0xffff &&
- info->switch_info.port_id >=
- ((1 << MLX5_PORT_ID_BONDING_PF_SHIFT) - 1)) ||
- priv->pf_bond > MLX5_PORT_ID_BONDING_PF_MASK) {
- DRV_LOG(ERR, "can't update switch port ID"
- " for bonding device");
- MLX5_ASSERT(false);
- return -ENODEV;
- }
- /*
- * Switch port ID for Host PF representor
- * (representor_id is -1) , set to 0xFFF
- */
- if (info->switch_info.port_id == 0xffff)
- info->switch_info.port_id = 0xfff;
- info->switch_info.port_id |=
- priv->pf_bond << MLX5_PORT_ID_BONDING_PF_SHIFT;
- }
MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) {
struct mlx5_priv *opriv =
rte_eth_devices[port_id].data->dev_private;
@@ -159,7 +159,7 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
* Configuring the VF instead of its representor,
* need to skip the special case of HPF on Bluefield.
*/
- if (priv->representor && priv->representor_id >= 0) {
+ if (priv->representor && !mlx5_is_hpf(dev)) {
DRV_LOG(DEBUG, "VF represented by port %u setting primary MAC address",
dev->data->port_id);
RTE_ETH_FOREACH_DEV_SIBLING(port_id, dev->data->port_id) {
@@ -169,7 +169,11 @@ mlx5_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
return mlx5_os_vf_mac_addr_modify
(priv,
mlx5_ifindex(&rte_eth_devices[port_id]),
- mac_addr, priv->representor_id);
+ mac_addr,
+ rte_eth_representor_id_parse(
+ priv->representor_id,
+ NULL, NULL, NULL)
+ );
}
}
rte_errno = -ENOTSUP;