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 8*ad17dc8cSYevgeny Kliteynik #define DR_STE_ENABLE_FLOW_TAG BIT(31) 9*ad17dc8cSYevgeny Kliteynik 10*ad17dc8cSYevgeny Kliteynik enum dr_ste_tunl_action { 11*ad17dc8cSYevgeny Kliteynik DR_STE_TUNL_ACTION_NONE = 0, 12*ad17dc8cSYevgeny Kliteynik DR_STE_TUNL_ACTION_ENABLE = 1, 13*ad17dc8cSYevgeny Kliteynik DR_STE_TUNL_ACTION_DECAP = 2, 14*ad17dc8cSYevgeny Kliteynik DR_STE_TUNL_ACTION_L3_DECAP = 3, 15*ad17dc8cSYevgeny Kliteynik DR_STE_TUNL_ACTION_POP_VLAN = 4, 16*ad17dc8cSYevgeny Kliteynik }; 17*ad17dc8cSYevgeny Kliteynik 18*ad17dc8cSYevgeny Kliteynik enum dr_ste_action_type { 19*ad17dc8cSYevgeny Kliteynik DR_STE_ACTION_TYPE_PUSH_VLAN = 1, 20*ad17dc8cSYevgeny Kliteynik DR_STE_ACTION_TYPE_ENCAP_L3 = 3, 21*ad17dc8cSYevgeny Kliteynik DR_STE_ACTION_TYPE_ENCAP = 4, 22*ad17dc8cSYevgeny Kliteynik }; 23*ad17dc8cSYevgeny Kliteynik 24d65e841dSYevgeny Kliteynik #define DR_STE_CALC_LU_TYPE(lookup_type, rx, inner) \ 25dd2d3c8dSYevgeny Kliteynik ((inner) ? DR_STE_V0_LU_TYPE_##lookup_type##_I : \ 26dd2d3c8dSYevgeny Kliteynik (rx) ? DR_STE_V0_LU_TYPE_##lookup_type##_D : \ 27dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_##lookup_type##_O) 28dd2d3c8dSYevgeny Kliteynik 29dd2d3c8dSYevgeny Kliteynik enum { 30dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_NOP = 0x00, 31dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP = 0x05, 32dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I = 0x0a, 33dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_DST_O = 0x06, 34dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_DST_I = 0x07, 35dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_DST_D = 0x1b, 36dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_O = 0x08, 37dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_I = 0x09, 38dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_D = 0x1c, 39dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_O = 0x36, 40dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_I = 0x37, 41dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_D = 0x38, 42dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_O = 0x0d, 43dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_I = 0x0e, 44dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_D = 0x1e, 45dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_O = 0x0f, 46dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_I = 0x10, 47dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_D = 0x1f, 48dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_O = 0x11, 49dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_I = 0x12, 50dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_D = 0x20, 51dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_O = 0x29, 52dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_I = 0x2a, 53dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_D = 0x2b, 54dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_O = 0x13, 55dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_I = 0x14, 56dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_D = 0x21, 57dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_MISC_O = 0x2c, 58dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_MISC_I = 0x2d, 59dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_ETHL4_MISC_D = 0x2e, 60dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_MPLS_FIRST_O = 0x15, 61dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_MPLS_FIRST_I = 0x24, 62dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_MPLS_FIRST_D = 0x25, 63dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_GRE = 0x16, 64dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_FLEX_PARSER_0 = 0x22, 65dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_FLEX_PARSER_1 = 0x23, 66dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER = 0x19, 67dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_GENERAL_PURPOSE = 0x18, 68dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0 = 0x2f, 69dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1 = 0x30, 70dd2d3c8dSYevgeny Kliteynik DR_STE_V0_LU_TYPE_DONT_CARE = MLX5DR_STE_LU_TYPE_DONT_CARE, 71dd2d3c8dSYevgeny Kliteynik }; 72d65e841dSYevgeny Kliteynik 73*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_entry_type(u8 *hw_ste_p, u8 entry_type) 74*ad17dc8cSYevgeny Kliteynik { 75*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_general, hw_ste_p, entry_type, entry_type); 76*ad17dc8cSYevgeny Kliteynik } 77*ad17dc8cSYevgeny Kliteynik 78*ad17dc8cSYevgeny Kliteynik static u8 dr_ste_v0_get_entry_type(u8 *hw_ste_p) 79*ad17dc8cSYevgeny Kliteynik { 80*ad17dc8cSYevgeny Kliteynik return MLX5_GET(ste_general, hw_ste_p, entry_type); 81*ad17dc8cSYevgeny Kliteynik } 82*ad17dc8cSYevgeny Kliteynik 836b93b400SYevgeny Kliteynik static void dr_ste_v0_set_miss_addr(u8 *hw_ste_p, u64 miss_addr) 846b93b400SYevgeny Kliteynik { 856b93b400SYevgeny Kliteynik u64 index = miss_addr >> 6; 866b93b400SYevgeny Kliteynik 876b93b400SYevgeny Kliteynik /* Miss address for TX and RX STEs located in the same offsets */ 886b93b400SYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32, index >> 26); 896b93b400SYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6, index); 906b93b400SYevgeny Kliteynik } 916b93b400SYevgeny Kliteynik 926b93b400SYevgeny Kliteynik static u64 dr_ste_v0_get_miss_addr(u8 *hw_ste_p) 936b93b400SYevgeny Kliteynik { 946b93b400SYevgeny Kliteynik u64 index = 956b93b400SYevgeny Kliteynik (MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6) | 966b93b400SYevgeny Kliteynik MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32) << 26); 976b93b400SYevgeny Kliteynik 986b93b400SYevgeny Kliteynik return index << 6; 996b93b400SYevgeny Kliteynik } 1006b93b400SYevgeny Kliteynik 1016b93b400SYevgeny Kliteynik static void dr_ste_v0_set_byte_mask(u8 *hw_ste_p, u16 byte_mask) 1026b93b400SYevgeny Kliteynik { 1036b93b400SYevgeny Kliteynik MLX5_SET(ste_general, hw_ste_p, byte_mask, byte_mask); 1046b93b400SYevgeny Kliteynik } 1056b93b400SYevgeny Kliteynik 1066b93b400SYevgeny Kliteynik static u16 dr_ste_v0_get_byte_mask(u8 *hw_ste_p) 1076b93b400SYevgeny Kliteynik { 1086b93b400SYevgeny Kliteynik return MLX5_GET(ste_general, hw_ste_p, byte_mask); 1096b93b400SYevgeny Kliteynik } 1106b93b400SYevgeny Kliteynik 1116b93b400SYevgeny Kliteynik static void dr_ste_v0_set_lu_type(u8 *hw_ste_p, u16 lu_type) 1126b93b400SYevgeny Kliteynik { 1136b93b400SYevgeny Kliteynik MLX5_SET(ste_general, hw_ste_p, entry_sub_type, lu_type); 1146b93b400SYevgeny Kliteynik } 1156b93b400SYevgeny Kliteynik 1166b93b400SYevgeny Kliteynik static void dr_ste_v0_set_next_lu_type(u8 *hw_ste_p, u16 lu_type) 1176b93b400SYevgeny Kliteynik { 1186b93b400SYevgeny Kliteynik MLX5_SET(ste_general, hw_ste_p, next_lu_type, lu_type); 1196b93b400SYevgeny Kliteynik } 1206b93b400SYevgeny Kliteynik 1216b93b400SYevgeny Kliteynik static u16 dr_ste_v0_get_next_lu_type(u8 *hw_ste_p) 1226b93b400SYevgeny Kliteynik { 1236b93b400SYevgeny Kliteynik return MLX5_GET(ste_general, hw_ste_p, next_lu_type); 1246b93b400SYevgeny Kliteynik } 1256b93b400SYevgeny Kliteynik 126*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_hit_gvmi(u8 *hw_ste_p, u16 gvmi) 127*ad17dc8cSYevgeny Kliteynik { 128*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_general, hw_ste_p, next_table_base_63_48, gvmi); 129*ad17dc8cSYevgeny Kliteynik } 130*ad17dc8cSYevgeny Kliteynik 1316b93b400SYevgeny Kliteynik static void dr_ste_v0_set_hit_addr(u8 *hw_ste_p, u64 icm_addr, u32 ht_size) 1326b93b400SYevgeny Kliteynik { 1336b93b400SYevgeny Kliteynik u64 index = (icm_addr >> 5) | ht_size; 1346b93b400SYevgeny Kliteynik 1356b93b400SYevgeny Kliteynik MLX5_SET(ste_general, hw_ste_p, next_table_base_39_32_size, index >> 27); 1366b93b400SYevgeny Kliteynik MLX5_SET(ste_general, hw_ste_p, next_table_base_31_5_size, index); 1376b93b400SYevgeny Kliteynik } 1386b93b400SYevgeny Kliteynik 1396b93b400SYevgeny Kliteynik static void dr_ste_v0_init(u8 *hw_ste_p, u16 lu_type, 1406b93b400SYevgeny Kliteynik u8 entry_type, u16 gvmi) 1416b93b400SYevgeny Kliteynik { 142*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_entry_type(hw_ste_p, entry_type); 1436b93b400SYevgeny Kliteynik dr_ste_v0_set_lu_type(hw_ste_p, lu_type); 1446b93b400SYevgeny Kliteynik dr_ste_v0_set_next_lu_type(hw_ste_p, MLX5DR_STE_LU_TYPE_DONT_CARE); 1456b93b400SYevgeny Kliteynik 1466b93b400SYevgeny Kliteynik /* Set GVMI once, this is the same for RX/TX 1476b93b400SYevgeny Kliteynik * bits 63_48 of next table base / miss address encode the next GVMI 1486b93b400SYevgeny Kliteynik */ 1496b93b400SYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, gvmi, gvmi); 1506b93b400SYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, next_table_base_63_48, gvmi); 1516b93b400SYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_63_48, gvmi); 1526b93b400SYevgeny Kliteynik } 1536b93b400SYevgeny Kliteynik 154*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_rx_set_flow_tag(u8 *hw_ste_p, u32 flow_tag) 155*ad17dc8cSYevgeny Kliteynik { 156*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, qp_list_pointer, 157*ad17dc8cSYevgeny Kliteynik DR_STE_ENABLE_FLOW_TAG | flow_tag); 158*ad17dc8cSYevgeny Kliteynik } 159*ad17dc8cSYevgeny Kliteynik 160*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_counter_id(u8 *hw_ste_p, u32 ctr_id) 161*ad17dc8cSYevgeny Kliteynik { 162*ad17dc8cSYevgeny Kliteynik /* This can be used for both rx_steering_mult and for sx_transmit */ 163*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, counter_trigger_15_0, ctr_id); 164*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, counter_trigger_23_16, ctr_id >> 16); 165*ad17dc8cSYevgeny Kliteynik } 166*ad17dc8cSYevgeny Kliteynik 167*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_go_back_bit(u8 *hw_ste_p) 168*ad17dc8cSYevgeny Kliteynik { 169*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_sx_transmit, hw_ste_p, go_back, 1); 170*ad17dc8cSYevgeny Kliteynik } 171*ad17dc8cSYevgeny Kliteynik 172*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_tx_push_vlan(u8 *hw_ste_p, u32 vlan_hdr, 173*ad17dc8cSYevgeny Kliteynik bool go_back) 174*ad17dc8cSYevgeny Kliteynik { 175*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_sx_transmit, hw_ste_p, action_type, 176*ad17dc8cSYevgeny Kliteynik DR_STE_ACTION_TYPE_PUSH_VLAN); 177*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_sx_transmit, hw_ste_p, encap_pointer_vlan_data, vlan_hdr); 178*ad17dc8cSYevgeny Kliteynik /* Due to HW limitation we need to set this bit, otherwise reforamt + 179*ad17dc8cSYevgeny Kliteynik * push vlan will not work. 180*ad17dc8cSYevgeny Kliteynik */ 181*ad17dc8cSYevgeny Kliteynik if (go_back) 182*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_go_back_bit(hw_ste_p); 183*ad17dc8cSYevgeny Kliteynik } 184*ad17dc8cSYevgeny Kliteynik 185*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_tx_encap(void *hw_ste_p, u32 reformat_id, 186*ad17dc8cSYevgeny Kliteynik int size, bool encap_l3) 187*ad17dc8cSYevgeny Kliteynik { 188*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_sx_transmit, hw_ste_p, action_type, 189*ad17dc8cSYevgeny Kliteynik encap_l3 ? DR_STE_ACTION_TYPE_ENCAP_L3 : DR_STE_ACTION_TYPE_ENCAP); 190*ad17dc8cSYevgeny Kliteynik /* The hardware expects here size in words (2 byte) */ 191*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_sx_transmit, hw_ste_p, action_description, size / 2); 192*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_sx_transmit, hw_ste_p, encap_pointer_vlan_data, reformat_id); 193*ad17dc8cSYevgeny Kliteynik } 194*ad17dc8cSYevgeny Kliteynik 195*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_rx_decap(u8 *hw_ste_p) 196*ad17dc8cSYevgeny Kliteynik { 197*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action, 198*ad17dc8cSYevgeny Kliteynik DR_STE_TUNL_ACTION_DECAP); 199*ad17dc8cSYevgeny Kliteynik } 200*ad17dc8cSYevgeny Kliteynik 201*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_rx_pop_vlan(u8 *hw_ste_p) 202*ad17dc8cSYevgeny Kliteynik { 203*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action, 204*ad17dc8cSYevgeny Kliteynik DR_STE_TUNL_ACTION_POP_VLAN); 205*ad17dc8cSYevgeny Kliteynik } 206*ad17dc8cSYevgeny Kliteynik 207*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_rx_decap_l3(u8 *hw_ste_p, bool vlan) 208*ad17dc8cSYevgeny Kliteynik { 209*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action, 210*ad17dc8cSYevgeny Kliteynik DR_STE_TUNL_ACTION_L3_DECAP); 211*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_modify_packet, hw_ste_p, action_description, vlan ? 1 : 0); 212*ad17dc8cSYevgeny Kliteynik } 213*ad17dc8cSYevgeny Kliteynik 214*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_set_rewrite_actions(u8 *hw_ste_p, u16 num_of_actions, 215*ad17dc8cSYevgeny Kliteynik u32 re_write_index) 216*ad17dc8cSYevgeny Kliteynik { 217*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_modify_packet, hw_ste_p, number_of_re_write_actions, 218*ad17dc8cSYevgeny Kliteynik num_of_actions); 219*ad17dc8cSYevgeny Kliteynik MLX5_SET(ste_modify_packet, hw_ste_p, header_re_write_actions_pointer, 220*ad17dc8cSYevgeny Kliteynik re_write_index); 221*ad17dc8cSYevgeny Kliteynik } 222*ad17dc8cSYevgeny Kliteynik 223*ad17dc8cSYevgeny Kliteynik static void dr_ste_v0_arr_init_next(u8 **last_ste, 224*ad17dc8cSYevgeny Kliteynik u32 *added_stes, 225*ad17dc8cSYevgeny Kliteynik enum mlx5dr_ste_entry_type entry_type, 226*ad17dc8cSYevgeny Kliteynik u16 gvmi) 227*ad17dc8cSYevgeny Kliteynik { 228*ad17dc8cSYevgeny Kliteynik (*added_stes)++; 229*ad17dc8cSYevgeny Kliteynik *last_ste += DR_STE_SIZE; 230*ad17dc8cSYevgeny Kliteynik dr_ste_v0_init(*last_ste, MLX5DR_STE_LU_TYPE_DONT_CARE, 231*ad17dc8cSYevgeny Kliteynik entry_type, gvmi); 232*ad17dc8cSYevgeny Kliteynik } 233*ad17dc8cSYevgeny Kliteynik 234*ad17dc8cSYevgeny Kliteynik static void 235*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_actions_tx(struct mlx5dr_domain *dmn, 236*ad17dc8cSYevgeny Kliteynik u8 *action_type_set, 237*ad17dc8cSYevgeny Kliteynik u8 *last_ste, 238*ad17dc8cSYevgeny Kliteynik struct mlx5dr_ste_actions_attr *attr, 239*ad17dc8cSYevgeny Kliteynik u32 *added_stes) 240*ad17dc8cSYevgeny Kliteynik { 241*ad17dc8cSYevgeny Kliteynik bool encap = action_type_set[DR_ACTION_TYP_L2_TO_TNL_L2] || 242*ad17dc8cSYevgeny Kliteynik action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]; 243*ad17dc8cSYevgeny Kliteynik 244*ad17dc8cSYevgeny Kliteynik /* We want to make sure the modify header comes before L2 245*ad17dc8cSYevgeny Kliteynik * encapsulation. The reason for that is that we support 246*ad17dc8cSYevgeny Kliteynik * modify headers for outer headers only 247*ad17dc8cSYevgeny Kliteynik */ 248*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) { 249*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_entry_type(last_ste, MLX5DR_STE_TYPE_MODIFY_PKT); 250*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_rewrite_actions(last_ste, 251*ad17dc8cSYevgeny Kliteynik attr->modify_actions, 252*ad17dc8cSYevgeny Kliteynik attr->modify_index); 253*ad17dc8cSYevgeny Kliteynik } 254*ad17dc8cSYevgeny Kliteynik 255*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_PUSH_VLAN]) { 256*ad17dc8cSYevgeny Kliteynik int i; 257*ad17dc8cSYevgeny Kliteynik 258*ad17dc8cSYevgeny Kliteynik for (i = 0; i < attr->vlans.count; i++) { 259*ad17dc8cSYevgeny Kliteynik if (i || action_type_set[DR_ACTION_TYP_MODIFY_HDR]) 260*ad17dc8cSYevgeny Kliteynik dr_ste_v0_arr_init_next(&last_ste, 261*ad17dc8cSYevgeny Kliteynik added_stes, 262*ad17dc8cSYevgeny Kliteynik MLX5DR_STE_TYPE_TX, 263*ad17dc8cSYevgeny Kliteynik attr->gvmi); 264*ad17dc8cSYevgeny Kliteynik 265*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_tx_push_vlan(last_ste, 266*ad17dc8cSYevgeny Kliteynik attr->vlans.headers[i], 267*ad17dc8cSYevgeny Kliteynik encap); 268*ad17dc8cSYevgeny Kliteynik } 269*ad17dc8cSYevgeny Kliteynik } 270*ad17dc8cSYevgeny Kliteynik 271*ad17dc8cSYevgeny Kliteynik if (encap) { 272*ad17dc8cSYevgeny Kliteynik /* Modify header and encapsulation require a different STEs. 273*ad17dc8cSYevgeny Kliteynik * Since modify header STE format doesn't support encapsulation 274*ad17dc8cSYevgeny Kliteynik * tunneling_action. 275*ad17dc8cSYevgeny Kliteynik */ 276*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_MODIFY_HDR] || 277*ad17dc8cSYevgeny Kliteynik action_type_set[DR_ACTION_TYP_PUSH_VLAN]) 278*ad17dc8cSYevgeny Kliteynik dr_ste_v0_arr_init_next(&last_ste, 279*ad17dc8cSYevgeny Kliteynik added_stes, 280*ad17dc8cSYevgeny Kliteynik MLX5DR_STE_TYPE_TX, 281*ad17dc8cSYevgeny Kliteynik attr->gvmi); 282*ad17dc8cSYevgeny Kliteynik 283*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_tx_encap(last_ste, 284*ad17dc8cSYevgeny Kliteynik attr->reformat_id, 285*ad17dc8cSYevgeny Kliteynik attr->reformat_size, 286*ad17dc8cSYevgeny Kliteynik action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]); 287*ad17dc8cSYevgeny Kliteynik /* Whenever prio_tag_required enabled, we can be sure that the 288*ad17dc8cSYevgeny Kliteynik * previous table (ACL) already push vlan to our packet, 289*ad17dc8cSYevgeny Kliteynik * And due to HW limitation we need to set this bit, otherwise 290*ad17dc8cSYevgeny Kliteynik * push vlan + reformat will not work. 291*ad17dc8cSYevgeny Kliteynik */ 292*ad17dc8cSYevgeny Kliteynik if (MLX5_CAP_GEN(dmn->mdev, prio_tag_required)) 293*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_go_back_bit(last_ste); 294*ad17dc8cSYevgeny Kliteynik } 295*ad17dc8cSYevgeny Kliteynik 296*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_CTR]) 297*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_counter_id(last_ste, attr->ctr_id); 298*ad17dc8cSYevgeny Kliteynik 299*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_hit_gvmi(last_ste, attr->hit_gvmi); 300*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_hit_addr(last_ste, attr->final_icm_addr, 1); 301*ad17dc8cSYevgeny Kliteynik } 302*ad17dc8cSYevgeny Kliteynik 303*ad17dc8cSYevgeny Kliteynik static void 304*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_actions_rx(struct mlx5dr_domain *dmn, 305*ad17dc8cSYevgeny Kliteynik u8 *action_type_set, 306*ad17dc8cSYevgeny Kliteynik u8 *last_ste, 307*ad17dc8cSYevgeny Kliteynik struct mlx5dr_ste_actions_attr *attr, 308*ad17dc8cSYevgeny Kliteynik u32 *added_stes) 309*ad17dc8cSYevgeny Kliteynik { 310*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_CTR]) 311*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_counter_id(last_ste, attr->ctr_id); 312*ad17dc8cSYevgeny Kliteynik 313*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2]) { 314*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_entry_type(last_ste, MLX5DR_STE_TYPE_MODIFY_PKT); 315*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_rx_decap_l3(last_ste, attr->decap_with_vlan); 316*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_rewrite_actions(last_ste, 317*ad17dc8cSYevgeny Kliteynik attr->decap_actions, 318*ad17dc8cSYevgeny Kliteynik attr->decap_index); 319*ad17dc8cSYevgeny Kliteynik } 320*ad17dc8cSYevgeny Kliteynik 321*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2]) 322*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_rx_decap(last_ste); 323*ad17dc8cSYevgeny Kliteynik 324*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_POP_VLAN]) { 325*ad17dc8cSYevgeny Kliteynik int i; 326*ad17dc8cSYevgeny Kliteynik 327*ad17dc8cSYevgeny Kliteynik for (i = 0; i < attr->vlans.count; i++) { 328*ad17dc8cSYevgeny Kliteynik if (i || 329*ad17dc8cSYevgeny Kliteynik action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2] || 330*ad17dc8cSYevgeny Kliteynik action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2]) 331*ad17dc8cSYevgeny Kliteynik dr_ste_v0_arr_init_next(&last_ste, 332*ad17dc8cSYevgeny Kliteynik added_stes, 333*ad17dc8cSYevgeny Kliteynik MLX5DR_STE_TYPE_RX, 334*ad17dc8cSYevgeny Kliteynik attr->gvmi); 335*ad17dc8cSYevgeny Kliteynik 336*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_rx_pop_vlan(last_ste); 337*ad17dc8cSYevgeny Kliteynik } 338*ad17dc8cSYevgeny Kliteynik } 339*ad17dc8cSYevgeny Kliteynik 340*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) { 341*ad17dc8cSYevgeny Kliteynik if (dr_ste_v0_get_entry_type(last_ste) == MLX5DR_STE_TYPE_MODIFY_PKT) 342*ad17dc8cSYevgeny Kliteynik dr_ste_v0_arr_init_next(&last_ste, 343*ad17dc8cSYevgeny Kliteynik added_stes, 344*ad17dc8cSYevgeny Kliteynik MLX5DR_STE_TYPE_MODIFY_PKT, 345*ad17dc8cSYevgeny Kliteynik attr->gvmi); 346*ad17dc8cSYevgeny Kliteynik else 347*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_entry_type(last_ste, MLX5DR_STE_TYPE_MODIFY_PKT); 348*ad17dc8cSYevgeny Kliteynik 349*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_rewrite_actions(last_ste, 350*ad17dc8cSYevgeny Kliteynik attr->modify_actions, 351*ad17dc8cSYevgeny Kliteynik attr->modify_index); 352*ad17dc8cSYevgeny Kliteynik } 353*ad17dc8cSYevgeny Kliteynik 354*ad17dc8cSYevgeny Kliteynik if (action_type_set[DR_ACTION_TYP_TAG]) { 355*ad17dc8cSYevgeny Kliteynik if (dr_ste_v0_get_entry_type(last_ste) == MLX5DR_STE_TYPE_MODIFY_PKT) 356*ad17dc8cSYevgeny Kliteynik dr_ste_v0_arr_init_next(&last_ste, 357*ad17dc8cSYevgeny Kliteynik added_stes, 358*ad17dc8cSYevgeny Kliteynik MLX5DR_STE_TYPE_RX, 359*ad17dc8cSYevgeny Kliteynik attr->gvmi); 360*ad17dc8cSYevgeny Kliteynik 361*ad17dc8cSYevgeny Kliteynik dr_ste_v0_rx_set_flow_tag(last_ste, attr->flow_tag); 362*ad17dc8cSYevgeny Kliteynik } 363*ad17dc8cSYevgeny Kliteynik 364*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_hit_gvmi(last_ste, attr->hit_gvmi); 365*ad17dc8cSYevgeny Kliteynik dr_ste_v0_set_hit_addr(last_ste, attr->final_icm_addr, 1); 366*ad17dc8cSYevgeny Kliteynik } 367*ad17dc8cSYevgeny Kliteynik 368d65e841dSYevgeny Kliteynik static void 369d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value, 370d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 371d65e841dSYevgeny Kliteynik { 372d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 373d65e841dSYevgeny Kliteynik 37446779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_47_16, mask, dmac_47_16); 37546779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_15_0, mask, dmac_15_0); 376d65e841dSYevgeny Kliteynik 377d65e841dSYevgeny Kliteynik if (mask->smac_47_16 || mask->smac_15_0) { 378d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_47_32, 379d65e841dSYevgeny Kliteynik mask->smac_47_16 >> 16); 380d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_31_0, 381d65e841dSYevgeny Kliteynik mask->smac_47_16 << 16 | mask->smac_15_0); 382d65e841dSYevgeny Kliteynik mask->smac_47_16 = 0; 383d65e841dSYevgeny Kliteynik mask->smac_15_0 = 0; 384d65e841dSYevgeny Kliteynik } 385d65e841dSYevgeny Kliteynik 38646779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_vlan_id, mask, first_vid); 38746779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_cfi, mask, first_cfi); 38846779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_priority, mask, first_prio); 38946779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_src_dst, bit_mask, l3_type, mask, ip_version); 390d65e841dSYevgeny Kliteynik 391d65e841dSYevgeny Kliteynik if (mask->cvlan_tag) { 392d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1); 393d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 394d65e841dSYevgeny Kliteynik } else if (mask->svlan_tag) { 395d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1); 396d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 397d65e841dSYevgeny Kliteynik } 398d65e841dSYevgeny Kliteynik } 399d65e841dSYevgeny Kliteynik 400d65e841dSYevgeny Kliteynik static int 401d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value, 402d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 403d65e841dSYevgeny Kliteynik u8 *tag) 404d65e841dSYevgeny Kliteynik { 405d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 406d65e841dSYevgeny Kliteynik 407d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_47_16, spec, dmac_47_16); 408d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_15_0, spec, dmac_15_0); 409d65e841dSYevgeny Kliteynik 410d65e841dSYevgeny Kliteynik if (spec->smac_47_16 || spec->smac_15_0) { 411d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, smac_47_32, 412d65e841dSYevgeny Kliteynik spec->smac_47_16 >> 16); 413d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, smac_31_0, 414d65e841dSYevgeny Kliteynik spec->smac_47_16 << 16 | spec->smac_15_0); 415d65e841dSYevgeny Kliteynik spec->smac_47_16 = 0; 416d65e841dSYevgeny Kliteynik spec->smac_15_0 = 0; 417d65e841dSYevgeny Kliteynik } 418d65e841dSYevgeny Kliteynik 419d65e841dSYevgeny Kliteynik if (spec->ip_version) { 420d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 421d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV4); 422d65e841dSYevgeny Kliteynik spec->ip_version = 0; 423d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 424d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV6); 425d65e841dSYevgeny Kliteynik spec->ip_version = 0; 426d65e841dSYevgeny Kliteynik } else { 427d65e841dSYevgeny Kliteynik return -EINVAL; 428d65e841dSYevgeny Kliteynik } 429d65e841dSYevgeny Kliteynik } 430d65e841dSYevgeny Kliteynik 431d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_vlan_id, spec, first_vid); 432d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_cfi, spec, first_cfi); 433d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst, tag, first_priority, spec, first_prio); 434d65e841dSYevgeny Kliteynik 435d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 436d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_CVLAN); 437d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 438d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 439d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_SVLAN); 440d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 441d65e841dSYevgeny Kliteynik } 442d65e841dSYevgeny Kliteynik return 0; 443d65e841dSYevgeny Kliteynik } 444d65e841dSYevgeny Kliteynik 445d65e841dSYevgeny Kliteynik static void 446d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb, 447d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 448d65e841dSYevgeny Kliteynik { 449d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask); 450d65e841dSYevgeny Kliteynik 451d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC_DST, sb->rx, sb->inner); 452d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 453d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_dst_tag; 454d65e841dSYevgeny Kliteynik } 455d65e841dSYevgeny Kliteynik 456d65e841dSYevgeny Kliteynik static int 457d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value, 458d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 459d65e841dSYevgeny Kliteynik u8 *tag) 460d65e841dSYevgeny Kliteynik { 461d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 462d65e841dSYevgeny Kliteynik 463d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96); 464d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64); 465d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32); 466d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0); 467d65e841dSYevgeny Kliteynik 468d65e841dSYevgeny Kliteynik return 0; 469d65e841dSYevgeny Kliteynik } 470d65e841dSYevgeny Kliteynik 471d65e841dSYevgeny Kliteynik static void 472d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb, 473d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 474d65e841dSYevgeny Kliteynik { 47546779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask); 476d65e841dSYevgeny Kliteynik 477d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_DST, 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_ipv6_dst_tag; 480d65e841dSYevgeny Kliteynik } 481d65e841dSYevgeny Kliteynik 482d65e841dSYevgeny Kliteynik static int 483d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_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_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96); 490d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64); 491d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32); 492d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0); 493d65e841dSYevgeny Kliteynik 494d65e841dSYevgeny Kliteynik return 0; 495d65e841dSYevgeny Kliteynik } 496d65e841dSYevgeny Kliteynik 497d65e841dSYevgeny Kliteynik static void 498d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb, 499d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 500d65e841dSYevgeny Kliteynik { 50146779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask); 502d65e841dSYevgeny Kliteynik 503d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_SRC, sb->rx, sb->inner); 504d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 505d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_src_tag; 506d65e841dSYevgeny Kliteynik } 507d65e841dSYevgeny Kliteynik 508d65e841dSYevgeny Kliteynik static int 509d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value, 510d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 511d65e841dSYevgeny Kliteynik u8 *tag) 512d65e841dSYevgeny Kliteynik { 513d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 514d65e841dSYevgeny Kliteynik 515d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_address, spec, dst_ip_31_0); 516d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_address, spec, src_ip_31_0); 517d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, tcp_dport); 518d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, udp_dport); 519d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, tcp_sport); 520d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, udp_sport); 521d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, protocol, spec, ip_protocol); 522d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, fragmented, spec, frag); 523d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, dscp, spec, ip_dscp); 524d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, ecn, spec, ip_ecn); 525d65e841dSYevgeny Kliteynik 526d65e841dSYevgeny Kliteynik if (spec->tcp_flags) { 527d65e841dSYevgeny Kliteynik DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, tag, spec); 528d65e841dSYevgeny Kliteynik spec->tcp_flags = 0; 529d65e841dSYevgeny Kliteynik } 530d65e841dSYevgeny Kliteynik 531d65e841dSYevgeny Kliteynik return 0; 532d65e841dSYevgeny Kliteynik } 533d65e841dSYevgeny Kliteynik 534d65e841dSYevgeny Kliteynik static void 535d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb, 536d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 537d65e841dSYevgeny Kliteynik { 53846779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask); 539d65e841dSYevgeny Kliteynik 540d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_5_TUPLE, sb->rx, sb->inner); 541d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 542d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag; 543d65e841dSYevgeny Kliteynik } 544d65e841dSYevgeny Kliteynik 545d65e841dSYevgeny Kliteynik static void 546d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value, 547d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 548d65e841dSYevgeny Kliteynik { 549d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 550d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_mask = &value->misc; 551d65e841dSYevgeny Kliteynik 55246779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_vlan_id, mask, first_vid); 55346779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_cfi, mask, first_cfi); 55446779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, first_priority, mask, first_prio); 55546779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, ip_fragmented, mask, frag); 55646779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, l3_ethertype, mask, ethertype); 55746779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_src, bit_mask, l3_type, mask, ip_version); 558d65e841dSYevgeny Kliteynik 559d65e841dSYevgeny Kliteynik if (mask->svlan_tag || mask->cvlan_tag) { 560d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, first_vlan_qualifier, -1); 561d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 562d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 563d65e841dSYevgeny Kliteynik } 564d65e841dSYevgeny Kliteynik 565d65e841dSYevgeny Kliteynik if (inner) { 566d65e841dSYevgeny Kliteynik if (misc_mask->inner_second_cvlan_tag || 567d65e841dSYevgeny Kliteynik misc_mask->inner_second_svlan_tag) { 568d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1); 569d65e841dSYevgeny Kliteynik misc_mask->inner_second_cvlan_tag = 0; 570d65e841dSYevgeny Kliteynik misc_mask->inner_second_svlan_tag = 0; 571d65e841dSYevgeny Kliteynik } 572d65e841dSYevgeny Kliteynik 57346779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 574d65e841dSYevgeny Kliteynik second_vlan_id, misc_mask, inner_second_vid); 57546779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 576d65e841dSYevgeny Kliteynik second_cfi, misc_mask, inner_second_cfi); 57746779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 578d65e841dSYevgeny Kliteynik second_priority, misc_mask, inner_second_prio); 579d65e841dSYevgeny Kliteynik } else { 580d65e841dSYevgeny Kliteynik if (misc_mask->outer_second_cvlan_tag || 581d65e841dSYevgeny Kliteynik misc_mask->outer_second_svlan_tag) { 582d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1); 583d65e841dSYevgeny Kliteynik misc_mask->outer_second_cvlan_tag = 0; 584d65e841dSYevgeny Kliteynik misc_mask->outer_second_svlan_tag = 0; 585d65e841dSYevgeny Kliteynik } 586d65e841dSYevgeny Kliteynik 58746779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 588d65e841dSYevgeny Kliteynik second_vlan_id, misc_mask, outer_second_vid); 58946779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 590d65e841dSYevgeny Kliteynik second_cfi, misc_mask, outer_second_cfi); 59146779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, 592d65e841dSYevgeny Kliteynik second_priority, misc_mask, outer_second_prio); 593d65e841dSYevgeny Kliteynik } 594d65e841dSYevgeny Kliteynik } 595d65e841dSYevgeny Kliteynik 596d65e841dSYevgeny Kliteynik static int 597d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value, 598d65e841dSYevgeny Kliteynik bool inner, u8 *tag) 599d65e841dSYevgeny Kliteynik { 600d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer; 601d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_spec = &value->misc; 602d65e841dSYevgeny Kliteynik 603d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_vlan_id, spec, first_vid); 604d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_cfi, spec, first_cfi); 605d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, first_priority, spec, first_prio); 606d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, ip_fragmented, spec, frag); 607d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, l3_ethertype, spec, ethertype); 608d65e841dSYevgeny Kliteynik 609d65e841dSYevgeny Kliteynik if (spec->ip_version) { 610d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 611d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV4); 612d65e841dSYevgeny Kliteynik spec->ip_version = 0; 613d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 614d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV6); 615d65e841dSYevgeny Kliteynik spec->ip_version = 0; 616d65e841dSYevgeny Kliteynik } else { 617d65e841dSYevgeny Kliteynik return -EINVAL; 618d65e841dSYevgeny Kliteynik } 619d65e841dSYevgeny Kliteynik } 620d65e841dSYevgeny Kliteynik 621d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 622d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_CVLAN); 623d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 624d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 625d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_SVLAN); 626d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 627d65e841dSYevgeny Kliteynik } 628d65e841dSYevgeny Kliteynik 629d65e841dSYevgeny Kliteynik if (inner) { 630d65e841dSYevgeny Kliteynik if (misc_spec->inner_second_cvlan_tag) { 631d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN); 632d65e841dSYevgeny Kliteynik misc_spec->inner_second_cvlan_tag = 0; 633d65e841dSYevgeny Kliteynik } else if (misc_spec->inner_second_svlan_tag) { 634d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN); 635d65e841dSYevgeny Kliteynik misc_spec->inner_second_svlan_tag = 0; 636d65e841dSYevgeny Kliteynik } 637d65e841dSYevgeny Kliteynik 638d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, inner_second_vid); 639d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, inner_second_cfi); 640d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, inner_second_prio); 641d65e841dSYevgeny Kliteynik } else { 642d65e841dSYevgeny Kliteynik if (misc_spec->outer_second_cvlan_tag) { 643d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN); 644d65e841dSYevgeny Kliteynik misc_spec->outer_second_cvlan_tag = 0; 645d65e841dSYevgeny Kliteynik } else if (misc_spec->outer_second_svlan_tag) { 646d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN); 647d65e841dSYevgeny Kliteynik misc_spec->outer_second_svlan_tag = 0; 648d65e841dSYevgeny Kliteynik } 649d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, outer_second_vid); 650d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, outer_second_cfi); 651d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, outer_second_prio); 652d65e841dSYevgeny Kliteynik } 653d65e841dSYevgeny Kliteynik 654d65e841dSYevgeny Kliteynik return 0; 655d65e841dSYevgeny Kliteynik } 656d65e841dSYevgeny Kliteynik 657d65e841dSYevgeny Kliteynik static void 658d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value, 659d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 660d65e841dSYevgeny Kliteynik { 661d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 662d65e841dSYevgeny Kliteynik 66346779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_47_16, mask, smac_47_16); 66446779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_15_0, mask, smac_15_0); 665d65e841dSYevgeny Kliteynik 666d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask); 667d65e841dSYevgeny Kliteynik } 668d65e841dSYevgeny Kliteynik 669d65e841dSYevgeny Kliteynik static int 670d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_tag(struct mlx5dr_match_param *value, 671d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 672d65e841dSYevgeny Kliteynik u8 *tag) 673d65e841dSYevgeny Kliteynik { 674d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 675d65e841dSYevgeny Kliteynik 676d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, smac_47_16, spec, smac_47_16); 677d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src, tag, smac_15_0, spec, smac_15_0); 678d65e841dSYevgeny Kliteynik 679d65e841dSYevgeny Kliteynik return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 680d65e841dSYevgeny Kliteynik } 681d65e841dSYevgeny Kliteynik 682d65e841dSYevgeny Kliteynik static void 683d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_init(struct mlx5dr_ste_build *sb, 684d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 685d65e841dSYevgeny Kliteynik { 686d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask); 687d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC, sb->rx, sb->inner); 688d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 689d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_tag; 690d65e841dSYevgeny Kliteynik } 691d65e841dSYevgeny Kliteynik 692d65e841dSYevgeny Kliteynik static void 693d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value, 69446779098SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 69546779098SYevgeny Kliteynik u8 *bit_mask) 696d65e841dSYevgeny Kliteynik { 69746779098SYevgeny Kliteynik struct mlx5dr_match_spec *mask = sb->inner ? &value->inner : &value->outer; 698d65e841dSYevgeny Kliteynik 69946779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_47_16, mask, dmac_47_16); 70046779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_15_0, mask, dmac_15_0); 701d65e841dSYevgeny Kliteynik 70246779098SYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, sb->inner, bit_mask); 703d65e841dSYevgeny Kliteynik } 704d65e841dSYevgeny Kliteynik 705d65e841dSYevgeny Kliteynik static int 706d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_tag(struct mlx5dr_match_param *value, 707d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 708d65e841dSYevgeny Kliteynik u8 *tag) 709d65e841dSYevgeny Kliteynik { 710d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 711d65e841dSYevgeny Kliteynik 712d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, tag, dmac_47_16, spec, dmac_47_16); 713d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst, tag, dmac_15_0, spec, dmac_15_0); 714d65e841dSYevgeny Kliteynik 715d65e841dSYevgeny Kliteynik return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 716d65e841dSYevgeny Kliteynik } 717d65e841dSYevgeny Kliteynik 718d65e841dSYevgeny Kliteynik static void 719d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb, 720d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 721d65e841dSYevgeny Kliteynik { 72246779098SYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_bit_mask(mask, sb, sb->bit_mask); 723d65e841dSYevgeny Kliteynik 724d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_DST, sb->rx, sb->inner); 725d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 726d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_dst_tag; 727d65e841dSYevgeny Kliteynik } 728d65e841dSYevgeny Kliteynik 729d65e841dSYevgeny Kliteynik static void 730d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value, 731d65e841dSYevgeny Kliteynik bool inner, u8 *bit_mask) 732d65e841dSYevgeny Kliteynik { 733d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 734d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 735d65e841dSYevgeny Kliteynik 73646779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_47_16, mask, dmac_47_16); 73746779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_15_0, mask, dmac_15_0); 73846779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_vlan_id, mask, first_vid); 73946779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_cfi, mask, first_cfi); 74046779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_priority, mask, first_prio); 74146779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, ip_fragmented, mask, frag); 74246779098SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, bit_mask, l3_ethertype, mask, ethertype); 74346779098SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_tnl, bit_mask, l3_type, mask, ip_version); 744d65e841dSYevgeny Kliteynik 745d65e841dSYevgeny Kliteynik if (misc->vxlan_vni) { 746d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, bit_mask, 747d65e841dSYevgeny Kliteynik l2_tunneling_network_id, (misc->vxlan_vni << 8)); 748d65e841dSYevgeny Kliteynik misc->vxlan_vni = 0; 749d65e841dSYevgeny Kliteynik } 750d65e841dSYevgeny Kliteynik 751d65e841dSYevgeny Kliteynik if (mask->svlan_tag || mask->cvlan_tag) { 752d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, bit_mask, first_vlan_qualifier, -1); 753d65e841dSYevgeny Kliteynik mask->cvlan_tag = 0; 754d65e841dSYevgeny Kliteynik mask->svlan_tag = 0; 755d65e841dSYevgeny Kliteynik } 756d65e841dSYevgeny Kliteynik } 757d65e841dSYevgeny Kliteynik 758d65e841dSYevgeny Kliteynik static int 759d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value, 760d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 761d65e841dSYevgeny Kliteynik u8 *tag) 762d65e841dSYevgeny Kliteynik { 763d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 764d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 765d65e841dSYevgeny Kliteynik 766d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_47_16, spec, dmac_47_16); 767d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_15_0, spec, dmac_15_0); 768d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_vlan_id, spec, first_vid); 769d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_cfi, spec, first_cfi); 770d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, ip_fragmented, spec, frag); 771d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, first_priority, spec, first_prio); 772d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl, tag, l3_ethertype, spec, ethertype); 773d65e841dSYevgeny Kliteynik 774d65e841dSYevgeny Kliteynik if (misc->vxlan_vni) { 775d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l2_tunneling_network_id, 776d65e841dSYevgeny Kliteynik (misc->vxlan_vni << 8)); 777d65e841dSYevgeny Kliteynik misc->vxlan_vni = 0; 778d65e841dSYevgeny Kliteynik } 779d65e841dSYevgeny Kliteynik 780d65e841dSYevgeny Kliteynik if (spec->cvlan_tag) { 781d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_CVLAN); 782d65e841dSYevgeny Kliteynik spec->cvlan_tag = 0; 783d65e841dSYevgeny Kliteynik } else if (spec->svlan_tag) { 784d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_SVLAN); 785d65e841dSYevgeny Kliteynik spec->svlan_tag = 0; 786d65e841dSYevgeny Kliteynik } 787d65e841dSYevgeny Kliteynik 788d65e841dSYevgeny Kliteynik if (spec->ip_version) { 789d65e841dSYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 790d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV4); 791d65e841dSYevgeny Kliteynik spec->ip_version = 0; 792d65e841dSYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 793d65e841dSYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV6); 794d65e841dSYevgeny Kliteynik spec->ip_version = 0; 795d65e841dSYevgeny Kliteynik } else { 796d65e841dSYevgeny Kliteynik return -EINVAL; 797d65e841dSYevgeny Kliteynik } 798d65e841dSYevgeny Kliteynik } 799d65e841dSYevgeny Kliteynik 800d65e841dSYevgeny Kliteynik return 0; 801d65e841dSYevgeny Kliteynik } 802d65e841dSYevgeny Kliteynik 803d65e841dSYevgeny Kliteynik static void 804d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb, 805d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 806d65e841dSYevgeny Kliteynik { 807d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask); 808d65e841dSYevgeny Kliteynik 809dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I; 810d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 811d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_tnl_tag; 812d65e841dSYevgeny Kliteynik } 813d65e841dSYevgeny Kliteynik 814d65e841dSYevgeny Kliteynik static int 815d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value, 816d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 817d65e841dSYevgeny Kliteynik u8 *tag) 818d65e841dSYevgeny Kliteynik { 819d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 820d65e841dSYevgeny Kliteynik 821d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, time_to_live, spec, ttl_hoplimit); 822d65e841dSYevgeny Kliteynik 823d65e841dSYevgeny Kliteynik return 0; 824d65e841dSYevgeny Kliteynik } 825d65e841dSYevgeny Kliteynik 826d65e841dSYevgeny Kliteynik static void 827d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb, 828d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 829d65e841dSYevgeny Kliteynik { 83046779098SYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask); 831d65e841dSYevgeny Kliteynik 832d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_MISC, sb->rx, sb->inner); 833d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 834d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_misc_tag; 835d65e841dSYevgeny Kliteynik } 836d65e841dSYevgeny Kliteynik 837d65e841dSYevgeny Kliteynik static int 838d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value, 839d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 840d65e841dSYevgeny Kliteynik u8 *tag) 841d65e841dSYevgeny Kliteynik { 842d65e841dSYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 843d65e841dSYevgeny Kliteynik 844d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, tcp_dport); 845d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, src_port, spec, tcp_sport); 846d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, udp_dport); 847d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, src_port, spec, udp_sport); 848d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, protocol, spec, ip_protocol); 849d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, fragmented, spec, frag); 850d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, dscp, spec, ip_dscp); 851d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, ecn, spec, ip_ecn); 852d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4, tag, ipv6_hop_limit, spec, ttl_hoplimit); 853d65e841dSYevgeny Kliteynik 854d65e841dSYevgeny Kliteynik if (spec->tcp_flags) { 855d65e841dSYevgeny Kliteynik DR_STE_SET_TCP_FLAGS(eth_l4, tag, spec); 856d65e841dSYevgeny Kliteynik spec->tcp_flags = 0; 857d65e841dSYevgeny Kliteynik } 858d65e841dSYevgeny Kliteynik 859d65e841dSYevgeny Kliteynik return 0; 860d65e841dSYevgeny Kliteynik } 861d65e841dSYevgeny Kliteynik 862d65e841dSYevgeny Kliteynik static void 863d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb, 864d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 865d65e841dSYevgeny Kliteynik { 86646779098SYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask); 867d65e841dSYevgeny Kliteynik 868d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4, sb->rx, sb->inner); 869d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 870d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_ipv6_l3_l4_tag; 871d65e841dSYevgeny Kliteynik } 872d65e841dSYevgeny Kliteynik 873d65e841dSYevgeny Kliteynik static int 874d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_tag(struct mlx5dr_match_param *value, 875d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 876d65e841dSYevgeny Kliteynik u8 *tag) 877d65e841dSYevgeny Kliteynik { 87846779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 879d65e841dSYevgeny Kliteynik 880d65e841dSYevgeny Kliteynik if (sb->inner) 88146779098SYevgeny Kliteynik DR_STE_SET_MPLS(mpls, misc2, inner, tag); 882d65e841dSYevgeny Kliteynik else 88346779098SYevgeny Kliteynik DR_STE_SET_MPLS(mpls, misc2, outer, tag); 884d65e841dSYevgeny Kliteynik 885d65e841dSYevgeny Kliteynik return 0; 886d65e841dSYevgeny Kliteynik } 887d65e841dSYevgeny Kliteynik 888d65e841dSYevgeny Kliteynik static void 889d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_init(struct mlx5dr_ste_build *sb, 890d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 891d65e841dSYevgeny Kliteynik { 89246779098SYevgeny Kliteynik dr_ste_v0_build_mpls_tag(mask, sb, sb->bit_mask); 893d65e841dSYevgeny Kliteynik 894d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(MPLS_FIRST, sb->rx, sb->inner); 895d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 896d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_mpls_tag; 897d65e841dSYevgeny Kliteynik } 898d65e841dSYevgeny Kliteynik 899d65e841dSYevgeny Kliteynik static int 900d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_tag(struct mlx5dr_match_param *value, 901d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 902d65e841dSYevgeny Kliteynik u8 *tag) 903d65e841dSYevgeny Kliteynik { 904d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 905d65e841dSYevgeny Kliteynik 906d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_protocol, misc, gre_protocol); 907d65e841dSYevgeny Kliteynik 908d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_k_present, misc, gre_k_present); 909d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_key_h, misc, gre_key_h); 910d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_key_l, misc, gre_key_l); 911d65e841dSYevgeny Kliteynik 912d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_c_present, misc, gre_c_present); 913d65e841dSYevgeny Kliteynik 914d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(gre, tag, gre_s_present, misc, gre_s_present); 915d65e841dSYevgeny Kliteynik 916d65e841dSYevgeny Kliteynik return 0; 917d65e841dSYevgeny Kliteynik } 918d65e841dSYevgeny Kliteynik 919d65e841dSYevgeny Kliteynik static void 920d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_init(struct mlx5dr_ste_build *sb, 921d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 922d65e841dSYevgeny Kliteynik { 92346779098SYevgeny Kliteynik dr_ste_v0_build_tnl_gre_tag(mask, sb, sb->bit_mask); 924d65e841dSYevgeny Kliteynik 925dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_GRE; 926d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 927d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gre_tag; 928d65e841dSYevgeny Kliteynik } 929d65e841dSYevgeny Kliteynik 930d65e841dSYevgeny Kliteynik static int 931d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_tag(struct mlx5dr_match_param *value, 932d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 933d65e841dSYevgeny Kliteynik u8 *tag) 934d65e841dSYevgeny Kliteynik { 93546779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc_2 = &value->misc2; 936d65e841dSYevgeny Kliteynik 93746779098SYevgeny Kliteynik if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2)) { 938d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label, 93946779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_label); 940d65e841dSYevgeny Kliteynik 941d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp, 94246779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_exp); 943d65e841dSYevgeny Kliteynik 944d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos, 94546779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_s_bos); 946d65e841dSYevgeny Kliteynik 947d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl, 94846779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_gre_ttl); 949d65e841dSYevgeny Kliteynik } else { 950d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label, 95146779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_label); 952d65e841dSYevgeny Kliteynik 953d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp, 95446779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_exp); 955d65e841dSYevgeny Kliteynik 956d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos, 95746779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_s_bos); 958d65e841dSYevgeny Kliteynik 959d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl, 96046779098SYevgeny Kliteynik misc_2, outer_first_mpls_over_udp_ttl); 961d65e841dSYevgeny Kliteynik } 962d65e841dSYevgeny Kliteynik return 0; 963d65e841dSYevgeny Kliteynik } 964d65e841dSYevgeny Kliteynik 965d65e841dSYevgeny Kliteynik static void 966d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_init(struct mlx5dr_ste_build *sb, 967d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 968d65e841dSYevgeny Kliteynik { 96946779098SYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_tag(mask, sb, sb->bit_mask); 970d65e841dSYevgeny Kliteynik 971dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 972d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 973d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_tag; 974d65e841dSYevgeny Kliteynik } 975d65e841dSYevgeny Kliteynik 976d65e841dSYevgeny Kliteynik #define ICMP_TYPE_OFFSET_FIRST_DW 24 977d65e841dSYevgeny Kliteynik #define ICMP_CODE_OFFSET_FIRST_DW 16 978d65e841dSYevgeny Kliteynik 979d65e841dSYevgeny Kliteynik static int 980d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_tag(struct mlx5dr_match_param *value, 981d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 982d65e841dSYevgeny Kliteynik u8 *tag) 983d65e841dSYevgeny Kliteynik { 984d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc_3 = &value->misc3; 98540ca842cSYevgeny Kliteynik u32 *icmp_header_data; 986d65e841dSYevgeny Kliteynik int dw0_location; 987d65e841dSYevgeny Kliteynik int dw1_location; 98840ca842cSYevgeny Kliteynik u8 *icmp_type; 98940ca842cSYevgeny Kliteynik u8 *icmp_code; 990d65e841dSYevgeny Kliteynik bool is_ipv4; 991d65e841dSYevgeny Kliteynik 992d65e841dSYevgeny Kliteynik is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc_3); 993d65e841dSYevgeny Kliteynik if (is_ipv4) { 99440ca842cSYevgeny Kliteynik icmp_header_data = &misc_3->icmpv4_header_data; 99540ca842cSYevgeny Kliteynik icmp_type = &misc_3->icmpv4_type; 99640ca842cSYevgeny Kliteynik icmp_code = &misc_3->icmpv4_code; 997d65e841dSYevgeny Kliteynik dw0_location = sb->caps->flex_parser_id_icmp_dw0; 998d65e841dSYevgeny Kliteynik dw1_location = sb->caps->flex_parser_id_icmp_dw1; 999d65e841dSYevgeny Kliteynik } else { 100040ca842cSYevgeny Kliteynik icmp_header_data = &misc_3->icmpv6_header_data; 100140ca842cSYevgeny Kliteynik icmp_type = &misc_3->icmpv6_type; 100240ca842cSYevgeny Kliteynik icmp_code = &misc_3->icmpv6_code; 1003d65e841dSYevgeny Kliteynik dw0_location = sb->caps->flex_parser_id_icmpv6_dw0; 1004d65e841dSYevgeny Kliteynik dw1_location = sb->caps->flex_parser_id_icmpv6_dw1; 1005d65e841dSYevgeny Kliteynik } 1006d65e841dSYevgeny Kliteynik 1007d65e841dSYevgeny Kliteynik switch (dw0_location) { 1008d65e841dSYevgeny Kliteynik case 4: 1009d65e841dSYevgeny Kliteynik MLX5_SET(ste_flex_parser_1, tag, flex_parser_4, 101040ca842cSYevgeny Kliteynik (*icmp_type << ICMP_TYPE_OFFSET_FIRST_DW) | 101140ca842cSYevgeny Kliteynik (*icmp_code << ICMP_TYPE_OFFSET_FIRST_DW)); 1012d65e841dSYevgeny Kliteynik 101340ca842cSYevgeny Kliteynik *icmp_type = 0; 101440ca842cSYevgeny Kliteynik *icmp_code = 0; 1015d65e841dSYevgeny Kliteynik break; 1016d65e841dSYevgeny Kliteynik default: 1017d65e841dSYevgeny Kliteynik return -EINVAL; 1018d65e841dSYevgeny Kliteynik } 1019d65e841dSYevgeny Kliteynik 1020d65e841dSYevgeny Kliteynik switch (dw1_location) { 1021d65e841dSYevgeny Kliteynik case 5: 1022d65e841dSYevgeny Kliteynik MLX5_SET(ste_flex_parser_1, tag, flex_parser_5, 102340ca842cSYevgeny Kliteynik *icmp_header_data); 102440ca842cSYevgeny Kliteynik *icmp_header_data = 0; 1025d65e841dSYevgeny Kliteynik break; 1026d65e841dSYevgeny Kliteynik default: 1027d65e841dSYevgeny Kliteynik return -EINVAL; 1028d65e841dSYevgeny Kliteynik } 1029d65e841dSYevgeny Kliteynik 1030d65e841dSYevgeny Kliteynik return 0; 1031d65e841dSYevgeny Kliteynik } 1032d65e841dSYevgeny Kliteynik 1033d65e841dSYevgeny Kliteynik static int 1034d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_init(struct mlx5dr_ste_build *sb, 1035d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 1036d65e841dSYevgeny Kliteynik { 1037d65e841dSYevgeny Kliteynik int ret; 1038d65e841dSYevgeny Kliteynik 103946779098SYevgeny Kliteynik ret = dr_ste_v0_build_icmp_tag(mask, sb, sb->bit_mask); 1040d65e841dSYevgeny Kliteynik if (ret) 1041d65e841dSYevgeny Kliteynik return ret; 1042d65e841dSYevgeny Kliteynik 1043dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_1; 1044d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1045d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_icmp_tag; 1046d65e841dSYevgeny Kliteynik 1047d65e841dSYevgeny Kliteynik return 0; 1048d65e841dSYevgeny Kliteynik } 1049d65e841dSYevgeny Kliteynik 1050d65e841dSYevgeny Kliteynik static int 1051d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_tag(struct mlx5dr_match_param *value, 1052d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 1053d65e841dSYevgeny Kliteynik u8 *tag) 1054d65e841dSYevgeny Kliteynik { 105546779098SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc_2 = &value->misc2; 1056d65e841dSYevgeny Kliteynik 1057d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field, 105846779098SYevgeny Kliteynik misc_2, metadata_reg_a); 1059d65e841dSYevgeny Kliteynik 1060d65e841dSYevgeny Kliteynik return 0; 1061d65e841dSYevgeny Kliteynik } 1062d65e841dSYevgeny Kliteynik 1063d65e841dSYevgeny Kliteynik static void 1064d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_init(struct mlx5dr_ste_build *sb, 1065d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 1066d65e841dSYevgeny Kliteynik { 106746779098SYevgeny Kliteynik dr_ste_v0_build_general_purpose_tag(mask, sb, sb->bit_mask); 1068d65e841dSYevgeny Kliteynik 1069dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_GENERAL_PURPOSE; 1070d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1071d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_general_purpose_tag; 1072d65e841dSYevgeny Kliteynik } 1073d65e841dSYevgeny Kliteynik 1074d65e841dSYevgeny Kliteynik static int 1075d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_tag(struct mlx5dr_match_param *value, 1076d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 1077d65e841dSYevgeny Kliteynik u8 *tag) 1078d65e841dSYevgeny Kliteynik { 1079d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1080d65e841dSYevgeny Kliteynik 1081d65e841dSYevgeny Kliteynik if (sb->inner) { 1082d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, inner_tcp_seq_num); 1083d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, inner_tcp_ack_num); 1084d65e841dSYevgeny Kliteynik } else { 1085d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, outer_tcp_seq_num); 1086d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, outer_tcp_ack_num); 1087d65e841dSYevgeny Kliteynik } 1088d65e841dSYevgeny Kliteynik 1089d65e841dSYevgeny Kliteynik return 0; 1090d65e841dSYevgeny Kliteynik } 1091d65e841dSYevgeny Kliteynik 1092d65e841dSYevgeny Kliteynik static void 1093d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb, 1094d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 1095d65e841dSYevgeny Kliteynik { 109646779098SYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_tag(mask, sb, sb->bit_mask); 1097d65e841dSYevgeny Kliteynik 1098d65e841dSYevgeny Kliteynik sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4_MISC, sb->rx, sb->inner); 1099d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1100d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_eth_l4_misc_tag; 1101d65e841dSYevgeny Kliteynik } 1102d65e841dSYevgeny Kliteynik 1103d65e841dSYevgeny Kliteynik static int 1104d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value, 1105d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 1106d65e841dSYevgeny Kliteynik u8 *tag) 1107d65e841dSYevgeny Kliteynik { 1108d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1109d65e841dSYevgeny Kliteynik 1110d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1111d65e841dSYevgeny Kliteynik outer_vxlan_gpe_flags, misc3, 1112d65e841dSYevgeny Kliteynik outer_vxlan_gpe_flags); 1113d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1114d65e841dSYevgeny Kliteynik outer_vxlan_gpe_next_protocol, misc3, 1115d65e841dSYevgeny Kliteynik outer_vxlan_gpe_next_protocol); 1116d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1117d65e841dSYevgeny Kliteynik outer_vxlan_gpe_vni, misc3, 1118d65e841dSYevgeny Kliteynik outer_vxlan_gpe_vni); 1119d65e841dSYevgeny Kliteynik 1120d65e841dSYevgeny Kliteynik return 0; 1121d65e841dSYevgeny Kliteynik } 1122d65e841dSYevgeny Kliteynik 1123d65e841dSYevgeny Kliteynik static void 1124d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb, 1125d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 1126d65e841dSYevgeny Kliteynik { 112746779098SYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask); 1128dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER; 1129d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1130d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag; 1131d65e841dSYevgeny Kliteynik } 1132d65e841dSYevgeny Kliteynik 1133d65e841dSYevgeny Kliteynik static int 1134d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value, 1135d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 1136d65e841dSYevgeny Kliteynik u8 *tag) 1137d65e841dSYevgeny Kliteynik { 1138d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 1139d65e841dSYevgeny Kliteynik 1140d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1141d65e841dSYevgeny Kliteynik geneve_protocol_type, misc, geneve_protocol_type); 1142d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1143d65e841dSYevgeny Kliteynik geneve_oam, misc, geneve_oam); 1144d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1145d65e841dSYevgeny Kliteynik geneve_opt_len, misc, geneve_opt_len); 1146d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1147d65e841dSYevgeny Kliteynik geneve_vni, misc, geneve_vni); 1148d65e841dSYevgeny Kliteynik 1149d65e841dSYevgeny Kliteynik return 0; 1150d65e841dSYevgeny Kliteynik } 1151d65e841dSYevgeny Kliteynik 1152d65e841dSYevgeny Kliteynik static void 1153d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb, 1154d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 1155d65e841dSYevgeny Kliteynik { 115646779098SYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask); 1157dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER; 1158d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1159d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tag; 1160d65e841dSYevgeny Kliteynik } 1161d65e841dSYevgeny Kliteynik 1162d65e841dSYevgeny Kliteynik static int 1163d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_tag(struct mlx5dr_match_param *value, 1164d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 1165d65e841dSYevgeny Kliteynik u8 *tag) 1166d65e841dSYevgeny Kliteynik { 1167d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1168d65e841dSYevgeny Kliteynik 1169d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0); 1170d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1); 1171d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2); 1172d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3); 1173d65e841dSYevgeny Kliteynik 1174d65e841dSYevgeny Kliteynik return 0; 1175d65e841dSYevgeny Kliteynik } 1176d65e841dSYevgeny Kliteynik 1177d65e841dSYevgeny Kliteynik static void 1178d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_init(struct mlx5dr_ste_build *sb, 1179d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 1180d65e841dSYevgeny Kliteynik { 118146779098SYevgeny Kliteynik dr_ste_v0_build_register_0_tag(mask, sb, sb->bit_mask); 1182d65e841dSYevgeny Kliteynik 1183dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0; 1184d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1185d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_register_0_tag; 1186d65e841dSYevgeny Kliteynik } 1187d65e841dSYevgeny Kliteynik 1188d65e841dSYevgeny Kliteynik static int 1189d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_tag(struct mlx5dr_match_param *value, 1190d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 1191d65e841dSYevgeny Kliteynik u8 *tag) 1192d65e841dSYevgeny Kliteynik { 1193d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1194d65e841dSYevgeny Kliteynik 1195d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4); 1196d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5); 1197d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6); 1198d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7); 1199d65e841dSYevgeny Kliteynik 1200d65e841dSYevgeny Kliteynik return 0; 1201d65e841dSYevgeny Kliteynik } 1202d65e841dSYevgeny Kliteynik 1203d65e841dSYevgeny Kliteynik static void 1204d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_init(struct mlx5dr_ste_build *sb, 1205d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 1206d65e841dSYevgeny Kliteynik { 120746779098SYevgeny Kliteynik dr_ste_v0_build_register_1_tag(mask, sb, sb->bit_mask); 1208d65e841dSYevgeny Kliteynik 1209dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1; 1210d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1211d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_register_1_tag; 1212d65e841dSYevgeny Kliteynik } 1213d65e841dSYevgeny Kliteynik 1214d65e841dSYevgeny Kliteynik static void 1215d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value, 1216d65e841dSYevgeny Kliteynik u8 *bit_mask) 1217d65e841dSYevgeny Kliteynik { 1218d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc_mask = &value->misc; 1219d65e841dSYevgeny Kliteynik 122046779098SYevgeny Kliteynik DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_gvmi, misc_mask, source_port); 122146779098SYevgeny Kliteynik DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_qp, misc_mask, source_sqn); 1222d65e841dSYevgeny Kliteynik misc_mask->source_eswitch_owner_vhca_id = 0; 1223d65e841dSYevgeny Kliteynik } 1224d65e841dSYevgeny Kliteynik 1225d65e841dSYevgeny Kliteynik static int 1226d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, 1227d65e841dSYevgeny Kliteynik struct mlx5dr_ste_build *sb, 1228d65e841dSYevgeny Kliteynik u8 *tag) 1229d65e841dSYevgeny Kliteynik { 1230d65e841dSYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 1231d65e841dSYevgeny Kliteynik struct mlx5dr_cmd_vport_cap *vport_cap; 1232d65e841dSYevgeny Kliteynik struct mlx5dr_domain *dmn = sb->dmn; 1233d65e841dSYevgeny Kliteynik struct mlx5dr_cmd_caps *caps; 1234d65e841dSYevgeny Kliteynik u8 *bit_mask = sb->bit_mask; 1235d65e841dSYevgeny Kliteynik bool source_gvmi_set; 1236d65e841dSYevgeny Kliteynik 1237d65e841dSYevgeny Kliteynik DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn); 1238d65e841dSYevgeny Kliteynik 1239d65e841dSYevgeny Kliteynik if (sb->vhca_id_valid) { 1240d65e841dSYevgeny Kliteynik /* Find port GVMI based on the eswitch_owner_vhca_id */ 1241d65e841dSYevgeny Kliteynik if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi) 1242d65e841dSYevgeny Kliteynik caps = &dmn->info.caps; 1243d65e841dSYevgeny Kliteynik else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id == 1244d65e841dSYevgeny Kliteynik dmn->peer_dmn->info.caps.gvmi)) 1245d65e841dSYevgeny Kliteynik caps = &dmn->peer_dmn->info.caps; 1246d65e841dSYevgeny Kliteynik else 1247d65e841dSYevgeny Kliteynik return -EINVAL; 12487863c912SYevgeny Kliteynik 12497863c912SYevgeny Kliteynik misc->source_eswitch_owner_vhca_id = 0; 1250d65e841dSYevgeny Kliteynik } else { 1251d65e841dSYevgeny Kliteynik caps = &dmn->info.caps; 1252d65e841dSYevgeny Kliteynik } 1253d65e841dSYevgeny Kliteynik 12547863c912SYevgeny Kliteynik source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi); 12557863c912SYevgeny Kliteynik if (source_gvmi_set) { 1256d65e841dSYevgeny Kliteynik vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port); 1257d65e841dSYevgeny Kliteynik if (!vport_cap) { 1258d65e841dSYevgeny Kliteynik mlx5dr_err(dmn, "Vport 0x%x is invalid\n", 1259d65e841dSYevgeny Kliteynik misc->source_port); 1260d65e841dSYevgeny Kliteynik return -EINVAL; 1261d65e841dSYevgeny Kliteynik } 1262d65e841dSYevgeny Kliteynik 12637863c912SYevgeny Kliteynik if (vport_cap->vport_gvmi) 1264d65e841dSYevgeny Kliteynik MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi); 1265d65e841dSYevgeny Kliteynik 1266d65e841dSYevgeny Kliteynik misc->source_port = 0; 12677863c912SYevgeny Kliteynik } 1268d65e841dSYevgeny Kliteynik 1269d65e841dSYevgeny Kliteynik return 0; 1270d65e841dSYevgeny Kliteynik } 1271d65e841dSYevgeny Kliteynik 1272d65e841dSYevgeny Kliteynik static void 1273d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb, 1274d65e841dSYevgeny Kliteynik struct mlx5dr_match_param *mask) 1275d65e841dSYevgeny Kliteynik { 1276d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask); 1277d65e841dSYevgeny Kliteynik 1278dd2d3c8dSYevgeny Kliteynik sb->lu_type = DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP; 1279d65e841dSYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1280d65e841dSYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v0_build_src_gvmi_qpn_tag; 1281d65e841dSYevgeny Kliteynik } 1282d65e841dSYevgeny Kliteynik 1283d65e841dSYevgeny Kliteynik struct mlx5dr_ste_ctx ste_ctx_v0 = { 12846b93b400SYevgeny Kliteynik /* Builders */ 1285d65e841dSYevgeny Kliteynik .build_eth_l2_src_dst_init = &dr_ste_v0_build_eth_l2_src_dst_init, 1286d65e841dSYevgeny Kliteynik .build_eth_l3_ipv6_src_init = &dr_ste_v0_build_eth_l3_ipv6_src_init, 1287d65e841dSYevgeny Kliteynik .build_eth_l3_ipv6_dst_init = &dr_ste_v0_build_eth_l3_ipv6_dst_init, 1288d65e841dSYevgeny Kliteynik .build_eth_l3_ipv4_5_tuple_init = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_init, 1289d65e841dSYevgeny Kliteynik .build_eth_l2_src_init = &dr_ste_v0_build_eth_l2_src_init, 1290d65e841dSYevgeny Kliteynik .build_eth_l2_dst_init = &dr_ste_v0_build_eth_l2_dst_init, 1291d65e841dSYevgeny Kliteynik .build_eth_l2_tnl_init = &dr_ste_v0_build_eth_l2_tnl_init, 1292d65e841dSYevgeny Kliteynik .build_eth_l3_ipv4_misc_init = &dr_ste_v0_build_eth_l3_ipv4_misc_init, 1293d65e841dSYevgeny Kliteynik .build_eth_ipv6_l3_l4_init = &dr_ste_v0_build_eth_ipv6_l3_l4_init, 1294d65e841dSYevgeny Kliteynik .build_mpls_init = &dr_ste_v0_build_mpls_init, 1295d65e841dSYevgeny Kliteynik .build_tnl_gre_init = &dr_ste_v0_build_tnl_gre_init, 1296d65e841dSYevgeny Kliteynik .build_tnl_mpls_init = &dr_ste_v0_build_tnl_mpls_init, 1297d65e841dSYevgeny Kliteynik .build_icmp_init = &dr_ste_v0_build_icmp_init, 1298d65e841dSYevgeny Kliteynik .build_general_purpose_init = &dr_ste_v0_build_general_purpose_init, 1299d65e841dSYevgeny Kliteynik .build_eth_l4_misc_init = &dr_ste_v0_build_eth_l4_misc_init, 1300d65e841dSYevgeny Kliteynik .build_tnl_vxlan_gpe_init = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init, 1301d65e841dSYevgeny Kliteynik .build_tnl_geneve_init = &dr_ste_v0_build_flex_parser_tnl_geneve_init, 1302d65e841dSYevgeny Kliteynik .build_register_0_init = &dr_ste_v0_build_register_0_init, 1303d65e841dSYevgeny Kliteynik .build_register_1_init = &dr_ste_v0_build_register_1_init, 1304d65e841dSYevgeny Kliteynik .build_src_gvmi_qpn_init = &dr_ste_v0_build_src_gvmi_qpn_init, 13056b93b400SYevgeny Kliteynik 13066b93b400SYevgeny Kliteynik /* Getters and Setters */ 13076b93b400SYevgeny Kliteynik .ste_init = &dr_ste_v0_init, 13086b93b400SYevgeny Kliteynik .set_next_lu_type = &dr_ste_v0_set_next_lu_type, 13096b93b400SYevgeny Kliteynik .get_next_lu_type = &dr_ste_v0_get_next_lu_type, 13106b93b400SYevgeny Kliteynik .set_miss_addr = &dr_ste_v0_set_miss_addr, 13116b93b400SYevgeny Kliteynik .get_miss_addr = &dr_ste_v0_get_miss_addr, 13126b93b400SYevgeny Kliteynik .set_hit_addr = &dr_ste_v0_set_hit_addr, 13136b93b400SYevgeny Kliteynik .set_byte_mask = &dr_ste_v0_set_byte_mask, 13146b93b400SYevgeny Kliteynik .get_byte_mask = &dr_ste_v0_get_byte_mask, 1315*ad17dc8cSYevgeny Kliteynik 1316*ad17dc8cSYevgeny Kliteynik /* Actions */ 1317*ad17dc8cSYevgeny Kliteynik .set_actions_rx = &dr_ste_v0_set_actions_rx, 1318*ad17dc8cSYevgeny Kliteynik .set_actions_tx = &dr_ste_v0_set_actions_tx, 1319d65e841dSYevgeny Kliteynik }; 1320