bus/pci: remove useless link dependency on ethdev
[dpdk.git] / drivers / net / mlx5 / mlx5.c
index 444d185..7e0d7ec 100644 (file)
@@ -926,7 +926,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)
                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;
 
@@ -1517,6 +1517,53 @@ mlx5_release_dbr(struct rte_eth_dev *dev, uint32_t umem_id, uint64_t offset)
        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.
  *
@@ -1798,7 +1845,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
         */
        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);
@@ -1856,7 +1903,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
         * 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;
 
@@ -1885,6 +1932,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
                        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",
@@ -2731,17 +2781,33 @@ exit:
        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++;
        }