crypto/mlx5: add WQE set initialization
[dpdk.git] / drivers / net / mlx5 / linux / mlx5_os.c
index be22d9c..aa5210f 100644 (file)
@@ -50,8 +50,6 @@
 #include "mlx5_nl.h"
 #include "mlx5_devx.h"
 
-#define MLX5_TAGS_HLIST_ARRAY_SIZE 8192
-
 #ifndef HAVE_IBV_MLX5_MOD_MPW
 #define MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED (1 << 2)
 #define MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW (1 << 3)
@@ -69,6 +67,44 @@ static rte_spinlock_t mlx5_shared_data_lock = RTE_SPINLOCK_INITIALIZER;
 /* Process local data for secondary processes. */
 static struct mlx5_local_data mlx5_local_data;
 
+/* rte flow indexed pool configuration. */
+static struct mlx5_indexed_pool_config icfg[] = {
+       {
+               .size = sizeof(struct rte_flow),
+               .trunk_size = 64,
+               .need_lock = 1,
+               .release_mem_en = 0,
+               .malloc = mlx5_malloc,
+               .free = mlx5_free,
+               .per_core_cache = 0,
+               .type = "ctl_flow_ipool",
+       },
+       {
+               .size = sizeof(struct rte_flow),
+               .trunk_size = 64,
+               .grow_trunk = 3,
+               .grow_shift = 2,
+               .need_lock = 1,
+               .release_mem_en = 0,
+               .malloc = mlx5_malloc,
+               .free = mlx5_free,
+               .per_core_cache = 1 << 14,
+               .type = "rte_flow_ipool",
+       },
+       {
+               .size = sizeof(struct rte_flow),
+               .trunk_size = 64,
+               .grow_trunk = 3,
+               .grow_shift = 2,
+               .need_lock = 1,
+               .release_mem_en = 0,
+               .malloc = mlx5_malloc,
+               .free = mlx5_free,
+               .per_core_cache = 0,
+               .type = "mcp_flow_ipool",
+       },
+};
+
 /**
  * Set the completion channel file descriptor interrupt as non-blocking.
  *
@@ -193,6 +229,79 @@ mlx5_alloc_verbs_buf(size_t size, void *data)
        return ret;
 }
 
+/**
+ * Detect misc5 support or not
+ *
+ * @param[in] priv
+ *   Device private data pointer
+ */
+#ifdef HAVE_MLX5DV_DR
+static void
+__mlx5_discovery_misc5_cap(struct mlx5_priv *priv)
+{
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+       /* Dummy VxLAN matcher to detect rdma-core misc5 cap
+        * Case: IPv4--->UDP--->VxLAN--->vni
+        */
+       void *tbl;
+       struct mlx5_flow_dv_match_params matcher_mask;
+       void *match_m;
+       void *matcher;
+       void *headers_m;
+       void *misc5_m;
+       uint32_t *tunnel_header_m;
+       struct mlx5dv_flow_matcher_attr dv_attr;
+
+       memset(&matcher_mask, 0, sizeof(matcher_mask));
+       matcher_mask.size = sizeof(matcher_mask.buf);
+       match_m = matcher_mask.buf;
+       headers_m = MLX5_ADDR_OF(fte_match_param, match_m, outer_headers);
+       misc5_m = MLX5_ADDR_OF(fte_match_param,
+                              match_m, misc_parameters_5);
+       tunnel_header_m = (uint32_t *)
+                               MLX5_ADDR_OF(fte_match_set_misc5,
+                               misc5_m, tunnel_header_1);
+       MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_protocol, 0xff);
+       MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_version, 4);
+       MLX5_SET(fte_match_set_lyr_2_4, headers_m, udp_dport, 0xffff);
+       *tunnel_header_m = 0xffffff;
+
+       tbl = mlx5_glue->dr_create_flow_tbl(priv->sh->rx_domain, 1);
+       if (!tbl) {
+               DRV_LOG(INFO, "No SW steering support");
+               return;
+       }
+       dv_attr.type = IBV_FLOW_ATTR_NORMAL,
+       dv_attr.match_mask = (void *)&matcher_mask,
+       dv_attr.match_criteria_enable =
+                       (1 << MLX5_MATCH_CRITERIA_ENABLE_OUTER_BIT) |
+                       (1 << MLX5_MATCH_CRITERIA_ENABLE_MISC5_BIT);
+       dv_attr.priority = 3;
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+       void *misc2_m;
+       if (priv->config.dv_esw_en) {
+               /* FDB enabled reg_c_0 */
+               dv_attr.match_criteria_enable |=
+                               (1 << MLX5_MATCH_CRITERIA_ENABLE_MISC2_BIT);
+               misc2_m = MLX5_ADDR_OF(fte_match_param,
+                                      match_m, misc_parameters_2);
+               MLX5_SET(fte_match_set_misc2, misc2_m,
+                        metadata_reg_c_0, 0xffff);
+       }
+#endif
+       matcher = mlx5_glue->dv_create_flow_matcher(priv->sh->ctx,
+                                                   &dv_attr, tbl);
+       if (matcher) {
+               priv->sh->misc5_cap = 1;
+               mlx5_glue->dv_destroy_flow_matcher(matcher);
+       }
+       mlx5_glue->dr_destroy_flow_tbl(tbl);
+#else
+       RTE_SET_USED(priv);
+#endif
+}
+#endif
+
 /**
  * Verbs callback to free a memory.
  *
@@ -223,7 +332,7 @@ static int
 mlx5_alloc_shared_dr(struct mlx5_priv *priv)
 {
        struct mlx5_dev_ctx_shared *sh = priv->sh;
-       char s[MLX5_HLIST_NAMESIZE] __rte_unused;
+       char s[MLX5_NAME_SIZE] __rte_unused;
        int err;
 
        MLX5_ASSERT(sh && sh->refcnt);
@@ -234,70 +343,46 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
                goto error;
        /* The resources below are only valid with DV support. */
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
-       /* Init port id action cache list. */
-       snprintf(s, sizeof(s), "%s_port_id_action_cache", sh->ibdev_name);
-       mlx5_cache_list_init(&sh->port_id_action_list, s, 0, sh,
-                            flow_dv_port_id_create_cb,
-                            flow_dv_port_id_match_cb,
-                            flow_dv_port_id_remove_cb);
-       /* Init push vlan action cache list. */
-       snprintf(s, sizeof(s), "%s_push_vlan_action_cache", sh->ibdev_name);
-       mlx5_cache_list_init(&sh->push_vlan_action_list, s, 0, sh,
-                            flow_dv_push_vlan_create_cb,
-                            flow_dv_push_vlan_match_cb,
-                            flow_dv_push_vlan_remove_cb);
-       /* Init sample action cache list. */
-       snprintf(s, sizeof(s), "%s_sample_action_cache", sh->ibdev_name);
-       mlx5_cache_list_init(&sh->sample_action_list, s, 0, sh,
-                            flow_dv_sample_create_cb,
-                            flow_dv_sample_match_cb,
-                            flow_dv_sample_remove_cb);
-       /* Init dest array action cache list. */
-       snprintf(s, sizeof(s), "%s_dest_array_cache", sh->ibdev_name);
-       mlx5_cache_list_init(&sh->dest_array_list, s, 0, sh,
-                            flow_dv_dest_array_create_cb,
-                            flow_dv_dest_array_match_cb,
-                            flow_dv_dest_array_remove_cb);
-       /* Create tags hash list table. */
-       snprintf(s, sizeof(s), "%s_tags", sh->ibdev_name);
-       sh->tag_table = mlx5_hlist_create(s, MLX5_TAGS_HLIST_ARRAY_SIZE, 0,
-                                         MLX5_HLIST_WRITE_MOST,
-                                         flow_dv_tag_create_cb,
-                                         flow_dv_tag_match_cb,
-                                         flow_dv_tag_remove_cb);
-       if (!sh->tag_table) {
-               DRV_LOG(ERR, "tags with hash creation failed.");
-               err = ENOMEM;
+       /* Init port id action list. */
+       snprintf(s, sizeof(s), "%s_port_id_action_list", sh->ibdev_name);
+       sh->port_id_action_list = mlx5_list_create(s, sh, true,
+                                                  flow_dv_port_id_create_cb,
+                                                  flow_dv_port_id_match_cb,
+                                                  flow_dv_port_id_remove_cb,
+                                                  flow_dv_port_id_clone_cb,
+                                                flow_dv_port_id_clone_free_cb);
+       if (!sh->port_id_action_list)
                goto error;
-       }
-       sh->tag_table->ctx = sh;
-       snprintf(s, sizeof(s), "%s_hdr_modify", sh->ibdev_name);
-       sh->modify_cmds = mlx5_hlist_create(s, MLX5_FLOW_HDR_MODIFY_HTABLE_SZ,
-                                           0, MLX5_HLIST_WRITE_MOST |
-                                           MLX5_HLIST_DIRECT_KEY,
-                                           flow_dv_modify_create_cb,
-                                           flow_dv_modify_match_cb,
-                                           flow_dv_modify_remove_cb);
-       if (!sh->modify_cmds) {
-               DRV_LOG(ERR, "hdr modify hash creation failed");
-               err = ENOMEM;
+       /* Init push vlan action list. */
+       snprintf(s, sizeof(s), "%s_push_vlan_action_list", sh->ibdev_name);
+       sh->push_vlan_action_list = mlx5_list_create(s, sh, true,
+                                                   flow_dv_push_vlan_create_cb,
+                                                   flow_dv_push_vlan_match_cb,
+                                                   flow_dv_push_vlan_remove_cb,
+                                                   flow_dv_push_vlan_clone_cb,
+                                              flow_dv_push_vlan_clone_free_cb);
+       if (!sh->push_vlan_action_list)
                goto error;
-       }
-       sh->modify_cmds->ctx = sh;
-       snprintf(s, sizeof(s), "%s_encaps_decaps", sh->ibdev_name);
-       sh->encaps_decaps = mlx5_hlist_create(s,
-                                             MLX5_FLOW_ENCAP_DECAP_HTABLE_SZ,
-                                             0, MLX5_HLIST_DIRECT_KEY |
-                                             MLX5_HLIST_WRITE_MOST,
-                                             flow_dv_encap_decap_create_cb,
-                                             flow_dv_encap_decap_match_cb,
-                                             flow_dv_encap_decap_remove_cb);
-       if (!sh->encaps_decaps) {
-               DRV_LOG(ERR, "encap decap hash creation failed");
-               err = ENOMEM;
+       /* Init sample action list. */
+       snprintf(s, sizeof(s), "%s_sample_action_list", sh->ibdev_name);
+       sh->sample_action_list = mlx5_list_create(s, sh, true,
+                                                 flow_dv_sample_create_cb,
+                                                 flow_dv_sample_match_cb,
+                                                 flow_dv_sample_remove_cb,
+                                                 flow_dv_sample_clone_cb,
+                                                 flow_dv_sample_clone_free_cb);
+       if (!sh->sample_action_list)
+               goto error;
+       /* Init dest array action list. */
+       snprintf(s, sizeof(s), "%s_dest_array_list", sh->ibdev_name);
+       sh->dest_array_list = mlx5_list_create(s, sh, true,
+                                              flow_dv_dest_array_create_cb,
+                                              flow_dv_dest_array_match_cb,
+                                              flow_dv_dest_array_remove_cb,
+                                              flow_dv_dest_array_clone_cb,
+                                             flow_dv_dest_array_clone_free_cb);
+       if (!sh->dest_array_list)
                goto error;
-       }
-       sh->encaps_decaps->ctx = sh;
 #endif
 #ifdef HAVE_MLX5DV_DR
        void *domain;
@@ -342,7 +427,7 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
                goto error;
        }
 #endif
-       if (!sh->tunnel_hub)
+       if (!sh->tunnel_hub && priv->config.dv_miss_info)
                err = mlx5_alloc_tunnel_hub(sh);
        if (err) {
                DRV_LOG(ERR, "mlx5_alloc_tunnel_hub failed err=%d", err);
@@ -364,6 +449,8 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
                if (sh->fdb_domain)
                        mlx5_glue->dr_allow_duplicate_rules(sh->fdb_domain, 0);
        }
+
+       __mlx5_discovery_misc5_cap(priv);
 #endif /* HAVE_MLX5DV_DR */
        sh->default_miss_action =
                        mlx5_glue->dr_create_flow_action_default_miss();
@@ -410,6 +497,22 @@ error:
                sh->tunnel_hub = NULL;
        }
        mlx5_free_table_hash_list(priv);
+       if (sh->port_id_action_list) {
+               mlx5_list_destroy(sh->port_id_action_list);
+               sh->port_id_action_list = NULL;
+       }
+       if (sh->push_vlan_action_list) {
+               mlx5_list_destroy(sh->push_vlan_action_list);
+               sh->push_vlan_action_list = NULL;
+       }
+       if (sh->sample_action_list) {
+               mlx5_list_destroy(sh->sample_action_list);
+               sh->sample_action_list = NULL;
+       }
+       if (sh->dest_array_list) {
+               mlx5_list_destroy(sh->dest_array_list);
+               sh->dest_array_list = NULL;
+       }
        return err;
 }
 
@@ -471,9 +574,23 @@ mlx5_os_free_shared_dr(struct mlx5_priv *priv)
                mlx5_release_tunnel_hub(sh, priv->dev_port);
                sh->tunnel_hub = NULL;
        }
-       mlx5_cache_list_destroy(&sh->port_id_action_list);
-       mlx5_cache_list_destroy(&sh->push_vlan_action_list);
        mlx5_free_table_hash_list(priv);
+       if (sh->port_id_action_list) {
+               mlx5_list_destroy(sh->port_id_action_list);
+               sh->port_id_action_list = NULL;
+       }
+       if (sh->push_vlan_action_list) {
+               mlx5_list_destroy(sh->push_vlan_action_list);
+               sh->push_vlan_action_list = NULL;
+       }
+       if (sh->sample_action_list) {
+               mlx5_list_destroy(sh->sample_action_list);
+               sh->sample_action_list = NULL;
+       }
+       if (sh->dest_array_list) {
+               mlx5_list_destroy(sh->dest_array_list);
+               sh->dest_array_list = NULL;
+       }
 }
 
 /**
@@ -832,6 +949,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
        int own_domain_id = 0;
        uint16_t port_id;
        struct mlx5_port_info vport_info = { .query_flags = 0 };
+       int i;
 
        /* Determine if this port representor is supposed to be spawned. */
        if (switch_info->representor && dpdk_dev->devargs &&
@@ -1313,6 +1431,8 @@ err_secondary:
                                goto error;
                        }
                }
+               if (config->hca_attr.flow.tunnel_header_0_1)
+                       sh->tunnel_header_0_1 = 1;
 #endif
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO
                if (config->hca_attr.flow_hit_aso &&
@@ -1575,7 +1695,6 @@ err_secondary:
                                      mlx5_ifindex(eth_dev),
                                      eth_dev->data->mac_addrs,
                                      MLX5_MAX_MAC_ADDRESSES);
-       priv->flows = 0;
        priv->ctrl_flows = 0;
        rte_spinlock_init(&priv->flow_list_lock);
        TAILQ_INIT(&priv->flow_meters);
@@ -1611,6 +1730,14 @@ err_secondary:
        mlx5_set_min_inline(spawn, config);
        /* Store device configuration on private structure. */
        priv->config = *config;
+       for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
+               icfg[i].release_mem_en = !!config->reclaim_mode;
+               if (config->reclaim_mode)
+                       icfg[i].per_core_cache = 0;
+               priv->flows[i] = mlx5_ipool_create(&icfg[i]);
+               if (!priv->flows[i])
+                       goto error;
+       }
        /* Create context for virtual machine VLAN workaround. */
        priv->vmwa_context = mlx5_vlan_vmwa_init(eth_dev, spawn->ifindex);
        if (config->dv_flow_en) {
@@ -1667,10 +1794,15 @@ err_secondary:
                        err = ENOTSUP;
                        goto error;
        }
-       mlx5_cache_list_init(&priv->hrxqs, "hrxq", 0, eth_dev,
-                            mlx5_hrxq_create_cb,
-                            mlx5_hrxq_match_cb,
-                            mlx5_hrxq_remove_cb);
+       priv->hrxqs = mlx5_list_create("hrxq", eth_dev, true,
+                                      mlx5_hrxq_create_cb,
+                                      mlx5_hrxq_match_cb,
+                                      mlx5_hrxq_remove_cb,
+                                      mlx5_hrxq_clone_cb,
+                                      mlx5_hrxq_clone_free_cb);
+       if (!priv->hrxqs)
+               goto error;
+       rte_rwlock_init(&priv->ind_tbls_lock);
        /* Query availability of metadata reg_c's. */
        err = mlx5_flow_discover_mreg_c(eth_dev);
        if (err < 0) {
@@ -1695,15 +1827,16 @@ err_secondary:
            priv->sh->dv_regc0_mask) {
                priv->mreg_cp_tbl = mlx5_hlist_create(MLX5_FLOW_MREG_HNAME,
                                                      MLX5_FLOW_MREG_HTABLE_SZ,
-                                                     0, 0,
+                                                     false, true, eth_dev,
                                                      flow_dv_mreg_create_cb,
                                                      flow_dv_mreg_match_cb,
-                                                     flow_dv_mreg_remove_cb);
+                                                     flow_dv_mreg_remove_cb,
+                                                     flow_dv_mreg_clone_cb,
+                                                   flow_dv_mreg_clone_free_cb);
                if (!priv->mreg_cp_tbl) {
                        err = ENOMEM;
                        goto error;
                }
-               priv->mreg_cp_tbl->ctx = eth_dev;
        }
        rte_spinlock_init(&priv->shared_act_sl);
        mlx5_flow_counter_mode_config(eth_dev);
@@ -1728,7 +1861,8 @@ error:
                        mlx5_l3t_destroy(priv->mtr_profile_tbl);
                if (own_domain_id)
                        claim_zero(rte_eth_switch_domain_free(priv->domain_id));
-               mlx5_cache_list_destroy(&priv->hrxqs);
+               if (priv->hrxqs)
+                       mlx5_list_destroy(priv->hrxqs);
                mlx5_free(priv);
                if (eth_dev != NULL)
                        eth_dev->data->dev_private = NULL;