> -----Original Message----- > From: Ori Kam <or...@mellanox.com> > Sent: Thursday, September 26, 2019 9:29 > To: Matan Azrad <ma...@mellanox.com>; Shahaf Shuler > <shah...@mellanox.com>; Slava Ovsiienko <viachesl...@mellanox.com> > Cc: dev@dpdk.org; Ori Kam <or...@mellanox.com>; jingjing...@intel.com; > step...@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 <or...@mellanox.com> Acked-by: Viacheslav Ovsiienko <viachesl...@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