1d65e841dSYevgeny Kliteynik // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2d65e841dSYevgeny Kliteynik /* Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. */ 3d65e841dSYevgeny Kliteynik 4d65e841dSYevgeny Kliteynik #include <linux/types.h> 5d65e841dSYevgeny Kliteynik #include <linux/crc32.h> 6d65e841dSYevgeny Kliteynik #include "dr_ste.h" 7d65e841dSYevgeny Kliteynik 8d65e841dSYevgeny Kliteynik #define DR_STE_CALC_LU_TYPE(lookup_type, rx, inner) \ 9*dd2d3c8dSYevgeny Kliteynik ((inner) ? DR_STE_V0_LU_TYPE_##lookup_type##_I : \ 10*dd2d3c8dSYevgeny Kliteynik (rx) ? DR_STE_V0_LU_TYPE_##lookup_type##_D : \ 11*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_##lookup_type##_O) 12*dd2d3c8dSYevgeny Kliteynik 13*dd2d3c8dSYevgeny Kliteynik enum { 14*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_NOP = 0x00, 15*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP = 0x05, 16*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I = 0x0a, 17*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_DST_O = 0x06, 18*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_DST_I = 0x07, 19*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_DST_D = 0x1b, 20*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_O = 0x08, 21*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_I = 0x09, 22*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_D = 0x1c, 23*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_O = 0x36, 24*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_I = 0x37, 25*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_D = 0x38, 26*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_O = 0x0d, 27*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_I = 0x0e, 28*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_D = 0x1e, 29*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_O = 0x0f, 30*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_I = 0x10, 31*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_D = 0x1f, 32*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_O = 0x11, 33*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_I = 0x12, 34*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_D = 0x20, 35*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_O = 0x29, 36*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_I = 0x2a, 37*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_D = 0x2b, 38*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_O = 0x13, 39*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_I = 0x14, 40*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_D = 0x21, 41*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_MISC_O = 0x2c, 42*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_MISC_I = 0x2d, 43*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_MISC_D = 0x2e, 44*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_MPLS_FIRST_O = 0x15, 45*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_MPLS_FIRST_I = 0x24, 46*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_MPLS_FIRST_D = 0x25, 47*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_GRE = 0x16, 48*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_FLEX_PARSER_0 = 0x22, 49*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_FLEX_PARSER_1 = 0x23, 50*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER = 0x19, 51*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_GENERAL_PURPOSE = 0x18, 52*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0 = 0x2f, 53*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1 = 0x30, 54*dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_DONT_CARE = MLX5DR_STE_LU_TYPE_DONT_CARE, 55*dd2d3c8dSYevgeny Kliteynik }; 56d65e841dSYevgeny Kliteynik 57d65e841dSYevgeny Kliteynik static void 58d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value, 59d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 60d65e841dSYevgeny Kliteynik { 61d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 62d65e841dSYevgeny Kliteynik 6346779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_47_16, mask, dmac_47_16); 6446779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_15_0, mask, dmac_15_0); 65d65e841dSYevgeny Kliteynik 66d65e841dSYevgeny Kliteynik if (mask->smac_47_16 || mask->smac_15_0) { 67d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_47_32, 68d65e841dSYevgeny Kliteynik mask->smac_47_16 >> 16); 69d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_31_0, 70d65e841dSYevgeny Kliteynik mask->smac_47_16 << 16 | mask->smac_15_0); 71d65e841dSYevgeny Kliteynik mask->smac_47_16 = 0; 72d65e841dSYevgeny Kliteynik mask->smac_15_0 = 0; 73d65e841dSYevgeny Kliteynik } 74d65e841dSYevgeny Kliteynik 7546779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_vlan_id, mask, first_vid); 7646779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_cfi, mask, first_cfi); 7746779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_priority, mask, first_prio); 7846779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_src_dst, bit_mask, l3_type, mask, ip_version); 79d65e841dSYevgeny Kliteynik 80d65e841dSYevgeny Kliteynik if (mask->cvlan_tag) { 81d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1); 82d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 83d65e841dSYevgeny Kliteynik } else if (mask->svlan_tag) { 84d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1); 85d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 86d65e841dSYevgeny Kliteynik } 87d65e841dSYevgeny Kliteynik } 88d65e841dSYevgeny Kliteynik 89d65e841dSYevgeny Kliteynik static int 90d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value, 91d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 92d65e841dSYevgeny Kliteynik u8 *tag) 93d65e841dSYevgeny Kliteynik { 94d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 95d65e841dSYevgeny Kliteynik 96d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_47_16, spec, dmac_47_16); 97d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_15_0, spec, dmac_15_0); 98d65e841dSYevgeny Kliteynik 99d65e841dSYevgeny Kliteynik if (spec->smac_47_16 || spec->smac_15_0) { 100d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, smac_47_32, 101d65e841dSYevgeny Kliteynik spec->smac_47_16 >> 16); 102d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, smac_31_0, 103d65e841dSYevgeny Kliteynik spec->smac_47_16 << 16 | spec->smac_15_0); 104d65e841dSYevgeny Kliteynik spec->smac_47_16 = 0; 105d65e841dSYevgeny Kliteynik spec->smac_15_0 = 0; 106d65e841dSYevgeny Kliteynik } 107d65e841dSYevgeny Kliteynik 108d65e841dSYevgeny Kliteynik if (spec->ip_version) { 109d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 110d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV4); 111d65e841dSYevgeny Kliteynik spec->ip_version = 0; 112d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 113d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV6); 114d65e841dSYevgeny Kliteynik spec->ip_version = 0; 115d65e841dSYevgeny Kliteynik } else { 116d65e841dSYevgeny Kliteynik return -EINVAL; 117d65e841dSYevgeny Kliteynik } 118d65e841dSYevgeny Kliteynik } 119d65e841dSYevgeny Kliteynik 120d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_vlan_id, spec, first_vid); 121d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_cfi, spec, first_cfi); 122d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_priority, spec, first_prio); 123d65e841dSYevgeny Kliteynik 124d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 125d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_CVLAN); 126d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 127d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 128d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_SVLAN); 129d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 130d65e841dSYevgeny Kliteynik } 131d65e841dSYevgeny Kliteynik return 0; 132d65e841dSYevgeny Kliteynik } 133d65e841dSYevgeny Kliteynik 134d65e841dSYevgeny Kliteynik static void 135d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb, 136d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 137d65e841dSYevgeny Kliteynik { 138d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask); 139d65e841dSYevgeny Kliteynik 140d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC_DST, sb->rx, sb->inner); 141d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 142d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_dst_tag; 143d65e841dSYevgeny Kliteynik } 144d65e841dSYevgeny Kliteynik 145d65e841dSYevgeny Kliteynik static int 146d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value, 147d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 148d65e841dSYevgeny Kliteynik u8 *tag) 149d65e841dSYevgeny Kliteynik { 150d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 151d65e841dSYevgeny Kliteynik 152d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96); 153d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64); 154d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32); 155d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0); 156d65e841dSYevgeny Kliteynik 157d65e841dSYevgeny Kliteynik return 0; 158d65e841dSYevgeny Kliteynik } 159d65e841dSYevgeny Kliteynik 160d65e841dSYevgeny Kliteynik static void 161d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb, 162d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 163d65e841dSYevgeny Kliteynik { 16446779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask); 165d65e841dSYevgeny Kliteynik 166d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_DST, sb->rx, sb->inner); 167d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 168d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_dst_tag; 169d65e841dSYevgeny Kliteynik } 170d65e841dSYevgeny Kliteynik 171d65e841dSYevgeny Kliteynik static int 172d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value, 173d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 174d65e841dSYevgeny Kliteynik u8 *tag) 175d65e841dSYevgeny Kliteynik { 176d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 177d65e841dSYevgeny Kliteynik 178d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96); 179d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64); 180d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32); 181d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0); 182d65e841dSYevgeny Kliteynik 183d65e841dSYevgeny Kliteynik return 0; 184d65e841dSYevgeny Kliteynik } 185d65e841dSYevgeny Kliteynik 186d65e841dSYevgeny Kliteynik static void 187d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb, 188d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 189d65e841dSYevgeny Kliteynik { 19046779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask); 191d65e841dSYevgeny Kliteynik 192d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_SRC, sb->rx, sb->inner); 193d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 194d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_src_tag; 195d65e841dSYevgeny Kliteynik } 196d65e841dSYevgeny Kliteynik 197d65e841dSYevgeny Kliteynik static int 198d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value, 199d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 200d65e841dSYevgeny Kliteynik u8 *tag) 201d65e841dSYevgeny Kliteynik { 202d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 203d65e841dSYevgeny Kliteynik 204d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_address, spec, dst_ip_31_0); 205d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_address, spec, src_ip_31_0); 206d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, tcp_dport); 207d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, udp_dport); 208d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, tcp_sport); 209d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, udp_sport); 210d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, protocol, spec, ip_protocol); 211d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, fragmented, spec, frag); 212d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, dscp, spec, ip_dscp); 213d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, ecn, spec, ip_ecn); 214d65e841dSYevgeny Kliteynik 215d65e841dSYevgeny Kliteynik if (spec->tcp_flags) { 216d65e841dSYevgeny Kliteynik DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, tag, spec); 217d65e841dSYevgeny Kliteynik spec->tcp_flags = 0; 218d65e841dSYevgeny Kliteynik } 219d65e841dSYevgeny Kliteynik 220d65e841dSYevgeny Kliteynik return 0; 221d65e841dSYevgeny Kliteynik } 222d65e841dSYevgeny Kliteynik 223d65e841dSYevgeny Kliteynik static void 224d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb, 225d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 226d65e841dSYevgeny Kliteynik { 22746779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask); 228d65e841dSYevgeny Kliteynik 229d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_5_TUPLE, sb->rx, sb->inner); 230d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 231d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag; 232d65e841dSYevgeny Kliteynik } 233d65e841dSYevgeny Kliteynik 234d65e841dSYevgeny Kliteynik static void 235d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value, 236d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 237d65e841dSYevgeny Kliteynik { 238d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 239d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_mask = &value->misc; 240d65e841dSYevgeny Kliteynik 24146779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_vlan_id, mask, first_vid); 24246779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_cfi, mask, first_cfi); 24346779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_priority, mask, first_prio); 24446779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, ip_fragmented, mask, frag); 24546779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, l3_ethertype, mask, ethertype); 24646779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_src, bit_mask, l3_type, mask, ip_version); 247d65e841dSYevgeny Kliteynik 248d65e841dSYevgeny Kliteynik if (mask->svlan_tag || mask->cvlan_tag) { 249d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, first_vlan_qualifier, -1); 250d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 251d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 252d65e841dSYevgeny Kliteynik } 253d65e841dSYevgeny Kliteynik 254d65e841dSYevgeny Kliteynik if (inner) { 255d65e841dSYevgeny Kliteynik if (misc_mask->inner_second_cvlan_tag || 256d65e841dSYevgeny Kliteynik misc_mask->inner_second_svlan_tag) { 257d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1); 258d65e841dSYevgeny Kliteynik misc_mask->inner_second_cvlan_tag = 0; 259d65e841dSYevgeny Kliteynik misc_mask->inner_second_svlan_tag = 0; 260d65e841dSYevgeny Kliteynik } 261d65e841dSYevgeny Kliteynik 26246779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 263d65e841dSYevgeny Kliteynik second_vlan_id, misc_mask, inner_second_vid); 26446779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 265d65e841dSYevgeny Kliteynik second_cfi, misc_mask, inner_second_cfi); 26646779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 267d65e841dSYevgeny Kliteynik second_priority, misc_mask, inner_second_prio); 268d65e841dSYevgeny Kliteynik } else { 269d65e841dSYevgeny Kliteynik if (misc_mask->outer_second_cvlan_tag || 270d65e841dSYevgeny Kliteynik misc_mask->outer_second_svlan_tag) { 271d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1); 272d65e841dSYevgeny Kliteynik misc_mask->outer_second_cvlan_tag = 0; 273d65e841dSYevgeny Kliteynik misc_mask->outer_second_svlan_tag = 0; 274d65e841dSYevgeny Kliteynik } 275d65e841dSYevgeny Kliteynik 27646779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 277d65e841dSYevgeny Kliteynik second_vlan_id, misc_mask, outer_second_vid); 27846779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 279d65e841dSYevgeny Kliteynik second_cfi, misc_mask, outer_second_cfi); 28046779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 281d65e841dSYevgeny Kliteynik second_priority, misc_mask, outer_second_prio); 282d65e841dSYevgeny Kliteynik } 283d65e841dSYevgeny Kliteynik } 284d65e841dSYevgeny Kliteynik 285d65e841dSYevgeny Kliteynik static int 286d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value, 287d65e841dSYevgeny Kliteynik bool inner, u8 *tag) 288d65e841dSYevgeny Kliteynik { 289d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer; 290d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_spec = &value->misc; 291d65e841dSYevgeny Kliteynik 292d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_vlan_id, spec, first_vid); 293d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_cfi, spec, first_cfi); 294d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_priority, spec, first_prio); 295d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, ip_fragmented, spec, frag); 296d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, l3_ethertype, spec, ethertype); 297d65e841dSYevgeny Kliteynik 298d65e841dSYevgeny Kliteynik if (spec->ip_version) { 299d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 300d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV4); 301d65e841dSYevgeny Kliteynik spec->ip_version = 0; 302d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 303d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV6); 304d65e841dSYevgeny Kliteynik spec->ip_version = 0; 305d65e841dSYevgeny Kliteynik } else { 306d65e841dSYevgeny Kliteynik return -EINVAL; 307d65e841dSYevgeny Kliteynik } 308d65e841dSYevgeny Kliteynik } 309d65e841dSYevgeny Kliteynik 310d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 311d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_CVLAN); 312d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 313d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 314d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_SVLAN); 315d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 316d65e841dSYevgeny Kliteynik } 317d65e841dSYevgeny Kliteynik 318d65e841dSYevgeny Kliteynik if (inner) { 319d65e841dSYevgeny Kliteynik if (misc_spec->inner_second_cvlan_tag) { 320d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN); 321d65e841dSYevgeny Kliteynik misc_spec->inner_second_cvlan_tag = 0; 322d65e841dSYevgeny Kliteynik } else if (misc_spec->inner_second_svlan_tag) { 323d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN); 324d65e841dSYevgeny Kliteynik misc_spec->inner_second_svlan_tag = 0; 325d65e841dSYevgeny Kliteynik } 326d65e841dSYevgeny Kliteynik 327d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, inner_second_vid); 328d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, inner_second_cfi); 329d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, inner_second_prio); 330d65e841dSYevgeny Kliteynik } else { 331d65e841dSYevgeny Kliteynik if (misc_spec->outer_second_cvlan_tag) { 332d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN); 333d65e841dSYevgeny Kliteynik misc_spec->outer_second_cvlan_tag = 0; 334d65e841dSYevgeny Kliteynik } else if (misc_spec->outer_second_svlan_tag) { 335d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN); 336d65e841dSYevgeny Kliteynik misc_spec->outer_second_svlan_tag = 0; 337d65e841dSYevgeny Kliteynik } 338d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, outer_second_vid); 339d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, outer_second_cfi); 340d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, outer_second_prio); 341d65e841dSYevgeny Kliteynik } 342d65e841dSYevgeny Kliteynik 343d65e841dSYevgeny Kliteynik return 0; 344d65e841dSYevgeny Kliteynik } 345d65e841dSYevgeny Kliteynik 346d65e841dSYevgeny Kliteynik static void 347d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value, 348d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 349d65e841dSYevgeny Kliteynik { 350d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 351d65e841dSYevgeny Kliteynik 35246779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_47_16, mask, smac_47_16); 35346779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_15_0, mask, smac_15_0); 354d65e841dSYevgeny Kliteynik 355d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask); 356d65e841dSYevgeny Kliteynik } 357d65e841dSYevgeny Kliteynik 358d65e841dSYevgeny Kliteynik static int 359d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_tag(struct mlx5dr_match_param *value, 360d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 361d65e841dSYevgeny Kliteynik u8 *tag) 362d65e841dSYevgeny Kliteynik { 363d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 364d65e841dSYevgeny Kliteynik 365d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, smac_47_16, spec, smac_47_16); 366d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, smac_15_0, spec, smac_15_0); 367d65e841dSYevgeny Kliteynik 368d65e841dSYevgeny Kliteynik return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 369d65e841dSYevgeny Kliteynik } 370d65e841dSYevgeny Kliteynik 371d65e841dSYevgeny Kliteynik static void 372d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_init(struct mlx5dr_ste_build *sb, 373d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 374d65e841dSYevgeny Kliteynik { 375d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask); 376d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC, sb->rx, sb->inner); 377d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 378d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_tag; 379d65e841dSYevgeny Kliteynik } 380d65e841dSYevgeny Kliteynik 381d65e841dSYevgeny Kliteynik static void 382d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value, 38346779098SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 38446779098SYevgeny Kliteynik u8 *bit_mask) 385d65e841dSYevgeny Kliteynik { 38646779098SYevgeny Kliteynik struct mlx5dr_match_spec *mask = sb->inner ? &value->inner : &value->outer; 387d65e841dSYevgeny Kliteynik 38846779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_47_16, mask, dmac_47_16); 38946779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_15_0, mask, dmac_15_0); 390d65e841dSYevgeny Kliteynik 39146779098SYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, sb->inner, bit_mask); 392d65e841dSYevgeny Kliteynik } 393d65e841dSYevgeny Kliteynik 394d65e841dSYevgeny Kliteynik static int 395d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_tag(struct mlx5dr_match_param *value, 396d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 397d65e841dSYevgeny Kliteynik u8 *tag) 398d65e841dSYevgeny Kliteynik { 399d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 400d65e841dSYevgeny Kliteynik 401d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, tag, dmac_47_16, spec, dmac_47_16); 402d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, tag, dmac_15_0, spec, dmac_15_0); 403d65e841dSYevgeny Kliteynik 404d65e841dSYevgeny Kliteynik return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 405d65e841dSYevgeny Kliteynik } 406d65e841dSYevgeny Kliteynik 407d65e841dSYevgeny Kliteynik static void 408d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb, 409d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 410d65e841dSYevgeny Kliteynik { 41146779098SYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_bit_mask(mask, sb, sb->bit_mask); 412d65e841dSYevgeny Kliteynik 413d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_DST, sb->rx, sb->inner); 414d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 415d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_dst_tag; 416d65e841dSYevgeny Kliteynik } 417d65e841dSYevgeny Kliteynik 418d65e841dSYevgeny Kliteynik static void 419d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value, 420d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 421d65e841dSYevgeny Kliteynik { 422d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 423d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 424d65e841dSYevgeny Kliteynik 42546779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_47_16, mask, dmac_47_16); 42646779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_15_0, mask, dmac_15_0); 42746779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_vlan_id, mask, first_vid); 42846779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_cfi, mask, first_cfi); 42946779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_priority, mask, first_prio); 43046779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, ip_fragmented, mask, frag); 43146779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, l3_ethertype, mask, ethertype); 43246779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_tnl, bit_mask, l3_type, mask, ip_version); 433d65e841dSYevgeny Kliteynik 434d65e841dSYevgeny Kliteynik if (misc->vxlan_vni) { 435d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, bit_mask, 436d65e841dSYevgeny Kliteynik l2_tunneling_network_id, (misc->vxlan_vni << 8)); 437d65e841dSYevgeny Kliteynik misc->vxlan_vni = 0; 438d65e841dSYevgeny Kliteynik } 439d65e841dSYevgeny Kliteynik 440d65e841dSYevgeny Kliteynik if (mask->svlan_tag || mask->cvlan_tag) { 441d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, bit_mask, first_vlan_qualifier, -1); 442d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 443d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 444d65e841dSYevgeny Kliteynik } 445d65e841dSYevgeny Kliteynik } 446d65e841dSYevgeny Kliteynik 447d65e841dSYevgeny Kliteynik static int 448d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value, 449d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 450d65e841dSYevgeny Kliteynik u8 *tag) 451d65e841dSYevgeny Kliteynik { 452d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 453d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 454d65e841dSYevgeny Kliteynik 455d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_47_16, spec, dmac_47_16); 456d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_15_0, spec, dmac_15_0); 457d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_vlan_id, spec, first_vid); 458d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_cfi, spec, first_cfi); 459d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, ip_fragmented, spec, frag); 460d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_priority, spec, first_prio); 461d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, l3_ethertype, spec, ethertype); 462d65e841dSYevgeny Kliteynik 463d65e841dSYevgeny Kliteynik if (misc->vxlan_vni) { 464d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l2_tunneling_network_id, 465d65e841dSYevgeny Kliteynik (misc->vxlan_vni << 8)); 466d65e841dSYevgeny Kliteynik misc->vxlan_vni = 0; 467d65e841dSYevgeny Kliteynik } 468d65e841dSYevgeny Kliteynik 469d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 470d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_CVLAN); 471d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 472d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 473d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_SVLAN); 474d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 475d65e841dSYevgeny Kliteynik } 476d65e841dSYevgeny Kliteynik 477d65e841dSYevgeny Kliteynik if (spec->ip_version) { 478d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 479d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV4); 480d65e841dSYevgeny Kliteynik spec->ip_version = 0; 481d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 482d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV6); 483d65e841dSYevgeny Kliteynik spec->ip_version = 0; 484d65e841dSYevgeny Kliteynik } else { 485d65e841dSYevgeny Kliteynik return -EINVAL; 486d65e841dSYevgeny Kliteynik } 487d65e841dSYevgeny Kliteynik } 488d65e841dSYevgeny Kliteynik 489d65e841dSYevgeny Kliteynik return 0; 490d65e841dSYevgeny Kliteynik } 491d65e841dSYevgeny Kliteynik 492d65e841dSYevgeny Kliteynik static void 493d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb, 494d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 495d65e841dSYevgeny Kliteynik { 496d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask); 497d65e841dSYevgeny Kliteynik 498*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I; 499d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 500d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_tnl_tag; 501d65e841dSYevgeny Kliteynik } 502d65e841dSYevgeny Kliteynik 503d65e841dSYevgeny Kliteynik static int 504d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value, 505d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 506d65e841dSYevgeny Kliteynik u8 *tag) 507d65e841dSYevgeny Kliteynik { 508d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 509d65e841dSYevgeny Kliteynik 510d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, time_to_live, spec, ttl_hoplimit); 511d65e841dSYevgeny Kliteynik 512d65e841dSYevgeny Kliteynik return 0; 513d65e841dSYevgeny Kliteynik } 514d65e841dSYevgeny Kliteynik 515d65e841dSYevgeny Kliteynik static void 516d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb, 517d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 518d65e841dSYevgeny Kliteynik { 51946779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask); 520d65e841dSYevgeny Kliteynik 521d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_MISC, sb->rx, sb->inner); 522d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 523d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_misc_tag; 524d65e841dSYevgeny Kliteynik } 525d65e841dSYevgeny Kliteynik 526d65e841dSYevgeny Kliteynik static int 527d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value, 528d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 529d65e841dSYevgeny Kliteynik u8 *tag) 530d65e841dSYevgeny Kliteynik { 531d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 532d65e841dSYevgeny Kliteynik 533d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, tcp_dport); 534d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, src_port, spec, tcp_sport); 535d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, udp_dport); 536d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, src_port, spec, udp_sport); 537d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, protocol, spec, ip_protocol); 538d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, fragmented, spec, frag); 539d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dscp, spec, ip_dscp); 540d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, ecn, spec, ip_ecn); 541d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, ipv6_hop_limit, spec, ttl_hoplimit); 542d65e841dSYevgeny Kliteynik 543d65e841dSYevgeny Kliteynik if (spec->tcp_flags) { 544d65e841dSYevgeny Kliteynik DR_STE_SET_TCP_FLAGS(eth_l4, tag, spec); 545d65e841dSYevgeny Kliteynik spec->tcp_flags = 0; 546d65e841dSYevgeny Kliteynik } 547d65e841dSYevgeny Kliteynik 548d65e841dSYevgeny Kliteynik return 0; 549d65e841dSYevgeny Kliteynik } 550d65e841dSYevgeny Kliteynik 551d65e841dSYevgeny Kliteynik static void 552d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb, 553d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 554d65e841dSYevgeny Kliteynik { 55546779098SYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask); 556d65e841dSYevgeny Kliteynik 557d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4, sb->rx, sb->inner); 558d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 559d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_ipv6_l3_l4_tag; 560d65e841dSYevgeny Kliteynik } 561d65e841dSYevgeny Kliteynik 562d65e841dSYevgeny Kliteynik static int 563d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_tag(struct mlx5dr_match_param *value, 564d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 565d65e841dSYevgeny Kliteynik u8 *tag) 566d65e841dSYevgeny Kliteynik { 56746779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 568d65e841dSYevgeny Kliteynik 569d65e841dSYevgeny Kliteynik if (sb->inner) 57046779098SYevgeny Kliteynik DR_STE_SET_MPLS(mpls, misc2, inner, tag); 571d65e841dSYevgeny Kliteynik else 57246779098SYevgeny Kliteynik DR_STE_SET_MPLS(mpls, misc2, outer, tag); 573d65e841dSYevgeny Kliteynik 574d65e841dSYevgeny Kliteynik return 0; 575d65e841dSYevgeny Kliteynik } 576d65e841dSYevgeny Kliteynik 577d65e841dSYevgeny Kliteynik static void 578d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_init(struct mlx5dr_ste_build *sb, 579d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 580d65e841dSYevgeny Kliteynik { 58146779098SYevgeny Kliteynik dr_ste_v0_build_mpls_tag(mask, sb, sb->bit_mask); 582d65e841dSYevgeny Kliteynik 583d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(MPLS_FIRST, sb->rx, sb->inner); 584d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 585d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_mpls_tag; 586d65e841dSYevgeny Kliteynik } 587d65e841dSYevgeny Kliteynik 588d65e841dSYevgeny Kliteynik static int 589d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_tag(struct mlx5dr_match_param *value, 590d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 591d65e841dSYevgeny Kliteynik u8 *tag) 592d65e841dSYevgeny Kliteynik { 593d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 594d65e841dSYevgeny Kliteynik 595d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_protocol, misc, gre_protocol); 596d65e841dSYevgeny Kliteynik 597d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_k_present, misc, gre_k_present); 598d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_key_h, misc, gre_key_h); 599d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_key_l, misc, gre_key_l); 600d65e841dSYevgeny Kliteynik 601d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_c_present, misc, gre_c_present); 602d65e841dSYevgeny Kliteynik 603d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_s_present, misc, gre_s_present); 604d65e841dSYevgeny Kliteynik 605d65e841dSYevgeny Kliteynik return 0; 606d65e841dSYevgeny Kliteynik } 607d65e841dSYevgeny Kliteynik 608d65e841dSYevgeny Kliteynik static void 609d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_init(struct mlx5dr_ste_build *sb, 610d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 611d65e841dSYevgeny Kliteynik { 61246779098SYevgeny Kliteynik dr_ste_v0_build_tnl_gre_tag(mask, sb, sb->bit_mask); 613d65e841dSYevgeny Kliteynik 614*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_GRE; 615d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 616d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gre_tag; 617d65e841dSYevgeny Kliteynik } 618d65e841dSYevgeny Kliteynik 619d65e841dSYevgeny Kliteynik static int 620d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_tag(struct mlx5dr_match_param *value, 621d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 622d65e841dSYevgeny Kliteynik u8 *tag) 623d65e841dSYevgeny Kliteynik { 62446779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc_2 = &value->misc2; 625d65e841dSYevgeny Kliteynik 62646779098SYevgeny Kliteynik if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2)) { 627d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label, 62846779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_label); 629d65e841dSYevgeny Kliteynik 630d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp, 63146779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_exp); 632d65e841dSYevgeny Kliteynik 633d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos, 63446779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_s_bos); 635d65e841dSYevgeny Kliteynik 636d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl, 63746779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_ttl); 638d65e841dSYevgeny Kliteynik } else { 639d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label, 64046779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_label); 641d65e841dSYevgeny Kliteynik 642d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp, 64346779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_exp); 644d65e841dSYevgeny Kliteynik 645d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos, 64646779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_s_bos); 647d65e841dSYevgeny Kliteynik 648d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl, 64946779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_ttl); 650d65e841dSYevgeny Kliteynik } 651d65e841dSYevgeny Kliteynik return 0; 652d65e841dSYevgeny Kliteynik } 653d65e841dSYevgeny Kliteynik 654d65e841dSYevgeny Kliteynik static void 655d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_init(struct mlx5dr_ste_build *sb, 656d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 657d65e841dSYevgeny Kliteynik { 65846779098SYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_tag(mask, sb, sb->bit_mask); 659d65e841dSYevgeny Kliteynik 660*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 661d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 662d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_tag; 663d65e841dSYevgeny Kliteynik } 664d65e841dSYevgeny Kliteynik 665d65e841dSYevgeny Kliteynik #define ICMP_TYPE_OFFSET_FIRST_DW 24 666d65e841dSYevgeny Kliteynik #define ICMP_CODE_OFFSET_FIRST_DW 16 667d65e841dSYevgeny Kliteynik #define ICMP_HEADER_DATA_OFFSET_SECOND_DW 0 668d65e841dSYevgeny Kliteynik 669d65e841dSYevgeny Kliteynik static int 670d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_tag(struct mlx5dr_match_param *value, 671d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 672d65e841dSYevgeny Kliteynik u8 *tag) 673d65e841dSYevgeny Kliteynik { 674d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc_3 = &value->misc3; 675d65e841dSYevgeny Kliteynik u32 icmp_header_data; 676d65e841dSYevgeny Kliteynik int dw0_location; 677d65e841dSYevgeny Kliteynik int dw1_location; 678d65e841dSYevgeny Kliteynik u32 icmp_type; 679d65e841dSYevgeny Kliteynik u32 icmp_code; 680d65e841dSYevgeny Kliteynik bool is_ipv4; 681d65e841dSYevgeny Kliteynik 682d65e841dSYevgeny Kliteynik is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc_3); 683d65e841dSYevgeny Kliteynik if (is_ipv4) { 684d65e841dSYevgeny Kliteynik icmp_header_data = misc_3->icmpv4_header_data; 685d65e841dSYevgeny Kliteynik icmp_type = misc_3->icmpv4_type; 686d65e841dSYevgeny Kliteynik icmp_code = misc_3->icmpv4_code; 687d65e841dSYevgeny Kliteynik dw0_location = sb->caps->flex_parser_id_icmp_dw0; 688d65e841dSYevgeny Kliteynik dw1_location = sb->caps->flex_parser_id_icmp_dw1; 689d65e841dSYevgeny Kliteynik } else { 690d65e841dSYevgeny Kliteynik icmp_header_data = misc_3->icmpv6_header_data; 691d65e841dSYevgeny Kliteynik icmp_type = misc_3->icmpv6_type; 692d65e841dSYevgeny Kliteynik icmp_code = misc_3->icmpv6_code; 693d65e841dSYevgeny Kliteynik dw0_location = sb->caps->flex_parser_id_icmpv6_dw0; 694d65e841dSYevgeny Kliteynik dw1_location = sb->caps->flex_parser_id_icmpv6_dw1; 695d65e841dSYevgeny Kliteynik } 696d65e841dSYevgeny Kliteynik 697d65e841dSYevgeny Kliteynik switch (dw0_location) { 698d65e841dSYevgeny Kliteynik case 4: 699d65e841dSYevgeny Kliteynik if (icmp_type) { 700d65e841dSYevgeny Kliteynik MLX5_SET(ste_flex_parser_1, tag, flex_parser_4, 701d65e841dSYevgeny Kliteynik (icmp_type << ICMP_TYPE_OFFSET_FIRST_DW)); 702d65e841dSYevgeny Kliteynik if (is_ipv4) 703d65e841dSYevgeny Kliteynik misc_3->icmpv4_type = 0; 704d65e841dSYevgeny Kliteynik else 705d65e841dSYevgeny Kliteynik misc_3->icmpv6_type = 0; 706d65e841dSYevgeny Kliteynik } 707d65e841dSYevgeny Kliteynik 708d65e841dSYevgeny Kliteynik if (icmp_code) { 709d65e841dSYevgeny Kliteynik u32 cur_val = MLX5_GET(ste_flex_parser_1, tag, 710d65e841dSYevgeny Kliteynik flex_parser_4); 711d65e841dSYevgeny Kliteynik MLX5_SET(ste_flex_parser_1, tag, flex_parser_4, 712d65e841dSYevgeny Kliteynik cur_val | (icmp_code << ICMP_CODE_OFFSET_FIRST_DW)); 713d65e841dSYevgeny Kliteynik if (is_ipv4) 714d65e841dSYevgeny Kliteynik misc_3->icmpv4_code = 0; 715d65e841dSYevgeny Kliteynik else 716d65e841dSYevgeny Kliteynik misc_3->icmpv6_code = 0; 717d65e841dSYevgeny Kliteynik } 718d65e841dSYevgeny Kliteynik break; 719d65e841dSYevgeny Kliteynik default: 720d65e841dSYevgeny Kliteynik return -EINVAL; 721d65e841dSYevgeny Kliteynik } 722d65e841dSYevgeny Kliteynik 723d65e841dSYevgeny Kliteynik switch (dw1_location) { 724d65e841dSYevgeny Kliteynik case 5: 725d65e841dSYevgeny Kliteynik if (icmp_header_data) { 726d65e841dSYevgeny Kliteynik MLX5_SET(ste_flex_parser_1, tag, flex_parser_5, 727d65e841dSYevgeny Kliteynik (icmp_header_data << ICMP_HEADER_DATA_OFFSET_SECOND_DW)); 728d65e841dSYevgeny Kliteynik if (is_ipv4) 729d65e841dSYevgeny Kliteynik misc_3->icmpv4_header_data = 0; 730d65e841dSYevgeny Kliteynik else 731d65e841dSYevgeny Kliteynik misc_3->icmpv6_header_data = 0; 732d65e841dSYevgeny Kliteynik } 733d65e841dSYevgeny Kliteynik break; 734d65e841dSYevgeny Kliteynik default: 735d65e841dSYevgeny Kliteynik return -EINVAL; 736d65e841dSYevgeny Kliteynik } 737d65e841dSYevgeny Kliteynik 738d65e841dSYevgeny Kliteynik return 0; 739d65e841dSYevgeny Kliteynik } 740d65e841dSYevgeny Kliteynik 741d65e841dSYevgeny Kliteynik static int 742d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_init(struct mlx5dr_ste_build *sb, 743d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 744d65e841dSYevgeny Kliteynik { 745d65e841dSYevgeny Kliteynik int ret; 746d65e841dSYevgeny Kliteynik 74746779098SYevgeny Kliteynik ret = dr_ste_v0_build_icmp_tag(mask, sb, sb->bit_mask); 748d65e841dSYevgeny Kliteynik if (ret) 749d65e841dSYevgeny Kliteynik return ret; 750d65e841dSYevgeny Kliteynik 751*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_1; 752d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 753d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_icmp_tag; 754d65e841dSYevgeny Kliteynik 755d65e841dSYevgeny Kliteynik return 0; 756d65e841dSYevgeny Kliteynik } 757d65e841dSYevgeny Kliteynik 758d65e841dSYevgeny Kliteynik static int 759d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_tag(struct mlx5dr_match_param *value, 760d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 761d65e841dSYevgeny Kliteynik u8 *tag) 762d65e841dSYevgeny Kliteynik { 76346779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc_2 = &value->misc2; 764d65e841dSYevgeny Kliteynik 765d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field, 76646779098SYevgeny Kliteynik misc_2, metadata_reg_a); 767d65e841dSYevgeny Kliteynik 768d65e841dSYevgeny Kliteynik return 0; 769d65e841dSYevgeny Kliteynik } 770d65e841dSYevgeny Kliteynik 771d65e841dSYevgeny Kliteynik static void 772d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_init(struct mlx5dr_ste_build *sb, 773d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 774d65e841dSYevgeny Kliteynik { 77546779098SYevgeny Kliteynik dr_ste_v0_build_general_purpose_tag(mask, sb, sb->bit_mask); 776d65e841dSYevgeny Kliteynik 777*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_GENERAL_PURPOSE; 778d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 779d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_general_purpose_tag; 780d65e841dSYevgeny Kliteynik } 781d65e841dSYevgeny Kliteynik 782d65e841dSYevgeny Kliteynik static int 783d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_tag(struct mlx5dr_match_param *value, 784d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 785d65e841dSYevgeny Kliteynik u8 *tag) 786d65e841dSYevgeny Kliteynik { 787d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 788d65e841dSYevgeny Kliteynik 789d65e841dSYevgeny Kliteynik if (sb->inner) { 790d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, inner_tcp_seq_num); 791d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, inner_tcp_ack_num); 792d65e841dSYevgeny Kliteynik } else { 793d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, outer_tcp_seq_num); 794d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, outer_tcp_ack_num); 795d65e841dSYevgeny Kliteynik } 796d65e841dSYevgeny Kliteynik 797d65e841dSYevgeny Kliteynik return 0; 798d65e841dSYevgeny Kliteynik } 799d65e841dSYevgeny Kliteynik 800d65e841dSYevgeny Kliteynik static void 801d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb, 802d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 803d65e841dSYevgeny Kliteynik { 80446779098SYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_tag(mask, sb, sb->bit_mask); 805d65e841dSYevgeny Kliteynik 806d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4_MISC, sb->rx, sb->inner); 807d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 808d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l4_misc_tag; 809d65e841dSYevgeny Kliteynik } 810d65e841dSYevgeny Kliteynik 811d65e841dSYevgeny Kliteynik static int 812d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value, 813d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 814d65e841dSYevgeny Kliteynik u8 *tag) 815d65e841dSYevgeny Kliteynik { 816d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 817d65e841dSYevgeny Kliteynik 818d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 819d65e841dSYevgeny Kliteynik outer_vxlan_gpe_flags, misc3, 820d65e841dSYevgeny Kliteynik outer_vxlan_gpe_flags); 821d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 822d65e841dSYevgeny Kliteynik outer_vxlan_gpe_next_protocol, misc3, 823d65e841dSYevgeny Kliteynik outer_vxlan_gpe_next_protocol); 824d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 825d65e841dSYevgeny Kliteynik outer_vxlan_gpe_vni, misc3, 826d65e841dSYevgeny Kliteynik outer_vxlan_gpe_vni); 827d65e841dSYevgeny Kliteynik 828d65e841dSYevgeny Kliteynik return 0; 829d65e841dSYevgeny Kliteynik } 830d65e841dSYevgeny Kliteynik 831d65e841dSYevgeny Kliteynik static void 832d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb, 833d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 834d65e841dSYevgeny Kliteynik { 83546779098SYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask); 836*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER; 837d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 838d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag; 839d65e841dSYevgeny Kliteynik } 840d65e841dSYevgeny Kliteynik 841d65e841dSYevgeny Kliteynik static int 842d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value, 843d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 844d65e841dSYevgeny Kliteynik u8 *tag) 845d65e841dSYevgeny Kliteynik { 846d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 847d65e841dSYevgeny Kliteynik 848d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 849d65e841dSYevgeny Kliteynik geneve_protocol_type, misc, geneve_protocol_type); 850d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 851d65e841dSYevgeny Kliteynik geneve_oam, misc, geneve_oam); 852d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 853d65e841dSYevgeny Kliteynik geneve_opt_len, misc, geneve_opt_len); 854d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 855d65e841dSYevgeny Kliteynik geneve_vni, misc, geneve_vni); 856d65e841dSYevgeny Kliteynik 857d65e841dSYevgeny Kliteynik return 0; 858d65e841dSYevgeny Kliteynik } 859d65e841dSYevgeny Kliteynik 860d65e841dSYevgeny Kliteynik static void 861d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb, 862d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 863d65e841dSYevgeny Kliteynik { 86446779098SYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask); 865*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER; 866d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 867d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tag; 868d65e841dSYevgeny Kliteynik } 869d65e841dSYevgeny Kliteynik 870d65e841dSYevgeny Kliteynik static int 871d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_tag(struct mlx5dr_match_param *value, 872d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 873d65e841dSYevgeny Kliteynik u8 *tag) 874d65e841dSYevgeny Kliteynik { 875d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 876d65e841dSYevgeny Kliteynik 877d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0); 878d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1); 879d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2); 880d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3); 881d65e841dSYevgeny Kliteynik 882d65e841dSYevgeny Kliteynik return 0; 883d65e841dSYevgeny Kliteynik } 884d65e841dSYevgeny Kliteynik 885d65e841dSYevgeny Kliteynik static void 886d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_init(struct mlx5dr_ste_build *sb, 887d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 888d65e841dSYevgeny Kliteynik { 88946779098SYevgeny Kliteynik dr_ste_v0_build_register_0_tag(mask, sb, sb->bit_mask); 890d65e841dSYevgeny Kliteynik 891*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0; 892d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 893d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_register_0_tag; 894d65e841dSYevgeny Kliteynik } 895d65e841dSYevgeny Kliteynik 896d65e841dSYevgeny Kliteynik static int 897d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_tag(struct mlx5dr_match_param *value, 898d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 899d65e841dSYevgeny Kliteynik u8 *tag) 900d65e841dSYevgeny Kliteynik { 901d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 902d65e841dSYevgeny Kliteynik 903d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4); 904d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5); 905d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6); 906d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7); 907d65e841dSYevgeny Kliteynik 908d65e841dSYevgeny Kliteynik return 0; 909d65e841dSYevgeny Kliteynik } 910d65e841dSYevgeny Kliteynik 911d65e841dSYevgeny Kliteynik static void 912d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_init(struct mlx5dr_ste_build *sb, 913d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 914d65e841dSYevgeny Kliteynik { 91546779098SYevgeny Kliteynik dr_ste_v0_build_register_1_tag(mask, sb, sb->bit_mask); 916d65e841dSYevgeny Kliteynik 917*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1; 918d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 919d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_register_1_tag; 920d65e841dSYevgeny Kliteynik } 921d65e841dSYevgeny Kliteynik 922d65e841dSYevgeny Kliteynik static void 923d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value, 924d65e841dSYevgeny Kliteynik u8 *bit_mask) 925d65e841dSYevgeny Kliteynik { 926d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_mask = &value->misc; 927d65e841dSYevgeny Kliteynik 92846779098SYevgeny Kliteynik DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_gvmi, misc_mask, source_port); 92946779098SYevgeny Kliteynik DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_qp, misc_mask, source_sqn); 930d65e841dSYevgeny Kliteynik misc_mask->source_eswitch_owner_vhca_id = 0; 931d65e841dSYevgeny Kliteynik } 932d65e841dSYevgeny Kliteynik 933d65e841dSYevgeny Kliteynik static int 934d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, 935d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 936d65e841dSYevgeny Kliteynik u8 *tag) 937d65e841dSYevgeny Kliteynik { 938d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 939d65e841dSYevgeny Kliteynik struct mlx5dr_cmd_vport_cap *vport_cap; 940d65e841dSYevgeny Kliteynik struct mlx5dr_domain *dmn = sb->dmn; 941d65e841dSYevgeny Kliteynik struct mlx5dr_cmd_caps *caps; 942d65e841dSYevgeny Kliteynik u8 *bit_mask = sb->bit_mask; 943d65e841dSYevgeny Kliteynik bool source_gvmi_set; 944d65e841dSYevgeny Kliteynik 945d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn); 946d65e841dSYevgeny Kliteynik 947d65e841dSYevgeny Kliteynik if (sb->vhca_id_valid) { 948d65e841dSYevgeny Kliteynik /* Find port GVMI based on the eswitch_owner_vhca_id */ 949d65e841dSYevgeny Kliteynik if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi) 950d65e841dSYevgeny Kliteynik caps = &dmn->info.caps; 951d65e841dSYevgeny Kliteynik else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id == 952d65e841dSYevgeny Kliteynik dmn->peer_dmn->info.caps.gvmi)) 953d65e841dSYevgeny Kliteynik caps = &dmn->peer_dmn->info.caps; 954d65e841dSYevgeny Kliteynik else 955d65e841dSYevgeny Kliteynik return -EINVAL; 9567863c912SYevgeny Kliteynik 9577863c912SYevgeny Kliteynik misc->source_eswitch_owner_vhca_id = 0; 958d65e841dSYevgeny Kliteynik } else { 959d65e841dSYevgeny Kliteynik caps = &dmn->info.caps; 960d65e841dSYevgeny Kliteynik } 961d65e841dSYevgeny Kliteynik 9627863c912SYevgeny Kliteynik source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi); 9637863c912SYevgeny Kliteynik if (source_gvmi_set) { 964d65e841dSYevgeny Kliteynik vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port); 965d65e841dSYevgeny Kliteynik if (!vport_cap) { 966d65e841dSYevgeny Kliteynik mlx5dr_err(dmn, "Vport 0x%x is invalid\n", 967d65e841dSYevgeny Kliteynik misc->source_port); 968d65e841dSYevgeny Kliteynik return -EINVAL; 969d65e841dSYevgeny Kliteynik } 970d65e841dSYevgeny Kliteynik 9717863c912SYevgeny Kliteynik if (vport_cap->vport_gvmi) 972d65e841dSYevgeny Kliteynik MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi); 973d65e841dSYevgeny Kliteynik 974d65e841dSYevgeny Kliteynik misc->source_port = 0; 9757863c912SYevgeny Kliteynik } 976d65e841dSYevgeny Kliteynik 977d65e841dSYevgeny Kliteynik return 0; 978d65e841dSYevgeny Kliteynik } 979d65e841dSYevgeny Kliteynik 980d65e841dSYevgeny Kliteynik static void 981d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb, 982d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 983d65e841dSYevgeny Kliteynik { 984d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask); 985d65e841dSYevgeny Kliteynik 986*dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP; 987d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 988d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_src_gvmi_qpn_tag; 989d65e841dSYevgeny Kliteynik } 990d65e841dSYevgeny Kliteynik 991d65e841dSYevgeny Kliteynik struct mlx5dr_ste_ctx ste_ctx_v0 = { 992d65e841dSYevgeny Kliteynik .build_eth_l2_src_dst_init = &dr_ste_v0_build_eth_l2_src_dst_init, 993d65e841dSYevgeny Kliteynik .build_eth_l3_ipv6_src_init = &dr_ste_v0_build_eth_l3_ipv6_src_init, 994d65e841dSYevgeny Kliteynik .build_eth_l3_ipv6_dst_init = &dr_ste_v0_build_eth_l3_ipv6_dst_init, 995d65e841dSYevgeny Kliteynik .build_eth_l3_ipv4_5_tuple_init = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_init, 996d65e841dSYevgeny Kliteynik .build_eth_l2_src_init = &dr_ste_v0_build_eth_l2_src_init, 997d65e841dSYevgeny Kliteynik .build_eth_l2_dst_init = &dr_ste_v0_build_eth_l2_dst_init, 998d65e841dSYevgeny Kliteynik .build_eth_l2_tnl_init = &dr_ste_v0_build_eth_l2_tnl_init, 999d65e841dSYevgeny Kliteynik .build_eth_l3_ipv4_misc_init = &dr_ste_v0_build_eth_l3_ipv4_misc_init, 1000d65e841dSYevgeny Kliteynik .build_eth_ipv6_l3_l4_init = &dr_ste_v0_build_eth_ipv6_l3_l4_init, 1001d65e841dSYevgeny Kliteynik .build_mpls_init = &dr_ste_v0_build_mpls_init, 1002d65e841dSYevgeny Kliteynik .build_tnl_gre_init = &dr_ste_v0_build_tnl_gre_init, 1003d65e841dSYevgeny Kliteynik .build_tnl_mpls_init = &dr_ste_v0_build_tnl_mpls_init, 1004d65e841dSYevgeny Kliteynik .build_icmp_init = &dr_ste_v0_build_icmp_init, 1005d65e841dSYevgeny Kliteynik .build_general_purpose_init = &dr_ste_v0_build_general_purpose_init, 1006d65e841dSYevgeny Kliteynik .build_eth_l4_misc_init = &dr_ste_v0_build_eth_l4_misc_init, 1007d65e841dSYevgeny Kliteynik .build_tnl_vxlan_gpe_init = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init, 1008d65e841dSYevgeny Kliteynik .build_tnl_geneve_init = &dr_ste_v0_build_flex_parser_tnl_geneve_init, 1009d65e841dSYevgeny Kliteynik .build_register_0_init = &dr_ste_v0_build_register_0_init, 1010d65e841dSYevgeny Kliteynik .build_register_1_init = &dr_ste_v0_build_register_1_init, 1011d65e841dSYevgeny Kliteynik .build_src_gvmi_qpn_init = &dr_ste_v0_build_src_gvmi_qpn_init, 1012d65e841dSYevgeny Kliteynik }; 1013