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 "mlx5_ifc_dr_ste_v1.h" 6 #include "dr_ste_v1.h" 7 8 #define DR_STE_CALC_DFNR_TYPE(lookup_type, inner) \ 9 ((inner) ? DR_STE_V1_LU_TYPE_##lookup_type##_I : \ 10 DR_STE_V1_LU_TYPE_##lookup_type##_O) 11 12 enum dr_ste_v1_entry_format { 13 DR_STE_V1_TYPE_BWC_BYTE = 0x0, 14 DR_STE_V1_TYPE_BWC_DW = 0x1, 15 DR_STE_V1_TYPE_MATCH = 0x2, 16 DR_STE_V1_TYPE_MATCH_RANGES = 0x7, 17 }; 18 19 /* Lookup type is built from 2B: [ Definer mode 1B ][ Definer index 1B ] */ 20 enum { 21 DR_STE_V1_LU_TYPE_NOP = 0x0000, 22 DR_STE_V1_LU_TYPE_ETHL2_TNL = 0x0002, 23 DR_STE_V1_LU_TYPE_IBL3_EXT = 0x0102, 24 DR_STE_V1_LU_TYPE_ETHL2_O = 0x0003, 25 DR_STE_V1_LU_TYPE_IBL4 = 0x0103, 26 DR_STE_V1_LU_TYPE_ETHL2_I = 0x0004, 27 DR_STE_V1_LU_TYPE_SRC_QP_GVMI = 0x0104, 28 DR_STE_V1_LU_TYPE_ETHL2_SRC_O = 0x0005, 29 DR_STE_V1_LU_TYPE_ETHL2_HEADERS_O = 0x0105, 30 DR_STE_V1_LU_TYPE_ETHL2_SRC_I = 0x0006, 31 DR_STE_V1_LU_TYPE_ETHL2_HEADERS_I = 0x0106, 32 DR_STE_V1_LU_TYPE_ETHL3_IPV4_5_TUPLE_O = 0x0007, 33 DR_STE_V1_LU_TYPE_IPV6_DES_O = 0x0107, 34 DR_STE_V1_LU_TYPE_ETHL3_IPV4_5_TUPLE_I = 0x0008, 35 DR_STE_V1_LU_TYPE_IPV6_DES_I = 0x0108, 36 DR_STE_V1_LU_TYPE_ETHL4_O = 0x0009, 37 DR_STE_V1_LU_TYPE_IPV6_SRC_O = 0x0109, 38 DR_STE_V1_LU_TYPE_ETHL4_I = 0x000a, 39 DR_STE_V1_LU_TYPE_IPV6_SRC_I = 0x010a, 40 DR_STE_V1_LU_TYPE_ETHL2_SRC_DST_O = 0x000b, 41 DR_STE_V1_LU_TYPE_MPLS_O = 0x010b, 42 DR_STE_V1_LU_TYPE_ETHL2_SRC_DST_I = 0x000c, 43 DR_STE_V1_LU_TYPE_MPLS_I = 0x010c, 44 DR_STE_V1_LU_TYPE_ETHL3_IPV4_MISC_O = 0x000d, 45 DR_STE_V1_LU_TYPE_GRE = 0x010d, 46 DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER = 0x000e, 47 DR_STE_V1_LU_TYPE_GENERAL_PURPOSE = 0x010e, 48 DR_STE_V1_LU_TYPE_ETHL3_IPV4_MISC_I = 0x000f, 49 DR_STE_V1_LU_TYPE_STEERING_REGISTERS_0 = 0x010f, 50 DR_STE_V1_LU_TYPE_STEERING_REGISTERS_1 = 0x0110, 51 DR_STE_V1_LU_TYPE_FLEX_PARSER_OK = 0x0011, 52 DR_STE_V1_LU_TYPE_FLEX_PARSER_0 = 0x0111, 53 DR_STE_V1_LU_TYPE_FLEX_PARSER_1 = 0x0112, 54 DR_STE_V1_LU_TYPE_ETHL4_MISC_O = 0x0113, 55 DR_STE_V1_LU_TYPE_ETHL4_MISC_I = 0x0114, 56 DR_STE_V1_LU_TYPE_INVALID = 0x00ff, 57 DR_STE_V1_LU_TYPE_DONT_CARE = MLX5DR_STE_LU_TYPE_DONT_CARE, 58 }; 59 60 enum dr_ste_v1_header_anchors { 61 DR_STE_HEADER_ANCHOR_START_OUTER = 0x00, 62 DR_STE_HEADER_ANCHOR_1ST_VLAN = 0x02, 63 DR_STE_HEADER_ANCHOR_IPV6_IPV4 = 0x07, 64 DR_STE_HEADER_ANCHOR_INNER_MAC = 0x13, 65 DR_STE_HEADER_ANCHOR_INNER_IPV6_IPV4 = 0x19, 66 }; 67 68 enum dr_ste_v1_action_size { 69 DR_STE_ACTION_SINGLE_SZ = 4, 70 DR_STE_ACTION_DOUBLE_SZ = 8, 71 DR_STE_ACTION_TRIPLE_SZ = 12, 72 }; 73 74 enum dr_ste_v1_action_insert_ptr_attr { 75 DR_STE_V1_ACTION_INSERT_PTR_ATTR_NONE = 0, /* Regular push header (e.g. push vlan) */ 76 DR_STE_V1_ACTION_INSERT_PTR_ATTR_ENCAP = 1, /* Encapsulation / Tunneling */ 77 DR_STE_V1_ACTION_INSERT_PTR_ATTR_ESP = 2, /* IPsec */ 78 }; 79 80 enum dr_ste_v1_action_id { 81 DR_STE_V1_ACTION_ID_NOP = 0x00, 82 DR_STE_V1_ACTION_ID_COPY = 0x05, 83 DR_STE_V1_ACTION_ID_SET = 0x06, 84 DR_STE_V1_ACTION_ID_ADD = 0x07, 85 DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE = 0x08, 86 DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER = 0x09, 87 DR_STE_V1_ACTION_ID_INSERT_INLINE = 0x0a, 88 DR_STE_V1_ACTION_ID_INSERT_POINTER = 0x0b, 89 DR_STE_V1_ACTION_ID_FLOW_TAG = 0x0c, 90 DR_STE_V1_ACTION_ID_QUEUE_ID_SEL = 0x0d, 91 DR_STE_V1_ACTION_ID_ACCELERATED_LIST = 0x0e, 92 DR_STE_V1_ACTION_ID_MODIFY_LIST = 0x0f, 93 DR_STE_V1_ACTION_ID_ASO = 0x12, 94 DR_STE_V1_ACTION_ID_TRAILER = 0x13, 95 DR_STE_V1_ACTION_ID_COUNTER_ID = 0x14, 96 DR_STE_V1_ACTION_ID_MAX = 0x21, 97 /* use for special cases */ 98 DR_STE_V1_ACTION_ID_SPECIAL_ENCAP_L3 = 0x22, 99 }; 100 101 enum { 102 DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_0 = 0x00, 103 DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_1 = 0x01, 104 DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_2 = 0x02, 105 DR_STE_V1_ACTION_MDFY_FLD_SRC_L2_OUT_0 = 0x08, 106 DR_STE_V1_ACTION_MDFY_FLD_SRC_L2_OUT_1 = 0x09, 107 DR_STE_V1_ACTION_MDFY_FLD_L3_OUT_0 = 0x0e, 108 DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0 = 0x18, 109 DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_1 = 0x19, 110 DR_STE_V1_ACTION_MDFY_FLD_IPV4_OUT_0 = 0x40, 111 DR_STE_V1_ACTION_MDFY_FLD_IPV4_OUT_1 = 0x41, 112 DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_0 = 0x44, 113 DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_1 = 0x45, 114 DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_2 = 0x46, 115 DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_3 = 0x47, 116 DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_0 = 0x4c, 117 DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_1 = 0x4d, 118 DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_2 = 0x4e, 119 DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_3 = 0x4f, 120 DR_STE_V1_ACTION_MDFY_FLD_TCP_MISC_0 = 0x5e, 121 DR_STE_V1_ACTION_MDFY_FLD_TCP_MISC_1 = 0x5f, 122 DR_STE_V1_ACTION_MDFY_FLD_CFG_HDR_0_0 = 0x6f, 123 DR_STE_V1_ACTION_MDFY_FLD_CFG_HDR_0_1 = 0x70, 124 DR_STE_V1_ACTION_MDFY_FLD_METADATA_2_CQE = 0x7b, 125 DR_STE_V1_ACTION_MDFY_FLD_GNRL_PURPOSE = 0x7c, 126 DR_STE_V1_ACTION_MDFY_FLD_REGISTER_2_0 = 0x8c, 127 DR_STE_V1_ACTION_MDFY_FLD_REGISTER_2_1 = 0x8d, 128 DR_STE_V1_ACTION_MDFY_FLD_REGISTER_1_0 = 0x8e, 129 DR_STE_V1_ACTION_MDFY_FLD_REGISTER_1_1 = 0x8f, 130 DR_STE_V1_ACTION_MDFY_FLD_REGISTER_0_0 = 0x90, 131 DR_STE_V1_ACTION_MDFY_FLD_REGISTER_0_1 = 0x91, 132 }; 133 134 enum dr_ste_v1_aso_ctx_type { 135 DR_STE_V1_ASO_CTX_TYPE_POLICERS = 0x2, 136 }; 137 138 static const struct mlx5dr_ste_action_modify_field dr_ste_v1_action_modify_field_arr[] = { 139 [MLX5_ACTION_IN_FIELD_OUT_SMAC_47_16] = { 140 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_SRC_L2_OUT_0, .start = 0, .end = 31, 141 }, 142 [MLX5_ACTION_IN_FIELD_OUT_SMAC_15_0] = { 143 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_SRC_L2_OUT_1, .start = 16, .end = 31, 144 }, 145 [MLX5_ACTION_IN_FIELD_OUT_ETHERTYPE] = { 146 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_1, .start = 0, .end = 15, 147 }, 148 [MLX5_ACTION_IN_FIELD_OUT_DMAC_47_16] = { 149 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_0, .start = 0, .end = 31, 150 }, 151 [MLX5_ACTION_IN_FIELD_OUT_DMAC_15_0] = { 152 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_1, .start = 16, .end = 31, 153 }, 154 [MLX5_ACTION_IN_FIELD_OUT_IP_DSCP] = { 155 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L3_OUT_0, .start = 18, .end = 23, 156 }, 157 [MLX5_ACTION_IN_FIELD_OUT_TCP_FLAGS] = { 158 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_1, .start = 16, .end = 24, 159 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP, 160 }, 161 [MLX5_ACTION_IN_FIELD_OUT_TCP_SPORT] = { 162 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0, .start = 16, .end = 31, 163 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP, 164 }, 165 [MLX5_ACTION_IN_FIELD_OUT_TCP_DPORT] = { 166 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0, .start = 0, .end = 15, 167 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP, 168 }, 169 [MLX5_ACTION_IN_FIELD_OUT_IP_TTL] = { 170 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L3_OUT_0, .start = 8, .end = 15, 171 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4, 172 }, 173 [MLX5_ACTION_IN_FIELD_OUT_IPV6_HOPLIMIT] = { 174 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L3_OUT_0, .start = 8, .end = 15, 175 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 176 }, 177 [MLX5_ACTION_IN_FIELD_OUT_UDP_SPORT] = { 178 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0, .start = 16, .end = 31, 179 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_UDP, 180 }, 181 [MLX5_ACTION_IN_FIELD_OUT_UDP_DPORT] = { 182 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0, .start = 0, .end = 15, 183 .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_UDP, 184 }, 185 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_127_96] = { 186 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_0, .start = 0, .end = 31, 187 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 188 }, 189 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_95_64] = { 190 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_1, .start = 0, .end = 31, 191 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 192 }, 193 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_63_32] = { 194 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_2, .start = 0, .end = 31, 195 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 196 }, 197 [MLX5_ACTION_IN_FIELD_OUT_SIPV6_31_0] = { 198 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_3, .start = 0, .end = 31, 199 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 200 }, 201 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_127_96] = { 202 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_0, .start = 0, .end = 31, 203 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 204 }, 205 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_95_64] = { 206 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_1, .start = 0, .end = 31, 207 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 208 }, 209 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_63_32] = { 210 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_2, .start = 0, .end = 31, 211 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 212 }, 213 [MLX5_ACTION_IN_FIELD_OUT_DIPV6_31_0] = { 214 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_3, .start = 0, .end = 31, 215 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6, 216 }, 217 [MLX5_ACTION_IN_FIELD_OUT_SIPV4] = { 218 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV4_OUT_0, .start = 0, .end = 31, 219 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4, 220 }, 221 [MLX5_ACTION_IN_FIELD_OUT_DIPV4] = { 222 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV4_OUT_1, .start = 0, .end = 31, 223 .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4, 224 }, 225 [MLX5_ACTION_IN_FIELD_METADATA_REG_A] = { 226 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_GNRL_PURPOSE, .start = 0, .end = 31, 227 }, 228 [MLX5_ACTION_IN_FIELD_METADATA_REG_B] = { 229 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_METADATA_2_CQE, .start = 0, .end = 31, 230 }, 231 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_0] = { 232 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_0_0, .start = 0, .end = 31, 233 }, 234 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_1] = { 235 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_0_1, .start = 0, .end = 31, 236 }, 237 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_2] = { 238 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_1_0, .start = 0, .end = 31, 239 }, 240 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_3] = { 241 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_1_1, .start = 0, .end = 31, 242 }, 243 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_4] = { 244 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_2_0, .start = 0, .end = 31, 245 }, 246 [MLX5_ACTION_IN_FIELD_METADATA_REG_C_5] = { 247 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_2_1, .start = 0, .end = 31, 248 }, 249 [MLX5_ACTION_IN_FIELD_OUT_TCP_SEQ_NUM] = { 250 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_TCP_MISC_0, .start = 0, .end = 31, 251 }, 252 [MLX5_ACTION_IN_FIELD_OUT_TCP_ACK_NUM] = { 253 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_TCP_MISC_1, .start = 0, .end = 31, 254 }, 255 [MLX5_ACTION_IN_FIELD_OUT_FIRST_VID] = { 256 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_2, .start = 0, .end = 15, 257 }, 258 [MLX5_ACTION_IN_FIELD_OUT_EMD_31_0] = { 259 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_CFG_HDR_0_1, .start = 0, .end = 31, 260 }, 261 [MLX5_ACTION_IN_FIELD_OUT_EMD_47_32] = { 262 .hw_field = DR_STE_V1_ACTION_MDFY_FLD_CFG_HDR_0_0, .start = 0, .end = 15, 263 }, 264 }; 265 266 static void dr_ste_v1_set_entry_type(u8 *hw_ste_p, u8 entry_type) 267 { 268 MLX5_SET(ste_match_bwc_v1, hw_ste_p, entry_format, entry_type); 269 } 270 271 bool dr_ste_v1_is_miss_addr_set(u8 *hw_ste_p) 272 { 273 u8 entry_type = MLX5_GET(ste_match_bwc_v1, hw_ste_p, entry_format); 274 275 /* unlike MATCH STE, for MATCH_RANGES STE both hit and miss addresses 276 * are part of the action, so they both set as part of STE init 277 */ 278 return entry_type == DR_STE_V1_TYPE_MATCH_RANGES; 279 } 280 281 void dr_ste_v1_set_miss_addr(u8 *hw_ste_p, u64 miss_addr) 282 { 283 u64 index = miss_addr >> 6; 284 285 MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32, index >> 26); 286 MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6, index); 287 } 288 289 u64 dr_ste_v1_get_miss_addr(u8 *hw_ste_p) 290 { 291 u64 index = 292 ((u64)MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6) | 293 ((u64)MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32)) << 26); 294 295 return index << 6; 296 } 297 298 void dr_ste_v1_set_byte_mask(u8 *hw_ste_p, u16 byte_mask) 299 { 300 MLX5_SET(ste_match_bwc_v1, hw_ste_p, byte_mask, byte_mask); 301 } 302 303 u16 dr_ste_v1_get_byte_mask(u8 *hw_ste_p) 304 { 305 return MLX5_GET(ste_match_bwc_v1, hw_ste_p, byte_mask); 306 } 307 308 static void dr_ste_v1_set_lu_type(u8 *hw_ste_p, u16 lu_type) 309 { 310 MLX5_SET(ste_match_bwc_v1, hw_ste_p, entry_format, lu_type >> 8); 311 MLX5_SET(ste_match_bwc_v1, hw_ste_p, match_definer_ctx_idx, lu_type & 0xFF); 312 } 313 314 void dr_ste_v1_set_next_lu_type(u8 *hw_ste_p, u16 lu_type) 315 { 316 MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_entry_format, lu_type >> 8); 317 MLX5_SET(ste_match_bwc_v1, hw_ste_p, hash_definer_ctx_idx, lu_type & 0xFF); 318 } 319 320 u16 dr_ste_v1_get_next_lu_type(u8 *hw_ste_p) 321 { 322 u8 mode = MLX5_GET(ste_match_bwc_v1, hw_ste_p, next_entry_format); 323 u8 index = MLX5_GET(ste_match_bwc_v1, hw_ste_p, hash_definer_ctx_idx); 324 325 return (mode << 8 | index); 326 } 327 328 static void dr_ste_v1_set_hit_gvmi(u8 *hw_ste_p, u16 gvmi) 329 { 330 MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_63_48, gvmi); 331 } 332 333 void dr_ste_v1_set_hit_addr(u8 *hw_ste_p, u64 icm_addr, u32 ht_size) 334 { 335 u64 index = (icm_addr >> 5) | ht_size; 336 337 MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_39_32_size, index >> 27); 338 MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_31_5_size, index); 339 } 340 341 void dr_ste_v1_init(u8 *hw_ste_p, u16 lu_type, bool is_rx, u16 gvmi) 342 { 343 dr_ste_v1_set_lu_type(hw_ste_p, lu_type); 344 dr_ste_v1_set_next_lu_type(hw_ste_p, MLX5DR_STE_LU_TYPE_DONT_CARE); 345 346 MLX5_SET(ste_match_bwc_v1, hw_ste_p, gvmi, gvmi); 347 MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_63_48, gvmi); 348 MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_63_48, gvmi); 349 } 350 351 void dr_ste_v1_prepare_for_postsend(u8 *hw_ste_p, u32 ste_size) 352 { 353 u8 *tag = hw_ste_p + DR_STE_SIZE_CTRL; 354 u8 *mask = tag + DR_STE_SIZE_TAG; 355 u8 tmp_tag[DR_STE_SIZE_TAG] = {}; 356 357 if (ste_size == DR_STE_SIZE_CTRL) 358 return; 359 360 WARN_ON(ste_size != DR_STE_SIZE); 361 362 /* Backup tag */ 363 memcpy(tmp_tag, tag, DR_STE_SIZE_TAG); 364 365 /* Swap mask and tag both are the same size */ 366 memcpy(tag, mask, DR_STE_SIZE_MASK); 367 memcpy(mask, tmp_tag, DR_STE_SIZE_TAG); 368 } 369 370 static void dr_ste_v1_set_rx_flow_tag(u8 *s_action, u32 flow_tag) 371 { 372 MLX5_SET(ste_single_action_flow_tag_v1, s_action, action_id, 373 DR_STE_V1_ACTION_ID_FLOW_TAG); 374 MLX5_SET(ste_single_action_flow_tag_v1, s_action, flow_tag, flow_tag); 375 } 376 377 static void dr_ste_v1_set_counter_id(u8 *hw_ste_p, u32 ctr_id) 378 { 379 MLX5_SET(ste_match_bwc_v1, hw_ste_p, counter_id, ctr_id); 380 } 381 382 static void dr_ste_v1_set_reparse(u8 *hw_ste_p) 383 { 384 MLX5_SET(ste_match_bwc_v1, hw_ste_p, reparse, 1); 385 } 386 387 static void dr_ste_v1_set_encap(u8 *hw_ste_p, u8 *d_action, 388 u32 reformat_id, int size) 389 { 390 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, action_id, 391 DR_STE_V1_ACTION_ID_INSERT_POINTER); 392 /* The hardware expects here size in words (2 byte) */ 393 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, size, size / 2); 394 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, pointer, reformat_id); 395 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, attributes, 396 DR_STE_V1_ACTION_INSERT_PTR_ATTR_ENCAP); 397 dr_ste_v1_set_reparse(hw_ste_p); 398 } 399 400 static void dr_ste_v1_set_insert_hdr(u8 *hw_ste_p, u8 *d_action, 401 u32 reformat_id, 402 u8 anchor, u8 offset, 403 int size) 404 { 405 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, 406 action_id, DR_STE_V1_ACTION_ID_INSERT_POINTER); 407 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, start_anchor, anchor); 408 409 /* The hardware expects here size and offset in words (2 byte) */ 410 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, size, size / 2); 411 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, start_offset, offset / 2); 412 413 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, pointer, reformat_id); 414 MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, attributes, 415 DR_STE_V1_ACTION_INSERT_PTR_ATTR_NONE); 416 417 dr_ste_v1_set_reparse(hw_ste_p); 418 } 419 420 static void dr_ste_v1_set_remove_hdr(u8 *hw_ste_p, u8 *s_action, 421 u8 anchor, u8 offset, 422 int size) 423 { 424 MLX5_SET(ste_single_action_remove_header_size_v1, s_action, 425 action_id, DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE); 426 MLX5_SET(ste_single_action_remove_header_size_v1, s_action, start_anchor, anchor); 427 428 /* The hardware expects here size and offset in words (2 byte) */ 429 MLX5_SET(ste_single_action_remove_header_size_v1, s_action, remove_size, size / 2); 430 MLX5_SET(ste_single_action_remove_header_size_v1, s_action, start_offset, offset / 2); 431 432 dr_ste_v1_set_reparse(hw_ste_p); 433 } 434 435 static void dr_ste_v1_set_push_vlan(u8 *hw_ste_p, u8 *d_action, 436 u32 vlan_hdr) 437 { 438 MLX5_SET(ste_double_action_insert_with_inline_v1, d_action, 439 action_id, DR_STE_V1_ACTION_ID_INSERT_INLINE); 440 /* The hardware expects offset to vlan header in words (2 byte) */ 441 MLX5_SET(ste_double_action_insert_with_inline_v1, d_action, 442 start_offset, HDR_LEN_L2_MACS >> 1); 443 MLX5_SET(ste_double_action_insert_with_inline_v1, d_action, 444 inline_data, vlan_hdr); 445 446 dr_ste_v1_set_reparse(hw_ste_p); 447 } 448 449 static void dr_ste_v1_set_pop_vlan(u8 *hw_ste_p, u8 *s_action, u8 vlans_num) 450 { 451 MLX5_SET(ste_single_action_remove_header_size_v1, s_action, 452 action_id, DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE); 453 MLX5_SET(ste_single_action_remove_header_size_v1, s_action, 454 start_anchor, DR_STE_HEADER_ANCHOR_1ST_VLAN); 455 /* The hardware expects here size in words (2 byte) */ 456 MLX5_SET(ste_single_action_remove_header_size_v1, s_action, 457 remove_size, (HDR_LEN_L2_VLAN >> 1) * vlans_num); 458 459 dr_ste_v1_set_reparse(hw_ste_p); 460 } 461 462 static void dr_ste_v1_set_encap_l3(u8 *hw_ste_p, 463 u8 *frst_s_action, 464 u8 *scnd_d_action, 465 u32 reformat_id, 466 int size) 467 { 468 /* Remove L2 headers */ 469 MLX5_SET(ste_single_action_remove_header_v1, frst_s_action, action_id, 470 DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER); 471 MLX5_SET(ste_single_action_remove_header_v1, frst_s_action, end_anchor, 472 DR_STE_HEADER_ANCHOR_IPV6_IPV4); 473 474 /* Encapsulate with given reformat ID */ 475 MLX5_SET(ste_double_action_insert_with_ptr_v1, scnd_d_action, action_id, 476 DR_STE_V1_ACTION_ID_INSERT_POINTER); 477 /* The hardware expects here size in words (2 byte) */ 478 MLX5_SET(ste_double_action_insert_with_ptr_v1, scnd_d_action, size, size / 2); 479 MLX5_SET(ste_double_action_insert_with_ptr_v1, scnd_d_action, pointer, reformat_id); 480 MLX5_SET(ste_double_action_insert_with_ptr_v1, scnd_d_action, attributes, 481 DR_STE_V1_ACTION_INSERT_PTR_ATTR_ENCAP); 482 483 dr_ste_v1_set_reparse(hw_ste_p); 484 } 485 486 static void dr_ste_v1_set_rx_decap(u8 *hw_ste_p, u8 *s_action) 487 { 488 MLX5_SET(ste_single_action_remove_header_v1, s_action, action_id, 489 DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER); 490 MLX5_SET(ste_single_action_remove_header_v1, s_action, decap, 1); 491 MLX5_SET(ste_single_action_remove_header_v1, s_action, vni_to_cqe, 1); 492 MLX5_SET(ste_single_action_remove_header_v1, s_action, end_anchor, 493 DR_STE_HEADER_ANCHOR_INNER_MAC); 494 495 dr_ste_v1_set_reparse(hw_ste_p); 496 } 497 498 static void dr_ste_v1_set_accelerated_rewrite_actions(u8 *hw_ste_p, 499 u8 *d_action, 500 u16 num_of_actions, 501 u32 rewrite_pattern, 502 u32 rewrite_args, 503 u8 *action_data) 504 { 505 if (action_data) { 506 memcpy(d_action, action_data, DR_MODIFY_ACTION_SIZE); 507 } else { 508 MLX5_SET(ste_double_action_accelerated_modify_action_list_v1, d_action, 509 action_id, DR_STE_V1_ACTION_ID_ACCELERATED_LIST); 510 MLX5_SET(ste_double_action_accelerated_modify_action_list_v1, d_action, 511 modify_actions_pattern_pointer, rewrite_pattern); 512 MLX5_SET(ste_double_action_accelerated_modify_action_list_v1, d_action, 513 number_of_modify_actions, num_of_actions); 514 MLX5_SET(ste_double_action_accelerated_modify_action_list_v1, d_action, 515 modify_actions_argument_pointer, rewrite_args); 516 } 517 518 dr_ste_v1_set_reparse(hw_ste_p); 519 } 520 521 static void dr_ste_v1_set_basic_rewrite_actions(u8 *hw_ste_p, 522 u8 *s_action, 523 u16 num_of_actions, 524 u32 rewrite_index) 525 { 526 MLX5_SET(ste_single_action_modify_list_v1, s_action, action_id, 527 DR_STE_V1_ACTION_ID_MODIFY_LIST); 528 MLX5_SET(ste_single_action_modify_list_v1, s_action, num_of_modify_actions, 529 num_of_actions); 530 MLX5_SET(ste_single_action_modify_list_v1, s_action, modify_actions_ptr, 531 rewrite_index); 532 533 dr_ste_v1_set_reparse(hw_ste_p); 534 } 535 536 static void dr_ste_v1_set_rewrite_actions(u8 *hw_ste_p, 537 u8 *action, 538 u16 num_of_actions, 539 u32 rewrite_pattern, 540 u32 rewrite_args, 541 u8 *action_data) 542 { 543 if (rewrite_pattern != MLX5DR_INVALID_PATTERN_INDEX) 544 return dr_ste_v1_set_accelerated_rewrite_actions(hw_ste_p, 545 action, 546 num_of_actions, 547 rewrite_pattern, 548 rewrite_args, 549 action_data); 550 551 /* fall back to the code that doesn't support accelerated modify header */ 552 return dr_ste_v1_set_basic_rewrite_actions(hw_ste_p, 553 action, 554 num_of_actions, 555 rewrite_args); 556 } 557 558 static void dr_ste_v1_set_aso_flow_meter(u8 *d_action, 559 u32 object_id, 560 u32 offset, 561 u8 dest_reg_id, 562 u8 init_color) 563 { 564 MLX5_SET(ste_double_action_aso_v1, d_action, action_id, 565 DR_STE_V1_ACTION_ID_ASO); 566 MLX5_SET(ste_double_action_aso_v1, d_action, aso_context_number, 567 object_id + (offset / MLX5DR_ASO_FLOW_METER_NUM_PER_OBJ)); 568 /* Convert reg_c index to HW 64bit index */ 569 MLX5_SET(ste_double_action_aso_v1, d_action, dest_reg_id, 570 (dest_reg_id - 1) / 2); 571 MLX5_SET(ste_double_action_aso_v1, d_action, aso_context_type, 572 DR_STE_V1_ASO_CTX_TYPE_POLICERS); 573 MLX5_SET(ste_double_action_aso_v1, d_action, flow_meter.line_id, 574 offset % MLX5DR_ASO_FLOW_METER_NUM_PER_OBJ); 575 MLX5_SET(ste_double_action_aso_v1, d_action, flow_meter.initial_color, 576 init_color); 577 } 578 579 static void dr_ste_v1_set_match_range_pkt_len(u8 *hw_ste_p, u32 definer_id, 580 u32 min, u32 max) 581 { 582 MLX5_SET(ste_match_ranges_v1, hw_ste_p, match_definer_ctx_idx, definer_id); 583 584 /* When the STE will be sent, its mask and tags will be swapped in 585 * dr_ste_v1_prepare_for_postsend(). This, however, is match range STE 586 * which doesn't have mask, and shouldn't have mask/tag swapped. 587 * We're using the common utilities functions to send this STE, so need 588 * to allow for this swapping - place the values in the corresponding 589 * locations to allow flipping them when writing to ICM. 590 * 591 * min/max_value_2 corresponds to match_dw_0 in its definer. 592 * To allow mask/tag swapping, writing the min/max_2 to min/max_0. 593 * 594 * Pkt len is 2 bytes that are stored in the higher section of the DW. 595 */ 596 MLX5_SET(ste_match_ranges_v1, hw_ste_p, min_value_0, min << 16); 597 MLX5_SET(ste_match_ranges_v1, hw_ste_p, max_value_0, max << 16); 598 } 599 600 static void dr_ste_v1_arr_init_next_match(u8 **last_ste, 601 u32 *added_stes, 602 u16 gvmi) 603 { 604 u8 *action; 605 606 (*added_stes)++; 607 *last_ste += DR_STE_SIZE; 608 dr_ste_v1_init(*last_ste, MLX5DR_STE_LU_TYPE_DONT_CARE, 0, gvmi); 609 dr_ste_v1_set_entry_type(*last_ste, DR_STE_V1_TYPE_MATCH); 610 611 action = MLX5_ADDR_OF(ste_mask_and_match_v1, *last_ste, action); 612 memset(action, 0, MLX5_FLD_SZ_BYTES(ste_mask_and_match_v1, action)); 613 } 614 615 static void dr_ste_v1_arr_init_next_match_range(u8 **last_ste, 616 u32 *added_stes, 617 u16 gvmi) 618 { 619 dr_ste_v1_arr_init_next_match(last_ste, added_stes, gvmi); 620 dr_ste_v1_set_entry_type(*last_ste, DR_STE_V1_TYPE_MATCH_RANGES); 621 } 622 623 void dr_ste_v1_set_actions_tx(struct mlx5dr_domain *dmn, 624 u8 *action_type_set, 625 u32 actions_caps, 626 u8 *last_ste, 627 struct mlx5dr_ste_actions_attr *attr, 628 u32 *added_stes) 629 { 630 u8 *action = MLX5_ADDR_OF(ste_match_bwc_v1, last_ste, action); 631 u8 action_sz = DR_STE_ACTION_DOUBLE_SZ; 632 bool allow_modify_hdr = true; 633 bool allow_encap = true; 634 635 if (action_type_set[DR_ACTION_TYP_POP_VLAN]) { 636 if (action_sz < DR_STE_ACTION_SINGLE_SZ) { 637 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, 638 attr->gvmi); 639 action = MLX5_ADDR_OF(ste_mask_and_match_v1, 640 last_ste, action); 641 action_sz = DR_STE_ACTION_TRIPLE_SZ; 642 } 643 dr_ste_v1_set_pop_vlan(last_ste, action, attr->vlans.count); 644 action_sz -= DR_STE_ACTION_SINGLE_SZ; 645 action += DR_STE_ACTION_SINGLE_SZ; 646 647 /* Check if vlan_pop and modify_hdr on same STE is supported */ 648 if (!(actions_caps & DR_STE_CTX_ACTION_CAP_POP_MDFY)) 649 allow_modify_hdr = false; 650 } 651 652 if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) { 653 if (!allow_modify_hdr || action_sz < DR_STE_ACTION_DOUBLE_SZ) { 654 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, 655 attr->gvmi); 656 action = MLX5_ADDR_OF(ste_mask_and_match_v1, 657 last_ste, action); 658 action_sz = DR_STE_ACTION_TRIPLE_SZ; 659 } 660 dr_ste_v1_set_rewrite_actions(last_ste, action, 661 attr->modify_actions, 662 attr->modify_pat_idx, 663 attr->modify_index, 664 attr->single_modify_action); 665 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 666 action += DR_STE_ACTION_DOUBLE_SZ; 667 allow_encap = false; 668 } 669 670 if (action_type_set[DR_ACTION_TYP_PUSH_VLAN]) { 671 int i; 672 673 for (i = 0; i < attr->vlans.count; i++) { 674 if (action_sz < DR_STE_ACTION_DOUBLE_SZ || !allow_encap) { 675 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 676 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 677 action_sz = DR_STE_ACTION_TRIPLE_SZ; 678 allow_encap = true; 679 } 680 dr_ste_v1_set_push_vlan(last_ste, action, 681 attr->vlans.headers[i]); 682 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 683 action += DR_STE_ACTION_DOUBLE_SZ; 684 } 685 } 686 687 if (action_type_set[DR_ACTION_TYP_L2_TO_TNL_L2]) { 688 if (!allow_encap || action_sz < DR_STE_ACTION_DOUBLE_SZ) { 689 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 690 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 691 action_sz = DR_STE_ACTION_TRIPLE_SZ; 692 allow_encap = true; 693 } 694 dr_ste_v1_set_encap(last_ste, action, 695 attr->reformat.id, 696 attr->reformat.size); 697 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 698 action += DR_STE_ACTION_DOUBLE_SZ; 699 } else if (action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]) { 700 u8 *d_action; 701 702 if (action_sz < DR_STE_ACTION_TRIPLE_SZ) { 703 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 704 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 705 action_sz = DR_STE_ACTION_TRIPLE_SZ; 706 } 707 d_action = action + DR_STE_ACTION_SINGLE_SZ; 708 709 dr_ste_v1_set_encap_l3(last_ste, 710 action, d_action, 711 attr->reformat.id, 712 attr->reformat.size); 713 action_sz -= DR_STE_ACTION_TRIPLE_SZ; 714 action += DR_STE_ACTION_TRIPLE_SZ; 715 } else if (action_type_set[DR_ACTION_TYP_INSERT_HDR]) { 716 if (!allow_encap || action_sz < DR_STE_ACTION_DOUBLE_SZ) { 717 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 718 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 719 action_sz = DR_STE_ACTION_TRIPLE_SZ; 720 } 721 dr_ste_v1_set_insert_hdr(last_ste, action, 722 attr->reformat.id, 723 attr->reformat.param_0, 724 attr->reformat.param_1, 725 attr->reformat.size); 726 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 727 action += DR_STE_ACTION_DOUBLE_SZ; 728 } else if (action_type_set[DR_ACTION_TYP_REMOVE_HDR]) { 729 if (action_sz < DR_STE_ACTION_SINGLE_SZ) { 730 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 731 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 732 action_sz = DR_STE_ACTION_TRIPLE_SZ; 733 } 734 dr_ste_v1_set_remove_hdr(last_ste, action, 735 attr->reformat.param_0, 736 attr->reformat.param_1, 737 attr->reformat.size); 738 action_sz -= DR_STE_ACTION_SINGLE_SZ; 739 action += DR_STE_ACTION_SINGLE_SZ; 740 } 741 742 if (action_type_set[DR_ACTION_TYP_ASO_FLOW_METER]) { 743 if (action_sz < DR_STE_ACTION_DOUBLE_SZ) { 744 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 745 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 746 action_sz = DR_STE_ACTION_TRIPLE_SZ; 747 } 748 dr_ste_v1_set_aso_flow_meter(action, 749 attr->aso_flow_meter.obj_id, 750 attr->aso_flow_meter.offset, 751 attr->aso_flow_meter.dest_reg_id, 752 attr->aso_flow_meter.init_color); 753 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 754 action += DR_STE_ACTION_DOUBLE_SZ; 755 } 756 757 if (action_type_set[DR_ACTION_TYP_RANGE]) { 758 /* match ranges requires a new STE of its own type */ 759 dr_ste_v1_arr_init_next_match_range(&last_ste, added_stes, attr->gvmi); 760 dr_ste_v1_set_miss_addr(last_ste, attr->range.miss_icm_addr); 761 762 /* we do not support setting any action on the match ranges STE */ 763 action_sz = 0; 764 765 dr_ste_v1_set_match_range_pkt_len(last_ste, 766 attr->range.definer_id, 767 attr->range.min, 768 attr->range.max); 769 } 770 771 /* set counter ID on the last STE to adhere to DMFS behavior */ 772 if (action_type_set[DR_ACTION_TYP_CTR]) 773 dr_ste_v1_set_counter_id(last_ste, attr->ctr_id); 774 775 dr_ste_v1_set_hit_gvmi(last_ste, attr->hit_gvmi); 776 dr_ste_v1_set_hit_addr(last_ste, attr->final_icm_addr, 1); 777 } 778 779 void dr_ste_v1_set_actions_rx(struct mlx5dr_domain *dmn, 780 u8 *action_type_set, 781 u32 actions_caps, 782 u8 *last_ste, 783 struct mlx5dr_ste_actions_attr *attr, 784 u32 *added_stes) 785 { 786 u8 *action = MLX5_ADDR_OF(ste_match_bwc_v1, last_ste, action); 787 u8 action_sz = DR_STE_ACTION_DOUBLE_SZ; 788 bool allow_modify_hdr = true; 789 bool allow_ctr = true; 790 791 if (action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2]) { 792 dr_ste_v1_set_rewrite_actions(last_ste, action, 793 attr->decap_actions, 794 attr->decap_pat_idx, 795 attr->decap_index, 796 NULL); 797 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 798 action += DR_STE_ACTION_DOUBLE_SZ; 799 allow_modify_hdr = false; 800 allow_ctr = false; 801 } else if (action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2]) { 802 dr_ste_v1_set_rx_decap(last_ste, action); 803 action_sz -= DR_STE_ACTION_SINGLE_SZ; 804 action += DR_STE_ACTION_SINGLE_SZ; 805 allow_modify_hdr = false; 806 allow_ctr = false; 807 } 808 809 if (action_type_set[DR_ACTION_TYP_TAG]) { 810 if (action_sz < DR_STE_ACTION_SINGLE_SZ) { 811 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 812 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 813 action_sz = DR_STE_ACTION_TRIPLE_SZ; 814 allow_modify_hdr = true; 815 allow_ctr = true; 816 } 817 dr_ste_v1_set_rx_flow_tag(action, attr->flow_tag); 818 action_sz -= DR_STE_ACTION_SINGLE_SZ; 819 action += DR_STE_ACTION_SINGLE_SZ; 820 } 821 822 if (action_type_set[DR_ACTION_TYP_POP_VLAN]) { 823 if (action_sz < DR_STE_ACTION_SINGLE_SZ || 824 !allow_modify_hdr) { 825 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 826 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 827 action_sz = DR_STE_ACTION_TRIPLE_SZ; 828 } 829 830 dr_ste_v1_set_pop_vlan(last_ste, action, attr->vlans.count); 831 action_sz -= DR_STE_ACTION_SINGLE_SZ; 832 action += DR_STE_ACTION_SINGLE_SZ; 833 allow_ctr = false; 834 835 /* Check if vlan_pop and modify_hdr on same STE is supported */ 836 if (!(actions_caps & DR_STE_CTX_ACTION_CAP_POP_MDFY)) 837 allow_modify_hdr = false; 838 } 839 840 if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) { 841 /* Modify header and decapsulation must use different STEs */ 842 if (!allow_modify_hdr || action_sz < DR_STE_ACTION_DOUBLE_SZ) { 843 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 844 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 845 action_sz = DR_STE_ACTION_TRIPLE_SZ; 846 allow_modify_hdr = true; 847 allow_ctr = true; 848 } 849 dr_ste_v1_set_rewrite_actions(last_ste, action, 850 attr->modify_actions, 851 attr->modify_pat_idx, 852 attr->modify_index, 853 attr->single_modify_action); 854 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 855 action += DR_STE_ACTION_DOUBLE_SZ; 856 } 857 858 if (action_type_set[DR_ACTION_TYP_PUSH_VLAN]) { 859 int i; 860 861 for (i = 0; i < attr->vlans.count; i++) { 862 if (action_sz < DR_STE_ACTION_DOUBLE_SZ || 863 !allow_modify_hdr) { 864 dr_ste_v1_arr_init_next_match(&last_ste, 865 added_stes, 866 attr->gvmi); 867 action = MLX5_ADDR_OF(ste_mask_and_match_v1, 868 last_ste, action); 869 action_sz = DR_STE_ACTION_TRIPLE_SZ; 870 } 871 dr_ste_v1_set_push_vlan(last_ste, action, 872 attr->vlans.headers[i]); 873 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 874 action += DR_STE_ACTION_DOUBLE_SZ; 875 } 876 } 877 878 if (action_type_set[DR_ACTION_TYP_CTR]) { 879 /* Counter action set after decap and before insert_hdr 880 * to exclude decaped / encaped header respectively. 881 */ 882 if (!allow_ctr) { 883 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 884 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 885 action_sz = DR_STE_ACTION_TRIPLE_SZ; 886 allow_modify_hdr = true; 887 } 888 dr_ste_v1_set_counter_id(last_ste, attr->ctr_id); 889 allow_ctr = false; 890 } 891 892 if (action_type_set[DR_ACTION_TYP_L2_TO_TNL_L2]) { 893 if (action_sz < DR_STE_ACTION_DOUBLE_SZ) { 894 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 895 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 896 action_sz = DR_STE_ACTION_TRIPLE_SZ; 897 } 898 dr_ste_v1_set_encap(last_ste, action, 899 attr->reformat.id, 900 attr->reformat.size); 901 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 902 action += DR_STE_ACTION_DOUBLE_SZ; 903 allow_modify_hdr = false; 904 } else if (action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]) { 905 u8 *d_action; 906 907 if (action_sz < DR_STE_ACTION_TRIPLE_SZ) { 908 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 909 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 910 action_sz = DR_STE_ACTION_TRIPLE_SZ; 911 } 912 913 d_action = action + DR_STE_ACTION_SINGLE_SZ; 914 915 dr_ste_v1_set_encap_l3(last_ste, 916 action, d_action, 917 attr->reformat.id, 918 attr->reformat.size); 919 action_sz -= DR_STE_ACTION_TRIPLE_SZ; 920 allow_modify_hdr = false; 921 } else if (action_type_set[DR_ACTION_TYP_INSERT_HDR]) { 922 /* Modify header, decap, and encap must use different STEs */ 923 if (!allow_modify_hdr || action_sz < DR_STE_ACTION_DOUBLE_SZ) { 924 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 925 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 926 action_sz = DR_STE_ACTION_TRIPLE_SZ; 927 } 928 dr_ste_v1_set_insert_hdr(last_ste, action, 929 attr->reformat.id, 930 attr->reformat.param_0, 931 attr->reformat.param_1, 932 attr->reformat.size); 933 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 934 action += DR_STE_ACTION_DOUBLE_SZ; 935 allow_modify_hdr = false; 936 } else if (action_type_set[DR_ACTION_TYP_REMOVE_HDR]) { 937 if (action_sz < DR_STE_ACTION_SINGLE_SZ) { 938 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 939 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 940 action_sz = DR_STE_ACTION_TRIPLE_SZ; 941 allow_modify_hdr = true; 942 allow_ctr = true; 943 } 944 dr_ste_v1_set_remove_hdr(last_ste, action, 945 attr->reformat.param_0, 946 attr->reformat.param_1, 947 attr->reformat.size); 948 action_sz -= DR_STE_ACTION_SINGLE_SZ; 949 action += DR_STE_ACTION_SINGLE_SZ; 950 } 951 952 if (action_type_set[DR_ACTION_TYP_ASO_FLOW_METER]) { 953 if (action_sz < DR_STE_ACTION_DOUBLE_SZ) { 954 dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi); 955 action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action); 956 action_sz = DR_STE_ACTION_TRIPLE_SZ; 957 } 958 dr_ste_v1_set_aso_flow_meter(action, 959 attr->aso_flow_meter.obj_id, 960 attr->aso_flow_meter.offset, 961 attr->aso_flow_meter.dest_reg_id, 962 attr->aso_flow_meter.init_color); 963 action_sz -= DR_STE_ACTION_DOUBLE_SZ; 964 action += DR_STE_ACTION_DOUBLE_SZ; 965 } 966 967 if (action_type_set[DR_ACTION_TYP_RANGE]) { 968 /* match ranges requires a new STE of its own type */ 969 dr_ste_v1_arr_init_next_match_range(&last_ste, added_stes, attr->gvmi); 970 dr_ste_v1_set_miss_addr(last_ste, attr->range.miss_icm_addr); 971 972 /* we do not support setting any action on the match ranges STE */ 973 action_sz = 0; 974 975 dr_ste_v1_set_match_range_pkt_len(last_ste, 976 attr->range.definer_id, 977 attr->range.min, 978 attr->range.max); 979 } 980 981 dr_ste_v1_set_hit_gvmi(last_ste, attr->hit_gvmi); 982 dr_ste_v1_set_hit_addr(last_ste, attr->final_icm_addr, 1); 983 } 984 985 void dr_ste_v1_set_action_set(u8 *d_action, 986 u8 hw_field, 987 u8 shifter, 988 u8 length, 989 u32 data) 990 { 991 shifter += MLX5_MODIFY_HEADER_V1_QW_OFFSET; 992 MLX5_SET(ste_double_action_set_v1, d_action, action_id, DR_STE_V1_ACTION_ID_SET); 993 MLX5_SET(ste_double_action_set_v1, d_action, destination_dw_offset, hw_field); 994 MLX5_SET(ste_double_action_set_v1, d_action, destination_left_shifter, shifter); 995 MLX5_SET(ste_double_action_set_v1, d_action, destination_length, length); 996 MLX5_SET(ste_double_action_set_v1, d_action, inline_data, data); 997 } 998 999 void dr_ste_v1_set_action_add(u8 *d_action, 1000 u8 hw_field, 1001 u8 shifter, 1002 u8 length, 1003 u32 data) 1004 { 1005 shifter += MLX5_MODIFY_HEADER_V1_QW_OFFSET; 1006 MLX5_SET(ste_double_action_add_v1, d_action, action_id, DR_STE_V1_ACTION_ID_ADD); 1007 MLX5_SET(ste_double_action_add_v1, d_action, destination_dw_offset, hw_field); 1008 MLX5_SET(ste_double_action_add_v1, d_action, destination_left_shifter, shifter); 1009 MLX5_SET(ste_double_action_add_v1, d_action, destination_length, length); 1010 MLX5_SET(ste_double_action_add_v1, d_action, add_value, data); 1011 } 1012 1013 void dr_ste_v1_set_action_copy(u8 *d_action, 1014 u8 dst_hw_field, 1015 u8 dst_shifter, 1016 u8 dst_len, 1017 u8 src_hw_field, 1018 u8 src_shifter) 1019 { 1020 dst_shifter += MLX5_MODIFY_HEADER_V1_QW_OFFSET; 1021 src_shifter += MLX5_MODIFY_HEADER_V1_QW_OFFSET; 1022 MLX5_SET(ste_double_action_copy_v1, d_action, action_id, DR_STE_V1_ACTION_ID_COPY); 1023 MLX5_SET(ste_double_action_copy_v1, d_action, destination_dw_offset, dst_hw_field); 1024 MLX5_SET(ste_double_action_copy_v1, d_action, destination_left_shifter, dst_shifter); 1025 MLX5_SET(ste_double_action_copy_v1, d_action, destination_length, dst_len); 1026 MLX5_SET(ste_double_action_copy_v1, d_action, source_dw_offset, src_hw_field); 1027 MLX5_SET(ste_double_action_copy_v1, d_action, source_right_shifter, src_shifter); 1028 } 1029 1030 #define DR_STE_DECAP_L3_ACTION_NUM 8 1031 #define DR_STE_L2_HDR_MAX_SZ 20 1032 1033 int dr_ste_v1_set_action_decap_l3_list(void *data, 1034 u32 data_sz, 1035 u8 *hw_action, 1036 u32 hw_action_sz, 1037 u16 *used_hw_action_num) 1038 { 1039 u8 padded_data[DR_STE_L2_HDR_MAX_SZ] = {}; 1040 void *data_ptr = padded_data; 1041 u16 used_actions = 0; 1042 u32 inline_data_sz; 1043 u32 i; 1044 1045 if (hw_action_sz / DR_STE_ACTION_DOUBLE_SZ < DR_STE_DECAP_L3_ACTION_NUM) 1046 return -EINVAL; 1047 1048 inline_data_sz = 1049 MLX5_FLD_SZ_BYTES(ste_double_action_insert_with_inline_v1, inline_data); 1050 1051 /* Add an alignment padding */ 1052 memcpy(padded_data + data_sz % inline_data_sz, data, data_sz); 1053 1054 /* Remove L2L3 outer headers */ 1055 MLX5_SET(ste_single_action_remove_header_v1, hw_action, action_id, 1056 DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER); 1057 MLX5_SET(ste_single_action_remove_header_v1, hw_action, decap, 1); 1058 MLX5_SET(ste_single_action_remove_header_v1, hw_action, vni_to_cqe, 1); 1059 MLX5_SET(ste_single_action_remove_header_v1, hw_action, end_anchor, 1060 DR_STE_HEADER_ANCHOR_INNER_IPV6_IPV4); 1061 hw_action += DR_STE_ACTION_DOUBLE_SZ; 1062 used_actions++; /* Remove and NOP are a single double action */ 1063 1064 /* Point to the last dword of the header */ 1065 data_ptr += (data_sz / inline_data_sz) * inline_data_sz; 1066 1067 /* Add the new header using inline action 4Byte at a time, the header 1068 * is added in reversed order to the beginning of the packet to avoid 1069 * incorrect parsing by the HW. Since header is 14B or 18B an extra 1070 * two bytes are padded and later removed. 1071 */ 1072 for (i = 0; i < data_sz / inline_data_sz + 1; i++) { 1073 void *addr_inline; 1074 1075 MLX5_SET(ste_double_action_insert_with_inline_v1, hw_action, action_id, 1076 DR_STE_V1_ACTION_ID_INSERT_INLINE); 1077 /* The hardware expects here offset to words (2 bytes) */ 1078 MLX5_SET(ste_double_action_insert_with_inline_v1, hw_action, start_offset, 0); 1079 1080 /* Copy bytes one by one to avoid endianness problem */ 1081 addr_inline = MLX5_ADDR_OF(ste_double_action_insert_with_inline_v1, 1082 hw_action, inline_data); 1083 memcpy(addr_inline, data_ptr - i * inline_data_sz, inline_data_sz); 1084 hw_action += DR_STE_ACTION_DOUBLE_SZ; 1085 used_actions++; 1086 } 1087 1088 /* Remove first 2 extra bytes */ 1089 MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, action_id, 1090 DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE); 1091 MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, start_offset, 0); 1092 /* The hardware expects here size in words (2 bytes) */ 1093 MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, remove_size, 1); 1094 used_actions++; 1095 1096 *used_hw_action_num = used_actions; 1097 1098 return 0; 1099 } 1100 1101 static void dr_ste_v1_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value, 1102 bool inner, u8 *bit_mask) 1103 { 1104 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 1105 1106 DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, dmac_47_16, mask, dmac_47_16); 1107 DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, dmac_15_0, mask, dmac_15_0); 1108 1109 DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, smac_47_16, mask, smac_47_16); 1110 DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, smac_15_0, mask, smac_15_0); 1111 1112 DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_vlan_id, mask, first_vid); 1113 DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_cfi, mask, first_cfi); 1114 DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_priority, mask, first_prio); 1115 DR_STE_SET_ONES(eth_l2_src_dst_v1, bit_mask, l3_type, mask, ip_version); 1116 1117 if (mask->cvlan_tag) { 1118 MLX5_SET(ste_eth_l2_src_dst_v1, bit_mask, first_vlan_qualifier, -1); 1119 mask->cvlan_tag = 0; 1120 } else if (mask->svlan_tag) { 1121 MLX5_SET(ste_eth_l2_src_dst_v1, bit_mask, first_vlan_qualifier, -1); 1122 mask->svlan_tag = 0; 1123 } 1124 } 1125 1126 static int dr_ste_v1_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value, 1127 struct mlx5dr_ste_build *sb, 1128 u8 *tag) 1129 { 1130 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1131 1132 DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, dmac_47_16, spec, dmac_47_16); 1133 DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, dmac_15_0, spec, dmac_15_0); 1134 1135 DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, smac_47_16, spec, smac_47_16); 1136 DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, smac_15_0, spec, smac_15_0); 1137 1138 if (spec->ip_version == IP_VERSION_IPV4) { 1139 MLX5_SET(ste_eth_l2_src_dst_v1, tag, l3_type, STE_IPV4); 1140 spec->ip_version = 0; 1141 } else if (spec->ip_version == IP_VERSION_IPV6) { 1142 MLX5_SET(ste_eth_l2_src_dst_v1, tag, l3_type, STE_IPV6); 1143 spec->ip_version = 0; 1144 } else if (spec->ip_version) { 1145 return -EINVAL; 1146 } 1147 1148 DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_vlan_id, spec, first_vid); 1149 DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_cfi, spec, first_cfi); 1150 DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_priority, spec, first_prio); 1151 1152 if (spec->cvlan_tag) { 1153 MLX5_SET(ste_eth_l2_src_dst_v1, tag, first_vlan_qualifier, DR_STE_CVLAN); 1154 spec->cvlan_tag = 0; 1155 } else if (spec->svlan_tag) { 1156 MLX5_SET(ste_eth_l2_src_dst_v1, tag, first_vlan_qualifier, DR_STE_SVLAN); 1157 spec->svlan_tag = 0; 1158 } 1159 return 0; 1160 } 1161 1162 void dr_ste_v1_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb, 1163 struct mlx5dr_match_param *mask) 1164 { 1165 dr_ste_v1_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask); 1166 1167 sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2_SRC_DST, sb->inner); 1168 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1169 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_src_dst_tag; 1170 } 1171 1172 static int dr_ste_v1_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value, 1173 struct mlx5dr_ste_build *sb, 1174 u8 *tag) 1175 { 1176 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1177 1178 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96); 1179 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64); 1180 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32); 1181 DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0); 1182 1183 return 0; 1184 } 1185 1186 void dr_ste_v1_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb, 1187 struct mlx5dr_match_param *mask) 1188 { 1189 dr_ste_v1_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask); 1190 1191 sb->lu_type = DR_STE_CALC_DFNR_TYPE(IPV6_DES, sb->inner); 1192 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1193 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv6_dst_tag; 1194 } 1195 1196 static int dr_ste_v1_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value, 1197 struct mlx5dr_ste_build *sb, 1198 u8 *tag) 1199 { 1200 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1201 1202 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96); 1203 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64); 1204 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32); 1205 DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0); 1206 1207 return 0; 1208 } 1209 1210 void dr_ste_v1_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb, 1211 struct mlx5dr_match_param *mask) 1212 { 1213 dr_ste_v1_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask); 1214 1215 sb->lu_type = DR_STE_CALC_DFNR_TYPE(IPV6_SRC, sb->inner); 1216 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1217 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv6_src_tag; 1218 } 1219 1220 static int dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value, 1221 struct mlx5dr_ste_build *sb, 1222 u8 *tag) 1223 { 1224 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1225 1226 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_address, spec, dst_ip_31_0); 1227 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_address, spec, src_ip_31_0); 1228 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_port, spec, tcp_dport); 1229 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_port, spec, udp_dport); 1230 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_port, spec, tcp_sport); 1231 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_port, spec, udp_sport); 1232 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, protocol, spec, ip_protocol); 1233 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, fragmented, spec, frag); 1234 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, dscp, spec, ip_dscp); 1235 DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, ecn, spec, ip_ecn); 1236 1237 if (spec->tcp_flags) { 1238 DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple_v1, tag, spec); 1239 spec->tcp_flags = 0; 1240 } 1241 1242 return 0; 1243 } 1244 1245 void dr_ste_v1_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb, 1246 struct mlx5dr_match_param *mask) 1247 { 1248 dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask); 1249 1250 sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL3_IPV4_5_TUPLE, sb->inner); 1251 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1252 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag; 1253 } 1254 1255 static void dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value, 1256 bool inner, u8 *bit_mask) 1257 { 1258 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 1259 struct mlx5dr_match_misc *misc_mask = &value->misc; 1260 1261 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_vlan_id, mask, first_vid); 1262 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_cfi, mask, first_cfi); 1263 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_priority, mask, first_prio); 1264 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, ip_fragmented, mask, frag); 1265 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, l3_ethertype, mask, ethertype); 1266 DR_STE_SET_ONES(eth_l2_src_v1, bit_mask, l3_type, mask, ip_version); 1267 1268 if (mask->svlan_tag || mask->cvlan_tag) { 1269 MLX5_SET(ste_eth_l2_src_v1, bit_mask, first_vlan_qualifier, -1); 1270 mask->cvlan_tag = 0; 1271 mask->svlan_tag = 0; 1272 } 1273 1274 if (inner) { 1275 if (misc_mask->inner_second_cvlan_tag || 1276 misc_mask->inner_second_svlan_tag) { 1277 MLX5_SET(ste_eth_l2_src_v1, bit_mask, second_vlan_qualifier, -1); 1278 misc_mask->inner_second_cvlan_tag = 0; 1279 misc_mask->inner_second_svlan_tag = 0; 1280 } 1281 1282 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 1283 second_vlan_id, misc_mask, inner_second_vid); 1284 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 1285 second_cfi, misc_mask, inner_second_cfi); 1286 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 1287 second_priority, misc_mask, inner_second_prio); 1288 } else { 1289 if (misc_mask->outer_second_cvlan_tag || 1290 misc_mask->outer_second_svlan_tag) { 1291 MLX5_SET(ste_eth_l2_src_v1, bit_mask, second_vlan_qualifier, -1); 1292 misc_mask->outer_second_cvlan_tag = 0; 1293 misc_mask->outer_second_svlan_tag = 0; 1294 } 1295 1296 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 1297 second_vlan_id, misc_mask, outer_second_vid); 1298 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 1299 second_cfi, misc_mask, outer_second_cfi); 1300 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 1301 second_priority, misc_mask, outer_second_prio); 1302 } 1303 } 1304 1305 static int dr_ste_v1_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value, 1306 bool inner, u8 *tag) 1307 { 1308 struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer; 1309 struct mlx5dr_match_misc *misc_spec = &value->misc; 1310 1311 DR_STE_SET_TAG(eth_l2_src_v1, tag, first_vlan_id, spec, first_vid); 1312 DR_STE_SET_TAG(eth_l2_src_v1, tag, first_cfi, spec, first_cfi); 1313 DR_STE_SET_TAG(eth_l2_src_v1, tag, first_priority, spec, first_prio); 1314 DR_STE_SET_TAG(eth_l2_src_v1, tag, ip_fragmented, spec, frag); 1315 DR_STE_SET_TAG(eth_l2_src_v1, tag, l3_ethertype, spec, ethertype); 1316 1317 if (spec->ip_version == IP_VERSION_IPV4) { 1318 MLX5_SET(ste_eth_l2_src_v1, tag, l3_type, STE_IPV4); 1319 spec->ip_version = 0; 1320 } else if (spec->ip_version == IP_VERSION_IPV6) { 1321 MLX5_SET(ste_eth_l2_src_v1, tag, l3_type, STE_IPV6); 1322 spec->ip_version = 0; 1323 } else if (spec->ip_version) { 1324 return -EINVAL; 1325 } 1326 1327 if (spec->cvlan_tag) { 1328 MLX5_SET(ste_eth_l2_src_v1, tag, first_vlan_qualifier, DR_STE_CVLAN); 1329 spec->cvlan_tag = 0; 1330 } else if (spec->svlan_tag) { 1331 MLX5_SET(ste_eth_l2_src_v1, tag, first_vlan_qualifier, DR_STE_SVLAN); 1332 spec->svlan_tag = 0; 1333 } 1334 1335 if (inner) { 1336 if (misc_spec->inner_second_cvlan_tag) { 1337 MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_CVLAN); 1338 misc_spec->inner_second_cvlan_tag = 0; 1339 } else if (misc_spec->inner_second_svlan_tag) { 1340 MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_SVLAN); 1341 misc_spec->inner_second_svlan_tag = 0; 1342 } 1343 1344 DR_STE_SET_TAG(eth_l2_src_v1, tag, second_vlan_id, misc_spec, inner_second_vid); 1345 DR_STE_SET_TAG(eth_l2_src_v1, tag, second_cfi, misc_spec, inner_second_cfi); 1346 DR_STE_SET_TAG(eth_l2_src_v1, tag, second_priority, misc_spec, inner_second_prio); 1347 } else { 1348 if (misc_spec->outer_second_cvlan_tag) { 1349 MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_CVLAN); 1350 misc_spec->outer_second_cvlan_tag = 0; 1351 } else if (misc_spec->outer_second_svlan_tag) { 1352 MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_SVLAN); 1353 misc_spec->outer_second_svlan_tag = 0; 1354 } 1355 DR_STE_SET_TAG(eth_l2_src_v1, tag, second_vlan_id, misc_spec, outer_second_vid); 1356 DR_STE_SET_TAG(eth_l2_src_v1, tag, second_cfi, misc_spec, outer_second_cfi); 1357 DR_STE_SET_TAG(eth_l2_src_v1, tag, second_priority, misc_spec, outer_second_prio); 1358 } 1359 1360 return 0; 1361 } 1362 1363 static void dr_ste_v1_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value, 1364 bool inner, u8 *bit_mask) 1365 { 1366 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 1367 1368 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, smac_47_16, mask, smac_47_16); 1369 DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, smac_15_0, mask, smac_15_0); 1370 1371 dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask); 1372 } 1373 1374 static int dr_ste_v1_build_eth_l2_src_tag(struct mlx5dr_match_param *value, 1375 struct mlx5dr_ste_build *sb, 1376 u8 *tag) 1377 { 1378 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1379 1380 DR_STE_SET_TAG(eth_l2_src_v1, tag, smac_47_16, spec, smac_47_16); 1381 DR_STE_SET_TAG(eth_l2_src_v1, tag, smac_15_0, spec, smac_15_0); 1382 1383 return dr_ste_v1_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 1384 } 1385 1386 void dr_ste_v1_build_eth_l2_src_init(struct mlx5dr_ste_build *sb, 1387 struct mlx5dr_match_param *mask) 1388 { 1389 dr_ste_v1_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask); 1390 1391 sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2_SRC, sb->inner); 1392 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1393 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_src_tag; 1394 } 1395 1396 static void dr_ste_v1_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value, 1397 bool inner, u8 *bit_mask) 1398 { 1399 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 1400 1401 DR_STE_SET_TAG(eth_l2_dst_v1, bit_mask, dmac_47_16, mask, dmac_47_16); 1402 DR_STE_SET_TAG(eth_l2_dst_v1, bit_mask, dmac_15_0, mask, dmac_15_0); 1403 1404 dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask); 1405 } 1406 1407 static int dr_ste_v1_build_eth_l2_dst_tag(struct mlx5dr_match_param *value, 1408 struct mlx5dr_ste_build *sb, 1409 u8 *tag) 1410 { 1411 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1412 1413 DR_STE_SET_TAG(eth_l2_dst_v1, tag, dmac_47_16, spec, dmac_47_16); 1414 DR_STE_SET_TAG(eth_l2_dst_v1, tag, dmac_15_0, spec, dmac_15_0); 1415 1416 return dr_ste_v1_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 1417 } 1418 1419 void dr_ste_v1_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb, 1420 struct mlx5dr_match_param *mask) 1421 { 1422 dr_ste_v1_build_eth_l2_dst_bit_mask(mask, sb->inner, sb->bit_mask); 1423 1424 sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2, sb->inner); 1425 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1426 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_dst_tag; 1427 } 1428 1429 static void dr_ste_v1_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value, 1430 bool inner, u8 *bit_mask) 1431 { 1432 struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 1433 struct mlx5dr_match_misc *misc = &value->misc; 1434 1435 DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, dmac_47_16, mask, dmac_47_16); 1436 DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, dmac_15_0, mask, dmac_15_0); 1437 DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_vlan_id, mask, first_vid); 1438 DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_cfi, mask, first_cfi); 1439 DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_priority, mask, first_prio); 1440 DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, ip_fragmented, mask, frag); 1441 DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, l3_ethertype, mask, ethertype); 1442 DR_STE_SET_ONES(eth_l2_tnl_v1, bit_mask, l3_type, mask, ip_version); 1443 1444 if (misc->vxlan_vni) { 1445 MLX5_SET(ste_eth_l2_tnl_v1, bit_mask, 1446 l2_tunneling_network_id, (misc->vxlan_vni << 8)); 1447 misc->vxlan_vni = 0; 1448 } 1449 1450 if (mask->svlan_tag || mask->cvlan_tag) { 1451 MLX5_SET(ste_eth_l2_tnl_v1, bit_mask, first_vlan_qualifier, -1); 1452 mask->cvlan_tag = 0; 1453 mask->svlan_tag = 0; 1454 } 1455 } 1456 1457 static int dr_ste_v1_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value, 1458 struct mlx5dr_ste_build *sb, 1459 u8 *tag) 1460 { 1461 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1462 struct mlx5dr_match_misc *misc = &value->misc; 1463 1464 DR_STE_SET_TAG(eth_l2_tnl_v1, tag, dmac_47_16, spec, dmac_47_16); 1465 DR_STE_SET_TAG(eth_l2_tnl_v1, tag, dmac_15_0, spec, dmac_15_0); 1466 DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_vlan_id, spec, first_vid); 1467 DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_cfi, spec, first_cfi); 1468 DR_STE_SET_TAG(eth_l2_tnl_v1, tag, ip_fragmented, spec, frag); 1469 DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_priority, spec, first_prio); 1470 DR_STE_SET_TAG(eth_l2_tnl_v1, tag, l3_ethertype, spec, ethertype); 1471 1472 if (misc->vxlan_vni) { 1473 MLX5_SET(ste_eth_l2_tnl_v1, tag, l2_tunneling_network_id, 1474 (misc->vxlan_vni << 8)); 1475 misc->vxlan_vni = 0; 1476 } 1477 1478 if (spec->cvlan_tag) { 1479 MLX5_SET(ste_eth_l2_tnl_v1, tag, first_vlan_qualifier, DR_STE_CVLAN); 1480 spec->cvlan_tag = 0; 1481 } else if (spec->svlan_tag) { 1482 MLX5_SET(ste_eth_l2_tnl_v1, tag, first_vlan_qualifier, DR_STE_SVLAN); 1483 spec->svlan_tag = 0; 1484 } 1485 1486 if (spec->ip_version == IP_VERSION_IPV4) { 1487 MLX5_SET(ste_eth_l2_tnl_v1, tag, l3_type, STE_IPV4); 1488 spec->ip_version = 0; 1489 } else if (spec->ip_version == IP_VERSION_IPV6) { 1490 MLX5_SET(ste_eth_l2_tnl_v1, tag, l3_type, STE_IPV6); 1491 spec->ip_version = 0; 1492 } else if (spec->ip_version) { 1493 return -EINVAL; 1494 } 1495 1496 return 0; 1497 } 1498 1499 void dr_ste_v1_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb, 1500 struct mlx5dr_match_param *mask) 1501 { 1502 dr_ste_v1_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask); 1503 1504 sb->lu_type = DR_STE_V1_LU_TYPE_ETHL2_TNL; 1505 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1506 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_tnl_tag; 1507 } 1508 1509 static int dr_ste_v1_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value, 1510 struct mlx5dr_ste_build *sb, 1511 u8 *tag) 1512 { 1513 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1514 1515 DR_STE_SET_TAG(eth_l3_ipv4_misc_v1, tag, time_to_live, spec, ttl_hoplimit); 1516 DR_STE_SET_TAG(eth_l3_ipv4_misc_v1, tag, ihl, spec, ipv4_ihl); 1517 1518 return 0; 1519 } 1520 1521 void dr_ste_v1_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb, 1522 struct mlx5dr_match_param *mask) 1523 { 1524 dr_ste_v1_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask); 1525 1526 sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL3_IPV4_MISC, sb->inner); 1527 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1528 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv4_misc_tag; 1529 } 1530 1531 static int dr_ste_v1_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value, 1532 struct mlx5dr_ste_build *sb, 1533 u8 *tag) 1534 { 1535 struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 1536 struct mlx5dr_match_misc *misc = &value->misc; 1537 1538 DR_STE_SET_TAG(eth_l4_v1, tag, dst_port, spec, tcp_dport); 1539 DR_STE_SET_TAG(eth_l4_v1, tag, src_port, spec, tcp_sport); 1540 DR_STE_SET_TAG(eth_l4_v1, tag, dst_port, spec, udp_dport); 1541 DR_STE_SET_TAG(eth_l4_v1, tag, src_port, spec, udp_sport); 1542 DR_STE_SET_TAG(eth_l4_v1, tag, protocol, spec, ip_protocol); 1543 DR_STE_SET_TAG(eth_l4_v1, tag, fragmented, spec, frag); 1544 DR_STE_SET_TAG(eth_l4_v1, tag, dscp, spec, ip_dscp); 1545 DR_STE_SET_TAG(eth_l4_v1, tag, ecn, spec, ip_ecn); 1546 DR_STE_SET_TAG(eth_l4_v1, tag, ipv6_hop_limit, spec, ttl_hoplimit); 1547 1548 if (sb->inner) 1549 DR_STE_SET_TAG(eth_l4_v1, tag, flow_label, misc, inner_ipv6_flow_label); 1550 else 1551 DR_STE_SET_TAG(eth_l4_v1, tag, flow_label, misc, outer_ipv6_flow_label); 1552 1553 if (spec->tcp_flags) { 1554 DR_STE_SET_TCP_FLAGS(eth_l4_v1, tag, spec); 1555 spec->tcp_flags = 0; 1556 } 1557 1558 return 0; 1559 } 1560 1561 void dr_ste_v1_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb, 1562 struct mlx5dr_match_param *mask) 1563 { 1564 dr_ste_v1_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask); 1565 1566 sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL4, sb->inner); 1567 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1568 sb->ste_build_tag_func = &dr_ste_v1_build_eth_ipv6_l3_l4_tag; 1569 } 1570 1571 static int dr_ste_v1_build_mpls_tag(struct mlx5dr_match_param *value, 1572 struct mlx5dr_ste_build *sb, 1573 u8 *tag) 1574 { 1575 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1576 1577 if (sb->inner) 1578 DR_STE_SET_MPLS(mpls_v1, misc2, inner, tag); 1579 else 1580 DR_STE_SET_MPLS(mpls_v1, misc2, outer, tag); 1581 1582 return 0; 1583 } 1584 1585 void dr_ste_v1_build_mpls_init(struct mlx5dr_ste_build *sb, 1586 struct mlx5dr_match_param *mask) 1587 { 1588 dr_ste_v1_build_mpls_tag(mask, sb, sb->bit_mask); 1589 1590 sb->lu_type = DR_STE_CALC_DFNR_TYPE(MPLS, sb->inner); 1591 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1592 sb->ste_build_tag_func = &dr_ste_v1_build_mpls_tag; 1593 } 1594 1595 static int dr_ste_v1_build_tnl_gre_tag(struct mlx5dr_match_param *value, 1596 struct mlx5dr_ste_build *sb, 1597 u8 *tag) 1598 { 1599 struct mlx5dr_match_misc *misc = &value->misc; 1600 1601 DR_STE_SET_TAG(gre_v1, tag, gre_protocol, misc, gre_protocol); 1602 DR_STE_SET_TAG(gre_v1, tag, gre_k_present, misc, gre_k_present); 1603 DR_STE_SET_TAG(gre_v1, tag, gre_key_h, misc, gre_key_h); 1604 DR_STE_SET_TAG(gre_v1, tag, gre_key_l, misc, gre_key_l); 1605 1606 DR_STE_SET_TAG(gre_v1, tag, gre_c_present, misc, gre_c_present); 1607 DR_STE_SET_TAG(gre_v1, tag, gre_s_present, misc, gre_s_present); 1608 1609 return 0; 1610 } 1611 1612 void dr_ste_v1_build_tnl_gre_init(struct mlx5dr_ste_build *sb, 1613 struct mlx5dr_match_param *mask) 1614 { 1615 dr_ste_v1_build_tnl_gre_tag(mask, sb, sb->bit_mask); 1616 1617 sb->lu_type = DR_STE_V1_LU_TYPE_GRE; 1618 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1619 sb->ste_build_tag_func = &dr_ste_v1_build_tnl_gre_tag; 1620 } 1621 1622 static int dr_ste_v1_build_tnl_mpls_tag(struct mlx5dr_match_param *value, 1623 struct mlx5dr_ste_build *sb, 1624 u8 *tag) 1625 { 1626 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1627 1628 if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc2)) { 1629 DR_STE_SET_TAG(mpls_v1, tag, mpls0_label, 1630 misc2, outer_first_mpls_over_gre_label); 1631 1632 DR_STE_SET_TAG(mpls_v1, tag, mpls0_exp, 1633 misc2, outer_first_mpls_over_gre_exp); 1634 1635 DR_STE_SET_TAG(mpls_v1, tag, mpls0_s_bos, 1636 misc2, outer_first_mpls_over_gre_s_bos); 1637 1638 DR_STE_SET_TAG(mpls_v1, tag, mpls0_ttl, 1639 misc2, outer_first_mpls_over_gre_ttl); 1640 } else { 1641 DR_STE_SET_TAG(mpls_v1, tag, mpls0_label, 1642 misc2, outer_first_mpls_over_udp_label); 1643 1644 DR_STE_SET_TAG(mpls_v1, tag, mpls0_exp, 1645 misc2, outer_first_mpls_over_udp_exp); 1646 1647 DR_STE_SET_TAG(mpls_v1, tag, mpls0_s_bos, 1648 misc2, outer_first_mpls_over_udp_s_bos); 1649 1650 DR_STE_SET_TAG(mpls_v1, tag, mpls0_ttl, 1651 misc2, outer_first_mpls_over_udp_ttl); 1652 } 1653 1654 return 0; 1655 } 1656 1657 void dr_ste_v1_build_tnl_mpls_init(struct mlx5dr_ste_build *sb, 1658 struct mlx5dr_match_param *mask) 1659 { 1660 dr_ste_v1_build_tnl_mpls_tag(mask, sb, sb->bit_mask); 1661 1662 sb->lu_type = DR_STE_V1_LU_TYPE_MPLS_I; 1663 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1664 sb->ste_build_tag_func = &dr_ste_v1_build_tnl_mpls_tag; 1665 } 1666 1667 static int dr_ste_v1_build_tnl_mpls_over_udp_tag(struct mlx5dr_match_param *value, 1668 struct mlx5dr_ste_build *sb, 1669 u8 *tag) 1670 { 1671 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1672 u8 *parser_ptr; 1673 u8 parser_id; 1674 u32 mpls_hdr; 1675 1676 mpls_hdr = misc2->outer_first_mpls_over_udp_label << HDR_MPLS_OFFSET_LABEL; 1677 misc2->outer_first_mpls_over_udp_label = 0; 1678 mpls_hdr |= misc2->outer_first_mpls_over_udp_exp << HDR_MPLS_OFFSET_EXP; 1679 misc2->outer_first_mpls_over_udp_exp = 0; 1680 mpls_hdr |= misc2->outer_first_mpls_over_udp_s_bos << HDR_MPLS_OFFSET_S_BOS; 1681 misc2->outer_first_mpls_over_udp_s_bos = 0; 1682 mpls_hdr |= misc2->outer_first_mpls_over_udp_ttl << HDR_MPLS_OFFSET_TTL; 1683 misc2->outer_first_mpls_over_udp_ttl = 0; 1684 1685 parser_id = sb->caps->flex_parser_id_mpls_over_udp; 1686 parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id); 1687 *(__be32 *)parser_ptr = cpu_to_be32(mpls_hdr); 1688 1689 return 0; 1690 } 1691 1692 void dr_ste_v1_build_tnl_mpls_over_udp_init(struct mlx5dr_ste_build *sb, 1693 struct mlx5dr_match_param *mask) 1694 { 1695 dr_ste_v1_build_tnl_mpls_over_udp_tag(mask, sb, sb->bit_mask); 1696 1697 /* STEs with lookup type FLEX_PARSER_{0/1} includes 1698 * flex parsers_{0-3}/{4-7} respectively. 1699 */ 1700 sb->lu_type = sb->caps->flex_parser_id_mpls_over_udp > DR_STE_MAX_FLEX_0_ID ? 1701 DR_STE_V1_LU_TYPE_FLEX_PARSER_1 : 1702 DR_STE_V1_LU_TYPE_FLEX_PARSER_0; 1703 1704 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1705 sb->ste_build_tag_func = &dr_ste_v1_build_tnl_mpls_over_udp_tag; 1706 } 1707 1708 static int dr_ste_v1_build_tnl_mpls_over_gre_tag(struct mlx5dr_match_param *value, 1709 struct mlx5dr_ste_build *sb, 1710 u8 *tag) 1711 { 1712 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1713 u8 *parser_ptr; 1714 u8 parser_id; 1715 u32 mpls_hdr; 1716 1717 mpls_hdr = misc2->outer_first_mpls_over_gre_label << HDR_MPLS_OFFSET_LABEL; 1718 misc2->outer_first_mpls_over_gre_label = 0; 1719 mpls_hdr |= misc2->outer_first_mpls_over_gre_exp << HDR_MPLS_OFFSET_EXP; 1720 misc2->outer_first_mpls_over_gre_exp = 0; 1721 mpls_hdr |= misc2->outer_first_mpls_over_gre_s_bos << HDR_MPLS_OFFSET_S_BOS; 1722 misc2->outer_first_mpls_over_gre_s_bos = 0; 1723 mpls_hdr |= misc2->outer_first_mpls_over_gre_ttl << HDR_MPLS_OFFSET_TTL; 1724 misc2->outer_first_mpls_over_gre_ttl = 0; 1725 1726 parser_id = sb->caps->flex_parser_id_mpls_over_gre; 1727 parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id); 1728 *(__be32 *)parser_ptr = cpu_to_be32(mpls_hdr); 1729 1730 return 0; 1731 } 1732 1733 void dr_ste_v1_build_tnl_mpls_over_gre_init(struct mlx5dr_ste_build *sb, 1734 struct mlx5dr_match_param *mask) 1735 { 1736 dr_ste_v1_build_tnl_mpls_over_gre_tag(mask, sb, sb->bit_mask); 1737 1738 /* STEs with lookup type FLEX_PARSER_{0/1} includes 1739 * flex parsers_{0-3}/{4-7} respectively. 1740 */ 1741 sb->lu_type = sb->caps->flex_parser_id_mpls_over_gre > DR_STE_MAX_FLEX_0_ID ? 1742 DR_STE_V1_LU_TYPE_FLEX_PARSER_1 : 1743 DR_STE_V1_LU_TYPE_FLEX_PARSER_0; 1744 1745 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1746 sb->ste_build_tag_func = &dr_ste_v1_build_tnl_mpls_over_gre_tag; 1747 } 1748 1749 static int dr_ste_v1_build_icmp_tag(struct mlx5dr_match_param *value, 1750 struct mlx5dr_ste_build *sb, 1751 u8 *tag) 1752 { 1753 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1754 bool is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc3); 1755 u32 *icmp_header_data; 1756 u8 *icmp_type; 1757 u8 *icmp_code; 1758 1759 if (is_ipv4) { 1760 icmp_header_data = &misc3->icmpv4_header_data; 1761 icmp_type = &misc3->icmpv4_type; 1762 icmp_code = &misc3->icmpv4_code; 1763 } else { 1764 icmp_header_data = &misc3->icmpv6_header_data; 1765 icmp_type = &misc3->icmpv6_type; 1766 icmp_code = &misc3->icmpv6_code; 1767 } 1768 1769 MLX5_SET(ste_icmp_v1, tag, icmp_header_data, *icmp_header_data); 1770 MLX5_SET(ste_icmp_v1, tag, icmp_type, *icmp_type); 1771 MLX5_SET(ste_icmp_v1, tag, icmp_code, *icmp_code); 1772 1773 *icmp_header_data = 0; 1774 *icmp_type = 0; 1775 *icmp_code = 0; 1776 1777 return 0; 1778 } 1779 1780 void dr_ste_v1_build_icmp_init(struct mlx5dr_ste_build *sb, 1781 struct mlx5dr_match_param *mask) 1782 { 1783 dr_ste_v1_build_icmp_tag(mask, sb, sb->bit_mask); 1784 1785 sb->lu_type = DR_STE_V1_LU_TYPE_ETHL4_MISC_O; 1786 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1787 sb->ste_build_tag_func = &dr_ste_v1_build_icmp_tag; 1788 } 1789 1790 static int dr_ste_v1_build_general_purpose_tag(struct mlx5dr_match_param *value, 1791 struct mlx5dr_ste_build *sb, 1792 u8 *tag) 1793 { 1794 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1795 1796 DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field, 1797 misc2, metadata_reg_a); 1798 1799 return 0; 1800 } 1801 1802 void dr_ste_v1_build_general_purpose_init(struct mlx5dr_ste_build *sb, 1803 struct mlx5dr_match_param *mask) 1804 { 1805 dr_ste_v1_build_general_purpose_tag(mask, sb, sb->bit_mask); 1806 1807 sb->lu_type = DR_STE_V1_LU_TYPE_GENERAL_PURPOSE; 1808 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1809 sb->ste_build_tag_func = &dr_ste_v1_build_general_purpose_tag; 1810 } 1811 1812 static int dr_ste_v1_build_eth_l4_misc_tag(struct mlx5dr_match_param *value, 1813 struct mlx5dr_ste_build *sb, 1814 u8 *tag) 1815 { 1816 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1817 1818 if (sb->inner) { 1819 DR_STE_SET_TAG(eth_l4_misc_v1, tag, seq_num, misc3, inner_tcp_seq_num); 1820 DR_STE_SET_TAG(eth_l4_misc_v1, tag, ack_num, misc3, inner_tcp_ack_num); 1821 } else { 1822 DR_STE_SET_TAG(eth_l4_misc_v1, tag, seq_num, misc3, outer_tcp_seq_num); 1823 DR_STE_SET_TAG(eth_l4_misc_v1, tag, ack_num, misc3, outer_tcp_ack_num); 1824 } 1825 1826 return 0; 1827 } 1828 1829 void dr_ste_v1_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb, 1830 struct mlx5dr_match_param *mask) 1831 { 1832 dr_ste_v1_build_eth_l4_misc_tag(mask, sb, sb->bit_mask); 1833 1834 sb->lu_type = DR_STE_V1_LU_TYPE_ETHL4_MISC_O; 1835 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1836 sb->ste_build_tag_func = &dr_ste_v1_build_eth_l4_misc_tag; 1837 } 1838 1839 static int 1840 dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value, 1841 struct mlx5dr_ste_build *sb, 1842 u8 *tag) 1843 { 1844 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 1845 1846 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1847 outer_vxlan_gpe_flags, misc3, 1848 outer_vxlan_gpe_flags); 1849 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1850 outer_vxlan_gpe_next_protocol, misc3, 1851 outer_vxlan_gpe_next_protocol); 1852 DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 1853 outer_vxlan_gpe_vni, misc3, 1854 outer_vxlan_gpe_vni); 1855 1856 return 0; 1857 } 1858 1859 void dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb, 1860 struct mlx5dr_match_param *mask) 1861 { 1862 dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask); 1863 1864 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER; 1865 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1866 sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag; 1867 } 1868 1869 static int 1870 dr_ste_v1_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value, 1871 struct mlx5dr_ste_build *sb, 1872 u8 *tag) 1873 { 1874 struct mlx5dr_match_misc *misc = &value->misc; 1875 1876 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1877 geneve_protocol_type, misc, geneve_protocol_type); 1878 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1879 geneve_oam, misc, geneve_oam); 1880 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1881 geneve_opt_len, misc, geneve_opt_len); 1882 DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 1883 geneve_vni, misc, geneve_vni); 1884 1885 return 0; 1886 } 1887 1888 void dr_ste_v1_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb, 1889 struct mlx5dr_match_param *mask) 1890 { 1891 dr_ste_v1_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask); 1892 1893 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER; 1894 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1895 sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_geneve_tag; 1896 } 1897 1898 static int dr_ste_v1_build_tnl_header_0_1_tag(struct mlx5dr_match_param *value, 1899 struct mlx5dr_ste_build *sb, 1900 uint8_t *tag) 1901 { 1902 struct mlx5dr_match_misc5 *misc5 = &value->misc5; 1903 1904 DR_STE_SET_TAG(tunnel_header, tag, tunnel_header_0, misc5, tunnel_header_0); 1905 DR_STE_SET_TAG(tunnel_header, tag, tunnel_header_1, misc5, tunnel_header_1); 1906 1907 return 0; 1908 } 1909 1910 void dr_ste_v1_build_tnl_header_0_1_init(struct mlx5dr_ste_build *sb, 1911 struct mlx5dr_match_param *mask) 1912 { 1913 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER; 1914 dr_ste_v1_build_tnl_header_0_1_tag(mask, sb, sb->bit_mask); 1915 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1916 sb->ste_build_tag_func = &dr_ste_v1_build_tnl_header_0_1_tag; 1917 } 1918 1919 static int dr_ste_v1_build_register_0_tag(struct mlx5dr_match_param *value, 1920 struct mlx5dr_ste_build *sb, 1921 u8 *tag) 1922 { 1923 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1924 1925 DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0); 1926 DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1); 1927 DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2); 1928 DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3); 1929 1930 return 0; 1931 } 1932 1933 void dr_ste_v1_build_register_0_init(struct mlx5dr_ste_build *sb, 1934 struct mlx5dr_match_param *mask) 1935 { 1936 dr_ste_v1_build_register_0_tag(mask, sb, sb->bit_mask); 1937 1938 sb->lu_type = DR_STE_V1_LU_TYPE_STEERING_REGISTERS_0; 1939 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1940 sb->ste_build_tag_func = &dr_ste_v1_build_register_0_tag; 1941 } 1942 1943 static int dr_ste_v1_build_register_1_tag(struct mlx5dr_match_param *value, 1944 struct mlx5dr_ste_build *sb, 1945 u8 *tag) 1946 { 1947 struct mlx5dr_match_misc2 *misc2 = &value->misc2; 1948 1949 DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4); 1950 DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5); 1951 DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6); 1952 DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7); 1953 1954 return 0; 1955 } 1956 1957 void dr_ste_v1_build_register_1_init(struct mlx5dr_ste_build *sb, 1958 struct mlx5dr_match_param *mask) 1959 { 1960 dr_ste_v1_build_register_1_tag(mask, sb, sb->bit_mask); 1961 1962 sb->lu_type = DR_STE_V1_LU_TYPE_STEERING_REGISTERS_1; 1963 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 1964 sb->ste_build_tag_func = &dr_ste_v1_build_register_1_tag; 1965 } 1966 1967 static void dr_ste_v1_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value, 1968 u8 *bit_mask) 1969 { 1970 struct mlx5dr_match_misc *misc_mask = &value->misc; 1971 1972 DR_STE_SET_ONES(src_gvmi_qp_v1, bit_mask, source_gvmi, misc_mask, source_port); 1973 DR_STE_SET_ONES(src_gvmi_qp_v1, bit_mask, source_qp, misc_mask, source_sqn); 1974 misc_mask->source_eswitch_owner_vhca_id = 0; 1975 } 1976 1977 static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, 1978 struct mlx5dr_ste_build *sb, 1979 u8 *tag) 1980 { 1981 struct mlx5dr_match_misc *misc = &value->misc; 1982 struct mlx5dr_cmd_vport_cap *vport_cap; 1983 struct mlx5dr_domain *dmn = sb->dmn; 1984 struct mlx5dr_domain *vport_dmn; 1985 u8 *bit_mask = sb->bit_mask; 1986 1987 DR_STE_SET_TAG(src_gvmi_qp_v1, tag, source_qp, misc, source_sqn); 1988 1989 if (sb->vhca_id_valid) { 1990 /* Find port GVMI based on the eswitch_owner_vhca_id */ 1991 if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi) 1992 vport_dmn = dmn; 1993 else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id == 1994 dmn->peer_dmn->info.caps.gvmi)) 1995 vport_dmn = dmn->peer_dmn; 1996 else 1997 return -EINVAL; 1998 1999 misc->source_eswitch_owner_vhca_id = 0; 2000 } else { 2001 vport_dmn = dmn; 2002 } 2003 2004 if (!MLX5_GET(ste_src_gvmi_qp_v1, bit_mask, source_gvmi)) 2005 return 0; 2006 2007 vport_cap = mlx5dr_domain_get_vport_cap(vport_dmn, misc->source_port); 2008 if (!vport_cap) { 2009 mlx5dr_err(dmn, "Vport 0x%x is disabled or invalid\n", 2010 misc->source_port); 2011 return -EINVAL; 2012 } 2013 2014 if (vport_cap->vport_gvmi) 2015 MLX5_SET(ste_src_gvmi_qp_v1, tag, source_gvmi, vport_cap->vport_gvmi); 2016 2017 misc->source_port = 0; 2018 return 0; 2019 } 2020 2021 void dr_ste_v1_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb, 2022 struct mlx5dr_match_param *mask) 2023 { 2024 dr_ste_v1_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask); 2025 2026 sb->lu_type = DR_STE_V1_LU_TYPE_SRC_QP_GVMI; 2027 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 2028 sb->ste_build_tag_func = &dr_ste_v1_build_src_gvmi_qpn_tag; 2029 } 2030 2031 static void dr_ste_v1_set_flex_parser(u32 *misc4_field_id, 2032 u32 *misc4_field_value, 2033 bool *parser_is_used, 2034 u8 *tag) 2035 { 2036 u32 id = *misc4_field_id; 2037 u8 *parser_ptr; 2038 2039 if (id >= DR_NUM_OF_FLEX_PARSERS || parser_is_used[id]) 2040 return; 2041 2042 parser_is_used[id] = true; 2043 parser_ptr = dr_ste_calc_flex_parser_offset(tag, id); 2044 2045 *(__be32 *)parser_ptr = cpu_to_be32(*misc4_field_value); 2046 *misc4_field_id = 0; 2047 *misc4_field_value = 0; 2048 } 2049 2050 static int dr_ste_v1_build_felx_parser_tag(struct mlx5dr_match_param *value, 2051 struct mlx5dr_ste_build *sb, 2052 u8 *tag) 2053 { 2054 struct mlx5dr_match_misc4 *misc_4_mask = &value->misc4; 2055 bool parser_is_used[DR_NUM_OF_FLEX_PARSERS] = {}; 2056 2057 dr_ste_v1_set_flex_parser(&misc_4_mask->prog_sample_field_id_0, 2058 &misc_4_mask->prog_sample_field_value_0, 2059 parser_is_used, tag); 2060 2061 dr_ste_v1_set_flex_parser(&misc_4_mask->prog_sample_field_id_1, 2062 &misc_4_mask->prog_sample_field_value_1, 2063 parser_is_used, tag); 2064 2065 dr_ste_v1_set_flex_parser(&misc_4_mask->prog_sample_field_id_2, 2066 &misc_4_mask->prog_sample_field_value_2, 2067 parser_is_used, tag); 2068 2069 dr_ste_v1_set_flex_parser(&misc_4_mask->prog_sample_field_id_3, 2070 &misc_4_mask->prog_sample_field_value_3, 2071 parser_is_used, tag); 2072 2073 return 0; 2074 } 2075 2076 void dr_ste_v1_build_flex_parser_0_init(struct mlx5dr_ste_build *sb, 2077 struct mlx5dr_match_param *mask) 2078 { 2079 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_0; 2080 dr_ste_v1_build_felx_parser_tag(mask, sb, sb->bit_mask); 2081 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 2082 sb->ste_build_tag_func = &dr_ste_v1_build_felx_parser_tag; 2083 } 2084 2085 void dr_ste_v1_build_flex_parser_1_init(struct mlx5dr_ste_build *sb, 2086 struct mlx5dr_match_param *mask) 2087 { 2088 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_1; 2089 dr_ste_v1_build_felx_parser_tag(mask, sb, sb->bit_mask); 2090 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 2091 sb->ste_build_tag_func = &dr_ste_v1_build_felx_parser_tag; 2092 } 2093 2094 static int 2095 dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_tag(struct mlx5dr_match_param *value, 2096 struct mlx5dr_ste_build *sb, 2097 u8 *tag) 2098 { 2099 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 2100 u8 parser_id = sb->caps->flex_parser_id_geneve_tlv_option_0; 2101 u8 *parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id); 2102 2103 MLX5_SET(ste_flex_parser_0, parser_ptr, flex_parser_3, 2104 misc3->geneve_tlv_option_0_data); 2105 misc3->geneve_tlv_option_0_data = 0; 2106 2107 return 0; 2108 } 2109 2110 void 2111 dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_init(struct mlx5dr_ste_build *sb, 2112 struct mlx5dr_match_param *mask) 2113 { 2114 dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_tag(mask, sb, sb->bit_mask); 2115 2116 /* STEs with lookup type FLEX_PARSER_{0/1} includes 2117 * flex parsers_{0-3}/{4-7} respectively. 2118 */ 2119 sb->lu_type = sb->caps->flex_parser_id_geneve_tlv_option_0 > 3 ? 2120 DR_STE_V1_LU_TYPE_FLEX_PARSER_1 : 2121 DR_STE_V1_LU_TYPE_FLEX_PARSER_0; 2122 2123 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 2124 sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_tag; 2125 } 2126 2127 static int 2128 dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_exist_tag(struct mlx5dr_match_param *value, 2129 struct mlx5dr_ste_build *sb, 2130 uint8_t *tag) 2131 { 2132 u8 parser_id = sb->caps->flex_parser_id_geneve_tlv_option_0; 2133 struct mlx5dr_match_misc *misc = &value->misc; 2134 2135 if (misc->geneve_tlv_option_0_exist) { 2136 MLX5_SET(ste_flex_parser_ok, tag, flex_parsers_ok, 1 << parser_id); 2137 misc->geneve_tlv_option_0_exist = 0; 2138 } 2139 2140 return 0; 2141 } 2142 2143 void 2144 dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_exist_init(struct mlx5dr_ste_build *sb, 2145 struct mlx5dr_match_param *mask) 2146 { 2147 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_OK; 2148 dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_exist_tag(mask, sb, sb->bit_mask); 2149 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 2150 sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_exist_tag; 2151 } 2152 2153 static int dr_ste_v1_build_flex_parser_tnl_gtpu_tag(struct mlx5dr_match_param *value, 2154 struct mlx5dr_ste_build *sb, 2155 u8 *tag) 2156 { 2157 struct mlx5dr_match_misc3 *misc3 = &value->misc3; 2158 2159 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, gtpu_msg_flags, misc3, gtpu_msg_flags); 2160 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, gtpu_msg_type, misc3, gtpu_msg_type); 2161 DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, gtpu_teid, misc3, gtpu_teid); 2162 2163 return 0; 2164 } 2165 2166 void dr_ste_v1_build_flex_parser_tnl_gtpu_init(struct mlx5dr_ste_build *sb, 2167 struct mlx5dr_match_param *mask) 2168 { 2169 dr_ste_v1_build_flex_parser_tnl_gtpu_tag(mask, sb, sb->bit_mask); 2170 2171 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER; 2172 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 2173 sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_gtpu_tag; 2174 } 2175 2176 static int 2177 dr_ste_v1_build_tnl_gtpu_flex_parser_0_tag(struct mlx5dr_match_param *value, 2178 struct mlx5dr_ste_build *sb, 2179 u8 *tag) 2180 { 2181 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_dw_0)) 2182 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_0, sb->caps, &value->misc3); 2183 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_teid)) 2184 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_teid, sb->caps, &value->misc3); 2185 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_dw_2)) 2186 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_2, sb->caps, &value->misc3); 2187 if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_first_ext_dw_0)) 2188 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_first_ext_dw_0, sb->caps, &value->misc3); 2189 return 0; 2190 } 2191 2192 void 2193 dr_ste_v1_build_tnl_gtpu_flex_parser_0_init(struct mlx5dr_ste_build *sb, 2194 struct mlx5dr_match_param *mask) 2195 { 2196 dr_ste_v1_build_tnl_gtpu_flex_parser_0_tag(mask, sb, sb->bit_mask); 2197 2198 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_0; 2199 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 2200 sb->ste_build_tag_func = &dr_ste_v1_build_tnl_gtpu_flex_parser_0_tag; 2201 } 2202 2203 static int 2204 dr_ste_v1_build_tnl_gtpu_flex_parser_1_tag(struct mlx5dr_match_param *value, 2205 struct mlx5dr_ste_build *sb, 2206 u8 *tag) 2207 { 2208 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_dw_0)) 2209 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_0, sb->caps, &value->misc3); 2210 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_teid)) 2211 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_teid, sb->caps, &value->misc3); 2212 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_dw_2)) 2213 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_2, sb->caps, &value->misc3); 2214 if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_first_ext_dw_0)) 2215 DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_first_ext_dw_0, sb->caps, &value->misc3); 2216 return 0; 2217 } 2218 2219 void 2220 dr_ste_v1_build_tnl_gtpu_flex_parser_1_init(struct mlx5dr_ste_build *sb, 2221 struct mlx5dr_match_param *mask) 2222 { 2223 dr_ste_v1_build_tnl_gtpu_flex_parser_1_tag(mask, sb, sb->bit_mask); 2224 2225 sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_1; 2226 sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 2227 sb->ste_build_tag_func = &dr_ste_v1_build_tnl_gtpu_flex_parser_1_tag; 2228 } 2229 2230 int dr_ste_v1_alloc_modify_hdr_ptrn_arg(struct mlx5dr_action *action) 2231 { 2232 struct mlx5dr_ptrn_mgr *ptrn_mgr; 2233 int ret; 2234 2235 ptrn_mgr = action->rewrite->dmn->ptrn_mgr; 2236 if (!ptrn_mgr) 2237 return -EOPNOTSUPP; 2238 2239 action->rewrite->arg = mlx5dr_arg_get_obj(action->rewrite->dmn->arg_mgr, 2240 action->rewrite->num_of_actions, 2241 action->rewrite->data); 2242 if (!action->rewrite->arg) { 2243 mlx5dr_err(action->rewrite->dmn, "Failed allocating args for modify header\n"); 2244 return -EAGAIN; 2245 } 2246 2247 action->rewrite->ptrn = 2248 mlx5dr_ptrn_cache_get_pattern(ptrn_mgr, 2249 action->rewrite->num_of_actions, 2250 action->rewrite->data); 2251 if (!action->rewrite->ptrn) { 2252 mlx5dr_err(action->rewrite->dmn, "Failed to get pattern\n"); 2253 ret = -EAGAIN; 2254 goto put_arg; 2255 } 2256 2257 return 0; 2258 2259 put_arg: 2260 mlx5dr_arg_put_obj(action->rewrite->dmn->arg_mgr, 2261 action->rewrite->arg); 2262 return ret; 2263 } 2264 2265 void dr_ste_v1_free_modify_hdr_ptrn_arg(struct mlx5dr_action *action) 2266 { 2267 mlx5dr_ptrn_cache_put_pattern(action->rewrite->dmn->ptrn_mgr, 2268 action->rewrite->ptrn); 2269 mlx5dr_arg_put_obj(action->rewrite->dmn->arg_mgr, 2270 action->rewrite->arg); 2271 } 2272 2273 static struct mlx5dr_ste_ctx ste_ctx_v1 = { 2274 /* Builders */ 2275 .build_eth_l2_src_dst_init = &dr_ste_v1_build_eth_l2_src_dst_init, 2276 .build_eth_l3_ipv6_src_init = &dr_ste_v1_build_eth_l3_ipv6_src_init, 2277 .build_eth_l3_ipv6_dst_init = &dr_ste_v1_build_eth_l3_ipv6_dst_init, 2278 .build_eth_l3_ipv4_5_tuple_init = &dr_ste_v1_build_eth_l3_ipv4_5_tuple_init, 2279 .build_eth_l2_src_init = &dr_ste_v1_build_eth_l2_src_init, 2280 .build_eth_l2_dst_init = &dr_ste_v1_build_eth_l2_dst_init, 2281 .build_eth_l2_tnl_init = &dr_ste_v1_build_eth_l2_tnl_init, 2282 .build_eth_l3_ipv4_misc_init = &dr_ste_v1_build_eth_l3_ipv4_misc_init, 2283 .build_eth_ipv6_l3_l4_init = &dr_ste_v1_build_eth_ipv6_l3_l4_init, 2284 .build_mpls_init = &dr_ste_v1_build_mpls_init, 2285 .build_tnl_gre_init = &dr_ste_v1_build_tnl_gre_init, 2286 .build_tnl_mpls_init = &dr_ste_v1_build_tnl_mpls_init, 2287 .build_tnl_mpls_over_udp_init = &dr_ste_v1_build_tnl_mpls_over_udp_init, 2288 .build_tnl_mpls_over_gre_init = &dr_ste_v1_build_tnl_mpls_over_gre_init, 2289 .build_icmp_init = &dr_ste_v1_build_icmp_init, 2290 .build_general_purpose_init = &dr_ste_v1_build_general_purpose_init, 2291 .build_eth_l4_misc_init = &dr_ste_v1_build_eth_l4_misc_init, 2292 .build_tnl_vxlan_gpe_init = &dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_init, 2293 .build_tnl_geneve_init = &dr_ste_v1_build_flex_parser_tnl_geneve_init, 2294 .build_tnl_geneve_tlv_opt_init = &dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_init, 2295 .build_tnl_geneve_tlv_opt_exist_init = &dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_exist_init, 2296 .build_register_0_init = &dr_ste_v1_build_register_0_init, 2297 .build_register_1_init = &dr_ste_v1_build_register_1_init, 2298 .build_src_gvmi_qpn_init = &dr_ste_v1_build_src_gvmi_qpn_init, 2299 .build_flex_parser_0_init = &dr_ste_v1_build_flex_parser_0_init, 2300 .build_flex_parser_1_init = &dr_ste_v1_build_flex_parser_1_init, 2301 .build_tnl_gtpu_init = &dr_ste_v1_build_flex_parser_tnl_gtpu_init, 2302 .build_tnl_header_0_1_init = &dr_ste_v1_build_tnl_header_0_1_init, 2303 .build_tnl_gtpu_flex_parser_0_init = &dr_ste_v1_build_tnl_gtpu_flex_parser_0_init, 2304 .build_tnl_gtpu_flex_parser_1_init = &dr_ste_v1_build_tnl_gtpu_flex_parser_1_init, 2305 2306 /* Getters and Setters */ 2307 .ste_init = &dr_ste_v1_init, 2308 .set_next_lu_type = &dr_ste_v1_set_next_lu_type, 2309 .get_next_lu_type = &dr_ste_v1_get_next_lu_type, 2310 .is_miss_addr_set = &dr_ste_v1_is_miss_addr_set, 2311 .set_miss_addr = &dr_ste_v1_set_miss_addr, 2312 .get_miss_addr = &dr_ste_v1_get_miss_addr, 2313 .set_hit_addr = &dr_ste_v1_set_hit_addr, 2314 .set_byte_mask = &dr_ste_v1_set_byte_mask, 2315 .get_byte_mask = &dr_ste_v1_get_byte_mask, 2316 /* Actions */ 2317 .actions_caps = DR_STE_CTX_ACTION_CAP_TX_POP | 2318 DR_STE_CTX_ACTION_CAP_RX_PUSH | 2319 DR_STE_CTX_ACTION_CAP_RX_ENCAP | 2320 DR_STE_CTX_ACTION_CAP_POP_MDFY, 2321 .set_actions_rx = &dr_ste_v1_set_actions_rx, 2322 .set_actions_tx = &dr_ste_v1_set_actions_tx, 2323 .modify_field_arr_sz = ARRAY_SIZE(dr_ste_v1_action_modify_field_arr), 2324 .modify_field_arr = dr_ste_v1_action_modify_field_arr, 2325 .set_action_set = &dr_ste_v1_set_action_set, 2326 .set_action_add = &dr_ste_v1_set_action_add, 2327 .set_action_copy = &dr_ste_v1_set_action_copy, 2328 .set_action_decap_l3_list = &dr_ste_v1_set_action_decap_l3_list, 2329 .alloc_modify_hdr_chunk = &dr_ste_v1_alloc_modify_hdr_ptrn_arg, 2330 .dealloc_modify_hdr_chunk = &dr_ste_v1_free_modify_hdr_ptrn_arg, 2331 2332 /* Send */ 2333 .prepare_for_postsend = &dr_ste_v1_prepare_for_postsend, 2334 }; 2335 2336 struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx_v1(void) 2337 { 2338 return &ste_ctx_v1; 2339 } 2340