net/cnxk: enable VLAN processing in vector Tx
[dpdk.git] / drivers / net / mlx5 / mlx5_flow.c
index c322d5d..c5c767a 100644 (file)
@@ -114,6 +114,30 @@ struct mlx5_flow_expand_rss {
        } entry[];
 };
 
+static void
+mlx5_dbg__print_pattern(const struct rte_flow_item *item);
+
+static bool
+mlx5_flow_is_rss_expandable_item(const struct rte_flow_item *item)
+{
+       switch (item->type) {
+       case RTE_FLOW_ITEM_TYPE_ETH:
+       case RTE_FLOW_ITEM_TYPE_VLAN:
+       case RTE_FLOW_ITEM_TYPE_IPV4:
+       case RTE_FLOW_ITEM_TYPE_IPV6:
+       case RTE_FLOW_ITEM_TYPE_UDP:
+       case RTE_FLOW_ITEM_TYPE_TCP:
+       case RTE_FLOW_ITEM_TYPE_VXLAN:
+       case RTE_FLOW_ITEM_TYPE_NVGRE:
+       case RTE_FLOW_ITEM_TYPE_GRE:
+       case RTE_FLOW_ITEM_TYPE_GENEVE:
+               return true;
+       default:
+               break;
+       }
+       return false;
+}
+
 static enum rte_flow_item_type
 mlx5_flow_expand_rss_item_complete(const struct rte_flow_item *item)
 {
@@ -273,8 +297,11 @@ mlx5_flow_expand_rss(struct mlx5_flow_expand_rss *buf, size_t size,
                addr = buf->entry[0].pattern;
        }
        for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
-               if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
-                       last_item = item;
+               if (!mlx5_flow_is_rss_expandable_item(item)) {
+                       user_pattern_size += sizeof(*item);
+                       continue;
+               }
+               last_item = item;
                for (i = 0; node->next && node->next[i]; ++i) {
                        next = &graph[node->next[i]];
                        if (next->type == item->type)
@@ -408,6 +435,7 @@ enum mlx5_expansion {
        MLX5_EXPANSION_VXLAN,
        MLX5_EXPANSION_VXLAN_GPE,
        MLX5_EXPANSION_GRE,
+       MLX5_EXPANSION_NVGRE,
        MLX5_EXPANSION_GRE_KEY,
        MLX5_EXPANSION_MPLS,
        MLX5_EXPANSION_ETH,
@@ -466,6 +494,7 @@ static const struct mlx5_flow_expand_node mlx5_support_expansion[] = {
                        (MLX5_EXPANSION_OUTER_IPV4_UDP,
                         MLX5_EXPANSION_OUTER_IPV4_TCP,
                         MLX5_EXPANSION_GRE,
+                        MLX5_EXPANSION_NVGRE,
                         MLX5_EXPANSION_IPV4,
                         MLX5_EXPANSION_IPV6),
                .type = RTE_FLOW_ITEM_TYPE_IPV4,
@@ -488,7 +517,8 @@ static const struct mlx5_flow_expand_node mlx5_support_expansion[] = {
                         MLX5_EXPANSION_OUTER_IPV6_TCP,
                         MLX5_EXPANSION_IPV4,
                         MLX5_EXPANSION_IPV6,
-                        MLX5_EXPANSION_GRE),
+                        MLX5_EXPANSION_GRE,
+                        MLX5_EXPANSION_NVGRE),
                .type = RTE_FLOW_ITEM_TYPE_IPV6,
                .rss_types = ETH_RSS_IPV6 | ETH_RSS_FRAG_IPV6 |
                        ETH_RSS_NONFRAG_IPV6_OTHER,
@@ -527,6 +557,10 @@ static const struct mlx5_flow_expand_node mlx5_support_expansion[] = {
                .type = RTE_FLOW_ITEM_TYPE_GRE_KEY,
                .optional = 1,
        },
+       [MLX5_EXPANSION_NVGRE] = {
+               .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_ETH),
+               .type = RTE_FLOW_ITEM_TYPE_NVGRE,
+       },
        [MLX5_EXPANSION_MPLS] = {
                .next = MLX5_FLOW_EXPAND_RSS_NEXT(MLX5_EXPANSION_IPV4,
                                                  MLX5_EXPANSION_IPV6),
@@ -2090,7 +2124,7 @@ mlx5_flow_validate_item_ipv4(const struct rte_flow_item *item,
                                          RTE_FLOW_ERROR_TYPE_ITEM, item,
                                          "IPv4 cannot follow L2/VLAN layer "
                                          "which ether type is not IPv4");
-       if (item_flags & MLX5_FLOW_LAYER_IPIP) {
+       if (item_flags & MLX5_FLOW_LAYER_TUNNEL) {
                if (mask && spec)
                        next_proto = mask->hdr.next_proto_id &
                                     spec->hdr.next_proto_id;
@@ -2198,7 +2232,7 @@ mlx5_flow_validate_item_ipv6(const struct rte_flow_item *item,
                                          "which ether type is not IPv6");
        if (mask && mask->hdr.proto == UINT8_MAX && spec)
                next_proto = spec->hdr.proto;
-       if (item_flags & MLX5_FLOW_LAYER_IPV6_ENCAP) {
+       if (item_flags & MLX5_FLOW_LAYER_TUNNEL) {
                if (next_proto == IPPROTO_IPIP || next_proto == IPPROTO_IPV6)
                        return rte_flow_error_set(error, EINVAL,
                                                  RTE_FLOW_ERROR_TYPE_ITEM,
@@ -4560,7 +4594,9 @@ get_meter_sub_policy(struct rte_eth_dev *dev,
                                   "Failed to find Meter Policy.");
                goto exit;
        }
-       if (policy->is_rss) {
+       if (policy->is_rss ||
+               (policy->is_queue &&
+       !policy->sub_policys[MLX5_MTR_DOMAIN_INGRESS][0]->rix_hrxq[0])) {
                struct mlx5_flow_workspace *wks =
                                mlx5_flow_get_thread_workspace();
                struct mlx5_flow_rss_desc rss_desc_v[MLX5_MTR_RTE_COLORS];
@@ -4576,34 +4612,49 @@ get_meter_sub_policy(struct rte_eth_dev *dev,
                for (i = 0; i < MLX5_MTR_RTE_COLORS; i++) {
                        struct mlx5_flow dev_flow = {0};
                        struct mlx5_flow_handle dev_handle = { {0} };
-                       const void *rss_act = policy->act_cnt[i].rss->conf;
-                       struct rte_flow_action rss_actions[2] = {
-                               [0] = {
+
+                       rss_desc_v[i] = wks->rss_desc;
+                       if (policy->is_rss) {
+                               const void *rss_act =
+                                       policy->act_cnt[i].rss->conf;
+                               struct rte_flow_action rss_actions[2] = {
+                                       [0] = {
                                        .type = RTE_FLOW_ACTION_TYPE_RSS,
                                        .conf = rss_act
-                               },
-                               [1] = {
+                                       },
+                                       [1] = {
                                        .type = RTE_FLOW_ACTION_TYPE_END,
                                        .conf = NULL
-                               }
-                       };
+                                       }
+                               };
 
-                       dev_flow.handle = &dev_handle;
-                       dev_flow.ingress = attr->ingress;
-                       dev_flow.flow = flow;
-                       dev_flow.external = 0;
+                               dev_flow.handle = &dev_handle;
+                               dev_flow.ingress = attr->ingress;
+                               dev_flow.flow = flow;
+                               dev_flow.external = 0;
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
-                       dev_flow.dv.transfer = attr->transfer;
+                               dev_flow.dv.transfer = attr->transfer;
 #endif
-                       /* Translate RSS action to get rss hash fields. */
-                       if (flow_drv_translate(dev, &dev_flow, attr,
+                               /**
+                                * Translate RSS action to get rss hash fields.
+                                */
+                               if (flow_drv_translate(dev, &dev_flow, attr,
                                                items, rss_actions, error))
-                               goto exit;
-                       rss_desc_v[i] = wks->rss_desc;
-                       rss_desc_v[i].key_len = MLX5_RSS_HASH_KEY_LEN;
-                       rss_desc_v[i].hash_fields = dev_flow.hash_fields;
-                       rss_desc_v[i].queue_num = rss_desc_v[i].hash_fields ?
-                                                 rss_desc_v[i].queue_num : 1;
+                                       goto exit;
+                               rss_desc_v[i].key_len = MLX5_RSS_HASH_KEY_LEN;
+                               rss_desc_v[i].hash_fields =
+                                               dev_flow.hash_fields;
+                               rss_desc_v[i].queue_num =
+                                               rss_desc_v[i].hash_fields ?
+                                               rss_desc_v[i].queue_num : 1;
+                       } else {
+                               /* This is queue action. */
+                               rss_desc_v[i].key_len = 0;
+                               rss_desc_v[i].hash_fields = 0;
+                               rss_desc_v[i].queue =
+                                       &policy->act_cnt[i].queue;
+                               rss_desc_v[i].queue_num = 1;
+                       }
                        rss_desc[i] = &rss_desc_v[i];
                }
                sub_policy = flow_drv_meter_sub_policy_rss_prepare(dev,
@@ -4795,8 +4846,8 @@ flow_meter_split_prep(struct rte_eth_dev *dev,
                                        RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
                                        "Failed to allocate meter flow id.");
                flow_id = tag_id - 1;
-               flow_id_bits = MLX5_REG_BITS - __builtin_clz(flow_id);
-               flow_id_bits = flow_id_bits ? flow_id_bits : 1;
+               flow_id_bits = (!flow_id) ? 1 :
+                               (MLX5_REG_BITS - __builtin_clz(flow_id));
                if ((flow_id_bits + priv->sh->mtrmng->max_mtr_bits) >
                    mtr_reg_bits) {
                        mlx5_ipool_free(fm->flow_ipool, tag_id);
@@ -6150,6 +6201,10 @@ flow_list_create(struct rte_eth_dev *dev, uint32_t *list,
                                           mlx5_support_expansion, graph_root);
                MLX5_ASSERT(ret > 0 &&
                       (unsigned int)ret < sizeof(expand_buffer.buffer));
+               if (rte_log_can_log(mlx5_logtype, RTE_LOG_DEBUG)) {
+                       for (i = 0; i < buf->entries; ++i)
+                               mlx5_dbg__print_pattern(buf->entry[i].pattern);
+               }
        } else {
                buf->entries = 1;
                buf->entry[0].pattern = (void *)(uintptr_t)items;
@@ -7216,6 +7271,24 @@ mlx5_flow_destroy_mtr_drop_tbls(struct rte_eth_dev *dev)
        fops->destroy_mtr_drop_tbls(dev);
 }
 
+/**
+ * Destroy the sub policy table with RX queue.
+ *
+ * @param[in] dev
+ *   Pointer to Ethernet device.
+ * @param[in] mtr_policy
+ *   Pointer to meter policy table.
+ */
+void
+mlx5_flow_destroy_sub_policy_with_rxq(struct rte_eth_dev *dev,
+               struct mlx5_flow_meter_policy *mtr_policy)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_DV);
+       fops->destroy_sub_policy_with_rxq(dev, mtr_policy);
+}
+
 /**
  * Allocate the needed aso flow meter id.
  *
@@ -8948,3 +9021,22 @@ mlx5_release_tunnel_hub(__rte_unused struct mlx5_dev_ctx_shared *sh,
 {
 }
 #endif /* HAVE_IBV_FLOW_DV_SUPPORT */
+
+static void
+mlx5_dbg__print_pattern(const struct rte_flow_item *item)
+{
+       int ret;
+       struct rte_flow_error error;
+
+       for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
+               char *item_name;
+               ret = rte_flow_conv(RTE_FLOW_CONV_OP_ITEM_NAME_PTR, &item_name,
+                                   sizeof(item_name),
+                                   (void *)(uintptr_t)item->type, &error);
+               if (ret > 0)
+                       printf("%s ", item_name);
+               else
+                       printf("%d\n", (int)item->type);
+       }
+       printf("END\n");
+}