@@ -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];
};
@@ -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
@@ -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");
@@ -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);
@@ -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;
+}
@@ -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_ */