From patchwork Fri Oct 4 19:54:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ori Kam X-Patchwork-Id: 60551 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2A39C1C440; Fri, 4 Oct 2019 21:55:45 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id 322461C300 for ; Fri, 4 Oct 2019 21:55:40 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE1 (envelope-from orika@mellanox.com) with ESMTPS (AES256-SHA encrypted); 4 Oct 2019 22:55:38 +0300 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 x94JsxSo006678; Fri, 4 Oct 2019 22:55:38 +0300 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: Fri, 4 Oct 2019 19:54:11 +0000 Message-Id: <1570218855-73478-11-git-send-email-orika@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1570218855-73478-1-git-send-email-orika@mellanox.com> References: <1569479349-36962-1-git-send-email-orika@mellanox.com> <1570218855-73478-1-git-send-email-orika@mellanox.com> Subject: [dpdk-dev] [PATCH v2 10/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 | 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 {