File Index
Files and directories
Sign in
FILE

definer.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c 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.