crypto/mlx5: add WQE set initialization
[dpdk.git] / drivers / net / mlx5 / mlx5_flow_dv.c
index c9af4cc..996106b 100644 (file)
@@ -311,6 +311,41 @@ mlx5_flow_tunnel_ip_check(const struct rte_flow_item *item __rte_unused,
        }
 }
 
+static inline struct mlx5_hlist *
+flow_dv_hlist_prepare(struct mlx5_dev_ctx_shared *sh, struct mlx5_hlist **phl,
+                    const char *name, uint32_t size, bool direct_key,
+                    bool lcores_share, void *ctx,
+                    mlx5_list_create_cb cb_create,
+                    mlx5_list_match_cb cb_match,
+                    mlx5_list_remove_cb cb_remove,
+                    mlx5_list_clone_cb cb_clone,
+                    mlx5_list_clone_free_cb cb_clone_free)
+{
+       struct mlx5_hlist *hl;
+       struct mlx5_hlist *expected = NULL;
+       char s[MLX5_NAME_SIZE];
+
+       hl = __atomic_load_n(phl, __ATOMIC_SEQ_CST);
+       if (likely(hl))
+               return hl;
+       snprintf(s, sizeof(s), "%s_%s", sh->ibdev_name, name);
+       hl = mlx5_hlist_create(s, size, direct_key, lcores_share,
+                       ctx, cb_create, cb_match, cb_remove, cb_clone,
+                       cb_clone_free);
+       if (!hl) {
+               DRV_LOG(ERR, "%s hash creation failed", name);
+               rte_errno = ENOMEM;
+               return NULL;
+       }
+       if (!__atomic_compare_exchange_n(phl, &expected, hl, false,
+                                        __ATOMIC_SEQ_CST,
+                                        __ATOMIC_SEQ_CST)) {
+               mlx5_hlist_destroy(hl);
+               hl = __atomic_load_n(phl, __ATOMIC_SEQ_CST);
+       }
+       return hl;
+}
+
 /* Update VLAN's VID/PCP based on input rte_flow_action.
  *
  * @param[in] action
@@ -2457,19 +2492,19 @@ flow_dv_validate_item_gtp_psc(const struct rte_flow_item *item,
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 static int
-flow_dv_validate_item_ipv4(const struct rte_flow_item *item,
-                          uint64_t item_flags,
-                          uint64_t last_item,
-                          uint16_t ether_type,
-                          struct rte_flow_error *error)
+flow_dv_validate_item_ipv4(struct rte_eth_dev *dev,
+                          const struct rte_flow_item *item,
+                          uint64_t item_flags, uint64_t last_item,
+                          uint16_t ether_type, struct rte_flow_error *error)
 {
        int ret;
+       struct mlx5_priv *priv = dev->data->dev_private;
        const struct rte_flow_item_ipv4 *spec = item->spec;
        const struct rte_flow_item_ipv4 *last = item->last;
        const struct rte_flow_item_ipv4 *mask = item->mask;
        rte_be16_t fragment_offset_spec = 0;
        rte_be16_t fragment_offset_last = 0;
-       const struct rte_flow_item_ipv4 nic_ipv4_mask = {
+       struct rte_flow_item_ipv4 nic_ipv4_mask = {
                .hdr = {
                        .src_addr = RTE_BE32(0xffffffff),
                        .dst_addr = RTE_BE32(0xffffffff),
@@ -2480,6 +2515,17 @@ flow_dv_validate_item_ipv4(const struct rte_flow_item *item,
                },
        };
 
+       if (mask && (mask->hdr.version_ihl & RTE_IPV4_HDR_IHL_MASK)) {
+               int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
+               bool ihl_cap = !tunnel ? priv->config.hca_attr.outer_ipv4_ihl :
+                              priv->config.hca_attr.inner_ipv4_ihl;
+               if (!ihl_cap)
+                       return rte_flow_error_set(error, ENOTSUP,
+                                                 RTE_FLOW_ERROR_TYPE_ITEM,
+                                                 item,
+                                                 "IPV4 ihl offload not supported");
+               nic_ipv4_mask.hdr.version_ihl = mask->hdr.version_ihl;
+       }
        ret = mlx5_flow_validate_item_ipv4(item, item_flags, last_item,
                                           ether_type, &nic_ipv4_mask,
                                           MLX5_ITEM_RANGE_ACCEPTED, error);
@@ -3730,8 +3776,20 @@ flow_dv_encap_decap_resource_register
                .error = error,
                .data = resource,
        };
+       struct mlx5_hlist *encaps_decaps;
        uint64_t key64;
 
+       encaps_decaps = flow_dv_hlist_prepare(sh, &sh->encaps_decaps,
+                               "encaps_decaps",
+                               MLX5_FLOW_ENCAP_DECAP_HTABLE_SZ,
+                               true, true, sh,
+                               flow_dv_encap_decap_create_cb,
+                               flow_dv_encap_decap_match_cb,
+                               flow_dv_encap_decap_remove_cb,
+                               flow_dv_encap_decap_clone_cb,
+                               flow_dv_encap_decap_clone_free_cb);
+       if (unlikely(!encaps_decaps))
+               return -rte_errno;
        resource->flags = dev_flow->dv.group ? 0 : 1;
        key64 =  __rte_raw_cksum(&encap_decap_key.v32,
                                 sizeof(encap_decap_key.v32), 0);
@@ -3739,7 +3797,7 @@ flow_dv_encap_decap_resource_register
            MLX5DV_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2 &&
            resource->size)
                key64 = __rte_raw_cksum(resource->buf, resource->size, key64);
-       entry = mlx5_hlist_register(sh->encaps_decaps, key64, &ctx);
+       entry = mlx5_hlist_register(encaps_decaps, key64, &ctx);
        if (!entry)
                return -rte_errno;
        resource = container_of(entry, typeof(*resource), entry);
@@ -5361,7 +5419,8 @@ flow_dv_modify_ipool_get(struct mlx5_dev_ctx_shared *sh, uint8_t index)
                       .grow_trunk = 3,
                       .grow_shift = 2,
                       .need_lock = 1,
-                      .release_mem_en = 1,
+                      .release_mem_en = !!sh->reclaim_mode,
+                      .per_core_cache = sh->reclaim_mode ? 0 : (1 << 16),
                       .malloc = mlx5_malloc,
                       .free = mlx5_free,
                       .type = "mlx5_modify_action_resource",
@@ -5744,8 +5803,20 @@ flow_dv_modify_hdr_resource_register
                .error = error,
                .data = resource,
        };
+       struct mlx5_hlist *modify_cmds;
        uint64_t key64;
 
+       modify_cmds = flow_dv_hlist_prepare(sh, &sh->modify_cmds,
+                               "hdr_modify",
+                               MLX5_FLOW_HDR_MODIFY_HTABLE_SZ,
+                               true, false, sh,
+                               flow_dv_modify_create_cb,
+                               flow_dv_modify_match_cb,
+                               flow_dv_modify_remove_cb,
+                               flow_dv_modify_clone_cb,
+                               flow_dv_modify_clone_free_cb);
+       if (unlikely(!modify_cmds))
+               return -rte_errno;
        resource->root = !dev_flow->dv.group;
        if (resource->actions_num > flow_dv_modify_hdr_action_max(dev,
                                                                resource->root))
@@ -5753,7 +5824,7 @@ flow_dv_modify_hdr_resource_register
                                          RTE_FLOW_ERROR_TYPE_ACTION, NULL,
                                          "too many modify header items");
        key64 = __rte_raw_cksum(&resource->ft_type, key_len, 0);
-       entry = mlx5_hlist_register(sh->modify_cmds, key64, &ctx);
+       entry = mlx5_hlist_register(modify_cmds, key64, &ctx);
        if (!entry)
                return -rte_errno;
        resource = container_of(entry, typeof(*resource), entry);
@@ -6936,7 +7007,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                case RTE_FLOW_ITEM_TYPE_IPV4:
                        mlx5_flow_tunnel_ip_check(items, next_protocol,
                                                  &item_flags, &tunnel);
-                       ret = flow_dv_validate_item_ipv4(items, item_flags,
+                       ret = flow_dv_validate_item_ipv4(dev, items, item_flags,
                                                         last_item, ether_type,
                                                         error);
                        if (ret < 0)
@@ -8315,7 +8386,7 @@ flow_dv_translate_item_ipv4(void *matcher, void *key,
        void *headers_v;
        char *l24_m;
        char *l24_v;
-       uint8_t tos;
+       uint8_t tos, ihl_m, ihl_v;
 
        if (inner) {
                headers_m = MLX5_ADDR_OF(fte_match_param, matcher,
@@ -8344,6 +8415,10 @@ flow_dv_translate_item_ipv4(void *matcher, void *key,
        *(uint32_t *)l24_m = ipv4_m->hdr.src_addr;
        *(uint32_t *)l24_v = ipv4_m->hdr.src_addr & ipv4_v->hdr.src_addr;
        tos = ipv4_m->hdr.type_of_service & ipv4_v->hdr.type_of_service;
+       ihl_m = ipv4_m->hdr.version_ihl & RTE_IPV4_HDR_IHL_MASK;
+       ihl_v = ipv4_v->hdr.version_ihl & RTE_IPV4_HDR_IHL_MASK;
+       MLX5_SET(fte_match_set_lyr_2_4, headers_m, ipv4_ihl, ihl_m);
+       MLX5_SET(fte_match_set_lyr_2_4, headers_v, ipv4_ihl, ihl_m & ihl_v);
        MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_ecn,
                 ipv4_m->hdr.type_of_service);
        MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_ecn, tos);
@@ -10600,8 +10675,20 @@ flow_dv_tag_resource_register
                                        .error = error,
                                        .data = &tag_be24,
                                        };
-
-       entry = mlx5_hlist_register(priv->sh->tag_table, tag_be24, &ctx);
+       struct mlx5_hlist *tag_table;
+
+       tag_table = flow_dv_hlist_prepare(priv->sh, &priv->sh->tag_table,
+                                     "tags",
+                                     MLX5_TAGS_HLIST_ARRAY_SIZE,
+                                     false, false, priv->sh,
+                                     flow_dv_tag_create_cb,
+                                     flow_dv_tag_match_cb,
+                                     flow_dv_tag_remove_cb,
+                                     flow_dv_tag_clone_cb,
+                                     flow_dv_tag_clone_free_cb);
+       if (unlikely(!tag_table))
+               return -rte_errno;
+       entry = mlx5_hlist_register(tag_table, tag_be24, &ctx);
        if (entry) {
                resource = container_of(entry, struct mlx5_flow_dv_tag_resource,
                                        entry);