common/mlx5: update MMO HCA capabilities
[dpdk.git] / drivers / net / mlx5 / mlx5_flow_dv.c
index 3f6f5dc..c6370cd 100644 (file)
@@ -2412,11 +2412,10 @@ flow_dv_validate_item_gtp_psc(const struct rte_flow_item *item,
 {
        const struct rte_flow_item_gtp *gtp_spec;
        const struct rte_flow_item_gtp *gtp_mask;
-       const struct rte_flow_item_gtp_psc *spec;
        const struct rte_flow_item_gtp_psc *mask;
        const struct rte_flow_item_gtp_psc nic_mask = {
-               .pdu_type = 0xFF,
-               .qfi = 0xFF,
+               .hdr.type = 0xF,
+               .hdr.qfi = 0x3F,
        };
 
        if (!gtp_item || !(last_item & MLX5_FLOW_LAYER_GTP))
@@ -2440,12 +2439,7 @@ flow_dv_validate_item_gtp_psc(const struct rte_flow_item *item,
        /* GTP spec is here and E flag is requested to match zero. */
        if (!item->spec)
                return 0;
-       spec = item->spec;
        mask = item->mask ? item->mask : &rte_flow_item_gtp_psc_mask;
-       if (spec->pdu_type > MLX5_GTP_EXT_MAX_PDU_TYPE)
-               return rte_flow_error_set
-                       (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,
-                        "PDU type should be smaller than 16");
        return mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
                                         (const uint8_t *)&nic_mask,
                                         sizeof(struct rte_flow_item_gtp_psc),
@@ -9953,14 +9947,14 @@ flow_dv_translate_item_gtp_psc(void *matcher, void *key,
                if (!gtp_psc_m)
                        gtp_psc_m = &rte_flow_item_gtp_psc_mask;
                dw_0.w32 = 0;
-               dw_0.type_flags = MLX5_GTP_PDU_TYPE_SHIFT(gtp_psc_m->pdu_type);
-               dw_0.qfi = gtp_psc_m->qfi;
+               dw_0.type_flags = MLX5_GTP_PDU_TYPE_SHIFT(gtp_psc_m->hdr.type);
+               dw_0.qfi = gtp_psc_m->hdr.qfi;
                MLX5_SET(fte_match_set_misc3, misc3_m, gtpu_first_ext_dw_0,
                         rte_cpu_to_be_32(dw_0.w32));
                dw_0.w32 = 0;
-               dw_0.type_flags = MLX5_GTP_PDU_TYPE_SHIFT(gtp_psc_v->pdu_type &
-                                                       gtp_psc_m->pdu_type);
-               dw_0.qfi = gtp_psc_v->qfi & gtp_psc_m->qfi;
+               dw_0.type_flags = MLX5_GTP_PDU_TYPE_SHIFT(gtp_psc_v->hdr.type &
+                                                       gtp_psc_m->hdr.type);
+               dw_0.qfi = gtp_psc_v->hdr.qfi & gtp_psc_m->hdr.qfi;
                MLX5_SET(fte_match_set_misc3, misc3_v, gtpu_first_ext_dw_0,
                         rte_cpu_to_be_32(dw_0.w32));
        }
@@ -12304,17 +12298,27 @@ flow_dv_aso_ct_dev_release(struct rte_eth_dev *dev, uint32_t idx)
 }
 
 static inline int
-flow_dv_aso_ct_release(struct rte_eth_dev *dev, uint32_t own_idx)
+flow_dv_aso_ct_release(struct rte_eth_dev *dev, uint32_t own_idx,
+                      struct rte_flow_error *error)
 {
        uint16_t owner = (uint16_t)MLX5_INDIRECT_ACT_CT_GET_OWNER(own_idx);
        uint32_t idx = MLX5_INDIRECT_ACT_CT_GET_IDX(own_idx);
        struct rte_eth_dev *owndev = &rte_eth_devices[owner];
-       RTE_SET_USED(dev);
+       int ret;
 
        MLX5_ASSERT(owner < RTE_MAX_ETHPORTS);
        if (dev->data->dev_started != 1)
-               return -1;
-       return flow_dv_aso_ct_dev_release(owndev, idx);
+               return rte_flow_error_set(error, EAGAIN,
+                                         RTE_FLOW_ERROR_TYPE_ACTION,
+                                         NULL,
+                                         "Indirect CT action cannot be destroyed when the port is stopped");
+       ret = flow_dv_aso_ct_dev_release(owndev, idx);
+       if (ret < 0)
+               return rte_flow_error_set(error, EAGAIN,
+                                         RTE_FLOW_ERROR_TYPE_ACTION,
+                                         NULL,
+                                         "Current state prevents indirect CT action from being destroyed");
+       return ret;
 }
 
 /*
@@ -12830,10 +12834,13 @@ flow_dv_translate(struct rte_eth_dev *dev,
                                MLX5_FLOW_FATE_QUEUE;
                        break;
                case MLX5_RTE_FLOW_ACTION_TYPE_AGE:
-                       flow->age = (uint32_t)(uintptr_t)(action->conf);
-                       age_act = flow_aso_age_get_by_idx(dev, flow->age);
-                       __atomic_fetch_add(&age_act->refcnt, 1,
-                                          __ATOMIC_RELAXED);
+                       owner_idx = (uint32_t)(uintptr_t)action->conf;
+                       age_act = flow_aso_age_get_by_idx(dev, owner_idx);
+                       if (flow->age == 0) {
+                               flow->age = owner_idx;
+                               __atomic_fetch_add(&age_act->refcnt, 1,
+                                                  __ATOMIC_RELAXED);
+                       }
                        age_act_pos = actions_n++;
                        action_flags |= MLX5_FLOW_ACTION_AGE;
                        break;
@@ -12843,9 +12850,9 @@ flow_dv_translate(struct rte_eth_dev *dev,
                        action_flags |= MLX5_FLOW_ACTION_AGE;
                        break;
                case MLX5_RTE_FLOW_ACTION_TYPE_COUNT:
-                       cnt_act = flow_dv_counter_get_by_idx(dev,
-                                       (uint32_t)(uintptr_t)action->conf,
-                                       NULL);
+                       owner_idx = (uint32_t)(uintptr_t)action->conf;
+                       cnt_act = flow_dv_counter_get_by_idx(dev, owner_idx,
+                                                            NULL);
                        MLX5_ASSERT(cnt_act != NULL);
                        /**
                         * When creating meter drop flow in drop table, the
@@ -12856,10 +12863,12 @@ flow_dv_translate(struct rte_eth_dev *dev,
                                dev_flow->dv.actions[actions_n++] =
                                                        cnt_act->action;
                        } else {
-                               flow->counter =
-                                       (uint32_t)(uintptr_t)(action->conf);
-                               __atomic_fetch_add(&cnt_act->shared_info.refcnt,
-                                               1, __ATOMIC_RELAXED);
+                               if (flow->counter == 0) {
+                                       flow->counter = owner_idx;
+                                       __atomic_fetch_add
+                                               (&cnt_act->shared_info.refcnt,
+                                                1, __ATOMIC_RELAXED);
+                               }
                                /* Save information first, will apply later. */
                                action_flags |= MLX5_FLOW_ACTION_COUNT;
                        }
@@ -13182,9 +13191,13 @@ flow_dv_translate(struct rte_eth_dev *dev,
                        else
                                dev_flow->dv.actions[actions_n] =
                                                        ct->dr_action_rply;
-                       flow->indirect_type = MLX5_INDIRECT_ACTION_TYPE_CT;
-                       flow->ct = owner_idx;
-                       __atomic_fetch_add(&ct->refcnt, 1, __ATOMIC_RELAXED);
+                       if (flow->ct == 0) {
+                               flow->indirect_type =
+                                               MLX5_INDIRECT_ACTION_TYPE_CT;
+                               flow->ct = owner_idx;
+                               __atomic_fetch_add(&ct->refcnt, 1,
+                                                  __ATOMIC_RELAXED);
+                       }
                        actions_n++;
                        action_flags |= MLX5_FLOW_ACTION_CT;
                        break;
@@ -14365,7 +14378,7 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
        }
        /* Keep the current age handling by default. */
        if (flow->indirect_type == MLX5_INDIRECT_ACTION_TYPE_CT && flow->ct)
-               flow_dv_aso_ct_release(dev, flow->ct);
+               flow_dv_aso_ct_release(dev, flow->ct, NULL);
        else if (flow->age)
                flow_dv_aso_age_release(dev, flow->age);
        if (flow->geneve_tlv_option) {
@@ -14742,12 +14755,6 @@ __flow_dv_action_rss_release(struct rte_eth_dev *dev, uint32_t idx,
                return rte_flow_error_set(error, EINVAL,
                                          RTE_FLOW_ERROR_TYPE_ACTION, NULL,
                                          "invalid shared action");
-       remaining = __flow_dv_action_rss_hrxqs_release(dev, shared_rss);
-       if (remaining)
-               return rte_flow_error_set(error, EBUSY,
-                                         RTE_FLOW_ERROR_TYPE_ACTION,
-                                         NULL,
-                                         "shared rss hrxq has references");
        if (!__atomic_compare_exchange_n(&shared_rss->refcnt, &old_refcnt,
                                         0, 0, __ATOMIC_ACQUIRE,
                                         __ATOMIC_RELAXED))
@@ -14755,6 +14762,12 @@ __flow_dv_action_rss_release(struct rte_eth_dev *dev, uint32_t idx,
                                          RTE_FLOW_ERROR_TYPE_ACTION,
                                          NULL,
                                          "shared rss has references");
+       remaining = __flow_dv_action_rss_hrxqs_release(dev, shared_rss);
+       if (remaining)
+               return rte_flow_error_set(error, EBUSY,
+                                         RTE_FLOW_ERROR_TYPE_ACTION,
+                                         NULL,
+                                         "shared rss hrxq has references");
        queue = shared_rss->ind_tbl->queues;
        remaining = mlx5_ind_table_obj_release(dev, shared_rss->ind_tbl, true);
        if (remaining)
@@ -14900,7 +14913,7 @@ flow_dv_action_destroy(struct rte_eth_dev *dev,
                                " released with references %d.", idx, ret);
                return 0;
        case MLX5_INDIRECT_ACTION_TYPE_CT:
-               ret = flow_dv_aso_ct_release(dev, idx);
+               ret = flow_dv_aso_ct_release(dev, idx, error);
                if (ret < 0)
                        return ret;
                if (ret > 0)
@@ -15119,7 +15132,7 @@ __flow_dv_destroy_sub_policy_rules(struct rte_eth_dev *dev,
                    policy->act_cnt[i].fate_action == MLX5_FLOW_FATE_MTR)
                        next_fm = mlx5_flow_meter_find(priv,
                                        policy->act_cnt[i].next_mtr_id, NULL);
-               TAILQ_FOREACH_SAFE(color_rule, &sub_policy->color_rules[i],
+               RTE_TAILQ_FOREACH_SAFE(color_rule, &sub_policy->color_rules[i],
                                   next_port, tmp) {
                        claim_zero(mlx5_flow_os_destroy_flow(color_rule->rule));
                        tbl = container_of(color_rule->matcher->tbl,