net/ice: clean input set macro definition
[dpdk.git] / drivers / net / mlx5 / mlx5_flow_dv.c
index e0874e3..1a74d5a 100644 (file)
@@ -1653,7 +1653,7 @@ mlx5_flow_field_id_to_modify_info
                break;
        case RTE_FLOW_FIELD_TCP_FLAGS:
                info[idx] = (struct field_modify_info){1, 0,
-                                       MLX5_MODI_IN_TCP_FLAGS};
+                                       MLX5_MODI_OUT_TCP_FLAGS};
                if (mask) {
                        mask[idx] = 0x0000003f;
                        if (width < 6)
@@ -1960,13 +1960,20 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused,
                                          "isn't supported");
                if (reg != REG_A)
                        nic_mask.data = priv->sh->dv_meta_mask;
-       } else if (attr->transfer) {
-               return rte_flow_error_set(error, ENOTSUP,
+       } else {
+               if (attr->transfer)
+                       return rte_flow_error_set(error, ENOTSUP,
                                        RTE_FLOW_ERROR_TYPE_ITEM, item,
                                        "extended metadata feature "
                                        "should be enabled when "
                                        "meta item is requested "
                                        "with e-switch mode ");
+               if (attr->ingress)
+                       return rte_flow_error_set(error, ENOTSUP,
+                                       RTE_FLOW_ERROR_TYPE_ITEM, item,
+                                       "match on metadata for ingress "
+                                       "is not supported in legacy "
+                                       "metadata mode");
        }
        if (!mask)
                mask = &rte_flow_item_meta_mask;
@@ -3118,6 +3125,8 @@ flow_dv_validate_action_set_tag(struct rte_eth_dev *dev,
  *
  * @param[in] dev
  *   Pointer to rte_eth_dev structure.
+ * @param[in] action
+ *   Pointer to the action structure.
  * @param[in] action_flags
  *   Holds the actions detected until now.
  * @param[out] error
@@ -3128,17 +3137,25 @@ flow_dv_validate_action_set_tag(struct rte_eth_dev *dev,
  */
 static int
 flow_dv_validate_action_count(struct rte_eth_dev *dev,
+                             const struct rte_flow_action *action,
                              uint64_t action_flags,
                              struct rte_flow_error *error)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
+       const struct rte_flow_action_count *count;
 
+       if (!priv->config.devx)
+               goto notsup_err;
        if (action_flags & MLX5_FLOW_ACTION_COUNT)
                return rte_flow_error_set(error, EINVAL,
                                          RTE_FLOW_ERROR_TYPE_ACTION, NULL,
                                          "duplicate count actions set");
-       if (!priv->config.devx)
-               goto notsup_err;
+       count = (const struct rte_flow_action_count *)action->conf;
+       if (count && count->shared && (action_flags & MLX5_FLOW_ACTION_AGE) &&
+           !priv->sh->flow_hit_aso_en)
+               return rte_flow_error_set(error, EINVAL,
+                                         RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+                                         "old age and shared count combination is not supported");
 #ifdef HAVE_IBV_FLOW_DEVX_COUNTERS
        return 0;
 #endif
@@ -5081,6 +5098,10 @@ flow_dv_modify_create_cb(struct mlx5_hlist *list, uint64_t key __rte_unused,
  *   Pointer to the RSS action.
  * @param[out] sample_rss
  *   Pointer to the RSS action in sample action list.
+ * @param[out] count
+ *   Pointer to the COUNT action in sample action list.
+ * @param[out] fdb_mirror_limit
+ *   Pointer to the FDB mirror limitation flag.
  * @param[out] error
  *   Pointer to error structure.
  *
@@ -5095,6 +5116,8 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
                               uint64_t item_flags,
                               const struct rte_flow_action_rss *rss,
                               const struct rte_flow_action_rss **sample_rss,
+                              const struct rte_flow_action_count **count,
+                              int *fdb_mirror_limit,
                               struct rte_flow_error *error)
 {
        struct mlx5_priv *priv = dev->data->dev_private;
@@ -5189,16 +5212,13 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
                        ++actions_n;
                        break;
                case RTE_FLOW_ACTION_TYPE_COUNT:
-                       if (*action_flags & MLX5_FLOW_ACTION_COUNT)
-                               return rte_flow_error_set(error, EINVAL,
-                                               RTE_FLOW_ERROR_TYPE_ACTION,
-                                               action,
-                                               "duplicate count action set");
-                       ret = flow_dv_validate_action_count(dev,
-                                                           sub_action_flags,
-                                                           error);
+                       ret = flow_dv_validate_action_count
+                               (dev, act,
+                                *action_flags | sub_action_flags,
+                                error);
                        if (ret < 0)
                                return ret;
+                       *count = act->conf;
                        sub_action_flags |= MLX5_FLOW_ACTION_COUNT;
                        *action_flags |= MLX5_FLOW_ACTION_COUNT;
                        ++actions_n;
@@ -5269,6 +5289,9 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
                                                  NULL,
                                                  "E-Switch must has a dest "
                                                  "port for mirroring");
+               if (!priv->config.hca_attr.reg_c_preserve &&
+                    priv->representor_id != -1)
+                       *fdb_mirror_limit = 1;
        }
        /* Continue validation for Xcap actions.*/
        if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) &&
@@ -6010,6 +6033,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
        uint16_t ether_type = 0;
        int actions_n = 0;
        uint8_t item_ipv6_proto = 0;
+       int fdb_mirror_limit = 0;
+       int modify_after_mirror = 0;
        const struct rte_flow_item *geneve_item = NULL;
        const struct rte_flow_item *gre_item = NULL;
        const struct rte_flow_item *gtp_item = NULL;
@@ -6017,6 +6042,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
        const struct rte_flow_action_raw_encap *encap;
        const struct rte_flow_action_rss *rss = NULL;
        const struct rte_flow_action_rss *sample_rss = NULL;
+       const struct rte_flow_action_count *count = NULL;
+       const struct rte_flow_action_count *sample_count = NULL;
        const struct rte_flow_item_tcp nic_tcp_mask = {
                .hdr = {
                        .tcp_flags = 0xFF,
@@ -6429,6 +6456,9 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                        ++actions_n;
                                action_flags |= MLX5_FLOW_ACTION_FLAG |
                                                MLX5_FLOW_ACTION_MARK_EXT;
+                               if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                                       modify_after_mirror = 1;
+
                        } else {
                                action_flags |= MLX5_FLOW_ACTION_FLAG;
                                ++actions_n;
@@ -6448,6 +6478,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                        ++actions_n;
                                action_flags |= MLX5_FLOW_ACTION_MARK |
                                                MLX5_FLOW_ACTION_MARK_EXT;
+                               if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                                       modify_after_mirror = 1;
                        } else {
                                action_flags |= MLX5_FLOW_ACTION_MARK;
                                ++actions_n;
@@ -6463,6 +6495,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= MLX5_FLOW_ACTION_SET_META;
                        rw_act_num += MLX5_ACT_NUM_SET_META;
                        break;
@@ -6475,6 +6509,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= MLX5_FLOW_ACTION_SET_TAG;
                        rw_act_num += MLX5_ACT_NUM_SET_TAG;
                        break;
@@ -6528,10 +6564,12 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        ++actions_n;
                        break;
                case RTE_FLOW_ACTION_TYPE_COUNT:
-                       ret = flow_dv_validate_action_count(dev, action_flags,
+                       ret = flow_dv_validate_action_count(dev, actions,
+                                                           action_flags,
                                                            error);
                        if (ret < 0)
                                return ret;
+                       count = actions->conf;
                        action_flags |= MLX5_FLOW_ACTION_COUNT;
                        ++actions_n;
                        break;
@@ -6635,6 +6673,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                        RTE_FLOW_ACTION_TYPE_SET_MAC_SRC ?
                                                MLX5_FLOW_ACTION_SET_MAC_SRC :
                                                MLX5_FLOW_ACTION_SET_MAC_DST;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        /*
                         * Even if the source and destination MAC addresses have
                         * overlap in the header with 4B alignment, the convert
@@ -6655,6 +6695,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= actions->type ==
                                        RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC ?
                                                MLX5_FLOW_ACTION_SET_IPV4_SRC :
@@ -6678,6 +6720,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= actions->type ==
                                        RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC ?
                                                MLX5_FLOW_ACTION_SET_IPV6_SRC :
@@ -6695,6 +6739,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= actions->type ==
                                        RTE_FLOW_ACTION_TYPE_SET_TP_SRC ?
                                                MLX5_FLOW_ACTION_SET_TP_SRC :
@@ -6712,6 +6758,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= actions->type ==
                                        RTE_FLOW_ACTION_TYPE_SET_TTL ?
                                                MLX5_FLOW_ACTION_SET_TTL :
@@ -6725,6 +6773,12 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                                           error);
                        if (ret)
                                return ret;
+                       if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) &&
+                           fdb_mirror_limit)
+                               return rte_flow_error_set(error, EINVAL,
+                                                 RTE_FLOW_ERROR_TYPE_ACTION,
+                                                 NULL,
+                                                 "sample and jump action combination is not supported");
                        ++actions_n;
                        action_flags |= MLX5_FLOW_ACTION_JUMP;
                        break;
@@ -6740,6 +6794,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= actions->type ==
                                        RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ ?
                                                MLX5_FLOW_ACTION_INC_TCP_SEQ :
@@ -6758,6 +6814,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= actions->type ==
                                        RTE_FLOW_ACTION_TYPE_INC_TCP_ACK ?
                                                MLX5_FLOW_ACTION_INC_TCP_ACK :
@@ -6797,6 +6855,24 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                                          error);
                        if (ret < 0)
                                return ret;
+                       /*
+                        * Validate the regular AGE action (using counter)
+                        * mutual exclusion with share counter actions.
+                        */
+                       if (!priv->sh->flow_hit_aso_en) {
+                               if (count && count->shared)
+                                       return rte_flow_error_set
+                                               (error, EINVAL,
+                                               RTE_FLOW_ERROR_TYPE_ACTION,
+                                               NULL,
+                                               "old age and shared count combination is not supported");
+                               if (sample_count)
+                                       return rte_flow_error_set
+                                               (error, EINVAL,
+                                               RTE_FLOW_ERROR_TYPE_ACTION,
+                                               NULL,
+                                               "old age action and count must be in the same sub flow");
+                       }
                        action_flags |= MLX5_FLOW_ACTION_AGE;
                        ++actions_n;
                        break;
@@ -6811,6 +6887,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= MLX5_FLOW_ACTION_SET_IPV4_DSCP;
                        rw_act_num += MLX5_ACT_NUM_SET_DSCP;
                        break;
@@ -6825,6 +6903,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        /* Count all modify-header actions as one action. */
                        if (!(action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS))
                                ++actions_n;
+                       if (action_flags & MLX5_FLOW_ACTION_SAMPLE)
+                               modify_after_mirror = 1;
                        action_flags |= MLX5_FLOW_ACTION_SET_IPV6_DSCP;
                        rw_act_num += MLX5_ACT_NUM_SET_DSCP;
                        break;
@@ -6833,6 +6913,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                                             actions, dev,
                                                             attr, item_flags,
                                                             rss, &sample_rss,
+                                                            &sample_count,
+                                                            &fdb_mirror_limit,
                                                             error);
                        if (ret < 0)
                                return ret;
@@ -7031,6 +7113,11 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                          NULL, "too many header modify"
                                          " actions to support");
        }
+       /* Eswitch egress mirror and modify flow has limitation on CX5 */
+       if (fdb_mirror_limit && modify_after_mirror)
+               return rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+                               "sample before modify action is not supported");
        return 0;
 }
 
@@ -12920,6 +13007,10 @@ __flow_dv_action_rss_update(struct rte_eth_dev *dev, uint32_t idx,
                return rte_flow_error_set(error, EINVAL,
                                          RTE_FLOW_ERROR_TYPE_ACTION, NULL,
                                          "invalid shared action to update");
+       if (priv->obj_ops.ind_table_modify == NULL)
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+                                         "cannot modify indirection table");
        queue = mlx5_malloc(MLX5_MEM_ZERO,
                            RTE_ALIGN_CEIL(queue_size, sizeof(void *)),
                            0, SOCKET_ID_ANY);
@@ -13802,6 +13893,20 @@ flow_dv_action_validate(struct rte_eth_dev *dev,
        RTE_SET_USED(conf);
        switch (action->type) {
        case RTE_FLOW_ACTION_TYPE_RSS:
+               /*
+                * priv->obj_ops is set according to driver capabilities.
+                * When DevX capabilities are
+                * sufficient, it is set to devx_obj_ops.
+                * Otherwise, it is set to ibv_obj_ops.
+                * ibv_obj_ops doesn't support ind_table_modify operation.
+                * In this case the shared RSS action can't be used.
+                */
+               if (priv->obj_ops.ind_table_modify == NULL)
+                       return rte_flow_error_set
+                                       (err, ENOTSUP,
+                                        RTE_FLOW_ERROR_TYPE_ACTION,
+                                        NULL,
+                                        "shared RSS action not supported");
                return mlx5_validate_action_rss(dev, action, err);
        case RTE_FLOW_ACTION_TYPE_AGE:
                if (!priv->sh->aso_age_mng)