FILE
definer.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2/* Copyright (c) 2024 NVIDIA Corporation & Affiliates */ 3 4#include "internal.h" 5 6/* Pattern tunnel Layer bits. */ 7#define MLX5_FLOW_LAYER_VXLAN BIT(12) 8#define MLX5_FLOW_LAYER_VXLAN_GPE BIT(13) 9#define MLX5_FLOW_LAYER_GRE BIT(14) 10#define MLX5_FLOW_LAYER_MPLS BIT(15) 11 12/* Pattern tunnel Layer bits (continued). */ 13#define MLX5_FLOW_LAYER_IPIP BIT(23) 14#define MLX5_FLOW_LAYER_IPV6_ENCAP BIT(24) 15#define MLX5_FLOW_LAYER_NVGRE BIT(25) 16#define MLX5_FLOW_LAYER_GENEVE BIT(26) 17 18#define MLX5_FLOW_ITEM_FLEX_TUNNEL BIT_ULL(39) 19 20/* Tunnel Masks. */ 21#define MLX5_FLOW_LAYER_TUNNEL \ 22 (MLX5_FLOW_LAYER_VXLAN | MLX5_FLOW_LAYER_VXLAN_GPE | \ 23 MLX5_FLOW_LAYER_GRE | MLX5_FLOW_LAYER_NVGRE | MLX5_FLOW_LAYER_MPLS | \ 24 MLX5_FLOW_LAYER_IPIP | MLX5_FLOW_LAYER_IPV6_ENCAP | \ 25 MLX5_FLOW_LAYER_GENEVE | MLX5_FLOW_LAYER_GTP | \ 26 MLX5_FLOW_ITEM_FLEX_TUNNEL) 27 28#define GTP_PDU_SC 0x85 29#define BAD_PORT 0xBAD 30#define ETH_TYPE_IPV4_VXLAN 0x0800 31#define ETH_TYPE_IPV6_VXLAN 0x86DD 32#define UDP_GTPU_PORT 2152 33#define UDP_PORT_MPLS 6635 34#define UDP_GENEVE_PORT 6081 35#define UDP_ROCEV2_PORT 4791 36#define HWS_FLOW_LAYER_TUNNEL_NO_MPLS (MLX5_FLOW_LAYER_TUNNEL & ~MLX5_FLOW_LAYER_MPLS) 37 38#define STE_NO_VLAN 0x0 39#define STE_SVLAN 0x1 40#define STE_CVLAN 0x2 41#define STE_NO_L3 0x0 42#define STE_IPV4 0x1 43#define STE_IPV6 0x2 44#define STE_NO_L4 0x0 45#define STE_TCP 0x1 46#define STE_UDP 0x2 47#define STE_ICMP 0x3 48#define STE_ESP 0x3 49 50#define IPV4 0x4 51#define IPV6 0x6 52 53/* Setter function based on bit offset and mask, for 32bit DW */ 54#define _HWS_SET32(p, v, byte_off, bit_off, mask) \ 55 do { \ 56 u32 _v = v; \ 57 *((__be32 *)(p) + ((byte_off) / 4)) = \ 58 cpu_to_be32((be32_to_cpu(*((__be32 *)(p) + \ 59 ((byte_off) / 4))) & \ 60 (~((mask) << (bit_off)))) | \ 61 (((_v) & (mask)) << \ 62 (bit_off))); \ 63 } while (0) 64 65/* Setter function based on bit offset and mask, for unaligned 32bit DW */ 66#define HWS_SET32(p, v, byte_off, bit_off, mask) \ 67 do { \ 68 if (unlikely((bit_off) < 0)) { \ 69 u32 _bit_off = -1 * (bit_off); \ 70 u32 second_dw_mask = (mask) & ((1 << _bit_off) - 1); \ 71 _HWS_SET32(p, (v) >> _bit_off, byte_off, 0, (mask) >> _bit_off); \ 72 _HWS_SET32(p, (v) & second_dw_mask, (byte_off) + DW_SIZE, \ 73 (bit_off + BITS_IN_DW) % BITS_IN_DW, second_dw_mask); \ 74 } else { \ 75 _HWS_SET32(p, v, byte_off, (bit_off), (mask)); \ 76 } \ 77 } while (0) 78 79/* Getter for up to aligned 32bit DW */ 80#define HWS_GET32(p, byte_off, bit_off, mask) \ 81 ((be32_to_cpu(*((__be32 *)(p) + ((byte_off) / 4))) >> (bit_off)) & (mask)) 82 83#define HWS_CALC_FNAME(field, inner) \ 84 ((inner) ? MLX5HWS_DEFINER_FNAME_##field##_I : \ 85 MLX5HWS_DEFINER_FNAME_##field##_O) 86 87#define HWS_GET_MATCH_PARAM(match_param, hdr) \ 88 MLX5_GET(fte_match_param, match_param, hdr) 89 90#define HWS_IS_FLD_SET(match_param, hdr) \ 91 (!!(HWS_GET_MATCH_PARAM(match_param, hdr))) 92 93#define HWS_IS_FLD_SET_DW_ARR(match_param, hdr, sz_in_bits) ({ \ 94 BUILD_BUG_ON((sz_in_bits) % 32); \ 95 u32 sz = sz_in_bits; \ 96 u32 res = 0; \ 97 u32 dw_off = __mlx5_dw_off(fte_match_param, hdr); \ 98 while (!res && sz >= 32) { \ 99 res = *((match_param) + (dw_off++)); \ 100 sz -= 32; \ 101 } \ 102 res; \ 103 }) 104 105#define HWS_IS_FLD_SET_SZ(match_param, hdr, sz_in_bits) \ 106 (((sz_in_bits) > 32) ? HWS_IS_FLD_SET_DW_ARR(match_param, hdr, sz_in_bits) : \ 107 !!(HWS_GET_MATCH_PARAM(match_param, hdr))) 108 109#define HWS_GET64_MATCH_PARAM(match_param, hdr) \ 110 MLX5_GET64(fte_match_param, match_param, hdr) 111 112#define HWS_IS_FLD64_SET(match_param, hdr) \ 113 (!!(HWS_GET64_MATCH_PARAM(match_param, hdr))) 114 115#define HWS_CALC_HDR_SRC(fc, s_hdr) \ 116 do { \ 117 (fc)->s_bit_mask = __mlx5_mask(fte_match_param, s_hdr); \ 118 (fc)->s_bit_off = __mlx5_dw_bit_off(fte_match_param, s_hdr); \ 119 (fc)->s_byte_off = MLX5_BYTE_OFF(fte_match_param, s_hdr); \ 120 } while (0) 121 122#define HWS_CALC_HDR_DST(fc, d_hdr) \ 123 do { \ 124 (fc)->bit_mask = __mlx5_mask(definer_hl, d_hdr); \ 125 (fc)->bit_off = __mlx5_dw_bit_off(definer_hl, d_hdr); \ 126 (fc)->byte_off = MLX5_BYTE_OFF(definer_hl, d_hdr); \ 127 } while (0) 128 129#define HWS_CALC_HDR(fc, s_hdr, d_hdr) \ 130 do { \ 131 HWS_CALC_HDR_SRC(fc, s_hdr); \ 132 HWS_CALC_HDR_DST(fc, d_hdr); \ 133 (fc)->tag_set = &hws_definer_generic_set; \ 134 } while (0) 135 136#define HWS_SET_HDR(fc_arr, match_param, fname, s_hdr, d_hdr) \ 137 do { \ 138 if (HWS_IS_FLD_SET(match_param, s_hdr)) \ 139 HWS_CALC_HDR(&(fc_arr)[MLX5HWS_DEFINER_FNAME_##fname], s_hdr, d_hdr); \ 140 } while (0) 141 142struct mlx5hws_definer_sel_ctrl { 143 u8 allowed_full_dw; /* Full DW selectors cover all offsets */ 144 u8 allowed_lim_dw; /* Limited DW selectors cover offset < 64 */ 145 u8 allowed_bytes; /* Bytes selectors, up to offset 255 */ 146 u8 used_full_dw; 147 u8 used_lim_dw; 148 u8 used_bytes; 149 u8 full_dw_selector[DW_SELECTORS]; 150 u8 lim_dw_selector[DW_SELECTORS_LIMITED]; 151 u8 byte_selector[BYTE_SELECTORS]; 152}; 153 154struct mlx5hws_definer_conv_data { 155 struct mlx5hws_context *ctx; 156 struct mlx5hws_definer_fc *fc; 157 /* enum mlx5hws_definer_match_flag */ 158 u32 match_flags; 159}; 160 161#define HWS_DEFINER_ENTRY(name)[MLX5HWS_DEFINER_FNAME_##name] = #name 162 163static const char * const hws_definer_fname_to_str[] = { 164 HWS_DEFINER_ENTRY(ETH_SMAC_47_16_O), 165 HWS_DEFINER_ENTRY(ETH_SMAC_47_16_I), 166 HWS_DEFINER_ENTRY(ETH_SMAC_15_0_O), 167 HWS_DEFINER_ENTRY(ETH_SMAC_15_0_I), 168 HWS_DEFINER_ENTRY(ETH_DMAC_47_16_O), 169 HWS_DEFINER_ENTRY(ETH_DMAC_47_16_I), 170 HWS_DEFINER_ENTRY(ETH_DMAC_15_0_O), 171 HWS_DEFINER_ENTRY(ETH_DMAC_15_0_I), 172 HWS_DEFINER_ENTRY(ETH_TYPE_O), 173 HWS_DEFINER_ENTRY(ETH_TYPE_I), 174 HWS_DEFINER_ENTRY(ETH_L3_TYPE_O), 175 HWS_DEFINER_ENTRY(ETH_L3_TYPE_I), 176 HWS_DEFINER_ENTRY(VLAN_TYPE_O), 177 HWS_DEFINER_ENTRY(VLAN_TYPE_I), 178 HWS_DEFINER_ENTRY(VLAN_FIRST_PRIO_O), 179 HWS_DEFINER_ENTRY(VLAN_FIRST_PRIO_I), 180 HWS_DEFINER_ENTRY(VLAN_CFI_O), 181 HWS_DEFINER_ENTRY(VLAN_CFI_I), 182 HWS_DEFINER_ENTRY(VLAN_ID_O), 183 HWS_DEFINER_ENTRY(VLAN_ID_I), 184 HWS_DEFINER_ENTRY(VLAN_SECOND_TYPE_O), 185 HWS_DEFINER_ENTRY(VLAN_SECOND_TYPE_I), 186 HWS_DEFINER_ENTRY(VLAN_SECOND_PRIO_O), 187 HWS_DEFINER_ENTRY(VLAN_SECOND_PRIO_I), 188 HWS_DEFINER_ENTRY(VLAN_SECOND_CFI_O), 189 HWS_DEFINER_ENTRY(VLAN_SECOND_CFI_I), 190 HWS_DEFINER_ENTRY(VLAN_SECOND_ID_O), 191 HWS_DEFINER_ENTRY(VLAN_SECOND_ID_I), 192 HWS_DEFINER_ENTRY(IPV4_IHL_O), 193 HWS_DEFINER_ENTRY(IPV4_IHL_I), 194 HWS_DEFINER_ENTRY(IP_DSCP_O), 195 HWS_DEFINER_ENTRY(IP_DSCP_I), 196 HWS_DEFINER_ENTRY(IP_ECN_O), 197 HWS_DEFINER_ENTRY(IP_ECN_I), 198 HWS_DEFINER_ENTRY(IP_TTL_O), 199 HWS_DEFINER_ENTRY(IP_TTL_I), 200 HWS_DEFINER_ENTRY(IPV4_DST_O), 201 HWS_DEFINER_ENTRY(IPV4_DST_I), 202 HWS_DEFINER_ENTRY(IPV4_SRC_O), 203 HWS_DEFINER_ENTRY(IPV4_SRC_I), 204 HWS_DEFINER_ENTRY(IP_VERSION_O), 205 HWS_DEFINER_ENTRY(IP_VERSION_I), 206 HWS_DEFINER_ENTRY(IP_FRAG_O), 207 HWS_DEFINER_ENTRY(IP_FRAG_I), 208 HWS_DEFINER_ENTRY(IP_LEN_O), 209 HWS_DEFINER_ENTRY(IP_LEN_I), 210 HWS_DEFINER_ENTRY(IP_TOS_O), 211 HWS_DEFINER_ENTRY(IP_TOS_I), 212 HWS_DEFINER_ENTRY(IPV6_FLOW_LABEL_O), 213 HWS_DEFINER_ENTRY(IPV6_FLOW_LABEL_I), 214 HWS_DEFINER_ENTRY(IPV6_DST_127_96_O), 215 HWS_DEFINER_ENTRY(IPV6_DST_95_64_O), 216 HWS_DEFINER_ENTRY(IPV6_DST_63_32_O), 217 HWS_DEFINER_ENTRY(IPV6_DST_31_0_O), 218 HWS_DEFINER_ENTRY(IPV6_DST_127_96_I), 219 HWS_DEFINER_ENTRY(IPV6_DST_95_64_I), 220 HWS_DEFINER_ENTRY(IPV6_DST_63_32_I), 221 HWS_DEFINER_ENTRY(IPV6_DST_31_0_I), 222 HWS_DEFINER_ENTRY(IPV6_SRC_127_96_O), 223 HWS_DEFINER_ENTRY(IPV6_SRC_95_64_O), 224 HWS_DEFINER_ENTRY(IPV6_SRC_63_32_O), 225 HWS_DEFINER_ENTRY(IPV6_SRC_31_0_O), 226 HWS_DEFINER_ENTRY(IPV6_SRC_127_96_I), 227 HWS_DEFINER_ENTRY(IPV6_SRC_95_64_I), 228 HWS_DEFINER_ENTRY(IPV6_SRC_63_32_I), 229 HWS_DEFINER_ENTRY(IPV6_SRC_31_0_I), 230 HWS_DEFINER_ENTRY(IP_PROTOCOL_O), 231 HWS_DEFINER_ENTRY(IP_PROTOCOL_I), 232 HWS_DEFINER_ENTRY(L4_SPORT_O), 233 HWS_DEFINER_ENTRY(L4_SPORT_I), 234 HWS_DEFINER_ENTRY(L4_DPORT_O), 235 HWS_DEFINER_ENTRY(L4_DPORT_I), 236 HWS_DEFINER_ENTRY(TCP_FLAGS_I), 237 HWS_DEFINER_ENTRY(TCP_FLAGS_O), 238 HWS_DEFINER_ENTRY(TCP_SEQ_NUM), 239 HWS_DEFINER_ENTRY(TCP_ACK_NUM), 240 HWS_DEFINER_ENTRY(GTP_TEID), 241 HWS_DEFINER_ENTRY(GTP_MSG_TYPE), 242 HWS_DEFINER_ENTRY(GTP_EXT_FLAG), 243 HWS_DEFINER_ENTRY(GTP_NEXT_EXT_HDR), 244 HWS_DEFINER_ENTRY(GTP_EXT_HDR_PDU), 245 HWS_DEFINER_ENTRY(GTP_EXT_HDR_QFI), 246 HWS_DEFINER_ENTRY(GTPU_DW0), 247 HWS_DEFINER_ENTRY(GTPU_FIRST_EXT_DW0), 248 HWS_DEFINER_ENTRY(GTPU_DW2), 249 HWS_DEFINER_ENTRY(FLEX_PARSER_0), 250 HWS_DEFINER_ENTRY(FLEX_PARSER_1), 251 HWS_DEFINER_ENTRY(FLEX_PARSER_2), 252 HWS_DEFINER_ENTRY(FLEX_PARSER_3), 253 HWS_DEFINER_ENTRY(FLEX_PARSER_4), 254 HWS_DEFINER_ENTRY(FLEX_PARSER_5), 255 HWS_DEFINER_ENTRY(FLEX_PARSER_6), 256 HWS_DEFINER_ENTRY(FLEX_PARSER_7), 257 HWS_DEFINER_ENTRY(VPORT_REG_C_0), 258 HWS_DEFINER_ENTRY(VXLAN_FLAGS), 259 HWS_DEFINER_ENTRY(VXLAN_VNI), 260 HWS_DEFINER_ENTRY(VXLAN_GPE_FLAGS), 261 HWS_DEFINER_ENTRY(VXLAN_GPE_RSVD0), 262 HWS_DEFINER_ENTRY(VXLAN_GPE_PROTO), 263 HWS_DEFINER_ENTRY(VXLAN_GPE_VNI), 264 HWS_DEFINER_ENTRY(VXLAN_GPE_RSVD1), 265 HWS_DEFINER_ENTRY(GENEVE_OPT_LEN), 266 HWS_DEFINER_ENTRY(GENEVE_OAM), 267 HWS_DEFINER_ENTRY(GENEVE_PROTO), 268 HWS_DEFINER_ENTRY(GENEVE_VNI), 269 HWS_DEFINER_ENTRY(SOURCE_QP), 270 HWS_DEFINER_ENTRY(SOURCE_GVMI), 271 HWS_DEFINER_ENTRY(REG_0), 272 HWS_DEFINER_ENTRY(REG_1), 273 HWS_DEFINER_ENTRY(REG_2), 274 HWS_DEFINER_ENTRY(REG_3), 275 HWS_DEFINER_ENTRY(REG_4), 276 HWS_DEFINER_ENTRY(REG_5), 277 HWS_DEFINER_ENTRY(REG_6), 278 HWS_DEFINER_ENTRY(REG_7), 279 HWS_DEFINER_ENTRY(REG_8), 280 HWS_DEFINER_ENTRY(REG_9), 281 HWS_DEFINER_ENTRY(REG_10), 282 HWS_DEFINER_ENTRY(REG_11), 283 HWS_DEFINER_ENTRY(REG_A), 284 HWS_DEFINER_ENTRY(REG_B), 285 HWS_DEFINER_ENTRY(GRE_KEY_PRESENT), 286 HWS_DEFINER_ENTRY(GRE_C), 287 HWS_DEFINER_ENTRY(GRE_K), 288 HWS_DEFINER_ENTRY(GRE_S), 289 HWS_DEFINER_ENTRY(GRE_PROTOCOL), 290 HWS_DEFINER_ENTRY(GRE_OPT_KEY), 291 HWS_DEFINER_ENTRY(GRE_OPT_SEQ), 292 HWS_DEFINER_ENTRY(GRE_OPT_CHECKSUM), 293 HWS_DEFINER_ENTRY(INTEGRITY_O), 294 HWS_DEFINER_ENTRY(INTEGRITY_I), 295 HWS_DEFINER_ENTRY(ICMP_DW1), 296 HWS_DEFINER_ENTRY(ICMP_DW2), 297 HWS_DEFINER_ENTRY(ICMP_DW3), 298 HWS_DEFINER_ENTRY(IPSEC_SPI), 299 HWS_DEFINER_ENTRY(IPSEC_SEQUENCE_NUMBER), 300 HWS_DEFINER_ENTRY(IPSEC_SYNDROME), 301 HWS_DEFINER_ENTRY(MPLS0_O), 302 HWS_DEFINER_ENTRY(MPLS1_O), 303 HWS_DEFINER_ENTRY(MPLS2_O), 304 HWS_DEFINER_ENTRY(MPLS3_O), 305 HWS_DEFINER_ENTRY(MPLS4_O), 306 HWS_DEFINER_ENTRY(MPLS0_I), 307 HWS_DEFINER_ENTRY(MPLS1_I), 308 HWS_DEFINER_ENTRY(MPLS2_I), 309 HWS_DEFINER_ENTRY(MPLS3_I), 310 HWS_DEFINER_ENTRY(MPLS4_I), 311 HWS_DEFINER_ENTRY(FLEX_PARSER0_OK), 312 HWS_DEFINER_ENTRY(FLEX_PARSER1_OK), 313 HWS_DEFINER_ENTRY(FLEX_PARSER2_OK), 314 HWS_DEFINER_ENTRY(FLEX_PARSER3_OK), 315 HWS_DEFINER_ENTRY(FLEX_PARSER4_OK), 316 HWS_DEFINER_ENTRY(FLEX_PARSER5_OK), 317 HWS_DEFINER_ENTRY(FLEX_PARSER6_OK), 318 HWS_DEFINER_ENTRY(FLEX_PARSER7_OK), 319 HWS_DEFINER_ENTRY(OKS2_MPLS0_O), 320 HWS_DEFINER_ENTRY(OKS2_MPLS1_O), 321 HWS_DEFINER_ENTRY(OKS2_MPLS2_O), 322 HWS_DEFINER_ENTRY(OKS2_MPLS3_O), 323 HWS_DEFINER_ENTRY(OKS2_MPLS4_O), 324 HWS_DEFINER_ENTRY(OKS2_MPLS0_I), 325 HWS_DEFINER_ENTRY(OKS2_MPLS1_I), 326 HWS_DEFINER_ENTRY(OKS2_MPLS2_I), 327 HWS_DEFINER_ENTRY(OKS2_MPLS3_I), 328 HWS_DEFINER_ENTRY(OKS2_MPLS4_I), 329 HWS_DEFINER_ENTRY(GENEVE_OPT_OK_0), 330 HWS_DEFINER_ENTRY(GENEVE_OPT_OK_1), 331 HWS_DEFINER_ENTRY(GENEVE_OPT_OK_2), 332 HWS_DEFINER_ENTRY(GENEVE_OPT_OK_3), 333 HWS_DEFINER_ENTRY(GENEVE_OPT_OK_4), 334 HWS_DEFINER_ENTRY(GENEVE_OPT_OK_5), 335 HWS_DEFINER_ENTRY(GENEVE_OPT_OK_6), 336 HWS_DEFINER_ENTRY(GENEVE_OPT_OK_7), 337 HWS_DEFINER_ENTRY(GENEVE_OPT_DW_0), 338 HWS_DEFINER_ENTRY(GENEVE_OPT_DW_1), 339 HWS_DEFINER_ENTRY(GENEVE_OPT_DW_2), 340 HWS_DEFINER_ENTRY(GENEVE_OPT_DW_3), 341 HWS_DEFINER_ENTRY(GENEVE_OPT_DW_4), 342 HWS_DEFINER_ENTRY(GENEVE_OPT_DW_5), 343 HWS_DEFINER_ENTRY(GENEVE_OPT_DW_6), 344 HWS_DEFINER_ENTRY(GENEVE_OPT_DW_7), 345 HWS_DEFINER_ENTRY(IB_L4_OPCODE), 346 HWS_DEFINER_ENTRY(IB_L4_QPN), 347 HWS_DEFINER_ENTRY(IB_L4_A), 348 HWS_DEFINER_ENTRY(RANDOM_NUM), 349 HWS_DEFINER_ENTRY(PTYPE_L2_O), 350 HWS_DEFINER_ENTRY(PTYPE_L2_I), 351 HWS_DEFINER_ENTRY(PTYPE_L3_O), 352 HWS_DEFINER_ENTRY(PTYPE_L3_I), 353 HWS_DEFINER_ENTRY(PTYPE_L4_O), 354 HWS_DEFINER_ENTRY(PTYPE_L4_I), 355 HWS_DEFINER_ENTRY(PTYPE_L4_EXT_O), 356 HWS_DEFINER_ENTRY(PTYPE_L4_EXT_I), 357 HWS_DEFINER_ENTRY(PTYPE_FRAG_O), 358 HWS_DEFINER_ENTRY(PTYPE_FRAG_I), 359 HWS_DEFINER_ENTRY(TNL_HDR_0), 360 HWS_DEFINER_ENTRY(TNL_HDR_1), 361 HWS_DEFINER_ENTRY(TNL_HDR_2), 362 HWS_DEFINER_ENTRY(TNL_HDR_3), 363 [MLX5HWS_DEFINER_FNAME_MAX] = "DEFINER_FNAME_UNKNOWN", 364}; 365 366const char *mlx5hws_definer_fname_to_str(enum mlx5hws_definer_fname fname) 367{ 368 if (fname > MLX5HWS_DEFINER_FNAME_MAX) 369 fname = MLX5HWS_DEFINER_FNAME_MAX; 370 return hws_definer_fname_to_str[fname]; 371} 372 373static void 374hws_definer_ones_set(struct mlx5hws_definer_fc *fc, 375 void *match_param, 376 u8 *tag) 377{ 378 HWS_SET32(tag, -1, fc->byte_off, fc->bit_off, fc->bit_mask); 379} 380 381static void 382hws_definer_generic_set(struct mlx5hws_definer_fc *fc, 383 void *match_param, 384 u8 *tag) 385{ 386 /* Can be optimized */ 387 u32 val = HWS_GET32(match_param, fc->s_byte_off, fc->s_bit_off, fc->s_bit_mask); 388 389 HWS_SET32(tag, val, fc->byte_off, fc->bit_off, fc->bit_mask); 390} 391 392static void 393hws_definer_outer_vlan_type_set(struct mlx5hws_definer_fc *fc, 394 void *match_param, 395 u8 *tag) 396{ 397 if (HWS_GET_MATCH_PARAM(match_param, outer_headers.cvlan_tag)) 398 HWS_SET32(tag, STE_CVLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 399 else if (HWS_GET_MATCH_PARAM(match_param, outer_headers.svlan_tag)) 400 HWS_SET32(tag, STE_SVLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 401 else 402 HWS_SET32(tag, STE_NO_VLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 403} 404 405static void 406hws_definer_inner_vlan_type_set(struct mlx5hws_definer_fc *fc, 407 void *match_param, 408 u8 *tag) 409{ 410 if (HWS_GET_MATCH_PARAM(match_param, inner_headers.cvlan_tag)) 411 HWS_SET32(tag, STE_CVLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 412 else if (HWS_GET_MATCH_PARAM(match_param, inner_headers.svlan_tag)) 413 HWS_SET32(tag, STE_SVLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 414 else 415 HWS_SET32(tag, STE_NO_VLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 416} 417 418static void 419hws_definer_second_vlan_type_set(struct mlx5hws_definer_fc *fc, 420 void *match_param, 421 u8 *tag, 422 bool inner) 423{ 424 u32 second_cvlan_tag = inner ? 425 HWS_GET_MATCH_PARAM(match_param, misc_parameters.inner_second_cvlan_tag) : 426 HWS_GET_MATCH_PARAM(match_param, misc_parameters.outer_second_cvlan_tag); 427 u32 second_svlan_tag = inner ? 428 HWS_GET_MATCH_PARAM(match_param, misc_parameters.inner_second_svlan_tag) : 429 HWS_GET_MATCH_PARAM(match_param, misc_parameters.outer_second_svlan_tag); 430 431 if (second_cvlan_tag) 432 HWS_SET32(tag, STE_CVLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 433 else if (second_svlan_tag) 434 HWS_SET32(tag, STE_SVLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 435 else 436 HWS_SET32(tag, STE_NO_VLAN, fc->byte_off, fc->bit_off, fc->bit_mask); 437} 438 439static void 440hws_definer_inner_second_vlan_type_set(struct mlx5hws_definer_fc *fc, 441 void *match_param, 442 u8 *tag) 443{ 444 hws_definer_second_vlan_type_set(fc, match_param, tag, true); 445} 446 447static void 448hws_definer_outer_second_vlan_type_set(struct mlx5hws_definer_fc *fc, 449 void *match_param, 450 u8 *tag) 451{ 452 hws_definer_second_vlan_type_set(fc, match_param, tag, false); 453} 454 455static void hws_definer_icmp_dw1_set(struct mlx5hws_definer_fc *fc, 456 void *match_param, 457 u8 *tag) 458{ 459 u32 code = HWS_GET_MATCH_PARAM(match_param, misc_parameters_3.icmp_code); 460 u32 type = HWS_GET_MATCH_PARAM(match_param, misc_parameters_3.icmp_type); 461 u32 dw = (type << __mlx5_dw_bit_off(header_icmp, type)) | 462 (code << __mlx5_dw_bit_off(header_icmp, code)); 463 464 HWS_SET32(tag, dw, fc->byte_off, fc->bit_off, fc->bit_mask); 465} 466 467static void 468hws_definer_icmpv6_dw1_set(struct mlx5hws_definer_fc *fc, 469 void *match_param, 470 u8 *tag) 471{ 472 u32 code = HWS_GET_MATCH_PARAM(match_param, misc_parameters_3.icmpv6_code); 473 u32 type = HWS_GET_MATCH_PARAM(match_param, misc_parameters_3.icmpv6_type); 474 u32 dw = (type << __mlx5_dw_bit_off(header_icmp, type)) | 475 (code << __mlx5_dw_bit_off(header_icmp, code)); 476 477 HWS_SET32(tag, dw, fc->byte_off, fc->bit_off, fc->bit_mask); 478} 479 480static void 481hws_definer_l3_type_set(struct mlx5hws_definer_fc *fc, 482 void *match_param, 483 u8 *tag) 484{ 485 u32 val = HWS_GET32(match_param, fc->s_byte_off, fc->s_bit_off, fc->s_bit_mask); 486 487 if (val == IPV4) 488 HWS_SET32(tag, STE_IPV4, fc->byte_off, fc->bit_off, fc->bit_mask); 489 else if (val == IPV6) 490 HWS_SET32(tag, STE_IPV6, fc->byte_off, fc->bit_off, fc->bit_mask); 491 else 492 HWS_SET32(tag, STE_NO_L3, fc->byte_off, fc->bit_off, fc->bit_mask); 493} 494 495static void 496hws_definer_set_source_port_gvmi(struct mlx5hws_definer_fc *fc, 497 void *match_param, 498 u8 *tag, 499 struct mlx5hws_context *peer_ctx) 500{ 501 u16 source_port = HWS_GET_MATCH_PARAM(match_param, misc_parameters.source_port); 502 u16 vport_gvmi = 0; 503 int ret; 504 505 ret = mlx5hws_vport_get_gvmi(peer_ctx, source_port, &vport_gvmi); 506 if (ret) { 507 HWS_SET32(tag, BAD_PORT, fc->byte_off, fc->bit_off, fc->bit_mask); 508 mlx5hws_err(fc->ctx, "Vport 0x%x is disabled or invalid\n", source_port); 509 return; 510 } 511 512 if (vport_gvmi) 513 HWS_SET32(tag, vport_gvmi, fc->byte_off, fc->bit_off, fc->bit_mask); 514} 515 516static void 517hws_definer_set_source_gvmi_vhca_id(struct mlx5hws_definer_fc *fc, 518 void *match_param, 519 u8 *tag) 520__must_hold(&fc->ctx->ctrl_lock) 521{ 522 int id = HWS_GET_MATCH_PARAM(match_param, misc_parameters.source_eswitch_owner_vhca_id); 523 struct mlx5hws_context *peer_ctx; 524 525 if (id == fc->ctx->caps->vhca_id) 526 peer_ctx = fc->ctx; 527 else 528 peer_ctx = xa_load(&fc->ctx->peer_ctx_xa, id); 529 530 if (!peer_ctx) { 531 HWS_SET32(tag, BAD_PORT, fc->byte_off, fc->bit_off, fc->bit_mask); 532 mlx5hws_err(fc->ctx, "Invalid vhca_id provided 0x%x\n", id); 533 return; 534 } 535 536 hws_definer_set_source_port_gvmi(fc, match_param, tag, peer_ctx); 537} 538 539static void 540hws_definer_set_source_gvmi(struct mlx5hws_definer_fc *fc, 541 void *match_param, 542 u8 *tag) 543{ 544 hws_definer_set_source_port_gvmi(fc, match_param, tag, fc->ctx); 545} 546 547static struct mlx5hws_definer_fc * 548hws_definer_flex_parser_steering_ok_bits_handler(struct mlx5hws_definer_conv_data *cd, 549 u8 parser_id) 550{ 551 struct mlx5hws_definer_fc *fc; 552 553 switch (parser_id) { 554 case 0: 555 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER0_OK]; 556 HWS_CALC_HDR_DST(fc, oks1.flex_parser0_steering_ok); 557 fc->tag_set = &hws_definer_generic_set; 558 break; 559 case 1: 560 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER1_OK]; 561 HWS_CALC_HDR_DST(fc, oks1.flex_parser1_steering_ok); 562 fc->tag_set = &hws_definer_generic_set; 563 break; 564 case 2: 565 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER2_OK]; 566 HWS_CALC_HDR_DST(fc, oks1.flex_parser2_steering_ok); 567 fc->tag_set = &hws_definer_generic_set; 568 break; 569 case 3: 570 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER3_OK]; 571 HWS_CALC_HDR_DST(fc, oks1.flex_parser3_steering_ok); 572 fc->tag_set = &hws_definer_generic_set; 573 break; 574 case 4: 575 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER4_OK]; 576 HWS_CALC_HDR_DST(fc, oks1.flex_parser4_steering_ok); 577 fc->tag_set = &hws_definer_generic_set; 578 break; 579 case 5: 580 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER5_OK]; 581 HWS_CALC_HDR_DST(fc, oks1.flex_parser5_steering_ok); 582 fc->tag_set = &hws_definer_generic_set; 583 break; 584 case 6: 585 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER6_OK]; 586 HWS_CALC_HDR_DST(fc, oks1.flex_parser6_steering_ok); 587 fc->tag_set = &hws_definer_generic_set; 588 break; 589 case 7: 590 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER7_OK]; 591 HWS_CALC_HDR_DST(fc, oks1.flex_parser7_steering_ok); 592 fc->tag_set = &hws_definer_generic_set; 593 break; 594 default: 595 mlx5hws_err(cd->ctx, "Unsupported flex parser steering ok index %u\n", parser_id); 596 return NULL; 597 } 598 599 return fc; 600} 601 602static struct mlx5hws_definer_fc * 603hws_definer_flex_parser_handler(struct mlx5hws_definer_conv_data *cd, 604 u8 parser_id) 605{ 606 struct mlx5hws_definer_fc *fc; 607 608 switch (parser_id) { 609 case 0: 610 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER_0]; 611 HWS_CALC_HDR_DST(fc, flex_parser.flex_parser_0); 612 fc->tag_set = &hws_definer_generic_set; 613 break; 614 case 1: 615 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER_1]; 616 HWS_CALC_HDR_DST(fc, flex_parser.flex_parser_1); 617 fc->tag_set = &hws_definer_generic_set; 618 break; 619 case 2: 620 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER_2]; 621 HWS_CALC_HDR_DST(fc, flex_parser.flex_parser_2); 622 fc->tag_set = &hws_definer_generic_set; 623 break; 624 case 3: 625 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER_3]; 626 HWS_CALC_HDR_DST(fc, flex_parser.flex_parser_3); 627 fc->tag_set = &hws_definer_generic_set; 628 break; 629 case 4: 630 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER_4]; 631 HWS_CALC_HDR_DST(fc, flex_parser.flex_parser_4); 632 fc->tag_set = &hws_definer_generic_set; 633 break; 634 case 5: 635 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER_5]; 636 HWS_CALC_HDR_DST(fc, flex_parser.flex_parser_5); 637 fc->tag_set = &hws_definer_generic_set; 638 break; 639 case 6: 640 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER_6]; 641 HWS_CALC_HDR_DST(fc, flex_parser.flex_parser_6); 642 fc->tag_set = &hws_definer_generic_set; 643 break; 644 case 7: 645 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_FLEX_PARSER_7]; 646 HWS_CALC_HDR_DST(fc, flex_parser.flex_parser_7); 647 fc->tag_set = &hws_definer_generic_set; 648 break; 649 default: 650 mlx5hws_err(cd->ctx, "Unsupported flex parser %u\n", parser_id); 651 return NULL; 652 } 653 654 return fc; 655} 656 657static struct mlx5hws_definer_fc * 658hws_definer_misc4_fields_handler(struct mlx5hws_definer_conv_data *cd, 659 bool *parser_is_used, 660 u32 id, 661 u32 value) 662{ 663 if (id || value) { 664 if (id >= HWS_NUM_OF_FLEX_PARSERS) { 665 mlx5hws_err(cd->ctx, "Unsupported parser id\n"); 666 return NULL; 667 } 668 669 if (parser_is_used[id]) { 670 mlx5hws_err(cd->ctx, "Parser id have been used\n"); 671 return NULL; 672 } 673 } 674 675 parser_is_used[id] = true; 676 677 return hws_definer_flex_parser_handler(cd, id); 678} 679 680static int 681hws_definer_check_match_flags(struct mlx5hws_definer_conv_data *cd) 682{ 683 u32 flags; 684 685 flags = cd->match_flags & (MLX5HWS_DEFINER_MATCH_FLAG_TNL_VXLAN_GPE | 686 MLX5HWS_DEFINER_MATCH_FLAG_TNL_GENEVE | 687 MLX5HWS_DEFINER_MATCH_FLAG_TNL_GTPU | 688 MLX5HWS_DEFINER_MATCH_FLAG_TNL_GRE | 689 MLX5HWS_DEFINER_MATCH_FLAG_TNL_VXLAN | 690 MLX5HWS_DEFINER_MATCH_FLAG_TNL_HEADER_0_1); 691 if (flags & (flags - 1)) 692 goto err_conflict; 693 694 flags = cd->match_flags & (MLX5HWS_DEFINER_MATCH_FLAG_TNL_GRE_OPT_KEY | 695 MLX5HWS_DEFINER_MATCH_FLAG_TNL_HEADER_2); 696 697 if (flags & (flags - 1)) 698 goto err_conflict; 699 700 flags = cd->match_flags & (MLX5HWS_DEFINER_MATCH_FLAG_TNL_MPLS_OVER_GRE | 701 MLX5HWS_DEFINER_MATCH_FLAG_TNL_MPLS_OVER_UDP); 702 if (flags & (flags - 1)) 703 goto err_conflict; 704 705 flags = cd->match_flags & (MLX5HWS_DEFINER_MATCH_FLAG_ICMPV4 | 706 MLX5HWS_DEFINER_MATCH_FLAG_ICMPV6 | 707 MLX5HWS_DEFINER_MATCH_FLAG_TCP_O | 708 MLX5HWS_DEFINER_MATCH_FLAG_TCP_I); 709 if (flags & (flags - 1)) 710 goto err_conflict; 711 712 return 0; 713 714err_conflict: 715 mlx5hws_err(cd->ctx, "Invalid definer fields combination: match_flags = 0x%08x\n", 716 cd->match_flags); 717 return -EINVAL; 718} 719 720static int 721hws_definer_conv_outer(struct mlx5hws_definer_conv_data *cd, 722 u32 *match_param) 723{ 724 bool is_ipv6, smac_set, dmac_set, ip_addr_set, ip_ver_set; 725 struct mlx5hws_definer_fc *fc = cd->fc; 726 struct mlx5hws_definer_fc *curr_fc; 727 u32 *s_ipv6, *d_ipv6; 728 729 if (HWS_IS_FLD_SET_SZ(match_param, outer_headers.l4_type, 0x2) || 730 HWS_IS_FLD_SET_SZ(match_param, outer_headers.l4_type_ext, 0x4) || 731 HWS_IS_FLD_SET_SZ(match_param, outer_headers.reserved_at_c6, 0xa) || 732 HWS_IS_FLD_SET_SZ(match_param, outer_headers.reserved_at_d4, 0x4)) { 733 mlx5hws_err(cd->ctx, "Unsupported outer parameters set\n"); 734 return -EINVAL; 735 } 736 737 ip_addr_set = HWS_IS_FLD_SET_SZ(match_param, 738 outer_headers.src_ipv4_src_ipv6, 739 0x80) || 740 HWS_IS_FLD_SET_SZ(match_param, 741 outer_headers.dst_ipv4_dst_ipv6, 0x80); 742 ip_ver_set = HWS_IS_FLD_SET(match_param, outer_headers.ip_version) || 743 HWS_IS_FLD_SET(match_param, outer_headers.ethertype); 744 745 if (ip_addr_set && !ip_ver_set) { 746 mlx5hws_err(cd->ctx, 747 "Unsupported match on IP address without version or ethertype\n"); 748 return -EINVAL; 749 } 750 751 /* L2 Check ethertype */ 752 HWS_SET_HDR(fc, match_param, ETH_TYPE_O, 753 outer_headers.ethertype, 754 eth_l2_outer.l3_ethertype); 755 /* L2 Check SMAC 47_16 */ 756 HWS_SET_HDR(fc, match_param, ETH_SMAC_47_16_O, 757 outer_headers.smac_47_16, eth_l2_src_outer.smac_47_16); 758 /* L2 Check SMAC 15_0 */ 759 HWS_SET_HDR(fc, match_param, ETH_SMAC_15_0_O, 760 outer_headers.smac_15_0, eth_l2_src_outer.smac_15_0); 761 /* L2 Check DMAC 47_16 */ 762 HWS_SET_HDR(fc, match_param, ETH_DMAC_47_16_O, 763 outer_headers.dmac_47_16, eth_l2_outer.dmac_47_16); 764 /* L2 Check DMAC 15_0 */ 765 HWS_SET_HDR(fc, match_param, ETH_DMAC_15_0_O, 766 outer_headers.dmac_15_0, eth_l2_outer.dmac_15_0); 767 768 /* L2 VLAN */ 769 HWS_SET_HDR(fc, match_param, VLAN_FIRST_PRIO_O, 770 outer_headers.first_prio, eth_l2_outer.first_priority); 771 HWS_SET_HDR(fc, match_param, VLAN_CFI_O, 772 outer_headers.first_cfi, eth_l2_outer.first_cfi); 773 HWS_SET_HDR(fc, match_param, VLAN_ID_O, 774 outer_headers.first_vid, eth_l2_outer.first_vlan_id); 775 776 /* L2 CVLAN and SVLAN */ 777 if (HWS_GET_MATCH_PARAM(match_param, outer_headers.cvlan_tag) || 778 HWS_GET_MATCH_PARAM(match_param, outer_headers.svlan_tag)) { 779 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_VLAN_TYPE_O]; 780 HWS_CALC_HDR_DST(curr_fc, eth_l2_outer.first_vlan_qualifier); 781 curr_fc->tag_set = &hws_definer_outer_vlan_type_set; 782 curr_fc->tag_mask_set = &hws_definer_ones_set; 783 } 784 785 /* L3 Check IP header */ 786 HWS_SET_HDR(fc, match_param, IP_PROTOCOL_O, 787 outer_headers.ip_protocol, 788 eth_l3_outer.protocol_next_header); 789 HWS_SET_HDR(fc, match_param, IP_VERSION_O, 790 outer_headers.ip_version, 791 eth_l3_outer.ip_version); 792 HWS_SET_HDR(fc, match_param, IP_TTL_O, 793 outer_headers.ttl_hoplimit, 794 eth_l3_outer.time_to_live_hop_limit); 795 796 /* L3 Check IPv4/IPv6 addresses */ 797 s_ipv6 = MLX5_ADDR_OF(fte_match_param, match_param, 798 outer_headers.src_ipv4_src_ipv6.ipv6_layout); 799 d_ipv6 = MLX5_ADDR_OF(fte_match_param, match_param, 800 outer_headers.dst_ipv4_dst_ipv6.ipv6_layout); 801 802 /* Assume IPv6 is used if ipv6 bits are set */ 803 is_ipv6 = s_ipv6[0] || s_ipv6[1] || s_ipv6[2] || 804 d_ipv6[0] || d_ipv6[1] || d_ipv6[2]; 805 806 /* IHL is an IPv4-specific field. */ 807 if (is_ipv6 && HWS_IS_FLD_SET(match_param, outer_headers.ipv4_ihl)) { 808 mlx5hws_err(cd->ctx, "Unsupported match on IPv6 address and IPv4 IHL\n"); 809 return -EINVAL; 810 } 811 812 if (is_ipv6) { 813 /* Handle IPv6 source address */ 814 HWS_SET_HDR(fc, match_param, IPV6_SRC_127_96_O, 815 outer_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_127_96, 816 ipv6_src_outer.ipv6_address_127_96); 817 HWS_SET_HDR(fc, match_param, IPV6_SRC_95_64_O, 818 outer_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_95_64, 819 ipv6_src_outer.ipv6_address_95_64); 820 HWS_SET_HDR(fc, match_param, IPV6_SRC_63_32_O, 821 outer_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_63_32, 822 ipv6_src_outer.ipv6_address_63_32); 823 HWS_SET_HDR(fc, match_param, IPV6_SRC_31_0_O, 824 outer_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_31_0, 825 ipv6_src_outer.ipv6_address_31_0); 826 /* Handle IPv6 destination address */ 827 HWS_SET_HDR(fc, match_param, IPV6_DST_127_96_O, 828 outer_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_127_96, 829 ipv6_dst_outer.ipv6_address_127_96); 830 HWS_SET_HDR(fc, match_param, IPV6_DST_95_64_O, 831 outer_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_95_64, 832 ipv6_dst_outer.ipv6_address_95_64); 833 HWS_SET_HDR(fc, match_param, IPV6_DST_63_32_O, 834 outer_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_63_32, 835 ipv6_dst_outer.ipv6_address_63_32); 836 HWS_SET_HDR(fc, match_param, IPV6_DST_31_0_O, 837 outer_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_31_0, 838 ipv6_dst_outer.ipv6_address_31_0); 839 } else { 840 /* Handle IPv4 source address */ 841 HWS_SET_HDR(fc, match_param, IPV4_SRC_O, 842 outer_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_31_0, 843 ipv4_src_dest_outer.source_address); 844 /* Handle IPv4 destination address */ 845 HWS_SET_HDR(fc, match_param, IPV4_DST_O, 846 outer_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_31_0, 847 ipv4_src_dest_outer.destination_address); 848 } 849 850 /* L4 Handle TCP/UDP */ 851 HWS_SET_HDR(fc, match_param, L4_SPORT_O, 852 outer_headers.tcp_sport, eth_l4_outer.source_port); 853 HWS_SET_HDR(fc, match_param, L4_DPORT_O, 854 outer_headers.tcp_dport, eth_l4_outer.destination_port); 855 HWS_SET_HDR(fc, match_param, L4_SPORT_O, 856 outer_headers.udp_sport, eth_l4_outer.source_port); 857 HWS_SET_HDR(fc, match_param, L4_DPORT_O, 858 outer_headers.udp_dport, eth_l4_outer.destination_port); 859 HWS_SET_HDR(fc, match_param, TCP_FLAGS_O, 860 outer_headers.tcp_flags, eth_l4_outer.tcp_flags); 861 862 /* L3 Handle DSCP, ECN and IHL */ 863 HWS_SET_HDR(fc, match_param, IP_DSCP_O, 864 outer_headers.ip_dscp, eth_l3_outer.dscp); 865 HWS_SET_HDR(fc, match_param, IP_ECN_O, 866 outer_headers.ip_ecn, eth_l3_outer.ecn); 867 HWS_SET_HDR(fc, match_param, IPV4_IHL_O, 868 outer_headers.ipv4_ihl, eth_l3_outer.ihl); 869 870 /* Set IP fragmented bit */ 871 if (HWS_IS_FLD_SET(match_param, outer_headers.frag)) { 872 smac_set = HWS_IS_FLD_SET(match_param, outer_headers.smac_15_0) || 873 HWS_IS_FLD_SET(match_param, outer_headers.smac_47_16); 874 dmac_set = HWS_IS_FLD_SET(match_param, outer_headers.dmac_15_0) || 875 HWS_IS_FLD_SET(match_param, outer_headers.dmac_47_16); 876 if (smac_set == dmac_set) { 877 HWS_SET_HDR(fc, match_param, IP_FRAG_O, 878 outer_headers.frag, eth_l4_outer.ip_fragmented); 879 } else { 880 HWS_SET_HDR(fc, match_param, IP_FRAG_O, 881 outer_headers.frag, eth_l2_src_outer.ip_fragmented); 882 } 883 } 884 885 /* L3_type set */ 886 if (HWS_IS_FLD_SET(match_param, outer_headers.ip_version)) { 887 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_ETH_L3_TYPE_O]; 888 HWS_CALC_HDR_DST(curr_fc, eth_l2_outer.l3_type); 889 curr_fc->tag_set = &hws_definer_l3_type_set; 890 curr_fc->tag_mask_set = &hws_definer_ones_set; 891 HWS_CALC_HDR_SRC(curr_fc, outer_headers.ip_version); 892 } 893 894 return 0; 895} 896 897static int 898hws_definer_conv_inner(struct mlx5hws_definer_conv_data *cd, 899 u32 *match_param) 900{ 901 bool is_ipv6, smac_set, dmac_set, ip_addr_set, ip_ver_set; 902 struct mlx5hws_definer_fc *fc = cd->fc; 903 struct mlx5hws_definer_fc *curr_fc; 904 u32 *s_ipv6, *d_ipv6; 905 906 if (HWS_IS_FLD_SET_SZ(match_param, inner_headers.l4_type, 0x2) || 907 HWS_IS_FLD_SET_SZ(match_param, inner_headers.l4_type_ext, 0x4) || 908 HWS_IS_FLD_SET_SZ(match_param, inner_headers.reserved_at_c6, 0xa) || 909 HWS_IS_FLD_SET_SZ(match_param, inner_headers.reserved_at_d4, 0x4)) { 910 mlx5hws_err(cd->ctx, "Unsupported inner parameters set\n"); 911 return -EINVAL; 912 } 913 914 ip_addr_set = HWS_IS_FLD_SET_SZ(match_param, 915 inner_headers.src_ipv4_src_ipv6, 916 0x80) || 917 HWS_IS_FLD_SET_SZ(match_param, 918 inner_headers.dst_ipv4_dst_ipv6, 0x80); 919 ip_ver_set = HWS_IS_FLD_SET(match_param, inner_headers.ip_version) || 920 HWS_IS_FLD_SET(match_param, inner_headers.ethertype); 921 922 if (ip_addr_set && !ip_ver_set) { 923 mlx5hws_err(cd->ctx, 924 "Unsupported match on IP address without version or ethertype\n"); 925 return -EINVAL; 926 } 927 928 /* L2 Check ethertype */ 929 HWS_SET_HDR(fc, match_param, ETH_TYPE_I, 930 inner_headers.ethertype, 931 eth_l2_inner.l3_ethertype); 932 /* L2 Check SMAC 47_16 */ 933 HWS_SET_HDR(fc, match_param, ETH_SMAC_47_16_I, 934 inner_headers.smac_47_16, eth_l2_src_inner.smac_47_16); 935 /* L2 Check SMAC 15_0 */ 936 HWS_SET_HDR(fc, match_param, ETH_SMAC_15_0_I, 937 inner_headers.smac_15_0, eth_l2_src_inner.smac_15_0); 938 /* L2 Check DMAC 47_16 */ 939 HWS_SET_HDR(fc, match_param, ETH_DMAC_47_16_I, 940 inner_headers.dmac_47_16, eth_l2_inner.dmac_47_16); 941 /* L2 Check DMAC 15_0 */ 942 HWS_SET_HDR(fc, match_param, ETH_DMAC_15_0_I, 943 inner_headers.dmac_15_0, eth_l2_inner.dmac_15_0); 944 945 /* L2 VLAN */ 946 HWS_SET_HDR(fc, match_param, VLAN_FIRST_PRIO_I, 947 inner_headers.first_prio, eth_l2_inner.first_priority); 948 HWS_SET_HDR(fc, match_param, VLAN_CFI_I, 949 inner_headers.first_cfi, eth_l2_inner.first_cfi); 950 HWS_SET_HDR(fc, match_param, VLAN_ID_I, 951 inner_headers.first_vid, eth_l2_inner.first_vlan_id); 952 953 /* L2 CVLAN and SVLAN */ 954 if (HWS_GET_MATCH_PARAM(match_param, inner_headers.cvlan_tag) || 955 HWS_GET_MATCH_PARAM(match_param, inner_headers.svlan_tag)) { 956 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_VLAN_TYPE_I]; 957 HWS_CALC_HDR_DST(curr_fc, eth_l2_inner.first_vlan_qualifier); 958 curr_fc->tag_set = &hws_definer_inner_vlan_type_set; 959 curr_fc->tag_mask_set = &hws_definer_ones_set; 960 } 961 /* L3 Check IP header */ 962 HWS_SET_HDR(fc, match_param, IP_PROTOCOL_I, 963 inner_headers.ip_protocol, 964 eth_l3_inner.protocol_next_header); 965 HWS_SET_HDR(fc, match_param, IP_VERSION_I, 966 inner_headers.ip_version, 967 eth_l3_inner.ip_version); 968 HWS_SET_HDR(fc, match_param, IP_TTL_I, 969 inner_headers.ttl_hoplimit, 970 eth_l3_inner.time_to_live_hop_limit); 971 972 /* L3 Check IPv4/IPv6 addresses */ 973 s_ipv6 = MLX5_ADDR_OF(fte_match_param, match_param, 974 inner_headers.src_ipv4_src_ipv6.ipv6_layout); 975 d_ipv6 = MLX5_ADDR_OF(fte_match_param, match_param, 976 inner_headers.dst_ipv4_dst_ipv6.ipv6_layout); 977 978 /* Assume IPv6 is used if ipv6 bits are set */ 979 is_ipv6 = s_ipv6[0] || s_ipv6[1] || s_ipv6[2] || 980 d_ipv6[0] || d_ipv6[1] || d_ipv6[2]; 981 982 /* IHL is an IPv4-specific field. */ 983 if (is_ipv6 && HWS_IS_FLD_SET(match_param, inner_headers.ipv4_ihl)) { 984 mlx5hws_err(cd->ctx, "Unsupported match on IPv6 address and IPv4 IHL\n"); 985 return -EINVAL; 986 } 987 988 if (is_ipv6) { 989 /* Handle IPv6 source address */ 990 HWS_SET_HDR(fc, match_param, IPV6_SRC_127_96_I, 991 inner_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_127_96, 992 ipv6_src_inner.ipv6_address_127_96); 993 HWS_SET_HDR(fc, match_param, IPV6_SRC_95_64_I, 994 inner_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_95_64, 995 ipv6_src_inner.ipv6_address_95_64); 996 HWS_SET_HDR(fc, match_param, IPV6_SRC_63_32_I, 997 inner_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_63_32, 998 ipv6_src_inner.ipv6_address_63_32); 999 HWS_SET_HDR(fc, match_param, IPV6_SRC_31_0_I, 1000 inner_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_31_0, 1001 ipv6_src_inner.ipv6_address_31_0); 1002 /* Handle IPv6 destination address */ 1003 HWS_SET_HDR(fc, match_param, IPV6_DST_127_96_I, 1004 inner_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_127_96, 1005 ipv6_dst_inner.ipv6_address_127_96); 1006 HWS_SET_HDR(fc, match_param, IPV6_DST_95_64_I, 1007 inner_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_95_64, 1008 ipv6_dst_inner.ipv6_address_95_64); 1009 HWS_SET_HDR(fc, match_param, IPV6_DST_63_32_I, 1010 inner_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_63_32, 1011 ipv6_dst_inner.ipv6_address_63_32); 1012 HWS_SET_HDR(fc, match_param, IPV6_DST_31_0_I, 1013 inner_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_31_0, 1014 ipv6_dst_inner.ipv6_address_31_0); 1015 } else { 1016 /* Handle IPv4 source address */ 1017 HWS_SET_HDR(fc, match_param, IPV4_SRC_I, 1018 inner_headers.src_ipv4_src_ipv6.ipv6_simple_layout.ipv6_31_0, 1019 ipv4_src_dest_inner.source_address); 1020 /* Handle IPv4 destination address */ 1021 HWS_SET_HDR(fc, match_param, IPV4_DST_I, 1022 inner_headers.dst_ipv4_dst_ipv6.ipv6_simple_layout.ipv6_31_0, 1023 ipv4_src_dest_inner.destination_address); 1024 } 1025 1026 /* L4 Handle TCP/UDP */ 1027 HWS_SET_HDR(fc, match_param, L4_SPORT_I, 1028 inner_headers.tcp_sport, eth_l4_inner.source_port); 1029 HWS_SET_HDR(fc, match_param, L4_DPORT_I, 1030 inner_headers.tcp_dport, eth_l4_inner.destination_port); 1031 HWS_SET_HDR(fc, match_param, L4_SPORT_I, 1032 inner_headers.udp_sport, eth_l4_inner.source_port); 1033 HWS_SET_HDR(fc, match_param, L4_DPORT_I, 1034 inner_headers.udp_dport, eth_l4_inner.destination_port); 1035 HWS_SET_HDR(fc, match_param, TCP_FLAGS_I, 1036 inner_headers.tcp_flags, eth_l4_inner.tcp_flags); 1037 1038 /* L3 Handle DSCP, ECN and IHL */ 1039 HWS_SET_HDR(fc, match_param, IP_DSCP_I, 1040 inner_headers.ip_dscp, eth_l3_inner.dscp); 1041 HWS_SET_HDR(fc, match_param, IP_ECN_I, 1042 inner_headers.ip_ecn, eth_l3_inner.ecn); 1043 HWS_SET_HDR(fc, match_param, IPV4_IHL_I, 1044 inner_headers.ipv4_ihl, eth_l3_inner.ihl); 1045 1046 /* Set IP fragmented bit */ 1047 if (HWS_IS_FLD_SET(match_param, inner_headers.frag)) { 1048 if (HWS_IS_FLD_SET(match_param, misc_parameters.vxlan_vni)) { 1049 HWS_SET_HDR(fc, match_param, IP_FRAG_I, 1050 inner_headers.frag, eth_l2_inner.ip_fragmented); 1051 } else { 1052 smac_set = HWS_IS_FLD_SET(match_param, inner_headers.smac_15_0) || 1053 HWS_IS_FLD_SET(match_param, inner_headers.smac_47_16); 1054 dmac_set = HWS_IS_FLD_SET(match_param, inner_headers.dmac_15_0) || 1055 HWS_IS_FLD_SET(match_param, inner_headers.dmac_47_16); 1056 if (smac_set == dmac_set) { 1057 HWS_SET_HDR(fc, match_param, IP_FRAG_I, 1058 inner_headers.frag, eth_l4_inner.ip_fragmented); 1059 } else { 1060 HWS_SET_HDR(fc, match_param, IP_FRAG_I, 1061 inner_headers.frag, eth_l2_src_inner.ip_fragmented); 1062 } 1063 } 1064 } 1065 1066 /* L3_type set */ 1067 if (HWS_IS_FLD_SET(match_param, inner_headers.ip_version)) { 1068 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_ETH_L3_TYPE_I]; 1069 HWS_CALC_HDR_DST(curr_fc, eth_l2_inner.l3_type); 1070 curr_fc->tag_set = &hws_definer_l3_type_set; 1071 curr_fc->tag_mask_set = &hws_definer_ones_set; 1072 HWS_CALC_HDR_SRC(curr_fc, inner_headers.ip_version); 1073 } 1074 1075 return 0; 1076} 1077 1078static int 1079hws_definer_conv_misc(struct mlx5hws_definer_conv_data *cd, 1080 u32 *match_param) 1081{ 1082 struct mlx5hws_cmd_query_caps *caps = cd->ctx->caps; 1083 struct mlx5hws_definer_fc *fc = cd->fc; 1084 struct mlx5hws_definer_fc *curr_fc; 1085 1086 if (HWS_IS_FLD_SET_SZ(match_param, misc_parameters.reserved_at_1, 0x1) || 1087 HWS_IS_FLD_SET_SZ(match_param, misc_parameters.reserved_at_64, 0xc) || 1088 HWS_IS_FLD_SET_SZ(match_param, misc_parameters.reserved_at_d8, 0x6) || 1089 HWS_IS_FLD_SET_SZ(match_param, misc_parameters.reserved_at_e0, 0xc) || 1090 HWS_IS_FLD_SET_SZ(match_param, misc_parameters.reserved_at_100, 0xc) || 1091 HWS_IS_FLD_SET_SZ(match_param, misc_parameters.reserved_at_120, 0xa) || 1092 HWS_IS_FLD_SET_SZ(match_param, misc_parameters.reserved_at_140, 0x8) || 1093 HWS_IS_FLD_SET(match_param, misc_parameters.bth_dst_qp) || 1094 HWS_IS_FLD_SET(match_param, misc_parameters.bth_opcode) || 1095 HWS_IS_FLD_SET(match_param, misc_parameters.inner_esp_spi) || 1096 HWS_IS_FLD_SET(match_param, misc_parameters.outer_esp_spi) || 1097 HWS_IS_FLD_SET(match_param, misc_parameters.source_vhca_port) || 1098 HWS_IS_FLD_SET_SZ(match_param, misc_parameters.reserved_at_1a0, 0x60)) { 1099 mlx5hws_err(cd->ctx, "Unsupported misc parameters set\n"); 1100 return -EINVAL; 1101 } 1102 1103 /* Check GRE related fields */ 1104 if (HWS_IS_FLD_SET(match_param, misc_parameters.gre_c_present)) { 1105 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GRE; 1106 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GRE_C]; 1107 HWS_CALC_HDR(curr_fc, 1108 misc_parameters.gre_c_present, 1109 tunnel_header.tunnel_header_0); 1110 curr_fc->bit_mask = __mlx5_mask(header_gre, gre_c_present); 1111 curr_fc->bit_off = __mlx5_dw_bit_off(header_gre, gre_c_present); 1112 } 1113 1114 if (HWS_IS_FLD_SET(match_param, misc_parameters.gre_k_present)) { 1115 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GRE; 1116 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GRE_K]; 1117 HWS_CALC_HDR(curr_fc, 1118 misc_parameters.gre_k_present, 1119 tunnel_header.tunnel_header_0); 1120 curr_fc->bit_mask = __mlx5_mask(header_gre, gre_k_present); 1121 curr_fc->bit_off = __mlx5_dw_bit_off(header_gre, gre_k_present); 1122 } 1123 1124 if (HWS_IS_FLD_SET(match_param, misc_parameters.gre_s_present)) { 1125 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GRE; 1126 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GRE_S]; 1127 HWS_CALC_HDR(curr_fc, 1128 misc_parameters.gre_s_present, 1129 tunnel_header.tunnel_header_0); 1130 curr_fc->bit_mask = __mlx5_mask(header_gre, gre_s_present); 1131 curr_fc->bit_off = __mlx5_dw_bit_off(header_gre, gre_s_present); 1132 } 1133 1134 if (HWS_IS_FLD_SET(match_param, misc_parameters.gre_protocol)) { 1135 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GRE; 1136 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GRE_PROTOCOL]; 1137 HWS_CALC_HDR(curr_fc, 1138 misc_parameters.gre_protocol, 1139 tunnel_header.tunnel_header_0); 1140 curr_fc->bit_mask = __mlx5_mask(header_gre, gre_protocol); 1141 curr_fc->bit_off = __mlx5_dw_bit_off(header_gre, gre_protocol); 1142 } 1143 1144 if (HWS_IS_FLD_SET(match_param, misc_parameters.gre_key.key)) { 1145 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GRE | 1146 MLX5HWS_DEFINER_MATCH_FLAG_TNL_GRE_OPT_KEY; 1147 HWS_SET_HDR(fc, match_param, GRE_OPT_KEY, 1148 misc_parameters.gre_key.key, tunnel_header.tunnel_header_2); 1149 } 1150 1151 /* Check GENEVE related fields */ 1152 if (HWS_IS_FLD_SET(match_param, misc_parameters.geneve_vni)) { 1153 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GENEVE; 1154 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GENEVE_VNI]; 1155 HWS_CALC_HDR(curr_fc, 1156 misc_parameters.geneve_vni, 1157 tunnel_header.tunnel_header_1); 1158 curr_fc->bit_mask = __mlx5_mask(header_geneve, vni); 1159 curr_fc->bit_off = __mlx5_dw_bit_off(header_geneve, vni); 1160 } 1161 1162 if (HWS_IS_FLD_SET(match_param, misc_parameters.geneve_opt_len)) { 1163 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GENEVE; 1164 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GENEVE_OPT_LEN]; 1165 HWS_CALC_HDR(curr_fc, 1166 misc_parameters.geneve_opt_len, 1167 tunnel_header.tunnel_header_0); 1168 curr_fc->bit_mask = __mlx5_mask(header_geneve, opt_len); 1169 curr_fc->bit_off = __mlx5_dw_bit_off(header_geneve, opt_len); 1170 } 1171 1172 if (HWS_IS_FLD_SET(match_param, misc_parameters.geneve_protocol_type)) { 1173 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GENEVE; 1174 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GENEVE_PROTO]; 1175 HWS_CALC_HDR(curr_fc, 1176 misc_parameters.geneve_protocol_type, 1177 tunnel_header.tunnel_header_0); 1178 curr_fc->bit_mask = __mlx5_mask(header_geneve, protocol_type); 1179 curr_fc->bit_off = __mlx5_dw_bit_off(header_geneve, protocol_type); 1180 } 1181 1182 if (HWS_IS_FLD_SET(match_param, misc_parameters.geneve_oam)) { 1183 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GENEVE; 1184 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GENEVE_OAM]; 1185 HWS_CALC_HDR(curr_fc, 1186 misc_parameters.geneve_oam, 1187 tunnel_header.tunnel_header_0); 1188 curr_fc->bit_mask = __mlx5_mask(header_geneve, o_flag); 1189 curr_fc->bit_off = __mlx5_dw_bit_off(header_geneve, o_flag); 1190 } 1191 1192 HWS_SET_HDR(fc, match_param, SOURCE_QP, 1193 misc_parameters.source_sqn, source_qp_gvmi.source_qp); 1194 HWS_SET_HDR(fc, match_param, IPV6_FLOW_LABEL_O, 1195 misc_parameters.outer_ipv6_flow_label, eth_l3_outer.flow_label); 1196 HWS_SET_HDR(fc, match_param, IPV6_FLOW_LABEL_I, 1197 misc_parameters.inner_ipv6_flow_label, eth_l3_inner.flow_label); 1198 1199 /* L2 Second VLAN */ 1200 HWS_SET_HDR(fc, match_param, VLAN_SECOND_PRIO_O, 1201 misc_parameters.outer_second_prio, eth_l2_outer.second_priority); 1202 HWS_SET_HDR(fc, match_param, VLAN_SECOND_PRIO_I, 1203 misc_parameters.inner_second_prio, eth_l2_inner.second_priority); 1204 HWS_SET_HDR(fc, match_param, VLAN_SECOND_CFI_O, 1205 misc_parameters.outer_second_cfi, eth_l2_outer.second_cfi); 1206 HWS_SET_HDR(fc, match_param, VLAN_SECOND_CFI_I, 1207 misc_parameters.inner_second_cfi, eth_l2_inner.second_cfi); 1208 HWS_SET_HDR(fc, match_param, VLAN_SECOND_ID_O, 1209 misc_parameters.outer_second_vid, eth_l2_outer.second_vlan_id); 1210 HWS_SET_HDR(fc, match_param, VLAN_SECOND_ID_I, 1211 misc_parameters.inner_second_vid, eth_l2_inner.second_vlan_id); 1212 1213 /* L2 Second CVLAN and SVLAN */ 1214 if (HWS_GET_MATCH_PARAM(match_param, misc_parameters.outer_second_cvlan_tag) || 1215 HWS_GET_MATCH_PARAM(match_param, misc_parameters.outer_second_svlan_tag)) { 1216 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_VLAN_SECOND_TYPE_O]; 1217 HWS_CALC_HDR_DST(curr_fc, eth_l2_outer.second_vlan_qualifier); 1218 curr_fc->tag_set = &hws_definer_outer_second_vlan_type_set; 1219 curr_fc->tag_mask_set = &hws_definer_ones_set; 1220 } 1221 1222 if (HWS_GET_MATCH_PARAM(match_param, misc_parameters.inner_second_cvlan_tag) || 1223 HWS_GET_MATCH_PARAM(match_param, misc_parameters.inner_second_svlan_tag)) { 1224 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_VLAN_SECOND_TYPE_I]; 1225 HWS_CALC_HDR_DST(curr_fc, eth_l2_inner.second_vlan_qualifier); 1226 curr_fc->tag_set = &hws_definer_inner_second_vlan_type_set; 1227 curr_fc->tag_mask_set = &hws_definer_ones_set; 1228 } 1229 1230 /* VXLAN VNI */ 1231 if (HWS_GET_MATCH_PARAM(match_param, misc_parameters.vxlan_vni)) { 1232 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_VXLAN; 1233 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_VXLAN_VNI]; 1234 HWS_CALC_HDR(curr_fc, misc_parameters.vxlan_vni, tunnel_header.tunnel_header_1); 1235 curr_fc->bit_mask = __mlx5_mask(header_vxlan, vni); 1236 curr_fc->bit_off = __mlx5_dw_bit_off(header_vxlan, vni); 1237 } 1238 1239 /* Flex protocol steering ok bits */ 1240 if (HWS_GET_MATCH_PARAM(match_param, misc_parameters.geneve_tlv_option_0_exist)) { 1241 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GENEVE; 1242 1243 if (!caps->flex_parser_ok_bits_supp) { 1244 mlx5hws_err(cd->ctx, "Unsupported flex_parser_ok_bits_supp capability\n"); 1245 return -EOPNOTSUPP; 1246 } 1247 1248 curr_fc = hws_definer_flex_parser_steering_ok_bits_handler( 1249 cd, caps->flex_parser_id_geneve_tlv_option_0); 1250 if (!curr_fc) 1251 return -EINVAL; 1252 1253 HWS_CALC_HDR_SRC(fc, misc_parameters.geneve_tlv_option_0_exist); 1254 } 1255 1256 if (HWS_GET_MATCH_PARAM(match_param, misc_parameters.source_port)) { 1257 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_SOURCE_GVMI]; 1258 HWS_CALC_HDR_DST(curr_fc, source_qp_gvmi.source_gvmi); 1259 curr_fc->tag_mask_set = &hws_definer_ones_set; 1260 curr_fc->tag_set = HWS_IS_FLD_SET(match_param, 1261 misc_parameters.source_eswitch_owner_vhca_id) ? 1262 &hws_definer_set_source_gvmi_vhca_id : 1263 &hws_definer_set_source_gvmi; 1264 } else { 1265 if (HWS_IS_FLD_SET(match_param, misc_parameters.source_eswitch_owner_vhca_id)) { 1266 mlx5hws_err(cd->ctx, 1267 "Unsupported source_eswitch_owner_vhca_id field usage\n"); 1268 return -EOPNOTSUPP; 1269 } 1270 } 1271 1272 return 0; 1273} 1274 1275static int 1276hws_definer_conv_misc2(struct mlx5hws_definer_conv_data *cd, 1277 u32 *match_param) 1278{ 1279 struct mlx5hws_cmd_query_caps *caps = cd->ctx->caps; 1280 struct mlx5hws_definer_fc *fc = cd->fc; 1281 struct mlx5hws_definer_fc *curr_fc; 1282 1283 if (HWS_IS_FLD_SET_SZ(match_param, misc_parameters_2.psp_syndrome, 0x8) || 1284 HWS_IS_FLD_SET_SZ(match_param, 1285 misc_parameters_2.ipsec_next_header, 0x8) || 1286 HWS_IS_FLD_SET_SZ(match_param, misc_parameters_2.reserved_at_1c0, 0x40) || 1287 HWS_IS_FLD_SET(match_param, misc_parameters_2.macsec_syndrome) || 1288 HWS_IS_FLD_SET(match_param, misc_parameters_2.ipsec_syndrome)) { 1289 mlx5hws_err(cd->ctx, "Unsupported misc2 parameters set\n"); 1290 return -EINVAL; 1291 } 1292 1293 HWS_SET_HDR(fc, match_param, MPLS0_O, 1294 misc_parameters_2.outer_first_mpls, mpls_outer.mpls0_label); 1295 HWS_SET_HDR(fc, match_param, MPLS0_I, 1296 misc_parameters_2.inner_first_mpls, mpls_inner.mpls0_label); 1297 HWS_SET_HDR(fc, match_param, REG_0, 1298 misc_parameters_2.metadata_reg_c_0, registers.register_c_0); 1299 HWS_SET_HDR(fc, match_param, REG_1, 1300 misc_parameters_2.metadata_reg_c_1, registers.register_c_1); 1301 HWS_SET_HDR(fc, match_param, REG_2, 1302 misc_parameters_2.metadata_reg_c_2, registers.register_c_2); 1303 HWS_SET_HDR(fc, match_param, REG_3, 1304 misc_parameters_2.metadata_reg_c_3, registers.register_c_3); 1305 HWS_SET_HDR(fc, match_param, REG_4, 1306 misc_parameters_2.metadata_reg_c_4, registers.register_c_4); 1307 HWS_SET_HDR(fc, match_param, REG_5, 1308 misc_parameters_2.metadata_reg_c_5, registers.register_c_5); 1309 HWS_SET_HDR(fc, match_param, REG_6, 1310 misc_parameters_2.metadata_reg_c_6, registers.register_c_6); 1311 HWS_SET_HDR(fc, match_param, REG_7, 1312 misc_parameters_2.metadata_reg_c_7, registers.register_c_7); 1313 HWS_SET_HDR(fc, match_param, REG_A, 1314 misc_parameters_2.metadata_reg_a, metadata.general_purpose); 1315 1316 if (HWS_IS_FLD_SET(match_param, misc_parameters_2.outer_first_mpls_over_gre)) { 1317 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_MPLS_OVER_GRE; 1318 1319 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_GRE_ENABLED)) { 1320 mlx5hws_err(cd->ctx, "Unsupported misc2 first mpls over gre parameters set\n"); 1321 return -EOPNOTSUPP; 1322 } 1323 1324 curr_fc = hws_definer_flex_parser_handler(cd, caps->flex_parser_id_mpls_over_gre); 1325 if (!curr_fc) 1326 return -EINVAL; 1327 1328 HWS_CALC_HDR_SRC(fc, misc_parameters_2.outer_first_mpls_over_gre); 1329 } 1330 1331 if (HWS_IS_FLD_SET(match_param, misc_parameters_2.outer_first_mpls_over_udp)) { 1332 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_MPLS_OVER_UDP; 1333 1334 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_MPLS_OVER_UDP_ENABLED)) { 1335 mlx5hws_err(cd->ctx, "Unsupported misc2 first mpls over udp parameters set\n"); 1336 return -EOPNOTSUPP; 1337 } 1338 1339 curr_fc = hws_definer_flex_parser_handler(cd, caps->flex_parser_id_mpls_over_udp); 1340 if (!curr_fc) 1341 return -EINVAL; 1342 1343 HWS_CALC_HDR_SRC(fc, misc_parameters_2.outer_first_mpls_over_udp); 1344 } 1345 1346 return 0; 1347} 1348 1349static int 1350hws_definer_conv_misc3(struct mlx5hws_definer_conv_data *cd, u32 *match_param) 1351{ 1352 struct mlx5hws_cmd_query_caps *caps = cd->ctx->caps; 1353 struct mlx5hws_definer_fc *fc = cd->fc; 1354 struct mlx5hws_definer_fc *curr_fc; 1355 bool vxlan_gpe_flex_parser_enabled; 1356 1357 /* Check reserved and unsupported fields */ 1358 if (HWS_IS_FLD_SET_SZ(match_param, misc_parameters_3.reserved_at_80, 0x8) || 1359 HWS_IS_FLD_SET_SZ(match_param, misc_parameters_3.reserved_at_b0, 0x10) || 1360 HWS_IS_FLD_SET_SZ(match_param, misc_parameters_3.reserved_at_170, 0x10) || 1361 HWS_IS_FLD_SET_SZ(match_param, misc_parameters_3.reserved_at_1e0, 0x20)) { 1362 mlx5hws_err(cd->ctx, "Unsupported misc3 parameters set\n"); 1363 return -EINVAL; 1364 } 1365 1366 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.inner_tcp_seq_num) || 1367 HWS_IS_FLD_SET(match_param, misc_parameters_3.inner_tcp_ack_num)) { 1368 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TCP_I; 1369 HWS_SET_HDR(fc, match_param, TCP_SEQ_NUM, 1370 misc_parameters_3.inner_tcp_seq_num, tcp_icmp.tcp_seq); 1371 HWS_SET_HDR(fc, match_param, TCP_ACK_NUM, 1372 misc_parameters_3.inner_tcp_ack_num, tcp_icmp.tcp_ack); 1373 } 1374 1375 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.outer_tcp_seq_num) || 1376 HWS_IS_FLD_SET(match_param, misc_parameters_3.outer_tcp_ack_num)) { 1377 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TCP_O; 1378 HWS_SET_HDR(fc, match_param, TCP_SEQ_NUM, 1379 misc_parameters_3.outer_tcp_seq_num, tcp_icmp.tcp_seq); 1380 HWS_SET_HDR(fc, match_param, TCP_ACK_NUM, 1381 misc_parameters_3.outer_tcp_ack_num, tcp_icmp.tcp_ack); 1382 } 1383 1384 vxlan_gpe_flex_parser_enabled = caps->flex_protocols & MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED; 1385 1386 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.outer_vxlan_gpe_vni)) { 1387 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_VXLAN_GPE; 1388 1389 if (!vxlan_gpe_flex_parser_enabled) { 1390 mlx5hws_err(cd->ctx, "Unsupported VXLAN GPE flex parser\n"); 1391 return -EOPNOTSUPP; 1392 } 1393 1394 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_VXLAN_GPE_VNI]; 1395 HWS_CALC_HDR(curr_fc, misc_parameters_3.outer_vxlan_gpe_vni, 1396 tunnel_header.tunnel_header_1); 1397 curr_fc->bit_mask = __mlx5_mask(header_vxlan_gpe, vni); 1398 curr_fc->bit_off = __mlx5_dw_bit_off(header_vxlan_gpe, vni); 1399 } 1400 1401 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.outer_vxlan_gpe_next_protocol)) { 1402 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_VXLAN_GPE; 1403 1404 if (!vxlan_gpe_flex_parser_enabled) { 1405 mlx5hws_err(cd->ctx, "Unsupported VXLAN GPE flex parser\n"); 1406 return -EOPNOTSUPP; 1407 } 1408 1409 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_VXLAN_GPE_PROTO]; 1410 HWS_CALC_HDR(curr_fc, misc_parameters_3.outer_vxlan_gpe_next_protocol, 1411 tunnel_header.tunnel_header_0); 1412 curr_fc->byte_off += MLX5_BYTE_OFF(header_vxlan_gpe, protocol); 1413 curr_fc->bit_mask = __mlx5_mask(header_vxlan_gpe, protocol); 1414 curr_fc->bit_off = __mlx5_dw_bit_off(header_vxlan_gpe, protocol); 1415 } 1416 1417 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.outer_vxlan_gpe_flags)) { 1418 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_VXLAN_GPE; 1419 1420 if (!vxlan_gpe_flex_parser_enabled) { 1421 mlx5hws_err(cd->ctx, "Unsupported VXLAN GPE flex parser\n"); 1422 return -EOPNOTSUPP; 1423 } 1424 1425 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_VXLAN_GPE_FLAGS]; 1426 HWS_CALC_HDR(curr_fc, misc_parameters_3.outer_vxlan_gpe_flags, 1427 tunnel_header.tunnel_header_0); 1428 curr_fc->bit_mask = __mlx5_mask(header_vxlan_gpe, flags); 1429 curr_fc->bit_off = __mlx5_dw_bit_off(header_vxlan_gpe, flags); 1430 } 1431 1432 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.icmp_header_data) || 1433 HWS_IS_FLD_SET(match_param, misc_parameters_3.icmp_type) || 1434 HWS_IS_FLD_SET(match_param, misc_parameters_3.icmp_code)) { 1435 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_ICMPV4; 1436 1437 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED)) { 1438 mlx5hws_err(cd->ctx, "Unsupported ICMPv4 flex parser\n"); 1439 return -EOPNOTSUPP; 1440 } 1441 1442 HWS_SET_HDR(fc, match_param, ICMP_DW3, 1443 misc_parameters_3.icmp_header_data, tcp_icmp.icmp_dw3); 1444 1445 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.icmp_type) || 1446 HWS_IS_FLD_SET(match_param, misc_parameters_3.icmp_code)) { 1447 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_ICMP_DW1]; 1448 HWS_CALC_HDR_DST(curr_fc, tcp_icmp.icmp_dw1); 1449 curr_fc->tag_set = &hws_definer_icmp_dw1_set; 1450 } 1451 } 1452 1453 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.icmpv6_header_data) || 1454 HWS_IS_FLD_SET(match_param, misc_parameters_3.icmpv6_type) || 1455 HWS_IS_FLD_SET(match_param, misc_parameters_3.icmpv6_code)) { 1456 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_ICMPV6; 1457 1458 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED)) { 1459 mlx5hws_err(cd->ctx, "Unsupported ICMPv6 parser\n"); 1460 return -EOPNOTSUPP; 1461 } 1462 1463 HWS_SET_HDR(fc, match_param, ICMP_DW3, 1464 misc_parameters_3.icmpv6_header_data, tcp_icmp.icmp_dw3); 1465 1466 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.icmpv6_type) || 1467 HWS_IS_FLD_SET(match_param, misc_parameters_3.icmpv6_code)) { 1468 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_ICMP_DW1]; 1469 HWS_CALC_HDR_DST(curr_fc, tcp_icmp.icmp_dw1); 1470 curr_fc->tag_set = &hws_definer_icmpv6_dw1_set; 1471 } 1472 } 1473 1474 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.geneve_tlv_option_0_data)) { 1475 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GENEVE; 1476 1477 curr_fc = 1478 hws_definer_flex_parser_handler(cd, 1479 caps->flex_parser_id_geneve_tlv_option_0); 1480 if (!curr_fc) 1481 return -EINVAL; 1482 1483 HWS_CALC_HDR_SRC(fc, misc_parameters_3.geneve_tlv_option_0_data); 1484 } 1485 1486 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.gtpu_teid)) { 1487 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GTPU; 1488 1489 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_TEID_ENABLED)) { 1490 mlx5hws_err(cd->ctx, "Unsupported GTPU TEID flex parser\n"); 1491 return -EOPNOTSUPP; 1492 } 1493 1494 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_GTP_TEID]; 1495 fc->tag_set = &hws_definer_generic_set; 1496 fc->bit_mask = __mlx5_mask(header_gtp, teid); 1497 fc->byte_off = caps->format_select_gtpu_dw_1 * DW_SIZE; 1498 HWS_CALC_HDR_SRC(fc, misc_parameters_3.gtpu_teid); 1499 } 1500 1501 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.gtpu_msg_type)) { 1502 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GTPU; 1503 1504 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_ENABLED)) { 1505 mlx5hws_err(cd->ctx, "Unsupported GTPU flex parser\n"); 1506 return -EOPNOTSUPP; 1507 } 1508 1509 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_GTP_MSG_TYPE]; 1510 fc->tag_set = &hws_definer_generic_set; 1511 fc->bit_mask = __mlx5_mask(header_gtp, msg_type); 1512 fc->bit_off = __mlx5_dw_bit_off(header_gtp, msg_type); 1513 fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE; 1514 HWS_CALC_HDR_SRC(fc, misc_parameters_3.gtpu_msg_type); 1515 } 1516 1517 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.gtpu_msg_flags)) { 1518 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GTPU; 1519 1520 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_ENABLED)) { 1521 mlx5hws_err(cd->ctx, "Unsupported GTPU flex parser\n"); 1522 return -EOPNOTSUPP; 1523 } 1524 1525 fc = &cd->fc[MLX5HWS_DEFINER_FNAME_GTP_MSG_TYPE]; 1526 fc->tag_set = &hws_definer_generic_set; 1527 fc->bit_mask = __mlx5_mask(header_gtp, msg_flags); 1528 fc->bit_off = __mlx5_dw_bit_off(header_gtp, msg_flags); 1529 fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE; 1530 HWS_CALC_HDR_SRC(fc, misc_parameters_3.gtpu_msg_flags); 1531 } 1532 1533 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.gtpu_dw_2)) { 1534 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GTPU; 1535 1536 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_DW_2_ENABLED)) { 1537 mlx5hws_err(cd->ctx, "Unsupported GTPU DW2 flex parser\n"); 1538 return -EOPNOTSUPP; 1539 } 1540 1541 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GTPU_DW2]; 1542 curr_fc->tag_set = &hws_definer_generic_set; 1543 curr_fc->bit_mask = -1; 1544 curr_fc->byte_off = caps->format_select_gtpu_dw_2 * DW_SIZE; 1545 HWS_CALC_HDR_SRC(fc, misc_parameters_3.gtpu_dw_2); 1546 } 1547 1548 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.gtpu_first_ext_dw_0)) { 1549 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GTPU; 1550 1551 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_FIRST_EXT_DW_0_ENABLED)) { 1552 mlx5hws_err(cd->ctx, "Unsupported GTPU first EXT DW0 flex parser\n"); 1553 return -EOPNOTSUPP; 1554 } 1555 1556 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GTPU_FIRST_EXT_DW0]; 1557 curr_fc->tag_set = &hws_definer_generic_set; 1558 curr_fc->bit_mask = -1; 1559 curr_fc->byte_off = caps->format_select_gtpu_ext_dw_0 * DW_SIZE; 1560 HWS_CALC_HDR_SRC(fc, misc_parameters_3.gtpu_first_ext_dw_0); 1561 } 1562 1563 if (HWS_IS_FLD_SET(match_param, misc_parameters_3.gtpu_dw_0)) { 1564 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_GTPU; 1565 1566 if (!(caps->flex_protocols & MLX5_FLEX_PARSER_GTPU_DW_0_ENABLED)) { 1567 mlx5hws_err(cd->ctx, "Unsupported GTPU DW0 flex parser\n"); 1568 return -EOPNOTSUPP; 1569 } 1570 1571 curr_fc = &fc[MLX5HWS_DEFINER_FNAME_GTPU_DW0]; 1572 curr_fc->tag_set = &hws_definer_generic_set; 1573 curr_fc->bit_mask = -1; 1574 curr_fc->byte_off = caps->format_select_gtpu_dw_0 * DW_SIZE; 1575 HWS_CALC_HDR_SRC(fc, misc_parameters_3.gtpu_dw_0); 1576 } 1577 1578 return 0; 1579} 1580 1581static int 1582hws_definer_conv_misc4(struct mlx5hws_definer_conv_data *cd, 1583 u32 *match_param) 1584{ 1585 bool parser_is_used[HWS_NUM_OF_FLEX_PARSERS] = {}; 1586 struct mlx5hws_definer_fc *fc; 1587 u32 id, value; 1588 1589 if (HWS_IS_FLD_SET_SZ(match_param, misc_parameters_4.reserved_at_100, 0x100)) { 1590 mlx5hws_err(cd->ctx, "Unsupported misc4 parameters set\n"); 1591 return -EINVAL; 1592 } 1593 1594 id = HWS_GET_MATCH_PARAM(match_param, misc_parameters_4.prog_sample_field_id_0); 1595 value = HWS_GET_MATCH_PARAM(match_param, misc_parameters_4.prog_sample_field_value_0); 1596 fc = hws_definer_misc4_fields_handler(cd, parser_is_used, id, value); 1597 if (!fc) 1598 return -EINVAL; 1599 1600 HWS_CALC_HDR_SRC(fc, misc_parameters_4.prog_sample_field_value_0); 1601 1602 id = HWS_GET_MATCH_PARAM(match_param, misc_parameters_4.prog_sample_field_id_1); 1603 value = HWS_GET_MATCH_PARAM(match_param, misc_parameters_4.prog_sample_field_value_1); 1604 fc = hws_definer_misc4_fields_handler(cd, parser_is_used, id, value); 1605 if (!fc) 1606 return -EINVAL; 1607 1608 HWS_CALC_HDR_SRC(fc, misc_parameters_4.prog_sample_field_value_1); 1609 1610 id = HWS_GET_MATCH_PARAM(match_param, misc_parameters_4.prog_sample_field_id_2); 1611 value = HWS_GET_MATCH_PARAM(match_param, misc_parameters_4.prog_sample_field_value_2); 1612 fc = hws_definer_misc4_fields_handler(cd, parser_is_used, id, value); 1613 if (!fc) 1614 return -EINVAL; 1615 1616 HWS_CALC_HDR_SRC(fc, misc_parameters_4.prog_sample_field_value_2); 1617 1618 id = HWS_GET_MATCH_PARAM(match_param, misc_parameters_4.prog_sample_field_id_3); 1619 value = HWS_GET_MATCH_PARAM(match_param, misc_parameters_4.prog_sample_field_value_3); 1620 fc = hws_definer_misc4_fields_handler(cd, parser_is_used, id, value); 1621 if (!fc) 1622 return -EINVAL; 1623 1624 HWS_CALC_HDR_SRC(fc, misc_parameters_4.prog_sample_field_value_3); 1625 1626 return 0; 1627} 1628 1629static int 1630hws_definer_conv_misc5(struct mlx5hws_definer_conv_data *cd, 1631 u32 *match_param) 1632{ 1633 struct mlx5hws_definer_fc *fc = cd->fc; 1634 1635 if (HWS_IS_FLD_SET(match_param, misc_parameters_5.macsec_tag_0) || 1636 HWS_IS_FLD_SET(match_param, misc_parameters_5.macsec_tag_1) || 1637 HWS_IS_FLD_SET(match_param, misc_parameters_5.macsec_tag_2) || 1638 HWS_IS_FLD_SET(match_param, misc_parameters_5.macsec_tag_3) || 1639 HWS_IS_FLD_SET_SZ(match_param, misc_parameters_5.reserved_at_100, 0x100)) { 1640 mlx5hws_err(cd->ctx, "Unsupported misc5 parameters set\n"); 1641 return -EINVAL; 1642 } 1643 1644 if (HWS_IS_FLD_SET(match_param, misc_parameters_5.tunnel_header_0)) { 1645 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_HEADER_0_1; 1646 HWS_SET_HDR(fc, match_param, TNL_HDR_0, 1647 misc_parameters_5.tunnel_header_0, tunnel_header.tunnel_header_0); 1648 } 1649 1650 if (HWS_IS_FLD_SET(match_param, misc_parameters_5.tunnel_header_1)) { 1651 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_HEADER_0_1; 1652 HWS_SET_HDR(fc, match_param, TNL_HDR_1, 1653 misc_parameters_5.tunnel_header_1, tunnel_header.tunnel_header_1); 1654 } 1655 1656 if (HWS_IS_FLD_SET(match_param, misc_parameters_5.tunnel_header_2)) { 1657 cd->match_flags |= MLX5HWS_DEFINER_MATCH_FLAG_TNL_HEADER_2; 1658 HWS_SET_HDR(fc, match_param, TNL_HDR_2, 1659 misc_parameters_5.tunnel_header_2, tunnel_header.tunnel_header_2); 1660 } 1661 1662 HWS_SET_HDR(fc, match_param, TNL_HDR_3, 1663 misc_parameters_5.tunnel_header_3, tunnel_header.tunnel_header_3); 1664 1665 return 0; 1666} 1667 1668static int hws_definer_get_fc_size(struct mlx5hws_definer_fc *fc) 1669{ 1670 u32 fc_sz = 0; 1671 int i; 1672 1673 /* For empty matcher, ZERO_SIZE_PTR is returned */ 1674 if (fc == ZERO_SIZE_PTR) 1675 return 0; 1676 1677 for (i = 0; i < MLX5HWS_DEFINER_FNAME_MAX; i++) 1678 if (fc[i].tag_set) 1679 fc_sz++; 1680 return fc_sz; 1681} 1682 1683static struct mlx5hws_definer_fc * 1684hws_definer_alloc_compressed_fc(struct mlx5hws_definer_fc *fc) 1685{ 1686 struct mlx5hws_definer_fc *compressed_fc = NULL; 1687 u32 definer_size = hws_definer_get_fc_size(fc); 1688 u32 fc_sz = 0; 1689 int i; 1690 1691 compressed_fc = kcalloc(definer_size, sizeof(*compressed_fc), GFP_KERNEL); 1692 if (!compressed_fc) 1693 return NULL; 1694 1695 /* For empty matcher, ZERO_SIZE_PTR is returned */ 1696 if (!definer_size) 1697 return compressed_fc; 1698 1699 for (i = 0, fc_sz = 0; i < MLX5HWS_DEFINER_FNAME_MAX; i++) { 1700 if (!fc[i].tag_set) 1701 continue; 1702 1703 fc[i].fname = i; 1704 memcpy(&compressed_fc[fc_sz++], &fc[i], sizeof(*compressed_fc)); 1705 } 1706 1707 return compressed_fc; 1708} 1709 1710static void 1711hws_definer_set_hl(u8 *hl, struct mlx5hws_definer_fc *fc) 1712{ 1713 int i; 1714 1715 /* nothing to do for empty matcher */ 1716 if (fc == ZERO_SIZE_PTR) 1717 return; 1718 1719 for (i = 0; i < MLX5HWS_DEFINER_FNAME_MAX; i++) { 1720 if (!fc[i].tag_set) 1721 continue; 1722 1723 HWS_SET32(hl, -1, fc[i].byte_off, fc[i].bit_off, fc[i].bit_mask); 1724 } 1725} 1726 1727static struct mlx5hws_definer_fc * 1728hws_definer_alloc_fc(struct mlx5hws_context *ctx, 1729 size_t len) 1730{ 1731 struct mlx5hws_definer_fc *fc; 1732 int i; 1733 1734 fc = kcalloc(len, sizeof(*fc), GFP_KERNEL); 1735 if (!fc) 1736 return NULL; 1737 1738 for (i = 0; i < len; i++) 1739 fc[i].ctx = ctx; 1740 1741 return fc; 1742} 1743 1744static int 1745hws_definer_conv_match_params_to_hl(struct mlx5hws_context *ctx, 1746 struct mlx5hws_match_template *mt, 1747 u8 *hl) 1748{ 1749 struct mlx5hws_definer_conv_data cd = {0}; 1750 struct mlx5hws_definer_fc *fc; 1751 int ret; 1752 1753 fc = hws_definer_alloc_fc(ctx, MLX5HWS_DEFINER_FNAME_MAX); 1754 if (!fc) 1755 return -ENOMEM; 1756 1757 cd.fc = fc; 1758 cd.ctx = ctx; 1759 1760 if (mt->match_criteria_enable & MLX5HWS_DEFINER_MATCH_CRITERIA_MISC6) { 1761 mlx5hws_err(ctx, "Unsupported match_criteria_enable provided\n"); 1762 ret = -EOPNOTSUPP; 1763 goto err_free_fc; 1764 } 1765 1766 if (mt->match_criteria_enable & MLX5HWS_DEFINER_MATCH_CRITERIA_OUTER) { 1767 ret = hws_definer_conv_outer(&cd, mt->match_param); 1768 if (ret) 1769 goto err_free_fc; 1770 } 1771 1772 if (mt->match_criteria_enable & MLX5HWS_DEFINER_MATCH_CRITERIA_INNER) { 1773 ret = hws_definer_conv_inner(&cd, mt->match_param); 1774 if (ret) 1775 goto err_free_fc; 1776 } 1777 1778 if (mt->match_criteria_enable & MLX5HWS_DEFINER_MATCH_CRITERIA_MISC) { 1779 ret = hws_definer_conv_misc(&cd, mt->match_param); 1780 if (ret) 1781 goto err_free_fc; 1782 } 1783 1784 if (mt->match_criteria_enable & MLX5HWS_DEFINER_MATCH_CRITERIA_MISC2) { 1785 ret = hws_definer_conv_misc2(&cd, mt->match_param); 1786 if (ret) 1787 goto err_free_fc; 1788 } 1789 1790 if (mt->match_criteria_enable & MLX5HWS_DEFINER_MATCH_CRITERIA_MISC3) { 1791 ret = hws_definer_conv_misc3(&cd, mt->match_param); 1792 if (ret) 1793 goto err_free_fc; 1794 } 1795 1796 if (mt->match_criteria_enable & MLX5HWS_DEFINER_MATCH_CRITERIA_MISC4) { 1797 ret = hws_definer_conv_misc4(&cd, mt->match_param); 1798 if (ret) 1799 goto err_free_fc; 1800 } 1801 1802 if (mt->match_criteria_enable & MLX5HWS_DEFINER_MATCH_CRITERIA_MISC5) { 1803 ret = hws_definer_conv_misc5(&cd, mt->match_param); 1804 if (ret) 1805 goto err_free_fc; 1806 } 1807 1808 /* Check there is no conflicted fields set together */ 1809 ret = hws_definer_check_match_flags(&cd); 1810 if (ret) 1811 goto err_free_fc; 1812 1813 /* Allocate fc array on mt */ 1814 mt->fc = hws_definer_alloc_compressed_fc(fc); 1815 if (!mt->fc) { 1816 mlx5hws_err(ctx, 1817 "Convert match params: failed to set field copy to match template\n"); 1818 ret = -ENOMEM; 1819 goto err_free_fc; 1820 } 1821 mt->fc_sz = hws_definer_get_fc_size(fc); 1822 1823 /* Fill in headers layout */ 1824 hws_definer_set_hl(hl, fc); 1825 1826 kfree(fc); 1827 return 0; 1828 1829err_free_fc: 1830 kfree(fc); 1831 return ret; 1832} 1833 1834static int 1835hws_definer_find_byte_in_tag(struct mlx5hws_definer *definer, 1836 u32 hl_byte_off, 1837 u32 *tag_byte_off) 1838{ 1839 int i, dw_to_scan; 1840 u8 byte_offset; 1841 1842 /* Avoid accessing unused DW selectors */ 1843 dw_to_scan = mlx5hws_definer_is_jumbo(definer) ? 1844 DW_SELECTORS : DW_SELECTORS_MATCH; 1845 1846 /* Add offset since each DW covers multiple BYTEs */ 1847 byte_offset = hl_byte_off % DW_SIZE; 1848 for (i = 0; i < dw_to_scan; i++) { 1849 if (definer->dw_selector[i] == hl_byte_off / DW_SIZE) { 1850 *tag_byte_off = byte_offset + DW_SIZE * (DW_SELECTORS - i - 1); 1851 return 0; 1852 } 1853 } 1854 1855 /* Add offset to skip DWs in definer */ 1856 byte_offset = DW_SIZE * DW_SELECTORS; 1857 /* Iterate in reverse since the code uses bytes from 7 -> 0 */ 1858 for (i = BYTE_SELECTORS; i-- > 0 ;) { 1859 if (definer->byte_selector[i] == hl_byte_off) { 1860 *tag_byte_off = byte_offset + (BYTE_SELECTORS - i - 1); 1861 return 0; 1862 } 1863 } 1864 1865 return -EINVAL; 1866} 1867 1868static int 1869hws_definer_fc_bind(struct mlx5hws_definer *definer, 1870 struct mlx5hws_definer_fc *fc, 1871 u32 fc_sz) 1872{ 1873 u32 tag_offset = 0; 1874 int ret, byte_diff; 1875 u32 i; 1876 1877 for (i = 0; i < fc_sz; i++) { 1878 /* Map header layout byte offset to byte offset in tag */ 1879 ret = hws_definer_find_byte_in_tag(definer, fc->byte_off, &tag_offset); 1880 if (ret) 1881 return ret; 1882 1883 /* Move setter based on the location in the definer */ 1884 byte_diff = fc->byte_off % DW_SIZE - tag_offset % DW_SIZE; 1885 fc->bit_off = fc->bit_off + byte_diff * BITS_IN_BYTE; 1886 1887 /* Update offset in headers layout to offset in tag */ 1888 fc->byte_off = tag_offset; 1889 fc++; 1890 } 1891 1892 return 0; 1893} 1894 1895static bool 1896hws_definer_best_hl_fit_recu(struct mlx5hws_definer_sel_ctrl *ctrl, 1897 u32 cur_dw, 1898 u32 *data) 1899{ 1900 u8 bytes_set; 1901 int byte_idx; 1902 bool ret; 1903 int i; 1904 1905 /* Reached end, nothing left to do */ 1906 if (cur_dw == MLX5_ST_SZ_DW(definer_hl)) 1907 return true; 1908 1909 /* No data set, can skip to next DW */ 1910 while (!*data) { 1911 cur_dw++; 1912 data++; 1913 1914 /* Reached end, nothing left to do */ 1915 if (cur_dw == MLX5_ST_SZ_DW(definer_hl)) 1916 return true; 1917 } 1918 1919 /* Used all DW selectors and Byte selectors, no possible solution */ 1920 if (ctrl->allowed_full_dw == ctrl->used_full_dw && 1921 ctrl->allowed_lim_dw == ctrl->used_lim_dw && 1922 ctrl->allowed_bytes == ctrl->used_bytes) 1923 return false; 1924 1925 /* Try to use limited DW selectors */ 1926 if (ctrl->allowed_lim_dw > ctrl->used_lim_dw && cur_dw < 64) { 1927 ctrl->lim_dw_selector[ctrl->used_lim_dw++] = cur_dw; 1928 1929 ret = hws_definer_best_hl_fit_recu(ctrl, cur_dw + 1, data + 1); 1930 if (ret) 1931 return ret; 1932 1933 ctrl->lim_dw_selector[--ctrl->used_lim_dw] = 0; 1934 } 1935 1936 /* Try to use DW selectors */ 1937 if (ctrl->allowed_full_dw > ctrl->used_full_dw) { 1938 ctrl->full_dw_selector[ctrl->used_full_dw++] = cur_dw; 1939 1940 ret = hws_definer_best_hl_fit_recu(ctrl, cur_dw + 1, data + 1); 1941 if (ret) 1942 return ret; 1943 1944 ctrl->full_dw_selector[--ctrl->used_full_dw] = 0; 1945 } 1946 1947 /* No byte selector for offset bigger than 255 */ 1948 if (cur_dw * DW_SIZE > 255) 1949 return false; 1950 1951 bytes_set = !!(0x000000ff & *data) + 1952 !!(0x0000ff00 & *data) + 1953 !!(0x00ff0000 & *data) + 1954 !!(0xff000000 & *data); 1955 1956 /* Check if there are enough byte selectors left */ 1957 if (bytes_set + ctrl->used_bytes > ctrl->allowed_bytes) 1958 return false; 1959 1960 /* Try to use Byte selectors */ 1961 for (i = 0; i < DW_SIZE; i++) 1962 if ((0xff000000 >> (i * BITS_IN_BYTE)) & be32_to_cpu((__force __be32)*data)) { 1963 /* Use byte selectors high to low */ 1964 byte_idx = ctrl->allowed_bytes - ctrl->used_bytes - 1; 1965 ctrl->byte_selector[byte_idx] = cur_dw * DW_SIZE + i; 1966 ctrl->used_bytes++; 1967 } 1968 1969 ret = hws_definer_best_hl_fit_recu(ctrl, cur_dw + 1, data + 1); 1970 if (ret) 1971 return ret; 1972 1973 for (i = 0; i < DW_SIZE; i++) 1974 if ((0xff << (i * BITS_IN_BYTE)) & be32_to_cpu((__force __be32)*data)) { 1975 ctrl->used_bytes--; 1976 byte_idx = ctrl->allowed_bytes - ctrl->used_bytes - 1; 1977 ctrl->byte_selector[byte_idx] = 0; 1978 } 1979 1980 return false; 1981} 1982 1983static void 1984hws_definer_copy_sel_ctrl(struct mlx5hws_definer_sel_ctrl *ctrl, 1985 struct mlx5hws_definer *definer) 1986{ 1987 memcpy(definer->byte_selector, ctrl->byte_selector, ctrl->allowed_bytes); 1988 memcpy(definer->dw_selector, ctrl->full_dw_selector, ctrl->allowed_full_dw); 1989 memcpy(definer->dw_selector + ctrl->allowed_full_dw, 1990 ctrl->lim_dw_selector, ctrl->allowed_lim_dw); 1991} 1992 1993static int 1994hws_definer_find_best_match_fit(struct mlx5hws_context *ctx, 1995 struct mlx5hws_definer *definer, 1996 u8 *hl, bool allow_jumbo) 1997{ 1998 struct mlx5hws_definer_sel_ctrl ctrl = {0}; 1999 bool found; 2000 2001 /* Try to create a match definer */ 2002 ctrl.allowed_full_dw = DW_SELECTORS_MATCH; 2003 ctrl.allowed_lim_dw = 0; 2004 ctrl.allowed_bytes = BYTE_SELECTORS; 2005 2006 found = hws_definer_best_hl_fit_recu(&ctrl, 0, (u32 *)hl); 2007 if (found) { 2008 hws_definer_copy_sel_ctrl(&ctrl, definer); 2009 definer->type = MLX5HWS_DEFINER_TYPE_MATCH; 2010 return 0; 2011 } 2012 2013 if (!allow_jumbo) 2014 return -E2BIG; 2015 2016 /* Try to create a full/limited jumbo definer */ 2017 ctrl.allowed_full_dw = ctx->caps->full_dw_jumbo_support ? DW_SELECTORS : 2018 DW_SELECTORS_MATCH; 2019 ctrl.allowed_lim_dw = ctx->caps->full_dw_jumbo_support ? 0 : 2020 DW_SELECTORS_LIMITED; 2021 ctrl.allowed_bytes = BYTE_SELECTORS; 2022 2023 found = hws_definer_best_hl_fit_recu(&ctrl, 0, (u32 *)hl); 2024 if (found) { 2025 hws_definer_copy_sel_ctrl(&ctrl, definer); 2026 definer->type = MLX5HWS_DEFINER_TYPE_JUMBO; 2027 return 0; 2028 } 2029 2030 return -E2BIG; 2031} 2032 2033static void 2034hws_definer_create_tag_mask(u32 *match_param, 2035 struct mlx5hws_definer_fc *fc, 2036 u32 fc_sz, 2037 u8 *tag) 2038{ 2039 u32 i; 2040 2041 for (i = 0; i < fc_sz; i++) { 2042 if (fc->tag_mask_set) 2043 fc->tag_mask_set(fc, match_param, tag); 2044 else 2045 fc->tag_set(fc, match_param, tag); 2046 fc++; 2047 } 2048} 2049 2050void mlx5hws_definer_create_tag(u32 *match_param, 2051 struct mlx5hws_definer_fc *fc, 2052 u32 fc_sz, 2053 u8 *tag) 2054{ 2055 u32 i; 2056 2057 for (i = 0; i < fc_sz; i++) { 2058 fc->tag_set(fc, match_param, tag); 2059 fc++; 2060 } 2061} 2062 2063int mlx5hws_definer_get_id(struct mlx5hws_definer *definer) 2064{ 2065 return definer->obj_id; 2066} 2067 2068int mlx5hws_definer_compare(struct mlx5hws_definer *definer_a, 2069 struct mlx5hws_definer *definer_b) 2070{ 2071 int i; 2072 2073 /* Future: Optimize by comparing selectors with valid mask only */ 2074 for (i = 0; i < BYTE_SELECTORS; i++) 2075 if (definer_a->byte_selector[i] != definer_b->byte_selector[i]) 2076 return 1; 2077 2078 for (i = 0; i < DW_SELECTORS; i++) 2079 if (definer_a->dw_selector[i] != definer_b->dw_selector[i]) 2080 return 1; 2081 2082 for (i = 0; i < MLX5HWS_JUMBO_TAG_SZ; i++) 2083 if (definer_a->mask.jumbo[i] != definer_b->mask.jumbo[i]) 2084 return 1; 2085 2086 return 0; 2087} 2088 2089int 2090mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx, 2091 struct mlx5hws_match_template *mt, 2092 struct mlx5hws_definer *match_definer, 2093 bool allow_jumbo) 2094{ 2095 u8 *match_hl; 2096 int ret; 2097 2098 /* Union header-layout (hl) is used for creating a single definer 2099 * field layout used with different bitmasks for hash and match. 2100 */ 2101 match_hl = kzalloc(MLX5_ST_SZ_BYTES(definer_hl), GFP_KERNEL); 2102 if (!match_hl) 2103 return -ENOMEM; 2104 2105 /* Convert all mt items to header layout (hl) 2106 * and allocate the match and range field copy array (fc & fcr). 2107 */ 2108 ret = hws_definer_conv_match_params_to_hl(ctx, mt, match_hl); 2109 if (ret) { 2110 mlx5hws_err(ctx, "Failed to convert items to header layout\n"); 2111 goto free_match_hl; 2112 } 2113 2114 /* Find the match definer layout for header layout match union */ 2115 ret = hws_definer_find_best_match_fit(ctx, match_definer, match_hl, 2116 allow_jumbo); 2117 if (ret) { 2118 if (ret == -E2BIG) 2119 mlx5hws_dbg(ctx, 2120 "Failed to create match definer from header layout - E2BIG\n"); 2121 else 2122 mlx5hws_err(ctx, 2123 "Failed to create match definer from header layout (%d)\n", 2124 ret); 2125 goto free_fc; 2126 } 2127 2128 kfree(match_hl); 2129 return 0; 2130 2131free_fc: 2132 kfree(mt->fc); 2133free_match_hl: 2134 kfree(match_hl); 2135 return ret; 2136} 2137 2138int mlx5hws_definer_init_cache(struct mlx5hws_definer_cache **cache) 2139{ 2140 struct mlx5hws_definer_cache *new_cache; 2141 2142 new_cache = kzalloc(sizeof(*new_cache), GFP_KERNEL); 2143 if (!new_cache) 2144 return -ENOMEM; 2145 2146 INIT_LIST_HEAD(&new_cache->list_head); 2147 *cache = new_cache; 2148 2149 return 0; 2150} 2151 2152void mlx5hws_definer_uninit_cache(struct mlx5hws_definer_cache *cache) 2153{ 2154 kfree(cache); 2155} 2156 2157int mlx5hws_definer_get_obj(struct mlx5hws_context *ctx, 2158 struct mlx5hws_definer *definer) 2159{ 2160 struct mlx5hws_definer_cache *cache = ctx->definer_cache; 2161 struct mlx5hws_cmd_definer_create_attr def_attr = {0}; 2162 struct mlx5hws_definer_cache_item *cached_definer; 2163 u32 obj_id; 2164 int ret; 2165 2166 /* Search definer cache for requested definer */ 2167 list_for_each_entry(cached_definer, &cache->list_head, list_node) { 2168 if (mlx5hws_definer_compare(&cached_definer->definer, definer)) 2169 continue; 2170 2171 /* Reuse definer and set LRU (move to be first in the list) */ 2172 list_move(&cached_definer->list_node, &cache->list_head); 2173 cached_definer->refcount++; 2174 return cached_definer->definer.obj_id; 2175 } 2176 2177 /* Allocate and create definer based on the bitmask tag */ 2178 def_attr.match_mask = definer->mask.jumbo; 2179 def_attr.dw_selector = definer->dw_selector; 2180 def_attr.byte_selector = definer->byte_selector; 2181 2182 ret = mlx5hws_cmd_definer_create(ctx->mdev, &def_attr, &obj_id); 2183 if (ret) 2184 return -1; 2185 2186 cached_definer = kzalloc(sizeof(*cached_definer), GFP_KERNEL); 2187 if (!cached_definer) 2188 goto free_definer_obj; 2189 2190 memcpy(&cached_definer->definer, definer, sizeof(*definer)); 2191 cached_definer->definer.obj_id = obj_id; 2192 cached_definer->refcount = 1; 2193 list_add(&cached_definer->list_node, &cache->list_head); 2194 2195 return obj_id; 2196 2197free_definer_obj: 2198 mlx5hws_cmd_definer_destroy(ctx->mdev, obj_id); 2199 return -1; 2200} 2201 2202static void 2203hws_definer_put_obj(struct mlx5hws_context *ctx, u32 obj_id) 2204{ 2205 struct mlx5hws_definer_cache_item *cached_definer; 2206 2207 list_for_each_entry(cached_definer, &ctx->definer_cache->list_head, list_node) { 2208 if (cached_definer->definer.obj_id != obj_id) 2209 continue; 2210 2211 /* Object found */ 2212 if (--cached_definer->refcount) 2213 return; 2214 2215 list_del_init(&cached_definer->list_node); 2216 mlx5hws_cmd_definer_destroy(ctx->mdev, cached_definer->definer.obj_id); 2217 kfree(cached_definer); 2218 return; 2219 } 2220 2221 /* Programming error, object must be part of cache */ 2222 pr_warn("HWS: failed putting definer object\n"); 2223} 2224 2225static struct mlx5hws_definer * 2226hws_definer_alloc(struct mlx5hws_context *ctx, 2227 struct mlx5hws_definer_fc *fc, 2228 int fc_sz, 2229 u32 *match_param, 2230 struct mlx5hws_definer *layout, 2231 bool bind_fc) 2232{ 2233 struct mlx5hws_definer *definer; 2234 int ret; 2235 2236 definer = kmemdup(layout, sizeof(*definer), GFP_KERNEL); 2237 if (!definer) 2238 return NULL; 2239 2240 /* Align field copy array based on given layout */ 2241 if (bind_fc) { 2242 ret = hws_definer_fc_bind(definer, fc, fc_sz); 2243 if (ret) { 2244 mlx5hws_err(ctx, "Failed to bind field copy to definer\n"); 2245 goto free_definer; 2246 } 2247 } 2248 2249 /* Create the tag mask used for definer creation */ 2250 hws_definer_create_tag_mask(match_param, fc, fc_sz, definer->mask.jumbo); 2251 2252 ret = mlx5hws_definer_get_obj(ctx, definer); 2253 if (ret < 0) 2254 goto free_definer; 2255 2256 definer->obj_id = ret; 2257 return definer; 2258 2259free_definer: 2260 kfree(definer); 2261 return NULL; 2262} 2263 2264void mlx5hws_definer_free(struct mlx5hws_context *ctx, 2265 struct mlx5hws_definer *definer) 2266{ 2267 hws_definer_put_obj(ctx, definer->obj_id); 2268 kfree(definer); 2269} 2270 2271static int 2272hws_definer_mt_match_init(struct mlx5hws_context *ctx, 2273 struct mlx5hws_match_template *mt, 2274 struct mlx5hws_definer *match_layout) 2275{ 2276 /* Create mandatory match definer */ 2277 mt->definer = hws_definer_alloc(ctx, 2278 mt->fc, 2279 mt->fc_sz, 2280 mt->match_param, 2281 match_layout, 2282 true); 2283 if (!mt->definer) { 2284 mlx5hws_err(ctx, "Failed to create match definer\n"); 2285 return -EINVAL; 2286 } 2287 2288 return 0; 2289} 2290 2291static void 2292hws_definer_mt_match_uninit(struct mlx5hws_context *ctx, 2293 struct mlx5hws_match_template *mt) 2294{ 2295 mlx5hws_definer_free(ctx, mt->definer); 2296} 2297 2298int mlx5hws_definer_mt_init(struct mlx5hws_context *ctx, 2299 struct mlx5hws_match_template *mt) 2300{ 2301 struct mlx5hws_definer match_layout = {0}; 2302 int ret; 2303 2304 ret = mlx5hws_definer_calc_layout(ctx, mt, &match_layout, true); 2305 if (ret) { 2306 mlx5hws_err(ctx, "Failed to calculate matcher definer layout\n"); 2307 return ret; 2308 } 2309 2310 /* Calculate definers needed for exact match */ 2311 ret = hws_definer_mt_match_init(ctx, mt, &match_layout); 2312 if (ret) { 2313 mlx5hws_err(ctx, "Failed to init match definers\n"); 2314 goto free_fc; 2315 } 2316 2317 return 0; 2318 2319free_fc: 2320 kfree(mt->fc); 2321 return ret; 2322} 2323 2324void mlx5hws_definer_mt_uninit(struct mlx5hws_context *ctx, 2325 struct mlx5hws_match_template *mt) 2326{ 2327 hws_definer_mt_match_uninit(ctx, mt); 2328 kfree(mt->fc); 2329}
~/
Read-only file preview.