[09/13] net/mlx5: add internal tag item and action
Checks
Commit Message
This commit introduce the setting and matching on regiters.
This item and and action will be used with number of different
features like hairpin, metering, metadata.
Signed-off-by: Ori Kam <orika@mellanox.com>
---
drivers/net/mlx5/mlx5_flow.c | 52 +++++++++++++
drivers/net/mlx5/mlx5_flow.h | 54 ++++++++++++--
drivers/net/mlx5/mlx5_flow_dv.c | 158 +++++++++++++++++++++++++++++++++++++++-
drivers/net/mlx5/mlx5_prm.h | 3 +-
4 files changed, 257 insertions(+), 10 deletions(-)
Comments
> -----Original Message-----
> From: Ori Kam <orika@mellanox.com>
> Sent: Thursday, September 26, 2019 9:29
> To: Matan Azrad <matan@mellanox.com>; Shahaf Shuler
> <shahafs@mellanox.com>; Slava Ovsiienko <viacheslavo@mellanox.com>
> Cc: dev@dpdk.org; Ori Kam <orika@mellanox.com>; jingjing.wu@intel.com;
> stephen@networkplumber.org
> Subject: [PATCH 09/13] net/mlx5: add internal tag item and action
>
> This commit introduce the setting and matching on regiters.
> This item and and action will be used with number of different features like
> hairpin, metering, metadata.
>
> Signed-off-by: Ori Kam <orika@mellanox.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
> ---
> drivers/net/mlx5/mlx5_flow.c | 52 +++++++++++++
> drivers/net/mlx5/mlx5_flow.h | 54 ++++++++++++--
> drivers/net/mlx5/mlx5_flow_dv.c | 158
> +++++++++++++++++++++++++++++++++++++++-
> drivers/net/mlx5/mlx5_prm.h | 3 +-
> 4 files changed, 257 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> index 482f65b..00afc18 100644
> --- a/drivers/net/mlx5/mlx5_flow.c
> +++ b/drivers/net/mlx5/mlx5_flow.c
> @@ -316,6 +316,58 @@ struct mlx5_flow_tunnel_info {
> },
> };
>
> +enum mlx5_feature_name {
> + MLX5_HAIRPIN_RX,
> + MLX5_HAIRPIN_TX,
> + MLX5_APPLICATION,
> +};
> +
> +/**
> + * Translate tag ID to register.
> + *
> + * @param[in] dev
> + * Pointer to the Ethernet device structure.
> + * @param[in] feature
> + * The feature that request the register.
> + * @param[in] id
> + * The request register ID.
> + * @param[out] error
> + * Error description in case of any.
> + *
> + * @return
> + * The request register on success, a negative errno
> + * value otherwise and rte_errno is set.
> + */
> +__rte_unused
> +static enum modify_reg flow_get_reg_id(struct rte_eth_dev *dev,
> + enum mlx5_feature_name feature,
> + uint32_t id,
> + struct rte_flow_error *error) {
> + static enum modify_reg id2reg[] = {
> + [0] = REG_A,
> + [1] = REG_C_2,
> + [2] = REG_C_3,
> + [3] = REG_C_4,
> + [4] = REG_B,};
> +
> + dev = (void *)dev;
> + switch (feature) {
> + case MLX5_HAIRPIN_RX:
> + return REG_B;
> + case MLX5_HAIRPIN_TX:
> + return REG_A;
> + case MLX5_APPLICATION:
> + if (id > 4)
> + return rte_flow_error_set(error, EINVAL,
> +
> RTE_FLOW_ERROR_TYPE_ITEM,
> + NULL, "invalid tag id");
> + return id2reg[id];
> + }
> + return rte_flow_error_set(error, EINVAL,
> RTE_FLOW_ERROR_TYPE_ITEM,
> + NULL, "invalid feature name");
> +}
> +
> /**
> * Discover the maximum number of priority available.
> *
> diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
> index 235bccd..0148c1b 100644
> --- a/drivers/net/mlx5/mlx5_flow.h
> +++ b/drivers/net/mlx5/mlx5_flow.h
> @@ -27,6 +27,43 @@
> #include "mlx5.h"
> #include "mlx5_prm.h"
>
> +enum modify_reg {
> + REG_A,
> + REG_B,
> + REG_C_0,
> + REG_C_1,
> + REG_C_2,
> + REG_C_3,
> + REG_C_4,
> + REG_C_5,
> + REG_C_6,
> + REG_C_7,
> +};
> +
> +/* Private rte flow items. */
> +enum mlx5_rte_flow_item_type {
> + MLX5_RTE_FLOW_ITEM_TYPE_END = INT_MIN,
> + MLX5_RTE_FLOW_ITEM_TYPE_TAG,
> +};
> +
> +/* Private rte flow actions. */
> +enum mlx5_rte_flow_action_type {
> + MLX5_RTE_FLOW_ACTION_TYPE_END = INT_MIN,
> + MLX5_RTE_FLOW_ACTION_TYPE_TAG,
> +};
> +
> +/* Matches on selected register. */
> +struct mlx5_rte_flow_item_tag {
> + uint16_t id;
> + rte_be32_t data;
> +};
> +
> +/* Modify selected register. */
> +struct mlx5_rte_flow_action_set_tag {
> + uint16_t id;
> + rte_be32_t data;
> +};
> +
> /* Pattern outer Layer bits. */
> #define MLX5_FLOW_LAYER_OUTER_L2 (1u << 0) #define
> MLX5_FLOW_LAYER_OUTER_L3_IPV4 (1u << 1) @@ -53,16 +90,17 @@
> /* General pattern items bits. */
> #define MLX5_FLOW_ITEM_METADATA (1u << 16) #define
> MLX5_FLOW_ITEM_PORT_ID (1u << 17)
> +#define MLX5_FLOW_ITEM_TAG (1u << 18)
>
> /* Pattern MISC bits. */
> -#define MLX5_FLOW_LAYER_ICMP (1u << 18) -#define
> MLX5_FLOW_LAYER_ICMP6 (1u << 19) -#define
> MLX5_FLOW_LAYER_GRE_KEY (1u << 20)
> +#define MLX5_FLOW_LAYER_ICMP (1u << 19) #define
> MLX5_FLOW_LAYER_ICMP6
> +(1u << 20) #define MLX5_FLOW_LAYER_GRE_KEY (1u << 21)
>
> /* Pattern tunnel Layer bits (continued). */ -#define
> MLX5_FLOW_LAYER_IPIP (1u << 21) -#define
> MLX5_FLOW_LAYER_IPV6_ENCAP (1u << 22) -#define
> MLX5_FLOW_LAYER_NVGRE (1u << 23)
> +#define MLX5_FLOW_LAYER_IPIP (1u << 22) #define
> +MLX5_FLOW_LAYER_IPV6_ENCAP (1u << 23) #define
> MLX5_FLOW_LAYER_NVGRE (1u
> +<< 24)
>
> /* Outer Masks. */
> #define MLX5_FLOW_LAYER_OUTER_L3 \
> @@ -139,6 +177,7 @@
> #define MLX5_FLOW_ACTION_DEC_TCP_SEQ (1u << 29) #define
> MLX5_FLOW_ACTION_INC_TCP_ACK (1u << 30) #define
> MLX5_FLOW_ACTION_DEC_TCP_ACK (1u << 31)
> +#define MLX5_FLOW_ACTION_SET_TAG (1ull << 32)
>
> #define MLX5_FLOW_FATE_ACTIONS \
> (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
> @@ -172,7 +211,8 @@
> MLX5_FLOW_ACTION_DEC_TCP_SEQ | \
> MLX5_FLOW_ACTION_INC_TCP_ACK | \
> MLX5_FLOW_ACTION_DEC_TCP_ACK | \
> -
> MLX5_FLOW_ACTION_OF_SET_VLAN_VID)
> +
> MLX5_FLOW_ACTION_OF_SET_VLAN_VID | \
> + MLX5_FLOW_ACTION_SET_TAG)
>
> #define MLX5_FLOW_VLAN_ACTIONS
> (MLX5_FLOW_ACTION_OF_POP_VLAN | \
> MLX5_FLOW_ACTION_OF_PUSH_VLAN)
> diff --git a/drivers/net/mlx5/mlx5_flow_dv.c
> b/drivers/net/mlx5/mlx5_flow_dv.c index 2a7e3ed..dde0831 100644
> --- a/drivers/net/mlx5/mlx5_flow_dv.c
> +++ b/drivers/net/mlx5/mlx5_flow_dv.c
> @@ -723,6 +723,59 @@ struct field_modify_info modify_tcp[] = {
>
> MLX5_MODIFICATION_TYPE_ADD, error); }
>
> +static enum mlx5_modification_field reg_to_field[] = {
> + [REG_A] = MLX5_MODI_META_DATA_REG_A,
> + [REG_B] = MLX5_MODI_META_DATA_REG_B,
> + [REG_C_0] = MLX5_MODI_META_REG_C_0,
> + [REG_C_1] = MLX5_MODI_META_REG_C_1,
> + [REG_C_2] = MLX5_MODI_META_REG_C_2,
> + [REG_C_3] = MLX5_MODI_META_REG_C_3,
> + [REG_C_4] = MLX5_MODI_META_REG_C_4,
> + [REG_C_5] = MLX5_MODI_META_REG_C_5,
> + [REG_C_6] = MLX5_MODI_META_REG_C_6,
> + [REG_C_7] = MLX5_MODI_META_REG_C_7,
> +};
> +
> +/**
> + * Convert register set to DV specification.
> + *
> + * @param[in,out] resource
> + * Pointer to the modify-header resource.
> + * @param[in] action
> + * Pointer to action specification.
> + * @param[out] error
> + * Pointer to the error structure.
> + *
> + * @return
> + * 0 on success, a negative errno value otherwise and rte_errno is set.
> + */
> +static int
> +flow_dv_convert_action_set_reg
> + (struct mlx5_flow_dv_modify_hdr_resource
> *resource,
> + const struct rte_flow_action *action,
> + struct rte_flow_error *error)
> +{
> + const struct mlx5_rte_flow_action_set_tag *conf = (action->conf);
> + struct mlx5_modification_cmd *actions = resource->actions;
> + uint32_t i = resource->actions_num;
> +
> + if (i >= MLX5_MODIFY_NUM)
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION,
> NULL,
> + "too many items to modify");
> + actions[i].action_type = MLX5_MODIFICATION_TYPE_SET;
> + actions[i].field = reg_to_field[conf->id];
> + actions[i].data0 = rte_cpu_to_be_32(actions[i].data0);
> + actions[i].data1 = conf->data;
> + ++i;
> + resource->actions_num = i;
> + if (!resource->actions_num)
> + return rte_flow_error_set(error, EINVAL,
> + RTE_FLOW_ERROR_TYPE_ACTION,
> NULL,
> + "invalid modification flow item");
> + return 0;
> +}
> +
> /**
> * Validate META item.
> *
> @@ -4640,6 +4693,94 @@ struct field_modify_info modify_tcp[] = { }
>
> /**
> + * Add tag item to matcher
> + *
> + * @param[in, out] matcher
> + * Flow matcher.
> + * @param[in, out] key
> + * Flow matcher value.
> + * @param[in] item
> + * Flow pattern to translate.
> + */
> +static void
> +flow_dv_translate_item_tag(void *matcher, void *key,
> + const struct rte_flow_item *item) {
> + 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);
> + const struct mlx5_rte_flow_item_tag *tag_v = item->spec;
> + const struct mlx5_rte_flow_item_tag *tag_m = item->mask;
> + enum modify_reg reg = tag_v->id;
> + rte_be32_t value = tag_v->data;
> + rte_be32_t mask = tag_m->data;
> +
> + switch (reg) {
> + case REG_A:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_a,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_a,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_B:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_b,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_b,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_C_0:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_c_0,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v,
> metadata_reg_c_0,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_C_1:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_c_1,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v,
> metadata_reg_c_1,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_C_2:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_c_2,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v,
> metadata_reg_c_2,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_C_3:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_c_3,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v,
> metadata_reg_c_3,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_C_4:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_c_4,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v,
> metadata_reg_c_4,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_C_5:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_c_5,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v,
> metadata_reg_c_5,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_C_6:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_c_6,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v,
> metadata_reg_c_6,
> + rte_be_to_cpu_32(value));
> + break;
> + case REG_C_7:
> + MLX5_SET(fte_match_set_misc2, misc2_m,
> metadata_reg_c_7,
> + rte_be_to_cpu_32(mask));
> + MLX5_SET(fte_match_set_misc2, misc2_v,
> metadata_reg_c_7,
> + rte_be_to_cpu_32(value));
> + break;
> + }
> +}
> +
> +/**
> * Add source vport match to the specified matcher.
> *
> * @param[in, out] matcher
> @@ -5225,8 +5366,9 @@ struct field_modify_info modify_tcp[] = {
> struct mlx5_flow_tbl_resource *tbl;
> uint32_t port_id = 0;
> struct mlx5_flow_dv_port_id_action_resource
> port_id_resource;
> + int action_type = actions->type;
>
> - switch (actions->type) {
> + switch (action_type) {
> case RTE_FLOW_ACTION_TYPE_VOID:
> break;
> case RTE_FLOW_ACTION_TYPE_PORT_ID:
> @@ -5541,6 +5683,12 @@ struct field_modify_info modify_tcp[] = {
> MLX5_FLOW_ACTION_INC_TCP_ACK
> :
>
> MLX5_FLOW_ACTION_DEC_TCP_ACK;
> break;
> + case MLX5_RTE_FLOW_ACTION_TYPE_TAG:
> + if (flow_dv_convert_action_set_reg(&res, actions,
> + error))
> + return -rte_errno;
> + action_flags |= MLX5_FLOW_ACTION_SET_TAG;
> + break;
> case RTE_FLOW_ACTION_TYPE_END:
> actions_end = true;
> if (action_flags &
> MLX5_FLOW_MODIFY_HDR_ACTIONS) { @@ -5565,8 +5713,9 @@ struct
> field_modify_info modify_tcp[] = {
> flow->actions = action_flags;
> for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
> int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
> + int item_type = items->type;
>
> - switch (items->type) {
> + switch (item_type) {
> case RTE_FLOW_ITEM_TYPE_PORT_ID:
> flow_dv_translate_item_port_id(dev, match_mask,
> match_value, items);
> @@ -5712,6 +5861,11 @@ struct field_modify_info modify_tcp[] = {
> items, tunnel);
> last_item = MLX5_FLOW_LAYER_ICMP6;
> break;
> + case MLX5_RTE_FLOW_ITEM_TYPE_TAG:
> + flow_dv_translate_item_tag(match_mask,
> match_value,
> + items);
> + last_item = MLX5_FLOW_ITEM_TAG;
> + break;
> default:
> break;
> }
> diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
> index d4084db..695578f 100644
> --- a/drivers/net/mlx5/mlx5_prm.h
> +++ b/drivers/net/mlx5/mlx5_prm.h
> @@ -623,7 +623,8 @@ struct mlx5_ifc_fte_match_set_misc2_bits {
> u8 metadata_reg_c_1[0x20];
> u8 metadata_reg_c_0[0x20];
> u8 metadata_reg_a[0x20];
> - u8 reserved_at_1a0[0x60];
> + u8 metadata_reg_b[0x20];
> + u8 reserved_at_1c0[0x40];
> };
>
> struct mlx5_ifc_fte_match_set_misc3_bits {
> --
> 1.8.3.1
@@ -316,6 +316,58 @@ struct mlx5_flow_tunnel_info {
},
};
+enum mlx5_feature_name {
+ MLX5_HAIRPIN_RX,
+ MLX5_HAIRPIN_TX,
+ MLX5_APPLICATION,
+};
+
+/**
+ * Translate tag ID to register.
+ *
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
+ * @param[in] feature
+ * The feature that request the register.
+ * @param[in] id
+ * The request register ID.
+ * @param[out] error
+ * Error description in case of any.
+ *
+ * @return
+ * The request register on success, a negative errno
+ * value otherwise and rte_errno is set.
+ */
+__rte_unused
+static enum modify_reg flow_get_reg_id(struct rte_eth_dev *dev,
+ enum mlx5_feature_name feature,
+ uint32_t id,
+ struct rte_flow_error *error)
+{
+ static enum modify_reg id2reg[] = {
+ [0] = REG_A,
+ [1] = REG_C_2,
+ [2] = REG_C_3,
+ [3] = REG_C_4,
+ [4] = REG_B,};
+
+ dev = (void *)dev;
+ switch (feature) {
+ case MLX5_HAIRPIN_RX:
+ return REG_B;
+ case MLX5_HAIRPIN_TX:
+ return REG_A;
+ case MLX5_APPLICATION:
+ if (id > 4)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "invalid tag id");
+ return id2reg[id];
+ }
+ return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
+ NULL, "invalid feature name");
+}
+
/**
* Discover the maximum number of priority available.
*
@@ -27,6 +27,43 @@
#include "mlx5.h"
#include "mlx5_prm.h"
+enum modify_reg {
+ REG_A,
+ REG_B,
+ REG_C_0,
+ REG_C_1,
+ REG_C_2,
+ REG_C_3,
+ REG_C_4,
+ REG_C_5,
+ REG_C_6,
+ REG_C_7,
+};
+
+/* Private rte flow items. */
+enum mlx5_rte_flow_item_type {
+ MLX5_RTE_FLOW_ITEM_TYPE_END = INT_MIN,
+ MLX5_RTE_FLOW_ITEM_TYPE_TAG,
+};
+
+/* Private rte flow actions. */
+enum mlx5_rte_flow_action_type {
+ MLX5_RTE_FLOW_ACTION_TYPE_END = INT_MIN,
+ MLX5_RTE_FLOW_ACTION_TYPE_TAG,
+};
+
+/* Matches on selected register. */
+struct mlx5_rte_flow_item_tag {
+ uint16_t id;
+ rte_be32_t data;
+};
+
+/* Modify selected register. */
+struct mlx5_rte_flow_action_set_tag {
+ uint16_t id;
+ rte_be32_t data;
+};
+
/* Pattern outer Layer bits. */
#define MLX5_FLOW_LAYER_OUTER_L2 (1u << 0)
#define MLX5_FLOW_LAYER_OUTER_L3_IPV4 (1u << 1)
@@ -53,16 +90,17 @@
/* General pattern items bits. */
#define MLX5_FLOW_ITEM_METADATA (1u << 16)
#define MLX5_FLOW_ITEM_PORT_ID (1u << 17)
+#define MLX5_FLOW_ITEM_TAG (1u << 18)
/* Pattern MISC bits. */
-#define MLX5_FLOW_LAYER_ICMP (1u << 18)
-#define MLX5_FLOW_LAYER_ICMP6 (1u << 19)
-#define MLX5_FLOW_LAYER_GRE_KEY (1u << 20)
+#define MLX5_FLOW_LAYER_ICMP (1u << 19)
+#define MLX5_FLOW_LAYER_ICMP6 (1u << 20)
+#define MLX5_FLOW_LAYER_GRE_KEY (1u << 21)
/* Pattern tunnel Layer bits (continued). */
-#define MLX5_FLOW_LAYER_IPIP (1u << 21)
-#define MLX5_FLOW_LAYER_IPV6_ENCAP (1u << 22)
-#define MLX5_FLOW_LAYER_NVGRE (1u << 23)
+#define MLX5_FLOW_LAYER_IPIP (1u << 22)
+#define MLX5_FLOW_LAYER_IPV6_ENCAP (1u << 23)
+#define MLX5_FLOW_LAYER_NVGRE (1u << 24)
/* Outer Masks. */
#define MLX5_FLOW_LAYER_OUTER_L3 \
@@ -139,6 +177,7 @@
#define MLX5_FLOW_ACTION_DEC_TCP_SEQ (1u << 29)
#define MLX5_FLOW_ACTION_INC_TCP_ACK (1u << 30)
#define MLX5_FLOW_ACTION_DEC_TCP_ACK (1u << 31)
+#define MLX5_FLOW_ACTION_SET_TAG (1ull << 32)
#define MLX5_FLOW_FATE_ACTIONS \
(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
@@ -172,7 +211,8 @@
MLX5_FLOW_ACTION_DEC_TCP_SEQ | \
MLX5_FLOW_ACTION_INC_TCP_ACK | \
MLX5_FLOW_ACTION_DEC_TCP_ACK | \
- MLX5_FLOW_ACTION_OF_SET_VLAN_VID)
+ MLX5_FLOW_ACTION_OF_SET_VLAN_VID | \
+ MLX5_FLOW_ACTION_SET_TAG)
#define MLX5_FLOW_VLAN_ACTIONS (MLX5_FLOW_ACTION_OF_POP_VLAN | \
MLX5_FLOW_ACTION_OF_PUSH_VLAN)
@@ -723,6 +723,59 @@ struct field_modify_info modify_tcp[] = {
MLX5_MODIFICATION_TYPE_ADD, error);
}
+static enum mlx5_modification_field reg_to_field[] = {
+ [REG_A] = MLX5_MODI_META_DATA_REG_A,
+ [REG_B] = MLX5_MODI_META_DATA_REG_B,
+ [REG_C_0] = MLX5_MODI_META_REG_C_0,
+ [REG_C_1] = MLX5_MODI_META_REG_C_1,
+ [REG_C_2] = MLX5_MODI_META_REG_C_2,
+ [REG_C_3] = MLX5_MODI_META_REG_C_3,
+ [REG_C_4] = MLX5_MODI_META_REG_C_4,
+ [REG_C_5] = MLX5_MODI_META_REG_C_5,
+ [REG_C_6] = MLX5_MODI_META_REG_C_6,
+ [REG_C_7] = MLX5_MODI_META_REG_C_7,
+};
+
+/**
+ * Convert register set to DV specification.
+ *
+ * @param[in,out] resource
+ * Pointer to the modify-header resource.
+ * @param[in] action
+ * Pointer to action specification.
+ * @param[out] error
+ * Pointer to the error structure.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+flow_dv_convert_action_set_reg
+ (struct mlx5_flow_dv_modify_hdr_resource *resource,
+ const struct rte_flow_action *action,
+ struct rte_flow_error *error)
+{
+ const struct mlx5_rte_flow_action_set_tag *conf = (action->conf);
+ struct mlx5_modification_cmd *actions = resource->actions;
+ uint32_t i = resource->actions_num;
+
+ if (i >= MLX5_MODIFY_NUM)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "too many items to modify");
+ actions[i].action_type = MLX5_MODIFICATION_TYPE_SET;
+ actions[i].field = reg_to_field[conf->id];
+ actions[i].data0 = rte_cpu_to_be_32(actions[i].data0);
+ actions[i].data1 = conf->data;
+ ++i;
+ resource->actions_num = i;
+ if (!resource->actions_num)
+ return rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+ "invalid modification flow item");
+ return 0;
+}
+
/**
* Validate META item.
*
@@ -4640,6 +4693,94 @@ struct field_modify_info modify_tcp[] = {
}
/**
+ * Add tag item to matcher
+ *
+ * @param[in, out] matcher
+ * Flow matcher.
+ * @param[in, out] key
+ * Flow matcher value.
+ * @param[in] item
+ * Flow pattern to translate.
+ */
+static void
+flow_dv_translate_item_tag(void *matcher, void *key,
+ const struct rte_flow_item *item)
+{
+ 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);
+ const struct mlx5_rte_flow_item_tag *tag_v = item->spec;
+ const struct mlx5_rte_flow_item_tag *tag_m = item->mask;
+ enum modify_reg reg = tag_v->id;
+ rte_be32_t value = tag_v->data;
+ rte_be32_t mask = tag_m->data;
+
+ switch (reg) {
+ case REG_A:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_a,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_a,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_B:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_b,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_b,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_C_0:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_0,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_0,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_C_1:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_1,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_1,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_C_2:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_2,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_2,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_C_3:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_3,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_3,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_C_4:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_4,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_4,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_C_5:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_5,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_5,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_C_6:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_6,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_6,
+ rte_be_to_cpu_32(value));
+ break;
+ case REG_C_7:
+ MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_7,
+ rte_be_to_cpu_32(mask));
+ MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_7,
+ rte_be_to_cpu_32(value));
+ break;
+ }
+}
+
+/**
* Add source vport match to the specified matcher.
*
* @param[in, out] matcher
@@ -5225,8 +5366,9 @@ struct field_modify_info modify_tcp[] = {
struct mlx5_flow_tbl_resource *tbl;
uint32_t port_id = 0;
struct mlx5_flow_dv_port_id_action_resource port_id_resource;
+ int action_type = actions->type;
- switch (actions->type) {
+ switch (action_type) {
case RTE_FLOW_ACTION_TYPE_VOID:
break;
case RTE_FLOW_ACTION_TYPE_PORT_ID:
@@ -5541,6 +5683,12 @@ struct field_modify_info modify_tcp[] = {
MLX5_FLOW_ACTION_INC_TCP_ACK :
MLX5_FLOW_ACTION_DEC_TCP_ACK;
break;
+ case MLX5_RTE_FLOW_ACTION_TYPE_TAG:
+ if (flow_dv_convert_action_set_reg(&res, actions,
+ error))
+ return -rte_errno;
+ action_flags |= MLX5_FLOW_ACTION_SET_TAG;
+ break;
case RTE_FLOW_ACTION_TYPE_END:
actions_end = true;
if (action_flags & MLX5_FLOW_MODIFY_HDR_ACTIONS) {
@@ -5565,8 +5713,9 @@ struct field_modify_info modify_tcp[] = {
flow->actions = action_flags;
for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
+ int item_type = items->type;
- switch (items->type) {
+ switch (item_type) {
case RTE_FLOW_ITEM_TYPE_PORT_ID:
flow_dv_translate_item_port_id(dev, match_mask,
match_value, items);
@@ -5712,6 +5861,11 @@ struct field_modify_info modify_tcp[] = {
items, tunnel);
last_item = MLX5_FLOW_LAYER_ICMP6;
break;
+ case MLX5_RTE_FLOW_ITEM_TYPE_TAG:
+ flow_dv_translate_item_tag(match_mask, match_value,
+ items);
+ last_item = MLX5_FLOW_ITEM_TAG;
+ break;
default:
break;
}
@@ -623,7 +623,8 @@ struct mlx5_ifc_fte_match_set_misc2_bits {
u8 metadata_reg_c_1[0x20];
u8 metadata_reg_c_0[0x20];
u8 metadata_reg_a[0x20];
- u8 reserved_at_1a0[0x60];
+ u8 metadata_reg_b[0x20];
+ u8 reserved_at_1c0[0x40];
};
struct mlx5_ifc_fte_match_set_misc3_bits {