net/mlx5: rename flow counter configuration macro
[dpdk.git] / drivers / net / mlx5 / mlx5_flow_dv.c
index 447f376..e8f409f 100644 (file)
 
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 
+/**
+ * Validate META item.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] item
+ *   Item specification.
+ * @param[in] attr
+ *   Attributes of flow that includes this item.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_validate_item_meta(struct rte_eth_dev *dev,
+                          const struct rte_flow_item *item,
+                          const struct rte_flow_attr *attr,
+                          struct rte_flow_error *error)
+{
+       const struct rte_flow_item_meta *spec = item->spec;
+       const struct rte_flow_item_meta *mask = item->mask;
+       const struct rte_flow_item_meta nic_mask = {
+               .data = RTE_BE32(UINT32_MAX)
+       };
+       int ret;
+       uint64_t offloads = dev->data->dev_conf.txmode.offloads;
+
+       if (!(offloads & DEV_TX_OFFLOAD_MATCH_METADATA))
+               return rte_flow_error_set(error, EPERM,
+                                         RTE_FLOW_ERROR_TYPE_ITEM,
+                                         NULL,
+                                         "match on metadata offload "
+                                         "configuration is off for this port");
+       if (!spec)
+               return rte_flow_error_set(error, EINVAL,
+                                         RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+                                         item->spec,
+                                         "data cannot be empty");
+       if (!spec->data)
+               return rte_flow_error_set(error, EINVAL,
+                                         RTE_FLOW_ERROR_TYPE_ITEM_SPEC,
+                                         NULL,
+                                         "data cannot be zero");
+       if (!mask)
+               mask = &rte_flow_item_meta_mask;
+       ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask,
+                                       (const uint8_t *)&nic_mask,
+                                       sizeof(struct rte_flow_item_meta),
+                                       error);
+       if (ret < 0)
+               return ret;
+       if (attr->ingress)
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
+                                         NULL,
+                                         "pattern not supported for ingress");
+       return 0;
+}
+
 /**
  * Verify the @p attributes will be correctly understood by the NIC and store
  * them in the @p flow if everything is correct.
@@ -68,21 +129,16 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev,
                                          RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
                                          NULL,
                                          "priority out of range");
-       if (attributes->egress)
-               return rte_flow_error_set(error, ENOTSUP,
-                                         RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
-                                         NULL,
-                                         "egress is not supported");
        if (attributes->transfer)
                return rte_flow_error_set(error, ENOTSUP,
                                          RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
                                          NULL,
                                          "transfer is not supported");
-       if (!attributes->ingress)
-               return rte_flow_error_set(error, EINVAL,
-                                         RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
-                                         NULL,
-                                         "ingress attribute is mandatory");
+       if (!(attributes->egress ^ attributes->ingress))
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+                                         "must specify exactly one of "
+                                         "ingress or egress");
        return 0;
 }
 
@@ -179,8 +235,11 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                               MLX5_FLOW_LAYER_OUTER_L4_UDP;
                        break;
                case RTE_FLOW_ITEM_TYPE_TCP:
-                       ret = mlx5_flow_validate_item_tcp(items, item_flags,
-                                                         next_protocol, error);
+                       ret = mlx5_flow_validate_item_tcp
+                                               (items, item_flags,
+                                                next_protocol,
+                                                &rte_flow_item_tcp_mask,
+                                                error);
                        if (ret < 0)
                                return ret;
                        item_flags |= tunnel ? MLX5_FLOW_LAYER_INNER_L4_TCP :
@@ -216,6 +275,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                return ret;
                        item_flags |= MLX5_FLOW_LAYER_MPLS;
                        break;
+               case RTE_FLOW_ITEM_TYPE_META:
+                       ret = flow_dv_validate_item_meta(dev, items, attr,
+                                                        error);
+                       if (ret < 0)
+                               return ret;
+                       item_flags |= MLX5_FLOW_ITEM_METADATA;
+                       break;
                default:
                        return rte_flow_error_set(error, ENOTSUP,
                                                  RTE_FLOW_ERROR_TYPE_ITEM,
@@ -233,7 +299,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        break;
                case RTE_FLOW_ACTION_TYPE_FLAG:
                        ret = mlx5_flow_validate_action_flag(action_flags,
-                                                            error);
+                                                            attr, error);
                        if (ret < 0)
                                return ret;
                        action_flags |= MLX5_FLOW_ACTION_FLAG;
@@ -242,7 +308,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                case RTE_FLOW_ACTION_TYPE_MARK:
                        ret = mlx5_flow_validate_action_mark(actions,
                                                             action_flags,
-                                                            error);
+                                                            attr, error);
                        if (ret < 0)
                                return ret;
                        action_flags |= MLX5_FLOW_ACTION_MARK;
@@ -250,7 +316,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                        break;
                case RTE_FLOW_ACTION_TYPE_DROP:
                        ret = mlx5_flow_validate_action_drop(action_flags,
-                                                            error);
+                                                            attr, error);
                        if (ret < 0)
                                return ret;
                        action_flags |= MLX5_FLOW_ACTION_DROP;
@@ -259,7 +325,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                case RTE_FLOW_ACTION_TYPE_QUEUE:
                        ret = mlx5_flow_validate_action_queue(actions,
                                                              action_flags, dev,
-                                                             error);
+                                                             attr, error);
                        if (ret < 0)
                                return ret;
                        action_flags |= MLX5_FLOW_ACTION_QUEUE;
@@ -268,14 +334,14 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                case RTE_FLOW_ACTION_TYPE_RSS:
                        ret = mlx5_flow_validate_action_rss(actions,
                                                            action_flags, dev,
-                                                           error);
+                                                           attr, error);
                        if (ret < 0)
                                return ret;
                        action_flags |= MLX5_FLOW_ACTION_RSS;
                        ++actions_n;
                        break;
                case RTE_FLOW_ACTION_TYPE_COUNT:
-                       ret = mlx5_flow_validate_action_count(dev, error);
+                       ret = mlx5_flow_validate_action_count(dev, attr, error);
                        if (ret < 0)
                                return ret;
                        action_flags |= MLX5_FLOW_ACTION_COUNT;
@@ -288,7 +354,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
                                                  "action not supported");
                }
        }
-       if (!(action_flags & MLX5_FLOW_FATE_ACTIONS))
+       if (!(action_flags & MLX5_FLOW_FATE_ACTIONS) && attr->ingress)
                return rte_flow_error_set(error, EINVAL,
                                          RTE_FLOW_ERROR_TYPE_ACTION, actions,
                                          "no fate action is found");
@@ -782,6 +848,8 @@ flow_dv_translate_item_nvgre(void *matcher, void *key,
        const struct rte_flow_item_nvgre *nvgre_v = item->spec;
        void *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters);
        void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters);
+       const char *tni_flow_id_m = (const char *)nvgre_m->tni;
+       const char *tni_flow_id_v = (const char *)nvgre_v->tni;
        char *gre_key_m;
        char *gre_key_v;
        int size;
@@ -794,9 +862,9 @@ flow_dv_translate_item_nvgre(void *matcher, void *key,
        size = sizeof(nvgre_m->tni) + sizeof(nvgre_m->flow_id);
        gre_key_m = MLX5_ADDR_OF(fte_match_set_misc, misc_m, gre_key_h);
        gre_key_v = MLX5_ADDR_OF(fte_match_set_misc, misc_v, gre_key_h);
-       memcpy(gre_key_m, nvgre_m->tni, size);
+       memcpy(gre_key_m, tni_flow_id_m, size);
        for (i = 0; i < size; ++i)
-               gre_key_v[i] = gre_key_m[i] & ((const char *)(nvgre_v->tni))[i];
+               gre_key_v[i] = gre_key_m[i] & tni_flow_id_v[i];
        flow_dv_translate_item_gre(matcher, key, item, inner);
 }
 
@@ -856,6 +924,41 @@ flow_dv_translate_item_vxlan(void *matcher, void *key,
                vni_v[i] = vni_m[i] & vxlan_v->vni[i];
 }
 
+/**
+ * Add META item to matcher
+ *
+ * @param[in, out] matcher
+ *   Flow matcher.
+ * @param[in, out] key
+ *   Flow matcher value.
+ * @param[in] item
+ *   Flow pattern to translate.
+ * @param[in] inner
+ *   Item is inner pattern.
+ */
+static void
+flow_dv_translate_item_meta(void *matcher, void *key,
+                           const struct rte_flow_item *item)
+{
+       const struct rte_flow_item_meta *meta_m;
+       const struct rte_flow_item_meta *meta_v;
+       void *misc2_m =
+               MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters_2);
+       void *misc2_v =
+               MLX5_ADDR_OF(fte_match_param, key, misc_parameters_2);
+
+       meta_m = (const void *)item->mask;
+       if (!meta_m)
+               meta_m = &rte_flow_item_meta_mask;
+       meta_v = (const void *)item->spec;
+       if (meta_v) {
+               MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_a,
+                        rte_be_to_cpu_32(meta_m->data));
+               MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_a,
+                        rte_be_to_cpu_32(meta_v->data & meta_m->data));
+       }
+}
+
 /**
  * Update the matcher and the value based the selected item.
  *
@@ -942,6 +1045,9 @@ flow_dv_create_item(void *matcher, void *key,
                flow_dv_translate_item_vxlan(tmatcher->mask.buf, key, item,
                                             inner);
                break;
+       case RTE_FLOW_ITEM_TYPE_META:
+               flow_dv_translate_item_meta(tmatcher->mask.buf, key, item);
+               break;
        default:
                break;
        }
@@ -972,12 +1078,14 @@ flow_dv_create_action(const struct rte_flow_action *action,
                dev_flow->dv.actions[actions_n].tag_value =
                        MLX5_FLOW_MARK_DEFAULT;
                actions_n++;
+               flow->actions |= MLX5_FLOW_ACTION_FLAG;
                break;
        case RTE_FLOW_ACTION_TYPE_MARK:
                dev_flow->dv.actions[actions_n].type = MLX5DV_FLOW_ACTION_TAG;
                dev_flow->dv.actions[actions_n].tag_value =
                        ((const struct rte_flow_action_mark *)
                         (action->conf))->id;
+               flow->actions |= MLX5_FLOW_ACTION_MARK;
                actions_n++;
                break;
        case RTE_FLOW_ACTION_TYPE_DROP:
@@ -988,6 +1096,7 @@ flow_dv_create_action(const struct rte_flow_action *action,
                queue = action->conf;
                flow->rss.queue_num = 1;
                (*flow->queue)[0] = queue->index;
+               flow->actions |= MLX5_FLOW_ACTION_QUEUE;
                break;
        case RTE_FLOW_ACTION_TYPE_RSS:
                rss = action->conf;
@@ -999,6 +1108,7 @@ flow_dv_create_action(const struct rte_flow_action *action,
                flow->rss.types = rss->types;
                flow->rss.level = rss->level;
                /* Added to array only in apply since we need the QP */
+               flow->actions |= MLX5_FLOW_ACTION_RSS;
                break;
        default:
                break;
@@ -1211,7 +1321,8 @@ flow_dv_apply(struct rte_eth_dev *dev, struct rte_flow *flow,
                        dv->actions[n].type = MLX5DV_FLOW_ACTION_DEST_IBV_QP;
                        dv->actions[n].qp = dv->hrxq->qp;
                        n++;
-               } else {
+               } else if (flow->actions &
+                          (MLX5_FLOW_ACTION_QUEUE | MLX5_FLOW_ACTION_RSS)) {
                        struct mlx5_hrxq *hrxq;
                        hrxq = mlx5_hrxq_get(dev, flow->key,
                                             MLX5_RSS_HASH_KEY_LEN,
@@ -1359,22 +1470,31 @@ flow_dv_destroy(struct rte_eth_dev *dev, struct rte_flow *flow)
 }
 
 /**
- * Fills the flow_ops with the function pointers.
+ * Query a flow.
  *
- * @param[out] flow_ops
- *   Pointer to driver_ops structure.
+ * @see rte_flow_query()
+ * @see rte_flow_ops
  */
-void
-mlx5_flow_dv_get_driver_ops(struct mlx5_flow_driver_ops *flow_ops)
+static int
+flow_dv_query(struct rte_eth_dev *dev __rte_unused,
+             struct rte_flow *flow __rte_unused,
+             const struct rte_flow_action *actions __rte_unused,
+             void *data __rte_unused,
+             struct rte_flow_error *error __rte_unused)
 {
-       *flow_ops = (struct mlx5_flow_driver_ops) {
-               .validate = flow_dv_validate,
-               .prepare = flow_dv_prepare,
-               .translate = flow_dv_translate,
-               .apply = flow_dv_apply,
-               .remove = flow_dv_remove,
-               .destroy = flow_dv_destroy,
-       };
+       rte_errno = ENOTSUP;
+       return -rte_errno;
 }
 
+
+const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
+       .validate = flow_dv_validate,
+       .prepare = flow_dv_prepare,
+       .translate = flow_dv_translate,
+       .apply = flow_dv_apply,
+       .remove = flow_dv_remove,
+       .destroy = flow_dv_destroy,
+       .query = flow_dv_query,
+};
+
 #endif /* HAVE_IBV_FLOW_DV_SUPPORT */