From abde8206f236c39b33498b8098c4760f68d78f18 Mon Sep 17 00:00:00 2001 From: Viacheslav Ovsiienko Date: Fri, 17 Jan 2020 11:01:34 +0000 Subject: [PATCH] net/mlx5: fix shared metadata matcher field setup Matcher is flow table related structure providing the flow pattern to be translated directly in hardware controlling data. Some fields in this structure might be split (by software) between multiple items. For example, the metadata register c0 field in the matcher might be split into two independent subfields - the source vport index and META item value. These subfields have no permanent assigned masks, the actual configuration is queried from the kernel drivers in runtime. To handle source vport value (the port of e-Switch which is origin of the packet) the kernel might use the dedicated vport field in the matcher or the part of register c0 field, depending on configuration. To setup the matcher structure fields the macro MLX5_SET is used. MLX5_SET configures the specified 32-bit field as whole entity. For metadata register c0 we should take into account the provided mask in order to configure the specified subfield bits only, otherwise setting vport overrides the META values and vice versa. Fixes: acfcd5c52f94 ("net/mlx5: update meta register matcher set") Cc: stable@dpdk.org Signed-off-by: Viacheslav Ovsiienko Acked-by: Matan Azrad --- drivers/net/mlx5/mlx5_flow_dv.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index e37ed93c12..e1b2534d9f 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -5920,6 +5920,7 @@ flow_dv_match_meta_reg(void *matcher, void *key, MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters_2); void *misc2_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters_2); + uint32_t temp; data &= mask; switch (reg_type) { @@ -5932,8 +5933,18 @@ flow_dv_match_meta_reg(void *matcher, void *key, MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_b, data); break; case REG_C_0: - MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_0, mask); - MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_0, data); + /* + * The metadata register C0 field might be divided into + * source vport index and META item value, we should set + * this field according to specified mask, not as whole one. + */ + temp = MLX5_GET(fte_match_set_misc2, misc2_m, metadata_reg_c_0); + temp |= mask; + MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_0, temp); + temp = MLX5_GET(fte_match_set_misc2, misc2_v, metadata_reg_c_0); + temp &= ~mask; + temp |= data; + MLX5_SET(fte_match_set_misc2, misc2_v, metadata_reg_c_0, temp); break; case REG_C_1: MLX5_SET(fte_match_set_misc2, misc2_m, metadata_reg_c_1, mask); -- 2.20.1