From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id A8AAEA009E for ; Sun, 27 Oct 2019 13:27:12 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id B75131BFCE; Sun, 27 Oct 2019 13:25:48 +0100 (CET) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id ED7801BF85 for ; Sun, 27 Oct 2019 13:25:30 +0100 (CET) Received: from Internal Mail-Server by MTLPINE1 (envelope-from orika@mellanox.com) with ESMTPS (AES256-SHA encrypted); 27 Oct 2019 14:25:26 +0200 Received: from pegasus04.mtr.labs.mlnx. (pegasus04.mtr.labs.mlnx [10.210.16.126]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id x9RCP6GA025523; Sun, 27 Oct 2019 14:25:26 +0200 From: Ori Kam To: Matan Azrad , Shahaf Shuler , Viacheslav Ovsiienko Cc: dev@dpdk.org, orika@mellanox.com, jingjing.wu@intel.com, stephen@networkplumber.org Date: Sun, 27 Oct 2019 12:24:58 +0000 Message-Id: <1572179102-163236-12-git-send-email-orika@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1572179102-163236-1-git-send-email-orika@mellanox.com> References: <1569479349-36962-1-git-send-email-orika@mellanox.com> <1572179102-163236-1-git-send-email-orika@mellanox.com> Subject: [dpdk-dev] [PATCH v6 11/14] net/mlx5: add internal tag item and action X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 Acked-by: Viacheslav Ovsiienko --- drivers/net/mlx5/mlx5_flow.c | 52 +++++++++++++ drivers/net/mlx5/mlx5_flow.h | 48 +++++++++++- drivers/net/mlx5/mlx5_flow_dv.c | 158 +++++++++++++++++++++++++++++++++++++++- drivers/net/mlx5/mlx5_prm.h | 3 +- 4 files changed, 254 insertions(+), 7 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index d4d956f..a309b6f 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 9658db1..a79b48b 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,11 +90,12 @@ /* 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) @@ -141,6 +179,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 | \ @@ -174,7 +213,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 e5f4c4c..1c9dc36 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -724,6 +724,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. * @@ -4720,6 +4773,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 @@ -5305,8 +5446,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: @@ -5621,6 +5763,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) { @@ -5645,8 +5793,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); @@ -5797,6 +5946,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 e4b19f8..96b9166 100644 --- a/drivers/net/mlx5/mlx5_prm.h +++ b/drivers/net/mlx5/mlx5_prm.h @@ -628,7 +628,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