[v2,2/4] net/mlx5/hws: introduce encap entropy hash calculation API

Message ID 20240208090919.11565-2-orika@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series [v2,1/4] ethdev: introduce encap hash calculation |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Ori Kam Feb. 8, 2024, 9:09 a.m. UTC
  From: Hamdan Igbaria <hamdani@nvidia.com>

Add new function for encap entropy hash calculation, the function
will check the device capability for the entropy hash type used
by the device, and will calculate the entropy hash value of the
user passed fields according this type.

Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h      |  8 ++-
 drivers/net/mlx5/hws/mlx5dr.h       | 38 ++++++++++++++
 drivers/net/mlx5/hws/mlx5dr_cmd.c   | 23 +++++++++
 drivers/net/mlx5/hws/mlx5dr_cmd.h   |  4 ++
 drivers/net/mlx5/hws/mlx5dr_crc32.c | 78 +++++++++++++++++++++++++++++
 drivers/net/mlx5/hws/mlx5dr_crc32.h |  5 ++
 6 files changed, 154 insertions(+), 2 deletions(-)
  

Patch

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index f64f25dbb7..ea765c1ea7 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -2132,7 +2132,10 @@  struct mlx5_ifc_flow_table_prop_layout_bits {
 struct mlx5_ifc_roce_caps_bits {
 	u8 reserved_0[0x1e];
 	u8 qp_ts_format[0x2];
-	u8 reserved_at_20[0x7e0];
+	u8 reserved_at_20[0xa0];
+	u8 r_roce_max_src_udp_port[0x10];
+	u8 r_roce_min_src_udp_port[0x10];
+	u8 reserved_at_e0[0x720];
 };
 
 struct mlx5_ifc_ft_fields_support_bits {
@@ -2370,7 +2373,8 @@  struct mlx5_ifc_cmd_hca_cap_2_bits {
 	u8 format_select_dw_gtpu_first_ext_dw_0[0x8];
 	u8 generate_wqe_type[0x20];
 	u8 reserved_at_2c0[0x160];
-	u8 reserved_at_420[0x1c];
+	u8 reserved_at_420[0x18];
+	u8 encap_entropy_hash_type[0x4];
 	u8 flow_table_hash_type[0x4];
 	u8 reserved_at_440[0x3c0];
 };
diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index d88f73ab57..321b649f8c 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -279,6 +279,27 @@  struct mlx5dr_action_dest_attr {
 	} reformat;
 };
 
+union mlx5dr_crc_encap_entropy_hash_ip_field {
+	uint8_t  ipv6_addr[16];
+	struct {
+		uint8_t  reserved[12];
+		rte_be32_t  ipv4_addr;
+	};
+};
+
+struct mlx5dr_crc_encap_entropy_hash_fields {
+	union mlx5dr_crc_encap_entropy_hash_ip_field dst;
+	union mlx5dr_crc_encap_entropy_hash_ip_field src;
+	uint8_t next_protocol;
+	rte_be16_t dst_port;
+	rte_be16_t src_port;
+}__rte_packed;
+
+enum mlx5dr_crc_encap_entropy_hash_size {
+	MLX5DR_CRC_ENCAP_ENTROPY_HASH_SIZE_8,
+	MLX5DR_CRC_ENCAP_ENTROPY_HASH_SIZE_16,
+};
+
 /* Open a context used for direct rule insertion using hardware steering.
  * Each context can contain multiple tables of different types.
  *
@@ -845,4 +866,21 @@  int mlx5dr_send_queue_action(struct mlx5dr_context *ctx,
  */
 int mlx5dr_debug_dump(struct mlx5dr_context *ctx, FILE *f);
 
+/* Calculate encap entropy hash value
+ *
+ * @param[in] ctx
+ *	The context to get from it's capabilities the entropy hash type.
+ * @param[in] data
+ *	The fields for the hash calculation.
+ * @param[in] entropy_res
+ *	An array to store the hash value to it.
+ * @param[in] res_size
+ *	The result size.
+ * @return zero on success non zero otherwise.
+ */
+int mlx5dr_crc_encap_entropy_hash_calc(struct mlx5dr_context *ctx,
+				       struct mlx5dr_crc_encap_entropy_hash_fields *data,
+				       uint8_t entropy_res[],
+				       enum mlx5dr_crc_encap_entropy_hash_size res_size);
+
 #endif
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c
index 876a47147d..f77b194708 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.c
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c
@@ -1103,6 +1103,8 @@  int mlx5dr_cmd_query_caps(struct ibv_context *ctx,
 	caps->ipsec_offload = MLX5_GET(query_hca_cap_out, out,
 				      capability.cmd_hca_cap.ipsec_offload);
 
+	caps->roce = MLX5_GET(query_hca_cap_out, out, capability.cmd_hca_cap.roce);
+
 	MLX5_SET(query_hca_cap_in, in, op_mod,
 		 MLX5_GET_HCA_CAP_OP_MOD_GENERAL_DEVICE_2 |
 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
@@ -1158,6 +1160,9 @@  int mlx5dr_cmd_query_caps(struct ibv_context *ctx,
 	caps->flow_table_hash_type = MLX5_GET(query_hca_cap_out, out,
 					      capability.cmd_hca_cap_2.flow_table_hash_type);
 
+	caps->encap_entropy_hash_type = MLX5_GET(query_hca_cap_out, out,
+						 capability.cmd_hca_cap_2.encap_entropy_hash_type);
+
 	MLX5_SET(query_hca_cap_in, in, op_mod,
 		 MLX5_GET_HCA_CAP_OP_MOD_NIC_FLOW_TABLE |
 		 MLX5_HCA_CAP_OPMOD_GET_CUR);
@@ -1306,6 +1311,24 @@  int mlx5dr_cmd_query_caps(struct ibv_context *ctx,
 						capability.esw_cap.merged_eswitch);
 	}
 
+	if (caps->roce) {
+		MLX5_SET(query_hca_cap_in, in, op_mod,
+			 MLX5_GET_HCA_CAP_OP_MOD_ROCE |
+			 MLX5_HCA_CAP_OPMOD_GET_CUR);
+
+		ret = mlx5_glue->devx_general_cmd(ctx, in, sizeof(in), out, sizeof(out));
+		if (ret) {
+			DR_LOG(ERR, "Failed to query roce caps");
+			rte_errno = errno;
+			return rte_errno;
+		}
+
+		caps->roce_max_src_udp_port = MLX5_GET(query_hca_cap_out, out,
+						capability.roce_caps.r_roce_max_src_udp_port);
+		caps->roce_min_src_udp_port = MLX5_GET(query_hca_cap_out, out,
+						capability.roce_caps.r_roce_min_src_udp_port);
+	}
+
 	ret = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
 	if (ret) {
 		DR_LOG(ERR, "Failed to query device attributes");
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h
index 18c2b07fc8..694231e08f 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.h
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h
@@ -246,6 +246,10 @@  struct mlx5dr_cmd_query_caps {
 	uint32_t shared_vhca_id;
 	char fw_ver[64];
 	bool ipsec_offload;
+	uint8_t encap_entropy_hash_type;
+	bool roce;
+	uint16_t roce_max_src_udp_port;
+	uint16_t roce_min_src_udp_port;
 };
 
 int mlx5dr_cmd_destroy_obj(struct mlx5dr_devx_obj *devx_obj);
diff --git a/drivers/net/mlx5/hws/mlx5dr_crc32.c b/drivers/net/mlx5/hws/mlx5dr_crc32.c
index 9c454eda0c..7431462e14 100644
--- a/drivers/net/mlx5/hws/mlx5dr_crc32.c
+++ b/drivers/net/mlx5/hws/mlx5dr_crc32.c
@@ -50,6 +50,42 @@  uint32_t dr_ste_crc_tab32[] = {
 	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
 };
 
+/* CRC table for the CRC-16, the polynome is 0x100b */
+uint16_t dr_crc_inner_crc_tab16[] = {
+	0x0000, 0x100B, 0x2016, 0x301D, 0x402C, 0x5027, 0x603A, 0x7031,
+	0x8058, 0x9053, 0xA04E, 0xB045, 0xC074, 0xD07F, 0xE062, 0xF069,
+	0x10BB, 0x00B0, 0x30AD, 0x20A6, 0x5097, 0x409C, 0x7081, 0x608A,
+	0x90E3, 0x80E8, 0xB0F5, 0xA0FE, 0xD0CF, 0xC0C4, 0xF0D9, 0xE0D2,
+	0x2176, 0x317D, 0x0160, 0x116B, 0x615A, 0x7151, 0x414C, 0x5147,
+	0xA12E, 0xB125, 0x8138, 0x9133, 0xE102, 0xF109, 0xC114, 0xD11F,
+	0x31CD, 0x21C6, 0x11DB, 0x01D0, 0x71E1, 0x61EA, 0x51F7, 0x41FC,
+	0xB195, 0xA19E, 0x9183, 0x8188, 0xF1B9, 0xE1B2, 0xD1AF, 0xC1A4,
+	0x42EC, 0x52E7, 0x62FA, 0x72F1, 0x02C0, 0x12CB, 0x22D6, 0x32DD,
+	0xC2B4, 0xD2BF, 0xE2A2, 0xF2A9, 0x8298, 0x9293, 0xA28E, 0xB285,
+	0x5257, 0x425C, 0x7241, 0x624A, 0x127B, 0x0270, 0x326D, 0x2266,
+	0xD20F, 0xC204, 0xF219, 0xE212, 0x9223, 0x8228, 0xB235, 0xA23E,
+	0x639A, 0x7391, 0x438C, 0x5387, 0x23B6, 0x33BD, 0x03A0, 0x13AB,
+	0xE3C2, 0xF3C9, 0xC3D4, 0xD3DF, 0xA3EE, 0xB3E5, 0x83F8, 0x93F3,
+	0x7321, 0x632A, 0x5337, 0x433C, 0x330D, 0x2306, 0x131B, 0x0310,
+	0xF379, 0xE372, 0xD36F, 0xC364, 0xB355, 0xA35E, 0x9343, 0x8348,
+	0x85D8, 0x95D3, 0xA5CE, 0xB5C5, 0xC5F4, 0xD5FF, 0xE5E2, 0xF5E9,
+	0x0580, 0x158B, 0x2596, 0x359D, 0x45AC, 0x55A7, 0x65BA, 0x75B1,
+	0x9563, 0x8568, 0xB575, 0xA57E, 0xD54F, 0xC544, 0xF559, 0xE552,
+	0x153B, 0x0530, 0x352D, 0x2526, 0x5517, 0x451C, 0x7501, 0x650A,
+	0xA4AE, 0xB4A5, 0x84B8, 0x94B3, 0xE482, 0xF489, 0xC494, 0xD49F,
+	0x24F6, 0x34FD, 0x04E0, 0x14EB, 0x64DA, 0x74D1, 0x44CC, 0x54C7,
+	0xB415, 0xA41E, 0x9403, 0x8408, 0xF439, 0xE432, 0xD42F, 0xC424,
+	0x344D, 0x2446, 0x145B, 0x0450, 0x7461, 0x646A, 0x5477, 0x447C,
+	0xC734, 0xD73F, 0xE722, 0xF729, 0x8718, 0x9713, 0xA70E, 0xB705,
+	0x476C, 0x5767, 0x677A, 0x7771, 0x0740, 0x174B, 0x2756, 0x375D,
+	0xD78F, 0xC784, 0xF799, 0xE792, 0x97A3, 0x87A8, 0xB7B5, 0xA7BE,
+	0x57D7, 0x47DC, 0x77C1, 0x67CA, 0x17FB, 0x07F0, 0x37ED, 0x27E6,
+	0xE642, 0xF649, 0xC654, 0xD65F, 0xA66E, 0xB665, 0x8678, 0x9673,
+	0x661A, 0x7611, 0x460C, 0x5607, 0x2636, 0x363D, 0x0620, 0x162B,
+	0xF6F9, 0xE6F2, 0xD6EF, 0xC6E4, 0xB6D5, 0xA6DE, 0x96C3, 0x86C8,
+	0x76A1, 0x66AA, 0x56B7, 0x46BC, 0x368D, 0x2686, 0x169B, 0x0690
+};
+
 uint32_t mlx5dr_crc32_calc(uint8_t *p, size_t len)
 {
 	uint32_t crc = 0;
@@ -59,3 +95,45 @@  uint32_t mlx5dr_crc32_calc(uint8_t *p, size_t len)
 
 	return rte_be_to_cpu_32(crc);
 }
+
+uint16_t mlx5dr_crc16_calc(uint8_t *p, size_t len, uint16_t crc_tab16[])
+{
+	uint16_t crc = 0;
+
+	while (len--)
+		crc = (crc << 8) ^ crc_tab16[((crc >> 8) ^ *p++) & 0xff];
+
+	return crc;
+}
+
+int mlx5dr_crc_encap_entropy_hash_calc(struct mlx5dr_context *ctx,
+				       struct mlx5dr_crc_encap_entropy_hash_fields *data,
+				       uint8_t entropy_res[],
+				       enum mlx5dr_crc_encap_entropy_hash_size res_size)
+{
+	struct mlx5dr_cmd_query_caps *caps = ctx->caps;
+	uint16_t max_hash, min_hash, res;
+
+	if (caps->encap_entropy_hash_type) {
+		DR_LOG(ERR, "calculation of encap_entropy_hash_type 0x%x not supported",
+		       caps->encap_entropy_hash_type);
+		rte_errno = ENOTSUP;
+		return rte_errno;
+	}
+
+	max_hash = caps->roce_max_src_udp_port;
+	min_hash = caps->roce_min_src_udp_port;
+
+	res = mlx5dr_crc16_calc((uint8_t *)data, sizeof(*data), dr_crc_inner_crc_tab16);
+
+	if (res_size == MLX5DR_CRC_ENCAP_ENTROPY_HASH_SIZE_16) {
+		*(uint16_t *)entropy_res = rte_cpu_to_be_16((min_hash | res) & max_hash);
+	} else if (res_size == MLX5DR_CRC_ENCAP_ENTROPY_HASH_SIZE_8) {
+		*entropy_res = (uint8_t)(res & 0xff);
+	} else {
+		rte_errno = ENOTSUP;
+		return rte_errno;
+	}
+
+	return 0;
+}
diff --git a/drivers/net/mlx5/hws/mlx5dr_crc32.h b/drivers/net/mlx5/hws/mlx5dr_crc32.h
index 9aab9e06ca..75b6009a15 100644
--- a/drivers/net/mlx5/hws/mlx5dr_crc32.h
+++ b/drivers/net/mlx5/hws/mlx5dr_crc32.h
@@ -10,4 +10,9 @@ 
  */
 uint32_t mlx5dr_crc32_calc(uint8_t *p, size_t len);
 
+/* Standard CRC16 calculation using the crc_tab16 param to indicate
+ * the pre-calculated polynome hash values.
+ */
+uint16_t mlx5dr_crc16_calc(uint8_t *p, size_t len, uint16_t crc_tab16[]);
+
 #endif /* MLX5DR_CRC32_C_ */