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 4B9C9A0528; Fri, 17 Jul 2020 09:12:18 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E03441BF5C; Fri, 17 Jul 2020 09:12:03 +0200 (CEST) Received: from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130]) by dpdk.org (Postfix) with ESMTP id F31691BEE1 for ; Fri, 17 Jul 2020 09:12:00 +0200 (CEST) From: Bing Zhao To: orika@mellanox.com, viacheslavo@mellanox.com Cc: rasland@mellanox.com, matan@mellanox.com, dev@dpdk.org, netanelg@mellanox.com Date: Fri, 17 Jul 2020 15:11:46 +0800 Message-Id: <1594969911-105341-3-git-send-email-bingz@mellanox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1594969911-105341-1-git-send-email-bingz@mellanox.com> References: <1594909426-64843-1-git-send-email-bingz@mellanox.com> <1594969911-105341-1-git-send-email-bingz@mellanox.com> Subject: [dpdk-dev] [PATCH v4 2/7] net/mlx5: add flow translation of eCPRI header 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" In the translation stage, the eCPRI item should be translated into the format that lower layer driver could use. All the fields that need to match must be in network byte order after translation, as well as the mask. Since the header in the item belongs to the network layers stack, and the input parameter of the header is considered to be in big-endian format already. Base on the definition in the PRM, the DW samples will be used for matching in the FTE/STE. Now, the type field and only the PC ID, RTC ID, and DLY MSR ID of the payload will be supported. The masks should be 00 ff 00 00 ff ff(00) 00 00 in the network order. Two DWs are needed to support such matching. The mask fields could be zeros to support some wildcard rules. But it makes no sense to support the rule matching only on the payload but without matching type field. The DW samples should be stored after the flex parser creation for eCPRI. There is no need to query the sample IDs each time when creating a flow rule with eCPRI item. It will not introduce insertion rate degradation significantly. Signed-off-by: Bing Zhao Acked-by: Viacheslav Ovsiienko --- v2: fix the endianess issue of type mask field checking. --- drivers/common/mlx5/mlx5_prm.h | 16 ++++++- drivers/net/mlx5/mlx5.c | 40 ++++++++++++++++ drivers/net/mlx5/mlx5.h | 18 +++++++ drivers/net/mlx5/mlx5_flow_dv.c | 102 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index b37be30..4c06c37 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -741,6 +741,18 @@ struct mlx5_ifc_fte_match_set_misc3_bits { u8 reserved_at_170[0x90]; }; +struct mlx5_ifc_fte_match_set_misc4_bits { + u8 prog_sample_field_value_0[0x20]; + u8 prog_sample_field_id_0[0x20]; + u8 prog_sample_field_value_1[0x20]; + u8 prog_sample_field_id_1[0x20]; + u8 prog_sample_field_value_2[0x20]; + u8 prog_sample_field_id_2[0x20]; + u8 prog_sample_field_value_3[0x20]; + u8 prog_sample_field_id_3[0x20]; + u8 reserved_at_100[0x100]; +}; + /* Flow matcher. */ struct mlx5_ifc_fte_match_param_bits { struct mlx5_ifc_fte_match_set_lyr_2_4_bits outer_headers; @@ -748,6 +760,7 @@ struct mlx5_ifc_fte_match_param_bits { struct mlx5_ifc_fte_match_set_lyr_2_4_bits inner_headers; struct mlx5_ifc_fte_match_set_misc2_bits misc_parameters_2; struct mlx5_ifc_fte_match_set_misc3_bits misc_parameters_3; + struct mlx5_ifc_fte_match_set_misc4_bits misc_parameters_4; }; enum { @@ -755,7 +768,8 @@ enum { MLX5_MATCH_CRITERIA_ENABLE_MISC_BIT, MLX5_MATCH_CRITERIA_ENABLE_INNER_BIT, MLX5_MATCH_CRITERIA_ENABLE_MISC2_BIT, - MLX5_MATCH_CRITERIA_ENABLE_MISC3_BIT + MLX5_MATCH_CRITERIA_ENABLE_MISC3_BIT, + MLX5_MATCH_CRITERIA_ENABLE_MISC4_BIT, }; enum { diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index 10196ac..1ba5e0c 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -608,6 +608,46 @@ struct mlx5_flow_id_pool * mlx5_ipool_destroy(sh->ipool[i]); } +/* + * Check if dynamic flex parser for eCPRI already exists. + * + * @param dev + * Pointer to Ethernet device structure. + * + * @return + * true on exists, false on not. + */ +bool +mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_flex_parser_profiles *prf = + &priv->sh->fp[MLX5_FLEX_PARSER_ECPRI_0]; + + return !!prf->obj; +} + +/* + * Allocation of a flex parser for eCPRI. Once created, this parser related + * resources will be held until the device is closed. + * + * @param dev + * Pointer to Ethernet device structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev) +{ + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_flex_parser_profiles *prf = + &priv->sh->fp[MLX5_FLEX_PARSER_ECPRI_0]; + + (void)prf; + return 0; +} + /** * Allocate shared device context. If there is multiport device the * master and representors will share this context, if there is single diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 1aa3a3e..9b29e3c 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -590,6 +590,20 @@ struct mlx5_dev_txpp { rte_atomic32_t err_ts_future; /* Timestamp in the distant future. */ }; +/* Supported flex parser profile ID. */ +enum mlx5_flex_parser_profile_id { + MLX5_FLEX_PARSER_ECPRI_0 = 0, + MLX5_FLEX_PARSER_MAX = 8, +}; + +/* Sample ID information of flex parser structure. */ +struct mlx5_flex_parser_profiles { + uint32_t num; /* Actual number of samples. */ + uint32_t ids[8]; /* Sample IDs for this profile. */ + uint8_t offset[8]; /* Bytes offset of each parser. */ + void *obj; /* Flex parser node object. */ +}; + /* * Shared Infiniband device context for Master/Representors * which belong to same IB device with multiple IB ports. @@ -649,6 +663,8 @@ struct mlx5_dev_ctx_shared { struct mlx5_devx_obj *td; /* Transport domain. */ struct mlx5_flow_id_pool *flow_id_pool; /* Flow ID pool. */ struct mlx5dv_devx_uar *tx_uar; /* Tx/packer pacing shared UAR. */ + struct mlx5_flex_parser_profiles fp[MLX5_FLEX_PARSER_MAX]; + /* Flex parser profiles information. */ struct mlx5_dev_shared_port port[]; /* per device port data array. */ }; @@ -784,6 +800,8 @@ int mlx5_dev_check_sibling_config(struct mlx5_priv *priv, int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu); int mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap); +bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev); +int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev); /* mlx5_ethdev.c */ diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index f042a42..cd2b0f0 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -7259,6 +7259,90 @@ struct field_modify_info modify_tcp[] = { rte_be_to_cpu_32(gtp_v->teid & gtp_m->teid)); } +/** + * Add eCPRI item to matcher and to the value. + * + * @param[in] dev + * The devich to configure through. + * @param[in, out] matcher + * Flow matcher. + * @param[in, out] key + * Flow matcher value. + * @param[in] item + * Flow pattern to translate. + * @param[in] samples + * Sample IDs to be used in the matching. + */ +static void +flow_dv_translate_item_ecpri(struct rte_eth_dev *dev, void *matcher, + void *key, const struct rte_flow_item *item) +{ + struct mlx5_priv *priv = dev->data->dev_private; + const struct rte_flow_item_ecpri *ecpri_m = item->mask; + const struct rte_flow_item_ecpri *ecpri_v = item->spec; + void *misc4_m = MLX5_ADDR_OF(fte_match_param, matcher, + misc_parameters_4); + void *misc4_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_4); + uint32_t *samples; + void *dw_m; + void *dw_v; + + if (!ecpri_v) + return; + if (!ecpri_m) + ecpri_m = &rte_flow_item_ecpri_mask; + /* + * Maximal four DW samples are supported in a single matching now. + * Two are used now for a eCPRI matching: + * 1. Type: one byte, mask should be 0x00ff0000 in network order + * 2. ID of a message: one or two bytes, mask 0xffff0000 or 0xff000000 + * if any. + */ + if (!ecpri_m->hdr.common.u32) + return; + samples = priv->sh->fp[MLX5_FLEX_PARSER_ECPRI_0].ids; + /* Need to take the whole DW as the mask to fill the entry. */ + dw_m = MLX5_ADDR_OF(fte_match_set_misc4, misc4_m, + prog_sample_field_value_0); + dw_v = MLX5_ADDR_OF(fte_match_set_misc4, misc4_v, + prog_sample_field_value_0); + /* Already big endian (network order) in the header. */ + *(uint32_t *)dw_m = ecpri_m->hdr.common.u32; + *(uint32_t *)dw_v = ecpri_v->hdr.common.u32; + /* Sample#0, used for matching type, offset 0. */ + MLX5_SET(fte_match_set_misc4, misc4_m, + prog_sample_field_id_0, samples[0]); + /* It makes no sense to set the sample ID in the mask field. */ + MLX5_SET(fte_match_set_misc4, misc4_v, + prog_sample_field_id_0, samples[0]); + /* + * Checking if message body part needs to be matched. + * Some wildcard rules only matching type field should be supported. + */ + if (ecpri_m->hdr.dummy[0]) { + switch (ecpri_v->hdr.common.type) { + case RTE_ECPRI_MSG_TYPE_IQ_DATA: + case RTE_ECPRI_MSG_TYPE_RTC_CTRL: + case RTE_ECPRI_MSG_TYPE_DLY_MSR: + dw_m = MLX5_ADDR_OF(fte_match_set_misc4, misc4_m, + prog_sample_field_value_1); + dw_v = MLX5_ADDR_OF(fte_match_set_misc4, misc4_v, + prog_sample_field_value_1); + *(uint32_t *)dw_m = ecpri_m->hdr.dummy[0]; + *(uint32_t *)dw_v = ecpri_v->hdr.dummy[0]; + /* Sample#1, to match message body, offset 4. */ + MLX5_SET(fte_match_set_misc4, misc4_m, + prog_sample_field_id_1, samples[1]); + MLX5_SET(fte_match_set_misc4, misc4_v, + prog_sample_field_id_1, samples[1]); + break; + default: + /* Others, do not match any sample ID. */ + break; + } + } +} + static uint32_t matcher_zero[MLX5_ST_SZ_DW(fte_match_param)] = { 0 }; #define HEADER_IS_ZERO(match_criteria, headers) \ @@ -7294,6 +7378,9 @@ struct field_modify_info modify_tcp[] = { match_criteria_enable |= (!HEADER_IS_ZERO(match_criteria, misc_parameters_3)) << MLX5_MATCH_CRITERIA_ENABLE_MISC3_BIT; + match_criteria_enable |= + (!HEADER_IS_ZERO(match_criteria, misc_parameters_4)) << + MLX5_MATCH_CRITERIA_ENABLE_MISC4_BIT; return match_criteria_enable; } @@ -8573,6 +8660,21 @@ struct field_modify_info modify_tcp[] = { MLX5_PRIORITY_MAP_L2 : MLX5_PRIORITY_MAP_L4; last_item = MLX5_FLOW_LAYER_GTP; break; + case RTE_FLOW_ITEM_TYPE_ECPRI: + if (!mlx5_flex_parser_ecpri_exist(dev)) { + ret = mlx5_flex_parser_ecpri_alloc(dev); + if (ret) + return rte_flow_error_set + (error, ret, + RTE_FLOW_ERROR_TYPE_ITEM, + NULL, + "cannot create eCPRI parser"); + } + flow_dv_translate_item_ecpri(dev, match_mask, + match_value, items); + /* No other protocol should follow eCPRI layer. */ + last_item = MLX5_FLOW_LAYER_ECPRI; + break; default: break; } -- 1.8.3.1