unsigned int c = 0;
uint16_t port_id;
- MLX5_ETH_FOREACH_DEV(port_id) {
+ MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) {
struct mlx5_priv *opriv =
rte_eth_devices[port_id].data->dev_private;
return ret;
}
+/**
+ * Check sibling device configurations.
+ *
+ * Sibling devices sharing the Infiniband device context
+ * should have compatible configurations. This regards
+ * representors and bonding slaves.
+ *
+ * @param priv
+ * Private device descriptor.
+ * @param config
+ * Configuration of the device is going to be created.
+ *
+ * @return
+ * 0 on success, EINVAL otherwise
+ */
+static int
+mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
+ struct mlx5_dev_config *config)
+{
+ struct mlx5_ibv_shared *sh = priv->sh;
+ struct mlx5_dev_config *sh_conf = NULL;
+ uint16_t port_id;
+
+ assert(sh);
+ /* Nothing to compare for the single/first device. */
+ if (sh->refcnt == 1)
+ return 0;
+ /* Find the device with shared context. */
+ MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) {
+ struct mlx5_priv *opriv =
+ rte_eth_devices[port_id].data->dev_private;
+
+ if (opriv && opriv != priv && opriv->sh == sh) {
+ sh_conf = &opriv->config;
+ break;
+ }
+ }
+ if (!sh_conf)
+ return 0;
+ if (sh_conf->dv_flow_en ^ config->dv_flow_en) {
+ DRV_LOG(ERR, "\"dv_flow_en\" configuration mismatch"
+ " for shared %s context", sh->ibdev_name);
+ rte_errno = EINVAL;
+ return rte_errno;
+ }
+ return 0;
+}
/**
* Spawn an Ethernet device from Verbs information.
*
*/
devx_port.comp_mask = MLX5DV_DEVX_PORT_VPORT |
MLX5DV_DEVX_PORT_MATCH_REG_C_0;
- err = mlx5dv_query_devx_port(sh->ctx, spawn->ibv_port, &devx_port);
+ err = mlx5_glue->devx_port_query(sh->ctx, spawn->ibv_port, &devx_port);
if (err) {
DRV_LOG(WARNING, "can't query devx port %d on device %s\n",
spawn->ibv_port, spawn->ibv_dev->name);
* Look for sibling devices in order to reuse their switch domain
* if any, otherwise allocate one.
*/
- MLX5_ETH_FOREACH_DEV(port_id) {
+ MLX5_ETH_FOREACH_DEV(port_id, priv->pci_dev) {
const struct mlx5_priv *opriv =
rte_eth_devices[port_id].data->dev_private;
strerror(rte_errno));
goto error;
}
+ err = mlx5_dev_check_sibling_config(priv, &config);
+ if (err)
+ goto error;
config.hw_csum = !!(sh->device_attr.device_cap_flags_ex &
IBV_DEVICE_RAW_IP_CSUM);
DRV_LOG(DEBUG, "checksum offloading is %ssupported",
return ret;
}
+/**
+ * Look for the ethernet device belonging to mlx5 driver.
+ *
+ * @param[in] port_id
+ * port_id to start looking for device.
+ * @param[in] pci_dev
+ * Pointer to the hint PCI device. When device is being probed
+ * the its siblings (master and preceding representors might
+ * not have assigned driver yet (because the mlx5_pci_probe()
+ * is not completed yet, for this case match on hint PCI
+ * device may be used to detect sibling device.
+ *
+ * @return
+ * port_id of found device, RTE_MAX_ETHPORT if not found.
+ */
uint16_t
-mlx5_eth_find_next(uint16_t port_id)
+mlx5_eth_find_next(uint16_t port_id, struct rte_pci_device *pci_dev)
{
while (port_id < RTE_MAX_ETHPORTS) {
struct rte_eth_dev *dev = &rte_eth_devices[port_id];
if (dev->state != RTE_ETH_DEV_UNUSED &&
dev->device &&
- dev->device->driver &&
- dev->device->driver->name &&
- !strcmp(dev->device->driver->name, MLX5_DRIVER_NAME))
+ (dev->device == &pci_dev->device ||
+ (dev->device->driver &&
+ dev->device->driver->name &&
+ !strcmp(dev->device->driver->name, MLX5_DRIVER_NAME))))
break;
port_id++;
}