1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2/* Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. */ 3 4#include <linux/types.h> 5#include <linux/crc32.h> 6#include "dr_ste.h" 7 8#define SVLAN_ETHERTYPE 0x88a8 9#define DR_STE_ENABLE_FLOW_TAG BIT(31) 10 11enum dr_ste_v0_entry_type { 12 DR_STE_TYPE_TX = 1, 13 DR_STE_TYPE_RX = 2, 14 DR_STE_TYPE_MODIFY_PKT = 6, 15}; 16 17enum dr_ste_v0_action_tunl { 18 DR_STE_TUNL_ACTION_NONE = 0, 19 DR_STE_TUNL_ACTION_ENABLE = 1, 20 DR_STE_TUNL_ACTION_DECAP = 2, 21 DR_STE_TUNL_ACTION_L3_DECAP = 3, 22 DR_STE_TUNL_ACTION_POP_VLAN = 4, 23}; 24 25enum dr_ste_v0_action_type { 26 DR_STE_ACTION_TYPE_PUSH_VLAN = 1, 27 DR_STE_ACTION_TYPE_ENCAP_L3 = 3, 28 DR_STE_ACTION_TYPE_ENCAP = 4, 29}; 30 31enum dr_ste_v0_action_mdfy_op { 32 DR_STE_ACTION_MDFY_OP_COPY = 0x1, 33 DR_STE_ACTION_MDFY_OP_SET = 0x2, 34 DR_STE_ACTION_MDFY_OP_ADD = 0x3, 35}; 36 37#define DR_STE_CALC_LU_TYPE(lookup_type, rx, inner) \ 38 ((inner) ? DR_STE_V0_LU_TYPE_##lookup_type##_I : \ 39 (rx) ? DR_STE_V0_LU_TYPE_##lookup_type##_D : \ 40 DR_STE_V0_LU_TYPE_##lookup_type##_O) 41 42enum { 43 DR_STE_V0_LU_TYPE_NOP = 0x00, 44 DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP = 0x05, 45 DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I = 0x0a, 46 DR_STE_V0_LU_TYPE_ETHL2_DST_O = 0x06, 47 DR_STE_V0_LU_TYPE_ETHL2_DST_I = 0x07, 48 DR_STE_V0_LU_TYPE_ETHL2_DST_D = 0x1b, 49 DR_STE_V0_LU_TYPE_ETHL2_SRC_O = 0x08, 50 DR_STE_V0_LU_TYPE_ETHL2_SRC_I = 0x09, 51 DR_STE_V0_LU_TYPE_ETHL2_SRC_D = 0x1c, 52 DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_O = 0x36, 53 DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_I = 0x37, 54 DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_D = 0x38, 55 DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_O = 0x0d, 56 DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_I = 0x0e, 57 DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_D = 0x1e, 58 DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_O = 0x0f, 59 DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_I = 0x10, 60 DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_D = 0x1f, 61 DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_O = 0x11, 62 DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_I = 0x12, 63 DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_D = 0x20, 64 DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_O = 0x29, 65 DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_I = 0x2a, 66 DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_D = 0x2b, 67 DR_STE_V0_LU_TYPE_ETHL4_O = 0x13, 68 DR_STE_V0_LU_TYPE_ETHL4_I = 0x14, 69 DR_STE_V0_LU_TYPE_ETHL4_D = 0x21, 70 DR_STE_V0_LU_TYPE_ETHL4_MISC_O = 0x2c, 71 DR_STE_V0_LU_TYPE_ETHL4_MISC_I = 0x2d, 72 DR_STE_V0_LU_TYPE_ETHL4_MISC_D = 0x2e, 73 DR_STE_V0_LU_TYPE_MPLS_FIRST_O = 0x15, 74 DR_STE_V0_LU_TYPE_MPLS_FIRST_I = 0x24, 75 DR_STE_V0_LU_TYPE_MPLS_FIRST_D = 0x25, 76 DR_STE_V0_LU_TYPE_GRE = 0x16, 77 DR_STE_V0_LU_TYPE_FLEX_PARSER_0 = 0x22, 78 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 = 0x23, 79 DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER = 0x19, 80 DR_STE_V0_LU_TYPE_GENERAL_PURPOSE = 0x18, 81 DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0 = 0x2f, 82 DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1 = 0x30, 83 DR_STE_V0_LU_TYPE_TUNNEL_HEADER = 0x34, 84 DR_STE_V0_LU_TYPE_DONT_CARE = MLX5DR_STE_LU_TYPE_DONT_CARE, 85}; 86 87enum { 88 DR_STE_V0_ACTION_MDFY_FLD_L2_0 = 0, 89 DR_STE_V0_ACTION_MDFY_FLD_L2_1 = 1, 90 DR_STE_V0_ACTION_MDFY_FLD_L2_2 = 2, 91 DR_STE_V0_ACTION_MDFY_FLD_L3_0 = 3, 92 DR_STE_V0_ACTION_MDFY_FLD_L3_1 = 4, 93 DR_STE_V0_ACTION_MDFY_FLD_L3_2 = 5, 94 DR_STE_V0_ACTION_MDFY_FLD_L3_3 = 6, 95 DR_STE_V0_ACTION_MDFY_FLD_L3_4 = 7, 96 DR_STE_V0_ACTION_MDFY_FLD_L4_0 = 8, 97 DR_STE_V0_ACTION_MDFY_FLD_L4_1 = 9, 98 DR_STE_V0_ACTION_MDFY_FLD_MPLS = 10, 99 DR_STE_V0_ACTION_MDFY_FLD_L2_TNL_0 = 11, 100 DR_STE_V0_ACTION_MDFY_FLD_REG_0 = 12, 101 DR_STE_V0_ACTION_MDFY_FLD_REG_1 = 13, 102 DR_STE_V0_ACTION_MDFY_FLD_REG_2 = 14, 103 DR_STE_V0_ACTION_MDFY_FLD_REG_3 = 15, 104 DR_STE_V0_ACTION_MDFY_FLD_L4_2 = 16, 105 DR_STE_V0_ACTION_MDFY_FLD_FLEX_0 = 17, 106 DR_STE_V0_ACTION_MDFY_FLD_FLEX_1 = 18, 107 DR_STE_V0_ACTION_MDFY_FLD_FLEX_2 = 19, 108 DR_STE_V0_ACTION_MDFY_FLD_FLEX_3 = 20, 109 DR_STE_V0_ACTION_MDFY_FLD_L2_TNL_1 = 21, 110 DR_STE_V0_ACTION_MDFY_FLD_METADATA = 22, 111 DR_STE_V0_ACTION_MDFY_FLD_RESERVED = 23, 112}; 113 114static const struct mlx5dr_ste_action_modify_field dr_ste_v0_action_modify_field_arr[] = { 115 [MLX5_ACTION_IN_FIELD_OUT_SMAC_47_16] = { 116 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_1, .start = 16, .end = 47, 117 }, 118 [MLX5_ACTION_IN_FIELD_OUT_SMAC_15_0] = { 119 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_1, .start = 0, .end = 15, 120 }, 121 [MLX5_ACTION_IN_FIELD_OUT_ETHERTYPE] = { 122 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_2, .start = 32, .end = 47, 123 }, 124 [MLX5_ACTION_IN_FIELD_OUT_DMAC_47_16] = { 125 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_0, .start = 16, .end = 47, 126 }, 127 [MLX5_ACTION_IN_FIELD_OUT_DMAC_15_0] = { 128 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_0, .start = 0, .end = 15, 129 }, 130 [MLX5_ACTION_IN_FIELD_OUT_IP_DSCP] = { 131 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_1, .start = 0, .end = 5, 132 }, 133 [MLX5_ACTION_IN_FIELD_OUT_TCP_FLAGS] = { 134 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 48, .end = 56, 135 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP, 136 }, 137 [MLX5_ACTION_IN_FIELD_OUT_TCP_SPORT] = { 138 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 0, .end = 15, 139 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP, 140 }, 141 [MLX5_ACTION_IN_FIELD_OUT_TCP_DPORT] = { 142 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 16, .end = 31, 143 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP, 144 }, 145 [MLX5_ACTION_IN_FIELD_OUT_IP_TTL] = { 146 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_1, .start = 8, .end = 15, 147 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4, 148 }, 149 [MLX5_ACTION_IN_FIELD_OUT_IPV6_HOPLIMIT] = { 150 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_1, .start = 8, .end = 15, 151 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 152 }, 153 [MLX5_ACTION_IN_FIELD_OUT_UDP_SPORT] = { 154 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 0, .end = 15, 155 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_UDP, 156 }, 157 [MLX5_ACTION_IN_FIELD_OUT_UDP_DPORT] = { 158 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_0, .start = 16, .end = 31, 159 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_UDP, 160 }, 161 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_127_96] = { 162 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_3, .start = 32, .end = 63, 163 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 164 }, 165 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_95_64] = { 166 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_3, .start = 0, .end = 31, 167 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 168 }, 169 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_63_32] = { 170 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_4, .start = 32, .end = 63, 171 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 172 }, 173 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_31_0] = { 174 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_4, .start = 0, .end = 31, 175 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 176 }, 177 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_127_96] = { 178 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_0, .start = 32, .end = 63, 179 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 180 }, 181 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_95_64] = { 182 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_0, .start = 0, .end = 31, 183 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 184 }, 185 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_63_32] = { 186 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_2, .start = 32, .end = 63, 187 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 188 }, 189 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_31_0] = { 190 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_2, .start = 0, .end = 31, 191 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 192 }, 193 [MLX5_ACTION_IN_FIELD_OUT_SIPV4] = { 194 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_0, .start = 0, .end = 31, 195 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4, 196 }, 197 [MLX5_ACTION_IN_FIELD_OUT_DIPV4] = { 198 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L3_0, .start = 32, .end = 63, 199 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4, 200 }, 201 [MLX5_ACTION_IN_FIELD_METADATA_REG_A] = { 202 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_METADATA, .start = 0, .end = 31, 203 }, 204 [MLX5_ACTION_IN_FIELD_METADATA_REG_B] = { 205 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_METADATA, .start = 32, .end = 63, 206 }, 207 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_0] = { 208 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_0, .start = 32, .end = 63, 209 }, 210 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_1] = { 211 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_0, .start = 0, .end = 31, 212 }, 213 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_2] = { 214 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_1, .start = 32, .end = 63, 215 }, 216 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_3] = { 217 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_1, .start = 0, .end = 31, 218 }, 219 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_4] = { 220 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_2, .start = 32, .end = 63, 221 }, 222 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_5] = { 223 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_REG_2, .start = 0, .end = 31, 224 }, 225 [MLX5_ACTION_IN_FIELD_OUT_TCP_SEQ_NUM] = { 226 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_1, .start = 32, .end = 63, 227 }, 228 [MLX5_ACTION_IN_FIELD_OUT_TCP_ACK_NUM] = { 229 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L4_1, .start = 0, .end = 31, 230 }, 231 [MLX5_ACTION_IN_FIELD_OUT_FIRST_VID] = { 232 .hw_field = DR_STE_V0_ACTION_MDFY_FLD_L2_2, .start = 0, .end = 15, 233 }, 234}; 235 236static void dr_ste_v0_set_entry_type(u8 *hw_ste_p, u8 entry_type) 237{ 238 MLX5_SET(ste_general, hw_ste_p, entry_type, entry_type); 239} 240 241static u8 dr_ste_v0_get_entry_type(u8 *hw_ste_p) 242{ 243 return MLX5_GET(ste_general, hw_ste_p, entry_type); 244} 245 246static void dr_ste_v0_set_miss_addr(u8 *hw_ste_p, u64 miss_addr) 247{ 248 u64 index = miss_addr >> 6; 249 250 /* Miss address for TX and RX STEs located in the same offsets */ 251 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32, index >> 26); 252 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6, index); 253} 254 255static u64 dr_ste_v0_get_miss_addr(u8 *hw_ste_p) 256{ 257 u64 index = 258 ((u64)MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6) | 259 ((u64)MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32)) << 26); 260 261 return index << 6; 262} 263 264static void dr_ste_v0_set_byte_mask(u8 *hw_ste_p, u16 byte_mask) 265{ 266 MLX5_SET(ste_general, hw_ste_p, byte_mask, byte_mask); 267} 268 269static u16 dr_ste_v0_get_byte_mask(u8 *hw_ste_p) 270{ 271 return MLX5_GET(ste_general, hw_ste_p, byte_mask); 272} 273 274static void dr_ste_v0_set_lu_type(u8 *hw_ste_p, u16 lu_type) 275{ 276 MLX5_SET(ste_general, hw_ste_p, entry_sub_type, lu_type); 277} 278 279static void dr_ste_v0_set_next_lu_type(u8 *hw_ste_p, u16 lu_type) 280{ 281 MLX5_SET(ste_general, hw_ste_p, next_lu_type, lu_type); 282} 283 284static u16 dr_ste_v0_get_next_lu_type(u8 *hw_ste_p) 285{ 286 return MLX5_GET(ste_general, hw_ste_p, next_lu_type); 287} 288 289static void dr_ste_v0_set_hit_gvmi(u8 *hw_ste_p, u16 gvmi) 290{ 291 MLX5_SET(ste_general, hw_ste_p, next_table_base_63_48, gvmi); 292} 293 294static void dr_ste_v0_set_hit_addr(u8 *hw_ste_p, u64 icm_addr, u32 ht_size) 295{ 296 u64 index = (icm_addr >> 5) | ht_size; 297 298 MLX5_SET(ste_general, hw_ste_p, next_table_base_39_32_size, index >> 27); 299 MLX5_SET(ste_general, hw_ste_p, next_table_base_31_5_size, index); 300} 301 302static void dr_ste_v0_init_full(u8 *hw_ste_p, u16 lu_type, 303 enum dr_ste_v0_entry_type entry_type, u16 gvmi) 304{ 305 dr_ste_v0_set_entry_type(hw_ste_p, entry_type); 306 dr_ste_v0_set_lu_type(hw_ste_p, lu_type); 307 dr_ste_v0_set_next_lu_type(hw_ste_p, MLX5DR_STE_LU_TYPE_DONT_CARE); 308 309 /* Set GVMI once, this is the same for RX/TX 310 * bits 63_48 of next table base / miss address encode the next GVMI 311 */ 312 MLX5_SET(ste_rx_steering_mult, hw_ste_p, gvmi, gvmi); 313 MLX5_SET(ste_rx_steering_mult, hw_ste_p, next_table_base_63_48, gvmi); 314 MLX5_SET(ste_rx_steering_mult, hw_ste_p, miss_address_63_48, gvmi); 315} 316 317static void dr_ste_v0_init(u8 *hw_ste_p, u16 lu_type, 318 bool is_rx, u16 gvmi) 319{ 320 enum dr_ste_v0_entry_type entry_type; 321 322 entry_type = is_rx ? DR_STE_TYPE_RX : DR_STE_TYPE_TX; 323 dr_ste_v0_init_full(hw_ste_p, lu_type, entry_type, gvmi); 324} 325 326static void dr_ste_v0_rx_set_flow_tag(u8 *hw_ste_p, u32 flow_tag) 327{ 328 MLX5_SET(ste_rx_steering_mult, hw_ste_p, qp_list_pointer, 329 DR_STE_ENABLE_FLOW_TAG | flow_tag); 330} 331 332static void dr_ste_v0_set_counter_id(u8 *hw_ste_p, u32 ctr_id) 333{ 334 /* This can be used for both rx_steering_mult and for sx_transmit */ 335 MLX5_SET(ste_rx_steering_mult, hw_ste_p, counter_trigger_15_0, ctr_id); 336 MLX5_SET(ste_rx_steering_mult, hw_ste_p, counter_trigger_23_16, ctr_id >> 16); 337} 338 339static void dr_ste_v0_set_go_back_bit(u8 *hw_ste_p) 340{ 341 MLX5_SET(ste_sx_transmit, hw_ste_p, go_back, 1); 342} 343 344static void dr_ste_v0_set_tx_push_vlan(u8 *hw_ste_p, u32 vlan_hdr, 345 bool go_back) 346{ 347 MLX5_SET(ste_sx_transmit, hw_ste_p, action_type, 348 DR_STE_ACTION_TYPE_PUSH_VLAN); 349 MLX5_SET(ste_sx_transmit, hw_ste_p, encap_pointer_vlan_data, vlan_hdr); 350 /* Due to HW limitation we need to set this bit, otherwise reformat + 351 * push vlan will not work. 352 */ 353 if (go_back) 354 dr_ste_v0_set_go_back_bit(hw_ste_p); 355} 356 357static void dr_ste_v0_set_tx_encap(void *hw_ste_p, u32 reformat_id, 358 int size, bool encap_l3) 359{ 360 MLX5_SET(ste_sx_transmit, hw_ste_p, action_type, 361 encap_l3 ? DR_STE_ACTION_TYPE_ENCAP_L3 : DR_STE_ACTION_TYPE_ENCAP); 362 /* The hardware expects here size in words (2 byte) */ 363 MLX5_SET(ste_sx_transmit, hw_ste_p, action_description, size / 2); 364 MLX5_SET(ste_sx_transmit, hw_ste_p, encap_pointer_vlan_data, reformat_id); 365} 366 367static void dr_ste_v0_set_rx_decap(u8 *hw_ste_p) 368{ 369 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action, 370 DR_STE_TUNL_ACTION_DECAP); 371 MLX5_SET(ste_rx_steering_mult, hw_ste_p, fail_on_error, 1); 372} 373 374static void dr_ste_v0_set_rx_pop_vlan(u8 *hw_ste_p) 375{ 376 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action, 377 DR_STE_TUNL_ACTION_POP_VLAN); 378} 379 380static void dr_ste_v0_set_rx_decap_l3(u8 *hw_ste_p, bool vlan) 381{ 382 MLX5_SET(ste_rx_steering_mult, hw_ste_p, tunneling_action, 383 DR_STE_TUNL_ACTION_L3_DECAP); 384 MLX5_SET(ste_modify_packet, hw_ste_p, action_description, vlan ? 1 : 0); 385 MLX5_SET(ste_rx_steering_mult, hw_ste_p, fail_on_error, 1); 386} 387 388static void dr_ste_v0_set_rewrite_actions(u8 *hw_ste_p, u16 num_of_actions, 389 u32 re_write_index) 390{ 391 MLX5_SET(ste_modify_packet, hw_ste_p, number_of_re_write_actions, 392 num_of_actions); 393 MLX5_SET(ste_modify_packet, hw_ste_p, header_re_write_actions_pointer, 394 re_write_index); 395} 396 397static void dr_ste_v0_arr_init_next(u8 **last_ste, 398 u32 *added_stes, 399 enum dr_ste_v0_entry_type entry_type, 400 u16 gvmi) 401{ 402 (*added_stes)++; 403 *last_ste += DR_STE_SIZE; 404 dr_ste_v0_init_full(*last_ste, MLX5DR_STE_LU_TYPE_DONT_CARE, 405 entry_type, gvmi); 406} 407 408static void 409dr_ste_v0_set_actions_tx(struct mlx5dr_domain *dmn, 410 u8 *action_type_set, 411 u32 actions_caps, 412 u8 *last_ste, 413 struct mlx5dr_ste_actions_attr *attr, 414 u32 *added_stes) 415{ 416 bool encap = action_type_set[DR_ACTION_TYP_L2_TO_TNL_L2] || 417 action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]; 418 419 /* We want to make sure the modify header comes before L2 420 * encapsulation. The reason for that is that we support 421 * modify headers for outer headers only 422 */ 423 if (action_type_set[DR_ACTION_TYP_MODIFY_HDR] && attr->modify_actions) { 424 dr_ste_v0_set_entry_type(last_ste, DR_STE_TYPE_MODIFY_PKT); 425 dr_ste_v0_set_rewrite_actions(last_ste, 426 attr->modify_actions, 427 attr->modify_index); 428 } 429 430 if (action_type_set[DR_ACTION_TYP_PUSH_VLAN]) { 431 int i; 432 433 for (i = 0; i < attr->vlans.count; i++) { 434 if (i || action_type_set[DR_ACTION_TYP_MODIFY_HDR]) 435 dr_ste_v0_arr_init_next(&last_ste, 436 added_stes, 437 DR_STE_TYPE_TX, 438 attr->gvmi); 439 440 dr_ste_v0_set_tx_push_vlan(last_ste, 441 attr->vlans.headers[i], 442 encap); 443 } 444 } 445 446 if (encap) { 447 /* Modify header and encapsulation require a different STEs. 448 * Since modify header STE format doesn't support encapsulation 449 * tunneling_action. 450 */ 451 if (action_type_set[DR_ACTION_TYP_MODIFY_HDR] || 452 action_type_set[DR_ACTION_TYP_PUSH_VLAN]) 453 dr_ste_v0_arr_init_next(&last_ste, 454 added_stes, 455 DR_STE_TYPE_TX, 456 attr->gvmi); 457 458 dr_ste_v0_set_tx_encap(last_ste, 459 attr->reformat.id, 460 attr->reformat.size, 461 action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]); 462 /* Whenever prio_tag_required enabled, we can be sure that the 463 * previous table (ACL) already push vlan to our packet, 464 * And due to HW limitation we need to set this bit, otherwise 465 * push vlan + reformat will not work. 466 */ 467 if (MLX5_CAP_GEN(dmn->mdev, prio_tag_required)) 468 dr_ste_v0_set_go_back_bit(last_ste); 469 } 470 471 if (action_type_set[DR_ACTION_TYP_CTR]) 472 dr_ste_v0_set_counter_id(last_ste, attr->ctr_id); 473 474 dr_ste_v0_set_hit_gvmi(last_ste, attr->hit_gvmi); 475 dr_ste_v0_set_hit_addr(last_ste, attr->final_icm_addr, 1); 476} 477 478static void 479dr_ste_v0_set_actions_rx(struct mlx5dr_domain *dmn, 480 u8 *action_type_set, 481 u32 actions_caps, 482 u8 *last_ste, 483 struct mlx5dr_ste_actions_attr *attr, 484 u32 *added_stes) 485{ 486 if (action_type_set[DR_ACTION_TYP_CTR]) 487 dr_ste_v0_set_counter_id(last_ste, attr->ctr_id); 488 489 if (action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2]) { 490 dr_ste_v0_set_entry_type(last_ste, DR_STE_TYPE_MODIFY_PKT); 491 dr_ste_v0_set_rx_decap_l3(last_ste, attr->decap_with_vlan); 492 dr_ste_v0_set_rewrite_actions(last_ste, 493 attr->decap_actions, 494 attr->decap_index); 495 } 496 497 if (action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2]) 498 dr_ste_v0_set_rx_decap(last_ste); 499 500 if (action_type_set[DR_ACTION_TYP_POP_VLAN]) { 501 int i; 502 503 for (i = 0; i < attr->vlans.count; i++) { 504 if (i || 505 action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2] || 506 action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2]) 507 dr_ste_v0_arr_init_next(&last_ste, 508 added_stes, 509 DR_STE_TYPE_RX, 510 attr->gvmi); 511 512 dr_ste_v0_set_rx_pop_vlan(last_ste); 513 } 514 } 515 516 if (action_type_set[DR_ACTION_TYP_MODIFY_HDR] && attr->modify_actions) { 517 if (dr_ste_v0_get_entry_type(last_ste) == DR_STE_TYPE_MODIFY_PKT) 518 dr_ste_v0_arr_init_next(&last_ste, 519 added_stes, 520 DR_STE_TYPE_MODIFY_PKT, 521 attr->gvmi); 522 else 523 dr_ste_v0_set_entry_type(last_ste, DR_STE_TYPE_MODIFY_PKT); 524 525 dr_ste_v0_set_rewrite_actions(last_ste, 526 attr->modify_actions, 527 attr->modify_index); 528 } 529 530 if (action_type_set[DR_ACTION_TYP_TAG]) { 531 if (dr_ste_v0_get_entry_type(last_ste) == DR_STE_TYPE_MODIFY_PKT) 532 dr_ste_v0_arr_init_next(&last_ste, 533 added_stes, 534 DR_STE_TYPE_RX, 535 attr->gvmi); 536 537 dr_ste_v0_rx_set_flow_tag(last_ste, attr->flow_tag); 538 } 539 540 dr_ste_v0_set_hit_gvmi(last_ste, attr->hit_gvmi); 541 dr_ste_v0_set_hit_addr(last_ste, attr->final_icm_addr, 1); 542} 543 544static void dr_ste_v0_set_action_set(u8 *hw_action, 545 u8 hw_field, 546 u8 shifter, 547 u8 length, 548 u32 data) 549{ 550 length = (length == 32) ? 0 : length; 551 MLX5_SET(dr_action_hw_set, hw_action, opcode, DR_STE_ACTION_MDFY_OP_SET); 552 MLX5_SET(dr_action_hw_set, hw_action, destination_field_code, hw_field); 553 MLX5_SET(dr_action_hw_set, hw_action, destination_left_shifter, shifter); 554 MLX5_SET(dr_action_hw_set, hw_action, destination_length, length); 555 MLX5_SET(dr_action_hw_set, hw_action, inline_data, data); 556} 557 558static void dr_ste_v0_set_action_add(u8 *hw_action, 559 u8 hw_field, 560 u8 shifter, 561 u8 length, 562 u32 data) 563{ 564 length = (length == 32) ? 0 : length; 565 MLX5_SET(dr_action_hw_set, hw_action, opcode, DR_STE_ACTION_MDFY_OP_ADD); 566 MLX5_SET(dr_action_hw_set, hw_action, destination_field_code, hw_field); 567 MLX5_SET(dr_action_hw_set, hw_action, destination_left_shifter, shifter); 568 MLX5_SET(dr_action_hw_set, hw_action, destination_length, length); 569 MLX5_SET(dr_action_hw_set, hw_action, inline_data, data); 570} 571 572static void dr_ste_v0_set_action_copy(u8 *hw_action, 573 u8 dst_hw_field, 574 u8 dst_shifter, 575 u8 dst_len, 576 u8 src_hw_field, 577 u8 src_shifter) 578{ 579 MLX5_SET(dr_action_hw_copy, hw_action, opcode, DR_STE_ACTION_MDFY_OP_COPY); 580 MLX5_SET(dr_action_hw_copy, hw_action, destination_field_code, dst_hw_field); 581 MLX5_SET(dr_action_hw_copy, hw_action, destination_left_shifter, dst_shifter); 582 MLX5_SET(dr_action_hw_copy, hw_action, destination_length, dst_len); 583 MLX5_SET(dr_action_hw_copy, hw_action, source_field_code, src_hw_field); 584 MLX5_SET(dr_action_hw_copy, hw_action, source_left_shifter, src_shifter); 585} 586 587#define DR_STE_DECAP_L3_MIN_ACTION_NUM 5 588 589static int 590dr_ste_v0_set_action_decap_l3_list(void *data, u32 data_sz, 591 u8 *hw_action, u32 hw_action_sz, 592 u16 *used_hw_action_num) 593{ 594 struct mlx5_ifc_l2_hdr_bits *l2_hdr = data; 595 u32 hw_action_num; 596 int required_actions; 597 u32 hdr_fld_4b; 598 u16 hdr_fld_2b; 599 u16 vlan_type; 600 bool vlan; 601 602 vlan = (data_sz != HDR_LEN_L2); 603 hw_action_num = hw_action_sz / MLX5_ST_SZ_BYTES(dr_action_hw_set); 604 required_actions = DR_STE_DECAP_L3_MIN_ACTION_NUM + !!vlan; 605 606 if (hw_action_num < required_actions) 607 return -ENOMEM; 608 609 /* dmac_47_16 */ 610 MLX5_SET(dr_action_hw_set, hw_action, 611 opcode, DR_STE_ACTION_MDFY_OP_SET); 612 MLX5_SET(dr_action_hw_set, hw_action, 613 destination_length, 0); 614 MLX5_SET(dr_action_hw_set, hw_action, 615 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_0); 616 MLX5_SET(dr_action_hw_set, hw_action, 617 destination_left_shifter, 16); 618 hdr_fld_4b = MLX5_GET(l2_hdr, l2_hdr, dmac_47_16); 619 MLX5_SET(dr_action_hw_set, hw_action, 620 inline_data, hdr_fld_4b); 621 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set); 622 623 /* smac_47_16 */ 624 MLX5_SET(dr_action_hw_set, hw_action, 625 opcode, DR_STE_ACTION_MDFY_OP_SET); 626 MLX5_SET(dr_action_hw_set, hw_action, 627 destination_length, 0); 628 MLX5_SET(dr_action_hw_set, hw_action, 629 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_1); 630 MLX5_SET(dr_action_hw_set, hw_action, destination_left_shifter, 16); 631 hdr_fld_4b = (MLX5_GET(l2_hdr, l2_hdr, smac_31_0) >> 16 | 632 MLX5_GET(l2_hdr, l2_hdr, smac_47_32) << 16); 633 MLX5_SET(dr_action_hw_set, hw_action, inline_data, hdr_fld_4b); 634 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set); 635 636 /* dmac_15_0 */ 637 MLX5_SET(dr_action_hw_set, hw_action, 638 opcode, DR_STE_ACTION_MDFY_OP_SET); 639 MLX5_SET(dr_action_hw_set, hw_action, 640 destination_length, 16); 641 MLX5_SET(dr_action_hw_set, hw_action, 642 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_0); 643 MLX5_SET(dr_action_hw_set, hw_action, 644 destination_left_shifter, 0); 645 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, dmac_15_0); 646 MLX5_SET(dr_action_hw_set, hw_action, 647 inline_data, hdr_fld_2b); 648 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set); 649 650 /* ethertype + (optional) vlan */ 651 MLX5_SET(dr_action_hw_set, hw_action, 652 opcode, DR_STE_ACTION_MDFY_OP_SET); 653 MLX5_SET(dr_action_hw_set, hw_action, 654 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_2); 655 MLX5_SET(dr_action_hw_set, hw_action, 656 destination_left_shifter, 32); 657 if (!vlan) { 658 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, ethertype); 659 MLX5_SET(dr_action_hw_set, hw_action, inline_data, hdr_fld_2b); 660 MLX5_SET(dr_action_hw_set, hw_action, destination_length, 16); 661 } else { 662 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, ethertype); 663 vlan_type = hdr_fld_2b == SVLAN_ETHERTYPE ? DR_STE_SVLAN : DR_STE_CVLAN; 664 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, vlan); 665 hdr_fld_4b = (vlan_type << 16) | hdr_fld_2b; 666 MLX5_SET(dr_action_hw_set, hw_action, inline_data, hdr_fld_4b); 667 MLX5_SET(dr_action_hw_set, hw_action, destination_length, 18); 668 } 669 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set); 670 671 /* smac_15_0 */ 672 MLX5_SET(dr_action_hw_set, hw_action, 673 opcode, DR_STE_ACTION_MDFY_OP_SET); 674 MLX5_SET(dr_action_hw_set, hw_action, 675 destination_length, 16); 676 MLX5_SET(dr_action_hw_set, hw_action, 677 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_1); 678 MLX5_SET(dr_action_hw_set, hw_action, 679 destination_left_shifter, 0); 680 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, smac_31_0); 681 MLX5_SET(dr_action_hw_set, hw_action, inline_data, hdr_fld_2b); 682 hw_action += MLX5_ST_SZ_BYTES(dr_action_hw_set); 683 684 if (vlan) { 685 MLX5_SET(dr_action_hw_set, hw_action, 686 opcode, DR_STE_ACTION_MDFY_OP_SET); 687 hdr_fld_2b = MLX5_GET(l2_hdr, l2_hdr, vlan_type); 688 MLX5_SET(dr_action_hw_set, hw_action, 689 inline_data, hdr_fld_2b); 690 MLX5_SET(dr_action_hw_set, hw_action, 691 destination_length, 16); 692 MLX5_SET(dr_action_hw_set, hw_action, 693 destination_field_code, DR_STE_V0_ACTION_MDFY_FLD_L2_2); 694 MLX5_SET(dr_action_hw_set, hw_action, 695 destination_left_shifter, 0); 696 } 697 698 *used_hw_action_num = required_actions; 699 700 return 0; 701} 702 703static void 704dr_ste_v0_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value, 705 bool inner, u8 *bit_mask) 706{ 707 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 708 709 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_47_16, mask, dmac_47_16); 710 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_15_0, mask, dmac_15_0); 711 712 if (mask->smac_47_16 || mask->smac_15_0) { 713 MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_47_32, 714 mask->smac_47_16 >> 16); 715 MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_31_0, 716 mask->smac_47_16 << 16 | mask->smac_15_0); 717 mask->smac_47_16 = 0; 718 mask->smac_15_0 = 0; 719 } 720 721 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_vlan_id, mask, first_vid); 722 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_cfi, mask, first_cfi); 723 DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_priority, mask, first_prio); 724 DR_STE_SET_ONES(eth_l2_src_dst, bit_mask, l3_type, mask, ip_version); 725 726 if (mask->cvlan_tag) { 727 MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1); 728 mask->cvlan_tag = 0; 729 } else if (mask->svlan_tag) { 730 MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1); 731 mask->svlan_tag = 0; 732 } 733} 734 735static int 736dr_ste_v0_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value, 737 struct mlx5dr_ste_build *sb, 738 u8 *tag) 739{ 740 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 741 742 DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_47_16, spec, dmac_47_16); 743 DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_15_0, spec, dmac_15_0); 744 745 if (spec->smac_47_16 || spec->smac_15_0) { 746 MLX5_SET(ste_eth_l2_src_dst, tag, smac_47_32, 747 spec->smac_47_16 >> 16); 748 MLX5_SET(ste_eth_l2_src_dst, tag, smac_31_0, 749 spec->smac_47_16 << 16 | spec->smac_15_0); 750 spec->smac_47_16 = 0; 751 spec->smac_15_0 = 0; 752 } 753 754 if (spec->ip_version) { 755 if (spec->ip_version == IP_VERSION_IPV4) { 756 MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV4); 757 spec->ip_version = 0; 758 } else if (spec->ip_version == IP_VERSION_IPV6) { 759 MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV6); 760 spec->ip_version = 0; 761 } else { 762 return -EINVAL; 763 } 764 } 765 766 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_vlan_id, spec, first_vid); 767 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_cfi, spec, first_cfi); 768 DR_STE_SET_TAG(eth_l2_src_dst, tag, first_priority, spec, first_prio); 769 770 if (spec->cvlan_tag) { 771 MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_CVLAN); 772 spec->cvlan_tag = 0; 773 } else if (spec->svlan_tag) { 774 MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_SVLAN); 775 spec->svlan_tag = 0; 776 } 777 return 0; 778} 779 780static void 781dr_ste_v0_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb, 782 struct mlx5dr_match_param *mask) 783{ 784 dr_ste_v0_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask); 785 786 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC_DST, sb->rx, sb->inner); 787 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 788 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_dst_tag; 789} 790 791static int 792dr_ste_v0_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value, 793 struct mlx5dr_ste_build *sb, 794 u8 *tag) 795{ 796 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 797 798 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96); 799 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64); 800 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32); 801 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0); 802 803 return 0; 804} 805 806static void 807dr_ste_v0_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb, 808 struct mlx5dr_match_param *mask) 809{ 810 dr_ste_v0_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask); 811 812 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_DST, sb->rx, sb->inner); 813 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 814 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_dst_tag; 815} 816 817static int 818dr_ste_v0_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value, 819 struct mlx5dr_ste_build *sb, 820 u8 *tag) 821{ 822 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 823 824 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96); 825 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64); 826 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32); 827 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0); 828 829 return 0; 830} 831 832static void 833dr_ste_v0_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb, 834 struct mlx5dr_match_param *mask) 835{ 836 dr_ste_v0_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask); 837 838 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_SRC, sb->rx, sb->inner); 839 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 840 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_src_tag; 841} 842 843static int 844dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value, 845 struct mlx5dr_ste_build *sb, 846 u8 *tag) 847{ 848 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 849 850 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_address, spec, dst_ip_31_0); 851 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_address, spec, src_ip_31_0); 852 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, tcp_dport); 853 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, udp_dport); 854 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, tcp_sport); 855 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, udp_sport); 856 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, protocol, spec, ip_protocol); 857 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, fragmented, spec, frag); 858 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, dscp, spec, ip_dscp); 859 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, ecn, spec, ip_ecn); 860 861 if (spec->tcp_flags) { 862 DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, tag, spec); 863 spec->tcp_flags = 0; 864 } 865 866 return 0; 867} 868 869static void 870dr_ste_v0_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb, 871 struct mlx5dr_match_param *mask) 872{ 873 dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask); 874 875 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_5_TUPLE, sb->rx, sb->inner); 876 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 877 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag; 878} 879 880static void 881dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value, 882 bool inner, u8 *bit_mask) 883{ 884 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 885 struct mlx5dr_match_misc *misc_mask = &value->misc; 886 887 DR_STE_SET_TAG(eth_l2_src, bit_mask, first_vlan_id, mask, first_vid); 888 DR_STE_SET_TAG(eth_l2_src, bit_mask, first_cfi, mask, first_cfi); 889 DR_STE_SET_TAG(eth_l2_src, bit_mask, first_priority, mask, first_prio); 890 DR_STE_SET_TAG(eth_l2_src, bit_mask, ip_fragmented, mask, frag); 891 DR_STE_SET_TAG(eth_l2_src, bit_mask, l3_ethertype, mask, ethertype); 892 DR_STE_SET_ONES(eth_l2_src, bit_mask, l3_type, mask, ip_version); 893 894 if (mask->svlan_tag || mask->cvlan_tag) { 895 MLX5_SET(ste_eth_l2_src, bit_mask, first_vlan_qualifier, -1); 896 mask->cvlan_tag = 0; 897 mask->svlan_tag = 0; 898 } 899 900 if (inner) { 901 if (misc_mask->inner_second_cvlan_tag || 902 misc_mask->inner_second_svlan_tag) { 903 MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1); 904 misc_mask->inner_second_cvlan_tag = 0; 905 misc_mask->inner_second_svlan_tag = 0; 906 } 907 908 DR_STE_SET_TAG(eth_l2_src, bit_mask, 909 second_vlan_id, misc_mask, inner_second_vid); 910 DR_STE_SET_TAG(eth_l2_src, bit_mask, 911 second_cfi, misc_mask, inner_second_cfi); 912 DR_STE_SET_TAG(eth_l2_src, bit_mask, 913 second_priority, misc_mask, inner_second_prio); 914 } else { 915 if (misc_mask->outer_second_cvlan_tag || 916 misc_mask->outer_second_svlan_tag) { 917 MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1); 918 misc_mask->outer_second_cvlan_tag = 0; 919 misc_mask->outer_second_svlan_tag = 0; 920 } 921 922 DR_STE_SET_TAG(eth_l2_src, bit_mask, 923 second_vlan_id, misc_mask, outer_second_vid); 924 DR_STE_SET_TAG(eth_l2_src, bit_mask, 925 second_cfi, misc_mask, outer_second_cfi); 926 DR_STE_SET_TAG(eth_l2_src, bit_mask, 927 second_priority, misc_mask, outer_second_prio); 928 } 929} 930 931static int 932dr_ste_v0_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value, 933 bool inner, u8 *tag) 934{ 935 struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer; 936 struct mlx5dr_match_misc *misc_spec = &value->misc; 937 938 DR_STE_SET_TAG(eth_l2_src, tag, first_vlan_id, spec, first_vid); 939 DR_STE_SET_TAG(eth_l2_src, tag, first_cfi, spec, first_cfi); 940 DR_STE_SET_TAG(eth_l2_src, tag, first_priority, spec, first_prio); 941 DR_STE_SET_TAG(eth_l2_src, tag, ip_fragmented, spec, frag); 942 DR_STE_SET_TAG(eth_l2_src, tag, l3_ethertype, spec, ethertype); 943 944 if (spec->ip_version) { 945 if (spec->ip_version == IP_VERSION_IPV4) { 946 MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV4); 947 spec->ip_version = 0; 948 } else if (spec->ip_version == IP_VERSION_IPV6) { 949 MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV6); 950 spec->ip_version = 0; 951 } else { 952 return -EINVAL; 953 } 954 } 955 956 if (spec->cvlan_tag) { 957 MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_CVLAN); 958 spec->cvlan_tag = 0; 959 } else if (spec->svlan_tag) { 960 MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_SVLAN); 961 spec->svlan_tag = 0; 962 } 963 964 if (inner) { 965 if (misc_spec->inner_second_cvlan_tag) { 966 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN); 967 misc_spec->inner_second_cvlan_tag = 0; 968 } else if (misc_spec->inner_second_svlan_tag) { 969 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN); 970 misc_spec->inner_second_svlan_tag = 0; 971 } 972 973 DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, inner_second_vid); 974 DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, inner_second_cfi); 975 DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, inner_second_prio); 976 } else { 977 if (misc_spec->outer_second_cvlan_tag) { 978 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN); 979 misc_spec->outer_second_cvlan_tag = 0; 980 } else if (misc_spec->outer_second_svlan_tag) { 981 MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN); 982 misc_spec->outer_second_svlan_tag = 0; 983 } 984 DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, outer_second_vid); 985 DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, outer_second_cfi); 986 DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, outer_second_prio); 987 } 988 989 return 0; 990} 991 992static void 993dr_ste_v0_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value, 994 bool inner, u8 *bit_mask) 995{ 996 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 997 998 DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_47_16, mask, smac_47_16); 999 DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_15_0, mask, smac_15_0); 1000 1001 dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask); 1002} 1003 1004static int 1005dr_ste_v0_build_eth_l2_src_tag(struct mlx5dr_match_param *value, 1006 struct mlx5dr_ste_build *sb, 1007 u8 *tag) 1008{ 1009 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1010 1011 DR_STE_SET_TAG(eth_l2_src, tag, smac_47_16, spec, smac_47_16); 1012 DR_STE_SET_TAG(eth_l2_src, tag, smac_15_0, spec, smac_15_0); 1013 1014 return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 1015} 1016 1017static void 1018dr_ste_v0_build_eth_l2_src_init(struct mlx5dr_ste_build *sb, 1019 struct mlx5dr_match_param *mask) 1020{ 1021 dr_ste_v0_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask); 1022 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC, sb->rx, sb->inner); 1023 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1024 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_tag; 1025} 1026 1027static void 1028dr_ste_v0_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value, 1029 struct mlx5dr_ste_build *sb, 1030 u8 *bit_mask) 1031{ 1032 struct mlx5dr_match_spec *mask = sb->inner ? &value->inner : &value->outer; 1033 1034 DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_47_16, mask, dmac_47_16); 1035 DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_15_0, mask, dmac_15_0); 1036 1037 dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, sb->inner, bit_mask); 1038} 1039 1040static int 1041dr_ste_v0_build_eth_l2_dst_tag(struct mlx5dr_match_param *value, 1042 struct mlx5dr_ste_build *sb, 1043 u8 *tag) 1044{ 1045 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1046 1047 DR_STE_SET_TAG(eth_l2_dst, tag, dmac_47_16, spec, dmac_47_16); 1048 DR_STE_SET_TAG(eth_l2_dst, tag, dmac_15_0, spec, dmac_15_0); 1049 1050 return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 1051} 1052 1053static void 1054dr_ste_v0_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb, 1055 struct mlx5dr_match_param *mask) 1056{ 1057 dr_ste_v0_build_eth_l2_dst_bit_mask(mask, sb, sb->bit_mask); 1058 1059 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_DST, sb->rx, sb->inner); 1060 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1061 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_dst_tag; 1062} 1063 1064static void 1065dr_ste_v0_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value, 1066 bool inner, u8 *bit_mask) 1067{ 1068 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 1069 struct mlx5dr_match_misc *misc = &value->misc; 1070 1071 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_47_16, mask, dmac_47_16); 1072 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_15_0, mask, dmac_15_0); 1073 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_vlan_id, mask, first_vid); 1074 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_cfi, mask, first_cfi); 1075 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_priority, mask, first_prio); 1076 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, ip_fragmented, mask, frag); 1077 DR_STE_SET_TAG(eth_l2_tnl, bit_mask, l3_ethertype, mask, ethertype); 1078 DR_STE_SET_ONES(eth_l2_tnl, bit_mask, l3_type, mask, ip_version); 1079 1080 if (misc->vxlan_vni) { 1081 MLX5_SET(ste_eth_l2_tnl, bit_mask, 1082 l2_tunneling_network_id, (misc->vxlan_vni << 8)); 1083 misc->vxlan_vni = 0; 1084 } 1085 1086 if (mask->svlan_tag || mask->cvlan_tag) { 1087 MLX5_SET(ste_eth_l2_tnl, bit_mask, first_vlan_qualifier, -1); 1088 mask->cvlan_tag = 0; 1089 mask->svlan_tag = 0; 1090 } 1091} 1092 1093static int 1094dr_ste_v0_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value, 1095 struct mlx5dr_ste_build *sb, 1096 u8 *tag) 1097{ 1098 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1099 struct mlx5dr_match_misc *misc = &value->misc; 1100 1101 DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_47_16, spec, dmac_47_16); 1102 DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_15_0, spec, dmac_15_0); 1103 DR_STE_SET_TAG(eth_l2_tnl, tag, first_vlan_id, spec, first_vid); 1104 DR_STE_SET_TAG(eth_l2_tnl, tag, first_cfi, spec, first_cfi); 1105 DR_STE_SET_TAG(eth_l2_tnl, tag, ip_fragmented, spec, frag); 1106 DR_STE_SET_TAG(eth_l2_tnl, tag, first_priority, spec, first_prio); 1107 DR_STE_SET_TAG(eth_l2_tnl, tag, l3_ethertype, spec, ethertype); 1108 1109 if (misc->vxlan_vni) { 1110 MLX5_SET(ste_eth_l2_tnl, tag, l2_tunneling_network_id, 1111 (misc->vxlan_vni << 8)); 1112 misc->vxlan_vni = 0; 1113 } 1114 1115 if (spec->cvlan_tag) { 1116 MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_CVLAN); 1117 spec->cvlan_tag = 0; 1118 } else if (spec->svlan_tag) { 1119 MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_SVLAN); 1120 spec->svlan_tag = 0; 1121 } 1122 1123 if (spec->ip_version) { 1124 if (spec->ip_version == IP_VERSION_IPV4) { 1125 MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV4); 1126 spec->ip_version = 0; 1127 } else if (spec->ip_version == IP_VERSION_IPV6) { 1128 MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV6); 1129 spec->ip_version = 0; 1130 } else { 1131 return -EINVAL; 1132 } 1133 } 1134 1135 return 0; 1136} 1137 1138static void 1139dr_ste_v0_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb, 1140 struct mlx5dr_match_param *mask) 1141{ 1142 dr_ste_v0_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask); 1143 1144 sb->lu_type = DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I; 1145 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1146 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_tnl_tag; 1147} 1148 1149static int 1150dr_ste_v0_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value, 1151 struct mlx5dr_ste_build *sb, 1152 u8 *tag) 1153{ 1154 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1155 1156 DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, time_to_live, spec, ttl_hoplimit); 1157 DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, ihl, spec, ipv4_ihl); 1158 1159 return 0; 1160} 1161 1162static void 1163dr_ste_v0_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb, 1164 struct mlx5dr_match_param *mask) 1165{ 1166 dr_ste_v0_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask); 1167 1168 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_MISC, sb->rx, sb->inner); 1169 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1170 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_misc_tag; 1171} 1172 1173static int 1174dr_ste_v0_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value, 1175 struct mlx5dr_ste_build *sb, 1176 u8 *tag) 1177{ 1178 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1179 struct mlx5dr_match_misc *misc = &value->misc; 1180 1181 DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, tcp_dport); 1182 DR_STE_SET_TAG(eth_l4, tag, src_port, spec, tcp_sport); 1183 DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, udp_dport); 1184 DR_STE_SET_TAG(eth_l4, tag, src_port, spec, udp_sport); 1185 DR_STE_SET_TAG(eth_l4, tag, protocol, spec, ip_protocol); 1186 DR_STE_SET_TAG(eth_l4, tag, fragmented, spec, frag); 1187 DR_STE_SET_TAG(eth_l4, tag, dscp, spec, ip_dscp); 1188 DR_STE_SET_TAG(eth_l4, tag, ecn, spec, ip_ecn); 1189 DR_STE_SET_TAG(eth_l4, tag, ipv6_hop_limit, spec, ttl_hoplimit); 1190 1191 if (sb->inner) 1192 DR_STE_SET_TAG(eth_l4, tag, flow_label, misc, inner_ipv6_flow_label); 1193 else 1194 DR_STE_SET_TAG(eth_l4, tag, flow_label, misc, outer_ipv6_flow_label); 1195 1196 if (spec->tcp_flags) { 1197 DR_STE_SET_TCP_FLAGS(eth_l4, tag, spec); 1198 spec->tcp_flags = 0; 1199 } 1200 1201 return 0; 1202} 1203 1204static void 1205dr_ste_v0_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb, 1206 struct mlx5dr_match_param *mask) 1207{ 1208 dr_ste_v0_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask); 1209 1210 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4, sb->rx, sb->inner); 1211 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1212 sb->ste_build_tag_func = &dr_ste_v0_build_eth_ipv6_l3_l4_tag; 1213} 1214 1215static int 1216dr_ste_v0_build_mpls_tag(struct mlx5dr_match_param *value, 1217 struct mlx5dr_ste_build *sb, 1218 u8 *tag) 1219{ 1220 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1221 1222 if (sb->inner) 1223 DR_STE_SET_MPLS(mpls, misc2, inner, tag); 1224 else 1225 DR_STE_SET_MPLS(mpls, misc2, outer, tag); 1226 1227 return 0; 1228} 1229 1230static void 1231dr_ste_v0_build_mpls_init(struct mlx5dr_ste_build *sb, 1232 struct mlx5dr_match_param *mask) 1233{ 1234 dr_ste_v0_build_mpls_tag(mask, sb, sb->bit_mask); 1235 1236 sb->lu_type = DR_STE_CALC_LU_TYPE(MPLS_FIRST, sb->rx, sb->inner); 1237 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1238 sb->ste_build_tag_func = &dr_ste_v0_build_mpls_tag; 1239} 1240 1241static int 1242dr_ste_v0_build_tnl_gre_tag(struct mlx5dr_match_param *value, 1243 struct mlx5dr_ste_build *sb, 1244 u8 *tag) 1245{ 1246 struct mlx5dr_match_misc *misc = &value->misc; 1247 1248 DR_STE_SET_TAG(gre, tag, gre_protocol, misc, gre_protocol); 1249 1250 DR_STE_SET_TAG(gre, tag, gre_k_present, misc, gre_k_present); 1251 DR_STE_SET_TAG(gre, tag, gre_key_h, misc, gre_key_h); 1252 DR_STE_SET_TAG(gre, tag, gre_key_l, misc, gre_key_l); 1253 1254 DR_STE_SET_TAG(gre, tag, gre_c_present, misc, gre_c_present); 1255 1256 DR_STE_SET_TAG(gre, tag, gre_s_present, misc, gre_s_present); 1257 1258 return 0; 1259} 1260 1261static void 1262dr_ste_v0_build_tnl_gre_init(struct mlx5dr_ste_build *sb, 1263 struct mlx5dr_match_param *mask) 1264{ 1265 dr_ste_v0_build_tnl_gre_tag(mask, sb, sb->bit_mask); 1266 1267 sb->lu_type = DR_STE_V0_LU_TYPE_GRE; 1268 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1269 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gre_tag; 1270} 1271 1272static int 1273dr_ste_v0_build_tnl_mpls_tag(struct mlx5dr_match_param *value, 1274 struct mlx5dr_ste_build *sb, 1275 u8 *tag) 1276{ 1277 struct mlx5dr_match_misc2 *misc_2 = &value->misc2; 1278 u32 mpls_hdr; 1279 1280 if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2)) { 1281 mpls_hdr = misc_2->outer_first_mpls_over_gre_label << HDR_MPLS_OFFSET_LABEL; 1282 misc_2->outer_first_mpls_over_gre_label = 0; 1283 mpls_hdr |= misc_2->outer_first_mpls_over_gre_exp << HDR_MPLS_OFFSET_EXP; 1284 misc_2->outer_first_mpls_over_gre_exp = 0; 1285 mpls_hdr |= misc_2->outer_first_mpls_over_gre_s_bos << HDR_MPLS_OFFSET_S_BOS; 1286 misc_2->outer_first_mpls_over_gre_s_bos = 0; 1287 mpls_hdr |= misc_2->outer_first_mpls_over_gre_ttl << HDR_MPLS_OFFSET_TTL; 1288 misc_2->outer_first_mpls_over_gre_ttl = 0; 1289 } else { 1290 mpls_hdr = misc_2->outer_first_mpls_over_udp_label << HDR_MPLS_OFFSET_LABEL; 1291 misc_2->outer_first_mpls_over_udp_label = 0; 1292 mpls_hdr |= misc_2->outer_first_mpls_over_udp_exp << HDR_MPLS_OFFSET_EXP; 1293 misc_2->outer_first_mpls_over_udp_exp = 0; 1294 mpls_hdr |= misc_2->outer_first_mpls_over_udp_s_bos << HDR_MPLS_OFFSET_S_BOS; 1295 misc_2->outer_first_mpls_over_udp_s_bos = 0; 1296 mpls_hdr |= misc_2->outer_first_mpls_over_udp_ttl << HDR_MPLS_OFFSET_TTL; 1297 misc_2->outer_first_mpls_over_udp_ttl = 0; 1298 } 1299 1300 MLX5_SET(ste_flex_parser_0, tag, flex_parser_3, mpls_hdr); 1301 return 0; 1302} 1303 1304static void 1305dr_ste_v0_build_tnl_mpls_init(struct mlx5dr_ste_build *sb, 1306 struct mlx5dr_match_param *mask) 1307{ 1308 dr_ste_v0_build_tnl_mpls_tag(mask, sb, sb->bit_mask); 1309 1310 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 1311 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1312 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_tag; 1313} 1314 1315static int 1316dr_ste_v0_build_tnl_mpls_over_udp_tag(struct mlx5dr_match_param *value, 1317 struct mlx5dr_ste_build *sb, 1318 u8 *tag) 1319{ 1320 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1321 u8 *parser_ptr; 1322 u8 parser_id; 1323 u32 mpls_hdr; 1324 1325 mpls_hdr = misc2->outer_first_mpls_over_udp_label << HDR_MPLS_OFFSET_LABEL; 1326 misc2->outer_first_mpls_over_udp_label = 0; 1327 mpls_hdr |= misc2->outer_first_mpls_over_udp_exp << HDR_MPLS_OFFSET_EXP; 1328 misc2->outer_first_mpls_over_udp_exp = 0; 1329 mpls_hdr |= misc2->outer_first_mpls_over_udp_s_bos << HDR_MPLS_OFFSET_S_BOS; 1330 misc2->outer_first_mpls_over_udp_s_bos = 0; 1331 mpls_hdr |= misc2->outer_first_mpls_over_udp_ttl << HDR_MPLS_OFFSET_TTL; 1332 misc2->outer_first_mpls_over_udp_ttl = 0; 1333 1334 parser_id = sb->caps->flex_parser_id_mpls_over_udp; 1335 parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id); 1336 *(__be32 *)parser_ptr = cpu_to_be32(mpls_hdr); 1337 1338 return 0; 1339} 1340 1341static void 1342dr_ste_v0_build_tnl_mpls_over_udp_init(struct mlx5dr_ste_build *sb, 1343 struct mlx5dr_match_param *mask) 1344{ 1345 dr_ste_v0_build_tnl_mpls_over_udp_tag(mask, sb, sb->bit_mask); 1346 /* STEs with lookup type FLEX_PARSER_{0/1} includes 1347 * flex parsers_{0-3}/{4-7} respectively. 1348 */ 1349 sb->lu_type = sb->caps->flex_parser_id_mpls_over_udp > DR_STE_MAX_FLEX_0_ID ? 1350 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 : 1351 DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 1352 1353 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1354 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_over_udp_tag; 1355} 1356 1357static int 1358dr_ste_v0_build_tnl_mpls_over_gre_tag(struct mlx5dr_match_param *value, 1359 struct mlx5dr_ste_build *sb, 1360 u8 *tag) 1361{ 1362 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1363 u8 *parser_ptr; 1364 u8 parser_id; 1365 u32 mpls_hdr; 1366 1367 mpls_hdr = misc2->outer_first_mpls_over_gre_label << HDR_MPLS_OFFSET_LABEL; 1368 misc2->outer_first_mpls_over_gre_label = 0; 1369 mpls_hdr |= misc2->outer_first_mpls_over_gre_exp << HDR_MPLS_OFFSET_EXP; 1370 misc2->outer_first_mpls_over_gre_exp = 0; 1371 mpls_hdr |= misc2->outer_first_mpls_over_gre_s_bos << HDR_MPLS_OFFSET_S_BOS; 1372 misc2->outer_first_mpls_over_gre_s_bos = 0; 1373 mpls_hdr |= misc2->outer_first_mpls_over_gre_ttl << HDR_MPLS_OFFSET_TTL; 1374 misc2->outer_first_mpls_over_gre_ttl = 0; 1375 1376 parser_id = sb->caps->flex_parser_id_mpls_over_gre; 1377 parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id); 1378 *(__be32 *)parser_ptr = cpu_to_be32(mpls_hdr); 1379 1380 return 0; 1381} 1382 1383static void 1384dr_ste_v0_build_tnl_mpls_over_gre_init(struct mlx5dr_ste_build *sb, 1385 struct mlx5dr_match_param *mask) 1386{ 1387 dr_ste_v0_build_tnl_mpls_over_gre_tag(mask, sb, sb->bit_mask); 1388 1389 /* STEs with lookup type FLEX_PARSER_{0/1} includes 1390 * flex parsers_{0-3}/{4-7} respectively. 1391 */ 1392 sb->lu_type = sb->caps->flex_parser_id_mpls_over_gre > DR_STE_MAX_FLEX_0_ID ? 1393 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 : 1394 DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 1395 1396 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1397 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_over_gre_tag; 1398} 1399 1400#define ICMP_TYPE_OFFSET_FIRST_DW 24 1401#define ICMP_CODE_OFFSET_FIRST_DW 16 1402 1403static int 1404dr_ste_v0_build_icmp_tag(struct mlx5dr_match_param *value, 1405 struct mlx5dr_ste_build *sb, 1406 u8 *tag) 1407{ 1408 struct mlx5dr_match_misc3 *misc_3 = &value->misc3; 1409 u32 *icmp_header_data; 1410 int dw0_location; 1411 int dw1_location; 1412 u8 *parser_ptr; 1413 u8 *icmp_type; 1414 u8 *icmp_code; 1415 bool is_ipv4; 1416 u32 icmp_hdr; 1417 1418 is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc_3); 1419 if (is_ipv4) { 1420 icmp_header_data = &misc_3->icmpv4_header_data; 1421 icmp_type = &misc_3->icmpv4_type; 1422 icmp_code = &misc_3->icmpv4_code; 1423 dw0_location = sb->caps->flex_parser_id_icmp_dw0; 1424 dw1_location = sb->caps->flex_parser_id_icmp_dw1; 1425 } else { 1426 icmp_header_data = &misc_3->icmpv6_header_data; 1427 icmp_type = &misc_3->icmpv6_type; 1428 icmp_code = &misc_3->icmpv6_code; 1429 dw0_location = sb->caps->flex_parser_id_icmpv6_dw0; 1430 dw1_location = sb->caps->flex_parser_id_icmpv6_dw1; 1431 } 1432 1433 parser_ptr = dr_ste_calc_flex_parser_offset(tag, dw0_location); 1434 icmp_hdr = (*icmp_type << ICMP_TYPE_OFFSET_FIRST_DW) | 1435 (*icmp_code << ICMP_CODE_OFFSET_FIRST_DW); 1436 *(__be32 *)parser_ptr = cpu_to_be32(icmp_hdr); 1437 *icmp_code = 0; 1438 *icmp_type = 0; 1439 1440 parser_ptr = dr_ste_calc_flex_parser_offset(tag, dw1_location); 1441 *(__be32 *)parser_ptr = cpu_to_be32(*icmp_header_data); 1442 *icmp_header_data = 0; 1443 1444 return 0; 1445} 1446 1447static void 1448dr_ste_v0_build_icmp_init(struct mlx5dr_ste_build *sb, 1449 struct mlx5dr_match_param *mask) 1450{ 1451 u8 parser_id; 1452 bool is_ipv4; 1453 1454 dr_ste_v0_build_icmp_tag(mask, sb, sb->bit_mask); 1455 1456 /* STEs with lookup type FLEX_PARSER_{0/1} includes 1457 * flex parsers_{0-3}/{4-7} respectively. 1458 */ 1459 is_ipv4 = DR_MASK_IS_ICMPV4_SET(&mask->misc3); 1460 parser_id = is_ipv4 ? sb->caps->flex_parser_id_icmp_dw0 : 1461 sb->caps->flex_parser_id_icmpv6_dw0; 1462 sb->lu_type = parser_id > DR_STE_MAX_FLEX_0_ID ? 1463 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 : 1464 DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 1465 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1466 sb->ste_build_tag_func = &dr_ste_v0_build_icmp_tag; 1467} 1468 1469static int 1470dr_ste_v0_build_general_purpose_tag(struct mlx5dr_match_param *value, 1471 struct mlx5dr_ste_build *sb, 1472 u8 *tag) 1473{ 1474 struct mlx5dr_match_misc2 *misc_2 = &value->misc2; 1475 1476 DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field, 1477 misc_2, metadata_reg_a); 1478 1479 return 0; 1480} 1481 1482static void 1483dr_ste_v0_build_general_purpose_init(struct mlx5dr_ste_build *sb, 1484 struct mlx5dr_match_param *mask) 1485{ 1486 dr_ste_v0_build_general_purpose_tag(mask, sb, sb->bit_mask); 1487 1488 sb->lu_type = DR_STE_V0_LU_TYPE_GENERAL_PURPOSE; 1489 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1490 sb->ste_build_tag_func = &dr_ste_v0_build_general_purpose_tag; 1491} 1492 1493static int 1494dr_ste_v0_build_eth_l4_misc_tag(struct mlx5dr_match_param *value, 1495 struct mlx5dr_ste_build *sb, 1496 u8 *tag) 1497{ 1498 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1499 1500 if (sb->inner) { 1501 DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, inner_tcp_seq_num); 1502 DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, inner_tcp_ack_num); 1503 } else { 1504 DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, outer_tcp_seq_num); 1505 DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, outer_tcp_ack_num); 1506 } 1507 1508 return 0; 1509} 1510 1511static void 1512dr_ste_v0_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb, 1513 struct mlx5dr_match_param *mask) 1514{ 1515 dr_ste_v0_build_eth_l4_misc_tag(mask, sb, sb->bit_mask); 1516 1517 sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4_MISC, sb->rx, sb->inner); 1518 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1519 sb->ste_build_tag_func = &dr_ste_v0_build_eth_l4_misc_tag; 1520} 1521 1522static int 1523dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value, 1524 struct mlx5dr_ste_build *sb, 1525 u8 *tag) 1526{ 1527 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1528 1529 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1530 outer_vxlan_gpe_flags, misc3, 1531 outer_vxlan_gpe_flags); 1532 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1533 outer_vxlan_gpe_next_protocol, misc3, 1534 outer_vxlan_gpe_next_protocol); 1535 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1536 outer_vxlan_gpe_vni, misc3, 1537 outer_vxlan_gpe_vni); 1538 1539 return 0; 1540} 1541 1542static void 1543dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb, 1544 struct mlx5dr_match_param *mask) 1545{ 1546 dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask); 1547 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER; 1548 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1549 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag; 1550} 1551 1552static int 1553dr_ste_v0_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value, 1554 struct mlx5dr_ste_build *sb, 1555 u8 *tag) 1556{ 1557 struct mlx5dr_match_misc *misc = &value->misc; 1558 1559 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1560 geneve_protocol_type, misc, geneve_protocol_type); 1561 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1562 geneve_oam, misc, geneve_oam); 1563 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1564 geneve_opt_len, misc, geneve_opt_len); 1565 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1566 geneve_vni, misc, geneve_vni); 1567 1568 return 0; 1569} 1570 1571static void 1572dr_ste_v0_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb, 1573 struct mlx5dr_match_param *mask) 1574{ 1575 dr_ste_v0_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask); 1576 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER; 1577 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1578 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tag; 1579} 1580 1581static int 1582dr_ste_v0_build_register_0_tag(struct mlx5dr_match_param *value, 1583 struct mlx5dr_ste_build *sb, 1584 u8 *tag) 1585{ 1586 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1587 1588 DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0); 1589 DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1); 1590 DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2); 1591 DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3); 1592 1593 return 0; 1594} 1595 1596static void 1597dr_ste_v0_build_register_0_init(struct mlx5dr_ste_build *sb, 1598 struct mlx5dr_match_param *mask) 1599{ 1600 dr_ste_v0_build_register_0_tag(mask, sb, sb->bit_mask); 1601 1602 sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0; 1603 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1604 sb->ste_build_tag_func = &dr_ste_v0_build_register_0_tag; 1605} 1606 1607static int 1608dr_ste_v0_build_register_1_tag(struct mlx5dr_match_param *value, 1609 struct mlx5dr_ste_build *sb, 1610 u8 *tag) 1611{ 1612 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1613 1614 DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4); 1615 DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5); 1616 DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6); 1617 DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7); 1618 1619 return 0; 1620} 1621 1622static void 1623dr_ste_v0_build_register_1_init(struct mlx5dr_ste_build *sb, 1624 struct mlx5dr_match_param *mask) 1625{ 1626 dr_ste_v0_build_register_1_tag(mask, sb, sb->bit_mask); 1627 1628 sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1; 1629 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1630 sb->ste_build_tag_func = &dr_ste_v0_build_register_1_tag; 1631} 1632 1633static void 1634dr_ste_v0_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value, 1635 u8 *bit_mask) 1636{ 1637 struct mlx5dr_match_misc *misc_mask = &value->misc; 1638 1639 DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_gvmi, misc_mask, source_port); 1640 DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_qp, misc_mask, source_sqn); 1641 misc_mask->source_eswitch_owner_vhca_id = 0; 1642} 1643 1644static int 1645dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, 1646 struct mlx5dr_ste_build *sb, 1647 u8 *tag) 1648{ 1649 struct mlx5dr_match_misc *misc = &value->misc; 1650 int id = misc->source_eswitch_owner_vhca_id; 1651 struct mlx5dr_cmd_vport_cap *vport_cap; 1652 struct mlx5dr_domain *dmn = sb->dmn; 1653 struct mlx5dr_domain *vport_dmn; 1654 u8 *bit_mask = sb->bit_mask; 1655 struct mlx5dr_domain *peer; 1656 bool source_gvmi_set; 1657 1658 DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn); 1659 1660 if (sb->vhca_id_valid) { 1661 peer = xa_load(&dmn->peer_dmn_xa, id); 1662 /* Find port GVMI based on the eswitch_owner_vhca_id */ 1663 if (id == dmn->info.caps.gvmi) 1664 vport_dmn = dmn; 1665 else if (peer && (id == peer->info.caps.gvmi)) 1666 vport_dmn = peer; 1667 else 1668 return -EINVAL; 1669 1670 misc->source_eswitch_owner_vhca_id = 0; 1671 } else { 1672 vport_dmn = dmn; 1673 } 1674 1675 source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi); 1676 if (source_gvmi_set) { 1677 vport_cap = mlx5dr_domain_get_vport_cap(vport_dmn, 1678 misc->source_port); 1679 if (!vport_cap) { 1680 mlx5dr_err(dmn, "Vport 0x%x is disabled or invalid\n", 1681 misc->source_port); 1682 return -EINVAL; 1683 } 1684 1685 if (vport_cap->vport_gvmi) 1686 MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi); 1687 1688 misc->source_port = 0; 1689 } 1690 1691 return 0; 1692} 1693 1694static void 1695dr_ste_v0_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb, 1696 struct mlx5dr_match_param *mask) 1697{ 1698 dr_ste_v0_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask); 1699 1700 sb->lu_type = DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP; 1701 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1702 sb->ste_build_tag_func = &dr_ste_v0_build_src_gvmi_qpn_tag; 1703} 1704 1705static void dr_ste_v0_set_flex_parser(u32 *misc4_field_id, 1706 u32 *misc4_field_value, 1707 bool *parser_is_used, 1708 u8 *tag) 1709{ 1710 u32 id = *misc4_field_id; 1711 u8 *parser_ptr; 1712 1713 if (id >= DR_NUM_OF_FLEX_PARSERS || parser_is_used[id]) 1714 return; 1715 1716 parser_is_used[id] = true; 1717 parser_ptr = dr_ste_calc_flex_parser_offset(tag, id); 1718 1719 *(__be32 *)parser_ptr = cpu_to_be32(*misc4_field_value); 1720 *misc4_field_id = 0; 1721 *misc4_field_value = 0; 1722} 1723 1724static int dr_ste_v0_build_flex_parser_tag(struct mlx5dr_match_param *value, 1725 struct mlx5dr_ste_build *sb, 1726 u8 *tag) 1727{ 1728 struct mlx5dr_match_misc4 *misc_4_mask = &value->misc4; 1729 bool parser_is_used[DR_NUM_OF_FLEX_PARSERS] = {}; 1730 1731 dr_ste_v0_set_flex_parser(&misc_4_mask->prog_sample_field_id_0, 1732 &misc_4_mask->prog_sample_field_value_0, 1733 parser_is_used, tag); 1734 1735 dr_ste_v0_set_flex_parser(&misc_4_mask->prog_sample_field_id_1, 1736 &misc_4_mask->prog_sample_field_value_1, 1737 parser_is_used, tag); 1738 1739 dr_ste_v0_set_flex_parser(&misc_4_mask->prog_sample_field_id_2, 1740 &misc_4_mask->prog_sample_field_value_2, 1741 parser_is_used, tag); 1742 1743 dr_ste_v0_set_flex_parser(&misc_4_mask->prog_sample_field_id_3, 1744 &misc_4_mask->prog_sample_field_value_3, 1745 parser_is_used, tag); 1746 1747 return 0; 1748} 1749 1750static void dr_ste_v0_build_flex_parser_0_init(struct mlx5dr_ste_build *sb, 1751 struct mlx5dr_match_param *mask) 1752{ 1753 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 1754 dr_ste_v0_build_flex_parser_tag(mask, sb, sb->bit_mask); 1755 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1756 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tag; 1757} 1758 1759static void dr_ste_v0_build_flex_parser_1_init(struct mlx5dr_ste_build *sb, 1760 struct mlx5dr_match_param *mask) 1761{ 1762 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_1; 1763 dr_ste_v0_build_flex_parser_tag(mask, sb, sb->bit_mask); 1764 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1765 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tag; 1766} 1767 1768static int 1769dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_tag(struct mlx5dr_match_param *value, 1770 struct mlx5dr_ste_build *sb, 1771 u8 *tag) 1772{ 1773 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1774 u8 parser_id = sb->caps->flex_parser_id_geneve_tlv_option_0; 1775 u8 *parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id); 1776 1777 MLX5_SET(ste_flex_parser_0, parser_ptr, flex_parser_3, 1778 misc3->geneve_tlv_option_0_data); 1779 misc3->geneve_tlv_option_0_data = 0; 1780 1781 return 0; 1782} 1783 1784static void 1785dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_init(struct mlx5dr_ste_build *sb, 1786 struct mlx5dr_match_param *mask) 1787{ 1788 dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_tag(mask, sb, sb->bit_mask); 1789 1790 /* STEs with lookup type FLEX_PARSER_{0/1} includes 1791 * flex parsers_{0-3}/{4-7} respectively. 1792 */ 1793 sb->lu_type = sb->caps->flex_parser_id_geneve_tlv_option_0 > 3 ? 1794 DR_STE_V0_LU_TYPE_FLEX_PARSER_1 : 1795 DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 1796 1797 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1798 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_tag; 1799} 1800 1801static int dr_ste_v0_build_flex_parser_tnl_gtpu_tag(struct mlx5dr_match_param *value, 1802 struct mlx5dr_ste_build *sb, 1803 u8 *tag) 1804{ 1805 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1806 1807 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, 1808 gtpu_msg_flags, misc3, 1809 gtpu_msg_flags); 1810 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, 1811 gtpu_msg_type, misc3, 1812 gtpu_msg_type); 1813 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, 1814 gtpu_teid, misc3, 1815 gtpu_teid); 1816 1817 return 0; 1818} 1819 1820static void dr_ste_v0_build_flex_parser_tnl_gtpu_init(struct mlx5dr_ste_build *sb, 1821 struct mlx5dr_match_param *mask) 1822{ 1823 dr_ste_v0_build_flex_parser_tnl_gtpu_tag(mask, sb, sb->bit_mask); 1824 1825 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER; 1826 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1827 sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_gtpu_tag; 1828} 1829 1830static int 1831dr_ste_v0_build_tnl_gtpu_flex_parser_0_tag(struct mlx5dr_match_param *value, 1832 struct mlx5dr_ste_build *sb, 1833 u8 *tag) 1834{ 1835 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_dw_0)) 1836 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_0, sb->caps, &value->misc3); 1837 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_teid)) 1838 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_teid, sb->caps, &value->misc3); 1839 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_dw_2)) 1840 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_2, sb->caps, &value->misc3); 1841 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_first_ext_dw_0)) 1842 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_first_ext_dw_0, sb->caps, &value->misc3); 1843 return 0; 1844} 1845 1846static void 1847dr_ste_v0_build_tnl_gtpu_flex_parser_0_init(struct mlx5dr_ste_build *sb, 1848 struct mlx5dr_match_param *mask) 1849{ 1850 dr_ste_v0_build_tnl_gtpu_flex_parser_0_tag(mask, sb, sb->bit_mask); 1851 1852 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0; 1853 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1854 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gtpu_flex_parser_0_tag; 1855} 1856 1857static int 1858dr_ste_v0_build_tnl_gtpu_flex_parser_1_tag(struct mlx5dr_match_param *value, 1859 struct mlx5dr_ste_build *sb, 1860 u8 *tag) 1861{ 1862 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_dw_0)) 1863 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_0, sb->caps, &value->misc3); 1864 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_teid)) 1865 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_teid, sb->caps, &value->misc3); 1866 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_dw_2)) 1867 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_2, sb->caps, &value->misc3); 1868 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_first_ext_dw_0)) 1869 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_first_ext_dw_0, sb->caps, &value->misc3); 1870 return 0; 1871} 1872 1873static void 1874dr_ste_v0_build_tnl_gtpu_flex_parser_1_init(struct mlx5dr_ste_build *sb, 1875 struct mlx5dr_match_param *mask) 1876{ 1877 dr_ste_v0_build_tnl_gtpu_flex_parser_1_tag(mask, sb, sb->bit_mask); 1878 1879 sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_1; 1880 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1881 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gtpu_flex_parser_1_tag; 1882} 1883 1884static int dr_ste_v0_build_tnl_header_0_1_tag(struct mlx5dr_match_param *value, 1885 struct mlx5dr_ste_build *sb, 1886 uint8_t *tag) 1887{ 1888 struct mlx5dr_match_misc5 *misc5 = &value->misc5; 1889 1890 DR_STE_SET_TAG(tunnel_header, tag, tunnel_header_0, misc5, tunnel_header_0); 1891 DR_STE_SET_TAG(tunnel_header, tag, tunnel_header_1, misc5, tunnel_header_1); 1892 1893 return 0; 1894} 1895 1896static void dr_ste_v0_build_tnl_header_0_1_init(struct mlx5dr_ste_build *sb, 1897 struct mlx5dr_match_param *mask) 1898{ 1899 sb->lu_type = DR_STE_V0_LU_TYPE_TUNNEL_HEADER; 1900 dr_ste_v0_build_tnl_header_0_1_tag(mask, sb, sb->bit_mask); 1901 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1902 sb->ste_build_tag_func = &dr_ste_v0_build_tnl_header_0_1_tag; 1903} 1904 1905static struct mlx5dr_ste_ctx ste_ctx_v0 = { 1906 /* Builders */ 1907 .build_eth_l2_src_dst_init = &dr_ste_v0_build_eth_l2_src_dst_init, 1908 .build_eth_l3_ipv6_src_init = &dr_ste_v0_build_eth_l3_ipv6_src_init, 1909 .build_eth_l3_ipv6_dst_init = &dr_ste_v0_build_eth_l3_ipv6_dst_init, 1910 .build_eth_l3_ipv4_5_tuple_init = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_init, 1911 .build_eth_l2_src_init = &dr_ste_v0_build_eth_l2_src_init, 1912 .build_eth_l2_dst_init = &dr_ste_v0_build_eth_l2_dst_init, 1913 .build_eth_l2_tnl_init = &dr_ste_v0_build_eth_l2_tnl_init, 1914 .build_eth_l3_ipv4_misc_init = &dr_ste_v0_build_eth_l3_ipv4_misc_init, 1915 .build_eth_ipv6_l3_l4_init = &dr_ste_v0_build_eth_ipv6_l3_l4_init, 1916 .build_mpls_init = &dr_ste_v0_build_mpls_init, 1917 .build_tnl_gre_init = &dr_ste_v0_build_tnl_gre_init, 1918 .build_tnl_mpls_init = &dr_ste_v0_build_tnl_mpls_init, 1919 .build_tnl_mpls_over_udp_init = &dr_ste_v0_build_tnl_mpls_over_udp_init, 1920 .build_tnl_mpls_over_gre_init = &dr_ste_v0_build_tnl_mpls_over_gre_init, 1921 .build_icmp_init = &dr_ste_v0_build_icmp_init, 1922 .build_general_purpose_init = &dr_ste_v0_build_general_purpose_init, 1923 .build_eth_l4_misc_init = &dr_ste_v0_build_eth_l4_misc_init, 1924 .build_tnl_vxlan_gpe_init = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init, 1925 .build_tnl_geneve_init = &dr_ste_v0_build_flex_parser_tnl_geneve_init, 1926 .build_tnl_geneve_tlv_opt_init = &dr_ste_v0_build_flex_parser_tnl_geneve_tlv_opt_init, 1927 .build_register_0_init = &dr_ste_v0_build_register_0_init, 1928 .build_register_1_init = &dr_ste_v0_build_register_1_init, 1929 .build_src_gvmi_qpn_init = &dr_ste_v0_build_src_gvmi_qpn_init, 1930 .build_flex_parser_0_init = &dr_ste_v0_build_flex_parser_0_init, 1931 .build_flex_parser_1_init = &dr_ste_v0_build_flex_parser_1_init, 1932 .build_tnl_gtpu_init = &dr_ste_v0_build_flex_parser_tnl_gtpu_init, 1933 .build_tnl_header_0_1_init = &dr_ste_v0_build_tnl_header_0_1_init, 1934 .build_tnl_gtpu_flex_parser_0_init = &dr_ste_v0_build_tnl_gtpu_flex_parser_0_init, 1935 .build_tnl_gtpu_flex_parser_1_init = &dr_ste_v0_build_tnl_gtpu_flex_parser_1_init, 1936 1937 /* Getters and Setters */ 1938 .ste_init = &dr_ste_v0_init, 1939 .set_next_lu_type = &dr_ste_v0_set_next_lu_type, 1940 .get_next_lu_type = &dr_ste_v0_get_next_lu_type, 1941 .set_miss_addr = &dr_ste_v0_set_miss_addr, 1942 .get_miss_addr = &dr_ste_v0_get_miss_addr, 1943 .set_hit_addr = &dr_ste_v0_set_hit_addr, 1944 .set_byte_mask = &dr_ste_v0_set_byte_mask, 1945 .get_byte_mask = &dr_ste_v0_get_byte_mask, 1946 1947 /* Actions */ 1948 .actions_caps = DR_STE_CTX_ACTION_CAP_NONE, 1949 .set_actions_rx = &dr_ste_v0_set_actions_rx, 1950 .set_actions_tx = &dr_ste_v0_set_actions_tx, 1951 .modify_field_arr_sz = ARRAY_SIZE(dr_ste_v0_action_modify_field_arr), 1952 .modify_field_arr = dr_ste_v0_action_modify_field_arr, 1953 .set_action_set = &dr_ste_v0_set_action_set, 1954 .set_action_add = &dr_ste_v0_set_action_add, 1955 .set_action_copy = &dr_ste_v0_set_action_copy, 1956 .set_action_decap_l3_list = &dr_ste_v0_set_action_decap_l3_list, 1957}; 1958 1959struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx_v0(void) 1960{ 1961 return &ste_ctx_v0; 1962} 1963