MLX5 PARSE_GRAPH_NODE defines the header_length_field_offset_mode bit,
starting from ConnectX-8. The bit value must match
HCA_CAP.header_length_field_offset_mode.

1. The patch copies header_length_field_offset_mode bit from a port
PARSE_GRAPH node capabilities to PARSE_GRAPH node definition.

2. The patch fixes the header_length_field_offset value to match
HCA_CAP.header_length_mask_width.

3. The patch replaces the static value in PARSE_GRAPH node
header_length_field_mask definition with one that matches
HCA_CAP.header_length_mask_width.

Fixes: a2234609bf7e ("net/mlx5: fix flex flow item header length")
Cc: [email protected]

Signed-off-by: Gregory Etelson <[email protected]>
Acked-by: Viacheslav Ovsiienko <[email protected]>
---
 drivers/net/mlx5/mlx5.c           | 28 +++++++++++++++++-----------
 drivers/net/mlx5/mlx5.h           |  3 ++-
 drivers/net/mlx5/mlx5_flow.h      |  2 ++
 drivers/net/mlx5/mlx5_flow_flex.c |  2 +-
 4 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index decf540c51..3884caed01 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1038,6 +1038,11 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
        return (rte_errno == 0) ? -ENODEV : -rte_errno;
 }
 
+/* IPv6 SRH header is defined in RFC 8754 */
+#define MLX5_SRH_HEADER_LENGTH_FIELD_OFFSET 8
+#define MLX5_SRH_HEADER_LENGTH_FIELD_SIZE 8
+#define MLX5_SRH_HEADER_LENGTH_SHIFT 3
+
 /*
  * Allocation of a flex parser for srh. Once refcnt is zero, the resources held
  * by this parser will be freed.
@@ -1078,18 +1083,14 @@ mlx5_alloc_srh_flex_parser(struct rte_eth_dev *dev)
        /* Srv6 first two DW are not counted in. */
        node.header_length_base_value = 0x8;
        /* The unit is uint64_t. */
-       node.header_length_field_shift = 0x3;
+       node.header_length_field_shift = MLX5_SRH_HEADER_LENGTH_SHIFT;
+       node.header_length_field_offset_mode = 
!attr->header_length_field_mode_wa;
        /* Header length is the 2nd byte. */
-       if (attr->header_length_field_mode_wa) {
-               /* Legacy firmware before ConnectX-8, we should provide offset 
WA. */
-               node.header_length_field_offset = 8;
-               if (attr->header_length_mask_width < 8)
-                       node.header_length_field_offset += 8 - 
attr->header_length_mask_width;
-       } else {
-               /* The new firmware, we can specify the correct offset 
directly. */
-               node.header_length_field_offset = 12;
-       }
-       node.header_length_field_mask = 0xF;
+       node.header_length_field_offset = MLX5_SRH_HEADER_LENGTH_FIELD_OFFSET;
+       if (attr->header_length_mask_width < MLX5_SRH_HEADER_LENGTH_FIELD_SIZE)
+               node.header_length_field_offset +=
+                       MLX5_SRH_HEADER_LENGTH_FIELD_SIZE - 
attr->header_length_mask_width;
+       node.header_length_field_mask = 
mlx5_flex_hdr_len_mask(MLX5_SRH_HEADER_LENGTH_SHIFT, attr);
        /* One byte next header protocol. */
        node.next_header_field_size = 0x8;
        node.in[0].arc_parse_graph_node = MLX5_GRAPH_ARC_NODE_IP;
@@ -1143,6 +1144,11 @@ mlx5_alloc_srh_flex_parser(struct rte_eth_dev *dev)
                                                (i + 1) * sizeof(uint32_t) * 
CHAR_BIT;
        }
        priv->sh->srh_flex_parser.flex.map[0].shift = 0;
+       DRV_LOG(NOTICE,
+               "SRH flex parser node object is created successfully. "
+               "Header extension length field size: %d bits\n",
+               attr->header_length_mask_width > 
MLX5_SRH_HEADER_LENGTH_FIELD_SIZE ?
+               MLX5_SRH_HEADER_LENGTH_FIELD_SIZE : 
attr->header_length_mask_width);
        return 0;
 error:
        if (fp)
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 966e802f5f..d84445db49 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1472,7 +1472,8 @@ struct mlx5_flex_item {
 };
 
 /*
- * Sample an IPv6 address and the first dword of SRv6 header.
+ * Sample IPv6 address in the first segment list
+ * and the first dword of SRv6 header.
  * Then it is 16 + 4 = 20 bytes which is 5 dwords.
  */
 #define MLX5_SRV6_SAMPLE_NUM 5
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 218b55d536..cad1a00265 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -3712,6 +3712,8 @@ flow_hw_get_ipv6_route_ext_mod_id_from_ctx(void *dr_ctx, 
uint8_t idx)
        return 0;
 }
 
+uint8_t mlx5_flex_hdr_len_mask(uint8_t shift, const struct mlx5_hca_flex_attr 
*attr);
+
 static inline bool
 mlx5_dv_modify_ipv6_traffic_class_supported(struct mlx5_priv *priv)
 {
diff --git a/drivers/net/mlx5/mlx5_flow_flex.c 
b/drivers/net/mlx5/mlx5_flow_flex.c
index d21e28f7fd..12d79ffb9e 100644
--- a/drivers/net/mlx5/mlx5_flow_flex.c
+++ b/drivers/net/mlx5/mlx5_flow_flex.c
@@ -458,7 +458,7 @@ mlx5_flex_release_index(struct rte_eth_dev *dev,
  *    6     b00000011  0x03
  *    7     b00000001  0x01
  */
-static uint8_t
+uint8_t
 mlx5_flex_hdr_len_mask(uint8_t shift,
                       const struct mlx5_hca_flex_attr *attr)
 {
-- 
2.51.0

Reply via email to