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) \ 9d65e841dSYevgeny Kliteynik ((inner) ? MLX5DR_STE_LU_TYPE_##lookup_type##_I : \ 10d65e841dSYevgeny Kliteynik (rx) ? MLX5DR_STE_LU_TYPE_##lookup_type##_D : \ 11d65e841dSYevgeny Kliteynik MLX5DR_STE_LU_TYPE_##lookup_type##_O) 12d65e841dSYevgeny Kliteynik 13d65e841dSYevgeny Kliteynik static void 14d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value, 15d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 16d65e841dSYevgeny Kliteynik { 17d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 18d65e841dSYevgeny Kliteynik 19*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_47_16, mask, dmac_47_16); 20*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_15_0, mask, dmac_15_0); 21d65e841dSYevgeny Kliteynik 22d65e841dSYevgeny Kliteynik if (mask->smac_47_16 || mask->smac_15_0) { 23d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_47_32, 24d65e841dSYevgeny Kliteynik mask->smac_47_16 >> 16); 25d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_31_0, 26d65e841dSYevgeny Kliteynik mask->smac_47_16 << 16 | mask->smac_15_0); 27d65e841dSYevgeny Kliteynik mask->smac_47_16 = 0; 28d65e841dSYevgeny Kliteynik mask->smac_15_0 = 0; 29d65e841dSYevgeny Kliteynik } 30d65e841dSYevgeny Kliteynik 31*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_vlan_id, mask, first_vid); 32*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_cfi, mask, first_cfi); 33*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_priority, mask, first_prio); 34*46779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_src_dst, bit_mask, l3_type, mask, ip_version); 35d65e841dSYevgeny Kliteynik 36d65e841dSYevgeny Kliteynik if (mask->cvlan_tag) { 37d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1); 38d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 39d65e841dSYevgeny Kliteynik } else if (mask->svlan_tag) { 40d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1); 41d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 42d65e841dSYevgeny Kliteynik } 43d65e841dSYevgeny Kliteynik } 44d65e841dSYevgeny Kliteynik 45d65e841dSYevgeny Kliteynik static int 46d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value, 47d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 48d65e841dSYevgeny Kliteynik u8 *tag) 49d65e841dSYevgeny Kliteynik { 50d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 51d65e841dSYevgeny Kliteynik 52d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_47_16, spec, dmac_47_16); 53d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_15_0, spec, dmac_15_0); 54d65e841dSYevgeny Kliteynik 55d65e841dSYevgeny Kliteynik if (spec->smac_47_16 || spec->smac_15_0) { 56d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, smac_47_32, 57d65e841dSYevgeny Kliteynik spec->smac_47_16 >> 16); 58d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, smac_31_0, 59d65e841dSYevgeny Kliteynik spec->smac_47_16 << 16 | spec->smac_15_0); 60d65e841dSYevgeny Kliteynik spec->smac_47_16 = 0; 61d65e841dSYevgeny Kliteynik spec->smac_15_0 = 0; 62d65e841dSYevgeny Kliteynik } 63d65e841dSYevgeny Kliteynik 64d65e841dSYevgeny Kliteynik if (spec->ip_version) { 65d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 66d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV4); 67d65e841dSYevgeny Kliteynik spec->ip_version = 0; 68d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 69d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV6); 70d65e841dSYevgeny Kliteynik spec->ip_version = 0; 71d65e841dSYevgeny Kliteynik } else { 72d65e841dSYevgeny Kliteynik return -EINVAL; 73d65e841dSYevgeny Kliteynik } 74d65e841dSYevgeny Kliteynik } 75d65e841dSYevgeny Kliteynik 76d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_vlan_id, spec, first_vid); 77d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_cfi, spec, first_cfi); 78d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_priority, spec, first_prio); 79d65e841dSYevgeny Kliteynik 80d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 81d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_CVLAN); 82d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 83d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 84d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_SVLAN); 85d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 86d65e841dSYevgeny Kliteynik } 87d65e841dSYevgeny Kliteynik return 0; 88d65e841dSYevgeny Kliteynik } 89d65e841dSYevgeny Kliteynik 90d65e841dSYevgeny Kliteynik static void 91d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb, 92d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 93d65e841dSYevgeny Kliteynik { 94d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask); 95d65e841dSYevgeny Kliteynik 96d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC_DST, sb->rx, sb->inner); 97d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 98d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_dst_tag; 99d65e841dSYevgeny Kliteynik } 100d65e841dSYevgeny Kliteynik 101d65e841dSYevgeny Kliteynik static int 102d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value, 103d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 104d65e841dSYevgeny Kliteynik u8 *tag) 105d65e841dSYevgeny Kliteynik { 106d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 107d65e841dSYevgeny Kliteynik 108d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96); 109d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64); 110d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32); 111d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0); 112d65e841dSYevgeny Kliteynik 113d65e841dSYevgeny Kliteynik return 0; 114d65e841dSYevgeny Kliteynik } 115d65e841dSYevgeny Kliteynik 116d65e841dSYevgeny Kliteynik static void 117d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb, 118d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 119d65e841dSYevgeny Kliteynik { 120*46779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask); 121d65e841dSYevgeny Kliteynik 122d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_DST, sb->rx, sb->inner); 123d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 124d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_dst_tag; 125d65e841dSYevgeny Kliteynik } 126d65e841dSYevgeny Kliteynik 127d65e841dSYevgeny Kliteynik static int 128d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value, 129d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 130d65e841dSYevgeny Kliteynik u8 *tag) 131d65e841dSYevgeny Kliteynik { 132d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 133d65e841dSYevgeny Kliteynik 134d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96); 135d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64); 136d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32); 137d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0); 138d65e841dSYevgeny Kliteynik 139d65e841dSYevgeny Kliteynik return 0; 140d65e841dSYevgeny Kliteynik } 141d65e841dSYevgeny Kliteynik 142d65e841dSYevgeny Kliteynik static void 143d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb, 144d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 145d65e841dSYevgeny Kliteynik { 146*46779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask); 147d65e841dSYevgeny Kliteynik 148d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_SRC, sb->rx, sb->inner); 149d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 150d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_src_tag; 151d65e841dSYevgeny Kliteynik } 152d65e841dSYevgeny Kliteynik 153d65e841dSYevgeny Kliteynik static int 154d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value, 155d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 156d65e841dSYevgeny Kliteynik u8 *tag) 157d65e841dSYevgeny Kliteynik { 158d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 159d65e841dSYevgeny Kliteynik 160d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_address, spec, dst_ip_31_0); 161d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_address, spec, src_ip_31_0); 162d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, tcp_dport); 163d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, udp_dport); 164d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, tcp_sport); 165d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, udp_sport); 166d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, protocol, spec, ip_protocol); 167d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, fragmented, spec, frag); 168d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, dscp, spec, ip_dscp); 169d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, ecn, spec, ip_ecn); 170d65e841dSYevgeny Kliteynik 171d65e841dSYevgeny Kliteynik if (spec->tcp_flags) { 172d65e841dSYevgeny Kliteynik DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, tag, spec); 173d65e841dSYevgeny Kliteynik spec->tcp_flags = 0; 174d65e841dSYevgeny Kliteynik } 175d65e841dSYevgeny Kliteynik 176d65e841dSYevgeny Kliteynik return 0; 177d65e841dSYevgeny Kliteynik } 178d65e841dSYevgeny Kliteynik 179d65e841dSYevgeny Kliteynik static void 180d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb, 181d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 182d65e841dSYevgeny Kliteynik { 183*46779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask); 184d65e841dSYevgeny Kliteynik 185d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_5_TUPLE, sb->rx, sb->inner); 186d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 187d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag; 188d65e841dSYevgeny Kliteynik } 189d65e841dSYevgeny Kliteynik 190d65e841dSYevgeny Kliteynik static void 191d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value, 192d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 193d65e841dSYevgeny Kliteynik { 194d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 195d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_mask = &value->misc; 196d65e841dSYevgeny Kliteynik 197*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_vlan_id, mask, first_vid); 198*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_cfi, mask, first_cfi); 199*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_priority, mask, first_prio); 200*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, ip_fragmented, mask, frag); 201*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, l3_ethertype, mask, ethertype); 202*46779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_src, bit_mask, l3_type, mask, ip_version); 203d65e841dSYevgeny Kliteynik 204d65e841dSYevgeny Kliteynik if (mask->svlan_tag || mask->cvlan_tag) { 205d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, first_vlan_qualifier, -1); 206d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 207d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 208d65e841dSYevgeny Kliteynik } 209d65e841dSYevgeny Kliteynik 210d65e841dSYevgeny Kliteynik if (inner) { 211d65e841dSYevgeny Kliteynik if (misc_mask->inner_second_cvlan_tag || 212d65e841dSYevgeny Kliteynik misc_mask->inner_second_svlan_tag) { 213d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1); 214d65e841dSYevgeny Kliteynik misc_mask->inner_second_cvlan_tag = 0; 215d65e841dSYevgeny Kliteynik misc_mask->inner_second_svlan_tag = 0; 216d65e841dSYevgeny Kliteynik } 217d65e841dSYevgeny Kliteynik 218*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 219d65e841dSYevgeny Kliteynik second_vlan_id, misc_mask, inner_second_vid); 220*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 221d65e841dSYevgeny Kliteynik second_cfi, misc_mask, inner_second_cfi); 222*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 223d65e841dSYevgeny Kliteynik second_priority, misc_mask, inner_second_prio); 224d65e841dSYevgeny Kliteynik } else { 225d65e841dSYevgeny Kliteynik if (misc_mask->outer_second_cvlan_tag || 226d65e841dSYevgeny Kliteynik misc_mask->outer_second_svlan_tag) { 227d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1); 228d65e841dSYevgeny Kliteynik misc_mask->outer_second_cvlan_tag = 0; 229d65e841dSYevgeny Kliteynik misc_mask->outer_second_svlan_tag = 0; 230d65e841dSYevgeny Kliteynik } 231d65e841dSYevgeny Kliteynik 232*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 233d65e841dSYevgeny Kliteynik second_vlan_id, misc_mask, outer_second_vid); 234*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 235d65e841dSYevgeny Kliteynik second_cfi, misc_mask, outer_second_cfi); 236*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 237d65e841dSYevgeny Kliteynik second_priority, misc_mask, outer_second_prio); 238d65e841dSYevgeny Kliteynik } 239d65e841dSYevgeny Kliteynik } 240d65e841dSYevgeny Kliteynik 241d65e841dSYevgeny Kliteynik static int 242d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value, 243d65e841dSYevgeny Kliteynik bool inner, u8 *tag) 244d65e841dSYevgeny Kliteynik { 245d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer; 246d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_spec = &value->misc; 247d65e841dSYevgeny Kliteynik 248d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_vlan_id, spec, first_vid); 249d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_cfi, spec, first_cfi); 250d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_priority, spec, first_prio); 251d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, ip_fragmented, spec, frag); 252d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, l3_ethertype, spec, ethertype); 253d65e841dSYevgeny Kliteynik 254d65e841dSYevgeny Kliteynik if (spec->ip_version) { 255d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 256d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV4); 257d65e841dSYevgeny Kliteynik spec->ip_version = 0; 258d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 259d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV6); 260d65e841dSYevgeny Kliteynik spec->ip_version = 0; 261d65e841dSYevgeny Kliteynik } else { 262d65e841dSYevgeny Kliteynik return -EINVAL; 263d65e841dSYevgeny Kliteynik } 264d65e841dSYevgeny Kliteynik } 265d65e841dSYevgeny Kliteynik 266d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 267d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_CVLAN); 268d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 269d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 270d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_SVLAN); 271d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 272d65e841dSYevgeny Kliteynik } 273d65e841dSYevgeny Kliteynik 274d65e841dSYevgeny Kliteynik if (inner) { 275d65e841dSYevgeny Kliteynik if (misc_spec->inner_second_cvlan_tag) { 276d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN); 277d65e841dSYevgeny Kliteynik misc_spec->inner_second_cvlan_tag = 0; 278d65e841dSYevgeny Kliteynik } else if (misc_spec->inner_second_svlan_tag) { 279d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN); 280d65e841dSYevgeny Kliteynik misc_spec->inner_second_svlan_tag = 0; 281d65e841dSYevgeny Kliteynik } 282d65e841dSYevgeny Kliteynik 283d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, inner_second_vid); 284d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, inner_second_cfi); 285d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, inner_second_prio); 286d65e841dSYevgeny Kliteynik } else { 287d65e841dSYevgeny Kliteynik if (misc_spec->outer_second_cvlan_tag) { 288d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN); 289d65e841dSYevgeny Kliteynik misc_spec->outer_second_cvlan_tag = 0; 290d65e841dSYevgeny Kliteynik } else if (misc_spec->outer_second_svlan_tag) { 291d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN); 292d65e841dSYevgeny Kliteynik misc_spec->outer_second_svlan_tag = 0; 293d65e841dSYevgeny Kliteynik } 294d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, outer_second_vid); 295d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, outer_second_cfi); 296d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, outer_second_prio); 297d65e841dSYevgeny Kliteynik } 298d65e841dSYevgeny Kliteynik 299d65e841dSYevgeny Kliteynik return 0; 300d65e841dSYevgeny Kliteynik } 301d65e841dSYevgeny Kliteynik 302d65e841dSYevgeny Kliteynik static void 303d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value, 304d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 305d65e841dSYevgeny Kliteynik { 306d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 307d65e841dSYevgeny Kliteynik 308*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_47_16, mask, smac_47_16); 309*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_15_0, mask, smac_15_0); 310d65e841dSYevgeny Kliteynik 311d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask); 312d65e841dSYevgeny Kliteynik } 313d65e841dSYevgeny Kliteynik 314d65e841dSYevgeny Kliteynik static int 315d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_tag(struct mlx5dr_match_param *value, 316d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 317d65e841dSYevgeny Kliteynik u8 *tag) 318d65e841dSYevgeny Kliteynik { 319d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 320d65e841dSYevgeny Kliteynik 321d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, smac_47_16, spec, smac_47_16); 322d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, smac_15_0, spec, smac_15_0); 323d65e841dSYevgeny Kliteynik 324d65e841dSYevgeny Kliteynik return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 325d65e841dSYevgeny Kliteynik } 326d65e841dSYevgeny Kliteynik 327d65e841dSYevgeny Kliteynik static void 328d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_init(struct mlx5dr_ste_build *sb, 329d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 330d65e841dSYevgeny Kliteynik { 331d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask); 332d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC, sb->rx, sb->inner); 333d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 334d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_tag; 335d65e841dSYevgeny Kliteynik } 336d65e841dSYevgeny Kliteynik 337d65e841dSYevgeny Kliteynik static void 338d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value, 339*46779098SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 340*46779098SYevgeny Kliteynik u8 *bit_mask) 341d65e841dSYevgeny Kliteynik { 342*46779098SYevgeny Kliteynik struct mlx5dr_match_spec *mask = sb->inner ? &value->inner : &value->outer; 343d65e841dSYevgeny Kliteynik 344*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_47_16, mask, dmac_47_16); 345*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_15_0, mask, dmac_15_0); 346d65e841dSYevgeny Kliteynik 347*46779098SYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, sb->inner, bit_mask); 348d65e841dSYevgeny Kliteynik } 349d65e841dSYevgeny Kliteynik 350d65e841dSYevgeny Kliteynik static int 351d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_tag(struct mlx5dr_match_param *value, 352d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 353d65e841dSYevgeny Kliteynik u8 *tag) 354d65e841dSYevgeny Kliteynik { 355d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 356d65e841dSYevgeny Kliteynik 357d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, tag, dmac_47_16, spec, dmac_47_16); 358d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, tag, dmac_15_0, spec, dmac_15_0); 359d65e841dSYevgeny Kliteynik 360d65e841dSYevgeny Kliteynik return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 361d65e841dSYevgeny Kliteynik } 362d65e841dSYevgeny Kliteynik 363d65e841dSYevgeny Kliteynik static void 364d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb, 365d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 366d65e841dSYevgeny Kliteynik { 367*46779098SYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_bit_mask(mask, sb, sb->bit_mask); 368d65e841dSYevgeny Kliteynik 369d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_DST, sb->rx, sb->inner); 370d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 371d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_dst_tag; 372d65e841dSYevgeny Kliteynik } 373d65e841dSYevgeny Kliteynik 374d65e841dSYevgeny Kliteynik static void 375d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value, 376d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 377d65e841dSYevgeny Kliteynik { 378d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 379d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 380d65e841dSYevgeny Kliteynik 381*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_47_16, mask, dmac_47_16); 382*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_15_0, mask, dmac_15_0); 383*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_vlan_id, mask, first_vid); 384*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_cfi, mask, first_cfi); 385*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_priority, mask, first_prio); 386*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, ip_fragmented, mask, frag); 387*46779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, l3_ethertype, mask, ethertype); 388*46779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_tnl, bit_mask, l3_type, mask, ip_version); 389d65e841dSYevgeny Kliteynik 390d65e841dSYevgeny Kliteynik if (misc->vxlan_vni) { 391d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, bit_mask, 392d65e841dSYevgeny Kliteynik l2_tunneling_network_id, (misc->vxlan_vni << 8)); 393d65e841dSYevgeny Kliteynik misc->vxlan_vni = 0; 394d65e841dSYevgeny Kliteynik } 395d65e841dSYevgeny Kliteynik 396d65e841dSYevgeny Kliteynik if (mask->svlan_tag || mask->cvlan_tag) { 397d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, bit_mask, first_vlan_qualifier, -1); 398d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 399d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 400d65e841dSYevgeny Kliteynik } 401d65e841dSYevgeny Kliteynik } 402d65e841dSYevgeny Kliteynik 403d65e841dSYevgeny Kliteynik static int 404d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value, 405d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 406d65e841dSYevgeny Kliteynik u8 *tag) 407d65e841dSYevgeny Kliteynik { 408d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 409d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 410d65e841dSYevgeny Kliteynik 411d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_47_16, spec, dmac_47_16); 412d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_15_0, spec, dmac_15_0); 413d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_vlan_id, spec, first_vid); 414d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_cfi, spec, first_cfi); 415d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, ip_fragmented, spec, frag); 416d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_priority, spec, first_prio); 417d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, l3_ethertype, spec, ethertype); 418d65e841dSYevgeny Kliteynik 419d65e841dSYevgeny Kliteynik if (misc->vxlan_vni) { 420d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l2_tunneling_network_id, 421d65e841dSYevgeny Kliteynik (misc->vxlan_vni << 8)); 422d65e841dSYevgeny Kliteynik misc->vxlan_vni = 0; 423d65e841dSYevgeny Kliteynik } 424d65e841dSYevgeny Kliteynik 425d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 426d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_CVLAN); 427d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 428d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 429d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_SVLAN); 430d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 431d65e841dSYevgeny Kliteynik } 432d65e841dSYevgeny Kliteynik 433d65e841dSYevgeny Kliteynik if (spec->ip_version) { 434d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 435d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV4); 436d65e841dSYevgeny Kliteynik spec->ip_version = 0; 437d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 438d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV6); 439d65e841dSYevgeny Kliteynik spec->ip_version = 0; 440d65e841dSYevgeny Kliteynik } else { 441d65e841dSYevgeny Kliteynik return -EINVAL; 442d65e841dSYevgeny Kliteynik } 443d65e841dSYevgeny Kliteynik } 444d65e841dSYevgeny Kliteynik 445d65e841dSYevgeny Kliteynik return 0; 446d65e841dSYevgeny Kliteynik } 447d65e841dSYevgeny Kliteynik 448d65e841dSYevgeny Kliteynik static void 449d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb, 450d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 451d65e841dSYevgeny Kliteynik { 452d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask); 453d65e841dSYevgeny Kliteynik 454d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_ETHL2_TUNNELING_I; 455d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 456d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_tnl_tag; 457d65e841dSYevgeny Kliteynik } 458d65e841dSYevgeny Kliteynik 459d65e841dSYevgeny Kliteynik static int 460d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value, 461d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 462d65e841dSYevgeny Kliteynik u8 *tag) 463d65e841dSYevgeny Kliteynik { 464d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 465d65e841dSYevgeny Kliteynik 466d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, time_to_live, spec, ttl_hoplimit); 467d65e841dSYevgeny Kliteynik 468d65e841dSYevgeny Kliteynik return 0; 469d65e841dSYevgeny Kliteynik } 470d65e841dSYevgeny Kliteynik 471d65e841dSYevgeny Kliteynik static void 472d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb, 473d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 474d65e841dSYevgeny Kliteynik { 475*46779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask); 476d65e841dSYevgeny Kliteynik 477d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_MISC, sb->rx, sb->inner); 478d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 479d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_misc_tag; 480d65e841dSYevgeny Kliteynik } 481d65e841dSYevgeny Kliteynik 482d65e841dSYevgeny Kliteynik static int 483d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value, 484d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 485d65e841dSYevgeny Kliteynik u8 *tag) 486d65e841dSYevgeny Kliteynik { 487d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 488d65e841dSYevgeny Kliteynik 489d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, tcp_dport); 490d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, src_port, spec, tcp_sport); 491d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, udp_dport); 492d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, src_port, spec, udp_sport); 493d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, protocol, spec, ip_protocol); 494d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, fragmented, spec, frag); 495d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dscp, spec, ip_dscp); 496d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, ecn, spec, ip_ecn); 497d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, ipv6_hop_limit, spec, ttl_hoplimit); 498d65e841dSYevgeny Kliteynik 499d65e841dSYevgeny Kliteynik if (spec->tcp_flags) { 500d65e841dSYevgeny Kliteynik DR_STE_SET_TCP_FLAGS(eth_l4, tag, spec); 501d65e841dSYevgeny Kliteynik spec->tcp_flags = 0; 502d65e841dSYevgeny Kliteynik } 503d65e841dSYevgeny Kliteynik 504d65e841dSYevgeny Kliteynik return 0; 505d65e841dSYevgeny Kliteynik } 506d65e841dSYevgeny Kliteynik 507d65e841dSYevgeny Kliteynik static void 508d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb, 509d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 510d65e841dSYevgeny Kliteynik { 511*46779098SYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask); 512d65e841dSYevgeny Kliteynik 513d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4, sb->rx, sb->inner); 514d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 515d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_ipv6_l3_l4_tag; 516d65e841dSYevgeny Kliteynik } 517d65e841dSYevgeny Kliteynik 518d65e841dSYevgeny Kliteynik static int 519d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_tag(struct mlx5dr_match_param *value, 520d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 521d65e841dSYevgeny Kliteynik u8 *tag) 522d65e841dSYevgeny Kliteynik { 523*46779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 524d65e841dSYevgeny Kliteynik 525d65e841dSYevgeny Kliteynik if (sb->inner) 526*46779098SYevgeny Kliteynik DR_STE_SET_MPLS(mpls, misc2, inner, tag); 527d65e841dSYevgeny Kliteynik else 528*46779098SYevgeny Kliteynik DR_STE_SET_MPLS(mpls, misc2, outer, tag); 529d65e841dSYevgeny Kliteynik 530d65e841dSYevgeny Kliteynik return 0; 531d65e841dSYevgeny Kliteynik } 532d65e841dSYevgeny Kliteynik 533d65e841dSYevgeny Kliteynik static void 534d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_init(struct mlx5dr_ste_build *sb, 535d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 536d65e841dSYevgeny Kliteynik { 537*46779098SYevgeny Kliteynik dr_ste_v0_build_mpls_tag(mask, sb, sb->bit_mask); 538d65e841dSYevgeny Kliteynik 539d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(MPLS_FIRST, sb->rx, sb->inner); 540d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 541d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_mpls_tag; 542d65e841dSYevgeny Kliteynik } 543d65e841dSYevgeny Kliteynik 544d65e841dSYevgeny Kliteynik static int 545d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_tag(struct mlx5dr_match_param *value, 546d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 547d65e841dSYevgeny Kliteynik u8 *tag) 548d65e841dSYevgeny Kliteynik { 549d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 550d65e841dSYevgeny Kliteynik 551d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_protocol, misc, gre_protocol); 552d65e841dSYevgeny Kliteynik 553d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_k_present, misc, gre_k_present); 554d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_key_h, misc, gre_key_h); 555d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_key_l, misc, gre_key_l); 556d65e841dSYevgeny Kliteynik 557d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_c_present, misc, gre_c_present); 558d65e841dSYevgeny Kliteynik 559d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_s_present, misc, gre_s_present); 560d65e841dSYevgeny Kliteynik 561d65e841dSYevgeny Kliteynik return 0; 562d65e841dSYevgeny Kliteynik } 563d65e841dSYevgeny Kliteynik 564d65e841dSYevgeny Kliteynik static void 565d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_init(struct mlx5dr_ste_build *sb, 566d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 567d65e841dSYevgeny Kliteynik { 568*46779098SYevgeny Kliteynik dr_ste_v0_build_tnl_gre_tag(mask, sb, sb->bit_mask); 569d65e841dSYevgeny Kliteynik 570d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_GRE; 571d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 572d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gre_tag; 573d65e841dSYevgeny Kliteynik } 574d65e841dSYevgeny Kliteynik 575d65e841dSYevgeny Kliteynik static int 576d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_tag(struct mlx5dr_match_param *value, 577d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 578d65e841dSYevgeny Kliteynik u8 *tag) 579d65e841dSYevgeny Kliteynik { 580*46779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc_2 = &value->misc2; 581d65e841dSYevgeny Kliteynik 582*46779098SYevgeny Kliteynik if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2)) { 583d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label, 584*46779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_label); 585d65e841dSYevgeny Kliteynik 586d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp, 587*46779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_exp); 588d65e841dSYevgeny Kliteynik 589d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos, 590*46779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_s_bos); 591d65e841dSYevgeny Kliteynik 592d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl, 593*46779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_ttl); 594d65e841dSYevgeny Kliteynik } else { 595d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label, 596*46779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_label); 597d65e841dSYevgeny Kliteynik 598d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp, 599*46779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_exp); 600d65e841dSYevgeny Kliteynik 601d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos, 602*46779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_s_bos); 603d65e841dSYevgeny Kliteynik 604d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl, 605*46779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_ttl); 606d65e841dSYevgeny Kliteynik } 607d65e841dSYevgeny Kliteynik return 0; 608d65e841dSYevgeny Kliteynik } 609d65e841dSYevgeny Kliteynik 610d65e841dSYevgeny Kliteynik static void 611d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_init(struct mlx5dr_ste_build *sb, 612d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 613d65e841dSYevgeny Kliteynik { 614*46779098SYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_tag(mask, sb, sb->bit_mask); 615d65e841dSYevgeny Kliteynik 616d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_0; 617d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 618d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_tag; 619d65e841dSYevgeny Kliteynik } 620d65e841dSYevgeny Kliteynik 621d65e841dSYevgeny Kliteynik #define ICMP_TYPE_OFFSET_FIRST_DW 24 622d65e841dSYevgeny Kliteynik #define ICMP_CODE_OFFSET_FIRST_DW 16 623d65e841dSYevgeny Kliteynik #define ICMP_HEADER_DATA_OFFSET_SECOND_DW 0 624d65e841dSYevgeny Kliteynik 625d65e841dSYevgeny Kliteynik static int 626d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_tag(struct mlx5dr_match_param *value, 627d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 628d65e841dSYevgeny Kliteynik u8 *tag) 629d65e841dSYevgeny Kliteynik { 630d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc_3 = &value->misc3; 631d65e841dSYevgeny Kliteynik u32 icmp_header_data; 632d65e841dSYevgeny Kliteynik int dw0_location; 633d65e841dSYevgeny Kliteynik int dw1_location; 634d65e841dSYevgeny Kliteynik u32 icmp_type; 635d65e841dSYevgeny Kliteynik u32 icmp_code; 636d65e841dSYevgeny Kliteynik bool is_ipv4; 637d65e841dSYevgeny Kliteynik 638d65e841dSYevgeny Kliteynik is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc_3); 639d65e841dSYevgeny Kliteynik if (is_ipv4) { 640d65e841dSYevgeny Kliteynik icmp_header_data = misc_3->icmpv4_header_data; 641d65e841dSYevgeny Kliteynik icmp_type = misc_3->icmpv4_type; 642d65e841dSYevgeny Kliteynik icmp_code = misc_3->icmpv4_code; 643d65e841dSYevgeny Kliteynik dw0_location = sb->caps->flex_parser_id_icmp_dw0; 644d65e841dSYevgeny Kliteynik dw1_location = sb->caps->flex_parser_id_icmp_dw1; 645d65e841dSYevgeny Kliteynik } else { 646d65e841dSYevgeny Kliteynik icmp_header_data = misc_3->icmpv6_header_data; 647d65e841dSYevgeny Kliteynik icmp_type = misc_3->icmpv6_type; 648d65e841dSYevgeny Kliteynik icmp_code = misc_3->icmpv6_code; 649d65e841dSYevgeny Kliteynik dw0_location = sb->caps->flex_parser_id_icmpv6_dw0; 650d65e841dSYevgeny Kliteynik dw1_location = sb->caps->flex_parser_id_icmpv6_dw1; 651d65e841dSYevgeny Kliteynik } 652d65e841dSYevgeny Kliteynik 653d65e841dSYevgeny Kliteynik switch (dw0_location) { 654d65e841dSYevgeny Kliteynik case 4: 655d65e841dSYevgeny Kliteynik if (icmp_type) { 656d65e841dSYevgeny Kliteynik MLX5_SET(ste_flex_parser_1, tag, flex_parser_4, 657d65e841dSYevgeny Kliteynik (icmp_type << ICMP_TYPE_OFFSET_FIRST_DW)); 658d65e841dSYevgeny Kliteynik if (is_ipv4) 659d65e841dSYevgeny Kliteynik misc_3->icmpv4_type = 0; 660d65e841dSYevgeny Kliteynik else 661d65e841dSYevgeny Kliteynik misc_3->icmpv6_type = 0; 662d65e841dSYevgeny Kliteynik } 663d65e841dSYevgeny Kliteynik 664d65e841dSYevgeny Kliteynik if (icmp_code) { 665d65e841dSYevgeny Kliteynik u32 cur_val = MLX5_GET(ste_flex_parser_1, tag, 666d65e841dSYevgeny Kliteynik flex_parser_4); 667d65e841dSYevgeny Kliteynik MLX5_SET(ste_flex_parser_1, tag, flex_parser_4, 668d65e841dSYevgeny Kliteynik cur_val | (icmp_code << ICMP_CODE_OFFSET_FIRST_DW)); 669d65e841dSYevgeny Kliteynik if (is_ipv4) 670d65e841dSYevgeny Kliteynik misc_3->icmpv4_code = 0; 671d65e841dSYevgeny Kliteynik else 672d65e841dSYevgeny Kliteynik misc_3->icmpv6_code = 0; 673d65e841dSYevgeny Kliteynik } 674d65e841dSYevgeny Kliteynik break; 675d65e841dSYevgeny Kliteynik default: 676d65e841dSYevgeny Kliteynik return -EINVAL; 677d65e841dSYevgeny Kliteynik } 678d65e841dSYevgeny Kliteynik 679d65e841dSYevgeny Kliteynik switch (dw1_location) { 680d65e841dSYevgeny Kliteynik case 5: 681d65e841dSYevgeny Kliteynik if (icmp_header_data) { 682d65e841dSYevgeny Kliteynik MLX5_SET(ste_flex_parser_1, tag, flex_parser_5, 683d65e841dSYevgeny Kliteynik (icmp_header_data << ICMP_HEADER_DATA_OFFSET_SECOND_DW)); 684d65e841dSYevgeny Kliteynik if (is_ipv4) 685d65e841dSYevgeny Kliteynik misc_3->icmpv4_header_data = 0; 686d65e841dSYevgeny Kliteynik else 687d65e841dSYevgeny Kliteynik misc_3->icmpv6_header_data = 0; 688d65e841dSYevgeny Kliteynik } 689d65e841dSYevgeny Kliteynik break; 690d65e841dSYevgeny Kliteynik default: 691d65e841dSYevgeny Kliteynik return -EINVAL; 692d65e841dSYevgeny Kliteynik } 693d65e841dSYevgeny Kliteynik 694d65e841dSYevgeny Kliteynik return 0; 695d65e841dSYevgeny Kliteynik } 696d65e841dSYevgeny Kliteynik 697d65e841dSYevgeny Kliteynik static int 698d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_init(struct mlx5dr_ste_build *sb, 699d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 700d65e841dSYevgeny Kliteynik { 701d65e841dSYevgeny Kliteynik int ret; 702d65e841dSYevgeny Kliteynik 703*46779098SYevgeny Kliteynik ret = dr_ste_v0_build_icmp_tag(mask, sb, sb->bit_mask); 704d65e841dSYevgeny Kliteynik if (ret) 705d65e841dSYevgeny Kliteynik return ret; 706d65e841dSYevgeny Kliteynik 707d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_1; 708d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 709d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_icmp_tag; 710d65e841dSYevgeny Kliteynik 711d65e841dSYevgeny Kliteynik return 0; 712d65e841dSYevgeny Kliteynik } 713d65e841dSYevgeny Kliteynik 714d65e841dSYevgeny Kliteynik static int 715d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_tag(struct mlx5dr_match_param *value, 716d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 717d65e841dSYevgeny Kliteynik u8 *tag) 718d65e841dSYevgeny Kliteynik { 719*46779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc_2 = &value->misc2; 720d65e841dSYevgeny Kliteynik 721d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field, 722*46779098SYevgeny Kliteynik misc_2, metadata_reg_a); 723d65e841dSYevgeny Kliteynik 724d65e841dSYevgeny Kliteynik return 0; 725d65e841dSYevgeny Kliteynik } 726d65e841dSYevgeny Kliteynik 727d65e841dSYevgeny Kliteynik static void 728d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_init(struct mlx5dr_ste_build *sb, 729d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 730d65e841dSYevgeny Kliteynik { 731*46779098SYevgeny Kliteynik dr_ste_v0_build_general_purpose_tag(mask, sb, sb->bit_mask); 732d65e841dSYevgeny Kliteynik 733d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_GENERAL_PURPOSE; 734d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 735d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_general_purpose_tag; 736d65e841dSYevgeny Kliteynik } 737d65e841dSYevgeny Kliteynik 738d65e841dSYevgeny Kliteynik static int 739d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_tag(struct mlx5dr_match_param *value, 740d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 741d65e841dSYevgeny Kliteynik u8 *tag) 742d65e841dSYevgeny Kliteynik { 743d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 744d65e841dSYevgeny Kliteynik 745d65e841dSYevgeny Kliteynik if (sb->inner) { 746d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, inner_tcp_seq_num); 747d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, inner_tcp_ack_num); 748d65e841dSYevgeny Kliteynik } else { 749d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, outer_tcp_seq_num); 750d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, outer_tcp_ack_num); 751d65e841dSYevgeny Kliteynik } 752d65e841dSYevgeny Kliteynik 753d65e841dSYevgeny Kliteynik return 0; 754d65e841dSYevgeny Kliteynik } 755d65e841dSYevgeny Kliteynik 756d65e841dSYevgeny Kliteynik static void 757d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb, 758d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 759d65e841dSYevgeny Kliteynik { 760*46779098SYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_tag(mask, sb, sb->bit_mask); 761d65e841dSYevgeny Kliteynik 762d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4_MISC, sb->rx, sb->inner); 763d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 764d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l4_misc_tag; 765d65e841dSYevgeny Kliteynik } 766d65e841dSYevgeny Kliteynik 767d65e841dSYevgeny Kliteynik static int 768d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value, 769d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 770d65e841dSYevgeny Kliteynik u8 *tag) 771d65e841dSYevgeny Kliteynik { 772d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 773d65e841dSYevgeny Kliteynik 774d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 775d65e841dSYevgeny Kliteynik outer_vxlan_gpe_flags, misc3, 776d65e841dSYevgeny Kliteynik outer_vxlan_gpe_flags); 777d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 778d65e841dSYevgeny Kliteynik outer_vxlan_gpe_next_protocol, misc3, 779d65e841dSYevgeny Kliteynik outer_vxlan_gpe_next_protocol); 780d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 781d65e841dSYevgeny Kliteynik outer_vxlan_gpe_vni, misc3, 782d65e841dSYevgeny Kliteynik outer_vxlan_gpe_vni); 783d65e841dSYevgeny Kliteynik 784d65e841dSYevgeny Kliteynik return 0; 785d65e841dSYevgeny Kliteynik } 786d65e841dSYevgeny Kliteynik 787d65e841dSYevgeny Kliteynik static void 788d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb, 789d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 790d65e841dSYevgeny Kliteynik { 791*46779098SYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask); 792d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER; 793d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 794d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag; 795d65e841dSYevgeny Kliteynik } 796d65e841dSYevgeny Kliteynik 797d65e841dSYevgeny Kliteynik static int 798d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value, 799d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 800d65e841dSYevgeny Kliteynik u8 *tag) 801d65e841dSYevgeny Kliteynik { 802d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 803d65e841dSYevgeny Kliteynik 804d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 805d65e841dSYevgeny Kliteynik geneve_protocol_type, misc, geneve_protocol_type); 806d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 807d65e841dSYevgeny Kliteynik geneve_oam, misc, geneve_oam); 808d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 809d65e841dSYevgeny Kliteynik geneve_opt_len, misc, geneve_opt_len); 810d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 811d65e841dSYevgeny Kliteynik geneve_vni, misc, geneve_vni); 812d65e841dSYevgeny Kliteynik 813d65e841dSYevgeny Kliteynik return 0; 814d65e841dSYevgeny Kliteynik } 815d65e841dSYevgeny Kliteynik 816d65e841dSYevgeny Kliteynik static void 817d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb, 818d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 819d65e841dSYevgeny Kliteynik { 820*46779098SYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask); 821d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER; 822d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 823d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tag; 824d65e841dSYevgeny Kliteynik } 825d65e841dSYevgeny Kliteynik 826d65e841dSYevgeny Kliteynik static int 827d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_tag(struct mlx5dr_match_param *value, 828d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 829d65e841dSYevgeny Kliteynik u8 *tag) 830d65e841dSYevgeny Kliteynik { 831d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 832d65e841dSYevgeny Kliteynik 833d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0); 834d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1); 835d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2); 836d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3); 837d65e841dSYevgeny Kliteynik 838d65e841dSYevgeny Kliteynik return 0; 839d65e841dSYevgeny Kliteynik } 840d65e841dSYevgeny Kliteynik 841d65e841dSYevgeny Kliteynik static void 842d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_init(struct mlx5dr_ste_build *sb, 843d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 844d65e841dSYevgeny Kliteynik { 845*46779098SYevgeny Kliteynik dr_ste_v0_build_register_0_tag(mask, sb, sb->bit_mask); 846d65e841dSYevgeny Kliteynik 847d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_STEERING_REGISTERS_0; 848d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 849d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_register_0_tag; 850d65e841dSYevgeny Kliteynik } 851d65e841dSYevgeny Kliteynik 852d65e841dSYevgeny Kliteynik static int 853d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_tag(struct mlx5dr_match_param *value, 854d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 855d65e841dSYevgeny Kliteynik u8 *tag) 856d65e841dSYevgeny Kliteynik { 857d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 858d65e841dSYevgeny Kliteynik 859d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4); 860d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5); 861d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6); 862d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7); 863d65e841dSYevgeny Kliteynik 864d65e841dSYevgeny Kliteynik return 0; 865d65e841dSYevgeny Kliteynik } 866d65e841dSYevgeny Kliteynik 867d65e841dSYevgeny Kliteynik static void 868d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_init(struct mlx5dr_ste_build *sb, 869d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 870d65e841dSYevgeny Kliteynik { 871*46779098SYevgeny Kliteynik dr_ste_v0_build_register_1_tag(mask, sb, sb->bit_mask); 872d65e841dSYevgeny Kliteynik 873d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_STEERING_REGISTERS_1; 874d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 875d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_register_1_tag; 876d65e841dSYevgeny Kliteynik } 877d65e841dSYevgeny Kliteynik 878d65e841dSYevgeny Kliteynik static void 879d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value, 880d65e841dSYevgeny Kliteynik u8 *bit_mask) 881d65e841dSYevgeny Kliteynik { 882d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_mask = &value->misc; 883d65e841dSYevgeny Kliteynik 884*46779098SYevgeny Kliteynik DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_gvmi, misc_mask, source_port); 885*46779098SYevgeny Kliteynik DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_qp, misc_mask, source_sqn); 886d65e841dSYevgeny Kliteynik misc_mask->source_eswitch_owner_vhca_id = 0; 887d65e841dSYevgeny Kliteynik } 888d65e841dSYevgeny Kliteynik 889d65e841dSYevgeny Kliteynik static int 890d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, 891d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 892d65e841dSYevgeny Kliteynik u8 *tag) 893d65e841dSYevgeny Kliteynik { 894d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 895d65e841dSYevgeny Kliteynik struct mlx5dr_cmd_vport_cap *vport_cap; 896d65e841dSYevgeny Kliteynik struct mlx5dr_domain *dmn = sb->dmn; 897d65e841dSYevgeny Kliteynik struct mlx5dr_cmd_caps *caps; 898d65e841dSYevgeny Kliteynik u8 *bit_mask = sb->bit_mask; 899d65e841dSYevgeny Kliteynik bool source_gvmi_set; 900d65e841dSYevgeny Kliteynik 901d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn); 902d65e841dSYevgeny Kliteynik 903d65e841dSYevgeny Kliteynik if (sb->vhca_id_valid) { 904d65e841dSYevgeny Kliteynik /* Find port GVMI based on the eswitch_owner_vhca_id */ 905d65e841dSYevgeny Kliteynik if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi) 906d65e841dSYevgeny Kliteynik caps = &dmn->info.caps; 907d65e841dSYevgeny Kliteynik else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id == 908d65e841dSYevgeny Kliteynik dmn->peer_dmn->info.caps.gvmi)) 909d65e841dSYevgeny Kliteynik caps = &dmn->peer_dmn->info.caps; 910d65e841dSYevgeny Kliteynik else 911d65e841dSYevgeny Kliteynik return -EINVAL; 9127863c912SYevgeny Kliteynik 9137863c912SYevgeny Kliteynik misc->source_eswitch_owner_vhca_id = 0; 914d65e841dSYevgeny Kliteynik } else { 915d65e841dSYevgeny Kliteynik caps = &dmn->info.caps; 916d65e841dSYevgeny Kliteynik } 917d65e841dSYevgeny Kliteynik 9187863c912SYevgeny Kliteynik source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi); 9197863c912SYevgeny Kliteynik if (source_gvmi_set) { 920d65e841dSYevgeny Kliteynik vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port); 921d65e841dSYevgeny Kliteynik if (!vport_cap) { 922d65e841dSYevgeny Kliteynik mlx5dr_err(dmn, "Vport 0x%x is invalid\n", 923d65e841dSYevgeny Kliteynik misc->source_port); 924d65e841dSYevgeny Kliteynik return -EINVAL; 925d65e841dSYevgeny Kliteynik } 926d65e841dSYevgeny Kliteynik 9277863c912SYevgeny Kliteynik if (vport_cap->vport_gvmi) 928d65e841dSYevgeny Kliteynik MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi); 929d65e841dSYevgeny Kliteynik 930d65e841dSYevgeny Kliteynik misc->source_port = 0; 9317863c912SYevgeny Kliteynik } 932d65e841dSYevgeny Kliteynik 933d65e841dSYevgeny Kliteynik return 0; 934d65e841dSYevgeny Kliteynik } 935d65e841dSYevgeny Kliteynik 936d65e841dSYevgeny Kliteynik static void 937d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb, 938d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 939d65e841dSYevgeny Kliteynik { 940d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask); 941d65e841dSYevgeny Kliteynik 942d65e841dSYevgeny Kliteynik sb->lu_type = MLX5DR_STE_LU_TYPE_SRC_GVMI_AND_QP; 943d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 944d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_src_gvmi_qpn_tag; 945d65e841dSYevgeny Kliteynik } 946d65e841dSYevgeny Kliteynik 947d65e841dSYevgeny Kliteynik struct mlx5dr_ste_ctx ste_ctx_v0 = { 948d65e841dSYevgeny Kliteynik .build_eth_l2_src_dst_init = &dr_ste_v0_build_eth_l2_src_dst_init, 949d65e841dSYevgeny Kliteynik .build_eth_l3_ipv6_src_init = &dr_ste_v0_build_eth_l3_ipv6_src_init, 950d65e841dSYevgeny Kliteynik .build_eth_l3_ipv6_dst_init = &dr_ste_v0_build_eth_l3_ipv6_dst_init, 951d65e841dSYevgeny Kliteynik .build_eth_l3_ipv4_5_tuple_init = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_init, 952d65e841dSYevgeny Kliteynik .build_eth_l2_src_init = &dr_ste_v0_build_eth_l2_src_init, 953d65e841dSYevgeny Kliteynik .build_eth_l2_dst_init = &dr_ste_v0_build_eth_l2_dst_init, 954d65e841dSYevgeny Kliteynik .build_eth_l2_tnl_init = &dr_ste_v0_build_eth_l2_tnl_init, 955d65e841dSYevgeny Kliteynik .build_eth_l3_ipv4_misc_init = &dr_ste_v0_build_eth_l3_ipv4_misc_init, 956d65e841dSYevgeny Kliteynik .build_eth_ipv6_l3_l4_init = &dr_ste_v0_build_eth_ipv6_l3_l4_init, 957d65e841dSYevgeny Kliteynik .build_mpls_init = &dr_ste_v0_build_mpls_init, 958d65e841dSYevgeny Kliteynik .build_tnl_gre_init = &dr_ste_v0_build_tnl_gre_init, 959d65e841dSYevgeny Kliteynik .build_tnl_mpls_init = &dr_ste_v0_build_tnl_mpls_init, 960d65e841dSYevgeny Kliteynik .build_icmp_init = &dr_ste_v0_build_icmp_init, 961d65e841dSYevgeny Kliteynik .build_general_purpose_init = &dr_ste_v0_build_general_purpose_init, 962d65e841dSYevgeny Kliteynik .build_eth_l4_misc_init = &dr_ste_v0_build_eth_l4_misc_init, 963d65e841dSYevgeny Kliteynik .build_tnl_vxlan_gpe_init = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init, 964d65e841dSYevgeny Kliteynik .build_tnl_geneve_init = &dr_ste_v0_build_flex_parser_tnl_geneve_init, 965d65e841dSYevgeny Kliteynik .build_register_0_init = &dr_ste_v0_build_register_0_init, 966d65e841dSYevgeny Kliteynik .build_register_1_init = &dr_ste_v0_build_register_1_init, 967d65e841dSYevgeny Kliteynik .build_src_gvmi_qpn_init = &dr_ste_v0_build_src_gvmi_qpn_init, 968d65e841dSYevgeny Kliteynik }; 969