net: add rte prefix to ether structures
[dpdk.git] / drivers / net / mlx5 / mlx5.c
index 9ff50df..2798e0e 100644 (file)
 /* Allow L3 VXLAN flow creation. */
 #define MLX5_L3_VXLAN_EN "l3_vxlan_en"
 
+/* Activate DV E-Switch flow steering. */
+#define MLX5_DV_ESW_EN "dv_esw_en"
+
 /* Activate DV flow steering. */
 #define MLX5_DV_FLOW_EN "dv_flow_en"
 
@@ -144,6 +147,7 @@ struct mlx5_dev_spawn_data {
        struct mlx5_switch_info info; /**< Switch information. */
        struct ibv_device *ibv_dev; /**< Associated IB device. */
        struct rte_eth_dev *eth_dev; /**< Associated Ethernet device. */
+       struct rte_pci_device *pci_dev; /**< Backend PCI device. */
 };
 
 static LIST_HEAD(, mlx5_ibv_shared) mlx5_ibv_list = LIST_HEAD_INITIALIZER();
@@ -222,6 +226,7 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn)
                sizeof(sh->ibdev_name));
        strncpy(sh->ibdev_path, sh->ctx->device->ibdev_path,
                sizeof(sh->ibdev_path));
+       sh->pci_dev = spawn->pci_dev;
        pthread_mutex_init(&sh->intr_mutex, NULL);
        /*
         * Setting port_id to max unallowed value means
@@ -236,6 +241,22 @@ mlx5_alloc_shared_ibctx(const struct mlx5_dev_spawn_data *spawn)
                err = ENOMEM;
                goto error;
        }
+       /*
+        * Once the device is added to the list of memory event
+        * callback, its global MR cache table cannot be expanded
+        * on the fly because of deadlock. If it overflows, lookup
+        * should be done by searching MR list linearly, which is slow.
+        *
+        * At this point the device is not added to the memory
+        * event list yet, context is just being created.
+        */
+       err = mlx5_mr_btree_init(&sh->mr.cache,
+                                MLX5_MR_BTREE_CACHE_N * 2,
+                                sh->pci_dev->device.numa_node);
+       if (err) {
+               err = rte_errno;
+               goto error;
+       }
        LIST_INSERT_HEAD(&mlx5_ibv_list, sh, next);
 exit:
        pthread_mutex_unlock(&mlx5_ibv_list_mutex);
@@ -283,6 +304,8 @@ mlx5_free_shared_ibctx(struct mlx5_ibv_shared *sh)
        assert(rte_eal_process_type() == RTE_PROC_PRIMARY);
        if (--sh->refcnt)
                goto exit;
+       /* Release created Memory Regions. */
+       mlx5_mr_release(sh);
        LIST_REMOVE(sh, next);
        /*
         *  Ensure there is no async event handler installed.
@@ -319,7 +342,7 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
 #ifdef HAVE_MLX5DV_DR
        struct mlx5_ibv_shared *sh = priv->sh;
        int err = 0;
-       void *ns;
+       void *domain;
 
        assert(sh);
        if (sh->dv_refcnt) {
@@ -329,34 +352,57 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
                return 0;
        }
        /* Reference counter is zero, we should initialize structures. */
-       ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_INGRESS_BYPASS);
-       if (!ns) {
-               DRV_LOG(ERR, "ingress mlx5dv_dr_create_ns failed");
+       domain = mlx5_glue->dr_create_domain(sh->ctx,
+                                            MLX5DV_DR_DOMAIN_TYPE_NIC_RX);
+       if (!domain) {
+               DRV_LOG(ERR, "ingress mlx5dv_dr_create_domain failed");
                err = errno;
                goto error;
        }
-       sh->rx_ns = ns;
-       ns = mlx5dv_dr_create_ns(sh->ctx, MLX5DV_DR_NS_DOMAIN_EGRESS_BYPASS);
-       if (!ns) {
-               DRV_LOG(ERR, "egress mlx5dv_dr_create_ns failed");
+       sh->rx_domain = domain;
+       domain = mlx5_glue->dr_create_domain(sh->ctx,
+                                            MLX5DV_DR_DOMAIN_TYPE_NIC_TX);
+       if (!domain) {
+               DRV_LOG(ERR, "egress mlx5dv_dr_create_domain failed");
                err = errno;
                goto error;
        }
        pthread_mutex_init(&sh->dv_mutex, NULL);
-       sh->tx_ns = ns;
+       sh->tx_domain = domain;
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+       if (priv->config.dv_esw_en) {
+               domain  = mlx5_glue->dr_create_domain
+                       (sh->ctx, MLX5DV_DR_DOMAIN_TYPE_FDB);
+               if (!domain) {
+                       DRV_LOG(ERR, "FDB mlx5dv_dr_create_domain failed");
+                       err = errno;
+                       goto error;
+               }
+               sh->fdb_domain = domain;
+               sh->esw_drop_action = mlx5_glue->dr_create_flow_action_drop();
+       }
+#endif
        sh->dv_refcnt++;
        priv->dr_shared = 1;
        return 0;
 
 error:
        /* Rollback the created objects. */
-       if (sh->rx_ns) {
-               mlx5dv_dr_destroy_ns(sh->rx_ns);
-               sh->rx_ns = NULL;
+       if (sh->rx_domain) {
+               mlx5_glue->dr_destroy_domain(sh->rx_domain);
+               sh->rx_domain = NULL;
+       }
+       if (sh->tx_domain) {
+               mlx5_glue->dr_destroy_domain(sh->tx_domain);
+               sh->tx_domain = NULL;
        }
-       if (sh->tx_ns) {
-               mlx5dv_dr_destroy_ns(sh->tx_ns);
-               sh->tx_ns = NULL;
+       if (sh->fdb_domain) {
+               mlx5_glue->dr_destroy_domain(sh->fdb_domain);
+               sh->fdb_domain = NULL;
+       }
+       if (sh->esw_drop_action) {
+               mlx5_glue->destroy_flow_action(sh->esw_drop_action);
+               sh->esw_drop_action = NULL;
        }
        return err;
 #else
@@ -385,14 +431,24 @@ mlx5_free_shared_dr(struct mlx5_priv *priv)
        assert(sh->dv_refcnt);
        if (sh->dv_refcnt && --sh->dv_refcnt)
                return;
-       if (sh->rx_ns) {
-               mlx5dv_dr_destroy_ns(sh->rx_ns);
-               sh->rx_ns = NULL;
+       if (sh->rx_domain) {
+               mlx5_glue->dr_destroy_domain(sh->rx_domain);
+               sh->rx_domain = NULL;
+       }
+       if (sh->tx_domain) {
+               mlx5_glue->dr_destroy_domain(sh->tx_domain);
+               sh->tx_domain = NULL;
+       }
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+       if (sh->fdb_domain) {
+               mlx5_glue->dr_destroy_domain(sh->fdb_domain);
+               sh->fdb_domain = NULL;
        }
-       if (sh->tx_ns) {
-               mlx5dv_dr_destroy_ns(sh->tx_ns);
-               sh->tx_ns = NULL;
+       if (sh->esw_drop_action) {
+               mlx5_glue->destroy_flow_action(sh->esw_drop_action);
+               sh->esw_drop_action = NULL;
        }
+#endif
        pthread_mutex_destroy(&sh->dv_mutex);
 #else
        (void)priv;
@@ -615,8 +671,11 @@ mlx5_dev_close(struct rte_eth_dev *dev)
        }
        mlx5_proc_priv_uninit(dev);
        mlx5_mprq_free_mp(dev);
-       mlx5_mr_release(dev);
+       /* Remove from memory callback device list. */
+       rte_rwlock_write_lock(&mlx5_shared_data->mem_event_rwlock);
        assert(priv->sh);
+       LIST_REMOVE(priv->sh, mem_event_cb);
+       rte_rwlock_write_unlock(&mlx5_shared_data->mem_event_rwlock);
        mlx5_free_shared_dr(priv);
        if (priv->rss_conf.rss_key != NULL)
                rte_free(priv->rss_conf.rss_key);
@@ -861,6 +920,8 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
                config->l3_vxlan_en = !!tmp;
        } else if (strcmp(MLX5_VF_NL_EN, key) == 0) {
                config->vf_nl_en = !!tmp;
+       } else if (strcmp(MLX5_DV_ESW_EN, key) == 0) {
+               config->dv_esw_en = !!tmp;
        } else if (strcmp(MLX5_DV_FLOW_EN, key) == 0) {
                config->dv_flow_en = !!tmp;
        } else if (strcmp(MLX5_MR_EXT_MEMSEG_EN, key) == 0) {
@@ -905,6 +966,7 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
                MLX5_RX_VEC_EN,
                MLX5_L3_VXLAN_EN,
                MLX5_VF_NL_EN,
+               MLX5_DV_ESW_EN,
                MLX5_DV_FLOW_EN,
                MLX5_MR_EXT_MEMSEG_EN,
                MLX5_REPRESENTOR,
@@ -1025,7 +1087,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
        unsigned int mprq_max_stride_size_n = 0;
        unsigned int mprq_min_stride_num_n = 0;
        unsigned int mprq_max_stride_num_n = 0;
-       struct ether_addr mac;
+       struct rte_ether_addr mac;
        char name[RTE_ETH_NAME_MAX_LEN];
        int own_domain_id = 0;
        uint16_t port_id;
@@ -1458,11 +1520,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
                        priv->tcf_context = NULL;
                }
        }
-       if (config.dv_flow_en) {
-               err = mlx5_alloc_shared_dr(priv);
-               if (err)
-                       goto error;
-       }
        TAILQ_INIT(&priv->flows);
        TAILQ_INIT(&priv->ctrl_flows);
        /* Hint libmlx5 to use PMD allocator for data plane resources */
@@ -1484,8 +1541,29 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
         * Verbs context returned by ibv_open_device().
         */
        mlx5_link_update(eth_dev, 0);
+#ifdef HAVE_IBV_DEVX_OBJ
+       if (config.devx) {
+               err = mlx5_devx_cmd_query_hca_attr(sh->ctx, &config.hca_attr);
+               if (err) {
+                       err = -err;
+                       goto error;
+               }
+       }
+#endif
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+       if (!(config.hca_attr.eswitch_manager && config.dv_flow_en &&
+             (switch_info->representor || switch_info->master)))
+               config.dv_esw_en = 0;
+#else
+       config.dv_esw_en = 0;
+#endif
        /* Store device configuration on private structure. */
        priv->config = config;
+       if (config.dv_flow_en) {
+               err = mlx5_alloc_shared_dr(priv);
+               if (err)
+                       goto error;
+       }
        /* Supported Verbs flow priority number detection. */
        err = mlx5_flow_discover_priorities(eth_dev);
        if (err < 0) {
@@ -1493,23 +1571,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
                goto error;
        }
        priv->config.flow_prio = err;
-       /*
-        * Once the device is added to the list of memory event
-        * callback, its global MR cache table cannot be expanded
-        * on the fly because of deadlock. If it overflows, lookup
-        * should be done by searching MR list linearly, which is slow.
-        */
-       err = mlx5_mr_btree_init(&priv->mr.cache,
-                                MLX5_MR_BTREE_CACHE_N * 2,
-                                eth_dev->device->numa_node);
-       if (err) {
-               err = rte_errno;
-               goto error;
-       }
        /* Add device to memory callback list. */
        rte_rwlock_write_lock(&mlx5_shared_data->mem_event_rwlock);
        LIST_INSERT_HEAD(&mlx5_shared_data->mem_event_cb_list,
-                        priv, mem_event_cb);
+                        sh, mem_event_cb);
        rte_rwlock_write_unlock(&mlx5_shared_data->mem_event_rwlock);
        return eth_dev;
 error:
@@ -1702,6 +1767,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                        list[ns].ibv_port = i;
                        list[ns].ibv_dev = ibv_match[0];
                        list[ns].eth_dev = NULL;
+                       list[ns].pci_dev = pci_dev;
                        list[ns].ifindex = mlx5_nl_ifindex
                                        (nl_rdma, list[ns].ibv_dev->name, i);
                        if (!list[ns].ifindex) {
@@ -1768,6 +1834,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                        list[ns].ibv_port = 1;
                        list[ns].ibv_dev = ibv_match[i];
                        list[ns].eth_dev = NULL;
+                       list[ns].pci_dev = pci_dev;
                        list[ns].ifindex = 0;
                        if (nl_rdma >= 0)
                                list[ns].ifindex = mlx5_nl_ifindex
@@ -1876,6 +1943,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                        .max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN,
                        .min_rxqs_num = MLX5_MPRQ_MIN_RXQS,
                },
+               .dv_esw_en = 1,
        };
        /* Device specific configuration. */
        switch (pci_dev->id.device_id) {
@@ -1964,14 +2032,9 @@ static int
 mlx5_pci_remove(struct rte_pci_device *pci_dev)
 {
        uint16_t port_id;
-       struct rte_eth_dev *port;
 
-       for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
-               port = &rte_eth_devices[port_id];
-               if (port->state != RTE_ETH_DEV_UNUSED &&
-                               port->device == &pci_dev->device)
-                       rte_eth_dev_close(port_id);
-       }
+       RTE_ETH_FOREACH_DEV_OF(port_id, &pci_dev->device)
+               rte_eth_dev_close(port_id);
        return 0;
 }