linux/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v1.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
   2/* Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. */
   3
   4#include <linux/types.h>
   5#include "mlx5_ifc_dr_ste_v1.h"
   6#include "dr_ste.h"
   7
   8#define DR_STE_CALC_DFNR_TYPE(lookup_type, inner) \
   9        ((inner) ? DR_STE_V1_LU_TYPE_##lookup_type##_I : \
  10                   DR_STE_V1_LU_TYPE_##lookup_type##_O)
  11
  12enum dr_ste_v1_entry_format {
  13        DR_STE_V1_TYPE_BWC_BYTE = 0x0,
  14        DR_STE_V1_TYPE_BWC_DW   = 0x1,
  15        DR_STE_V1_TYPE_MATCH    = 0x2,
  16};
  17
  18/* Lookup type is built from 2B: [ Definer mode 1B ][ Definer index 1B ] */
  19enum {
  20        DR_STE_V1_LU_TYPE_NOP                           = 0x0000,
  21        DR_STE_V1_LU_TYPE_ETHL2_TNL                     = 0x0002,
  22        DR_STE_V1_LU_TYPE_IBL3_EXT                      = 0x0102,
  23        DR_STE_V1_LU_TYPE_ETHL2_O                       = 0x0003,
  24        DR_STE_V1_LU_TYPE_IBL4                          = 0x0103,
  25        DR_STE_V1_LU_TYPE_ETHL2_I                       = 0x0004,
  26        DR_STE_V1_LU_TYPE_SRC_QP_GVMI                   = 0x0104,
  27        DR_STE_V1_LU_TYPE_ETHL2_SRC_O                   = 0x0005,
  28        DR_STE_V1_LU_TYPE_ETHL2_HEADERS_O               = 0x0105,
  29        DR_STE_V1_LU_TYPE_ETHL2_SRC_I                   = 0x0006,
  30        DR_STE_V1_LU_TYPE_ETHL2_HEADERS_I               = 0x0106,
  31        DR_STE_V1_LU_TYPE_ETHL3_IPV4_5_TUPLE_O          = 0x0007,
  32        DR_STE_V1_LU_TYPE_IPV6_DES_O                    = 0x0107,
  33        DR_STE_V1_LU_TYPE_ETHL3_IPV4_5_TUPLE_I          = 0x0008,
  34        DR_STE_V1_LU_TYPE_IPV6_DES_I                    = 0x0108,
  35        DR_STE_V1_LU_TYPE_ETHL4_O                       = 0x0009,
  36        DR_STE_V1_LU_TYPE_IPV6_SRC_O                    = 0x0109,
  37        DR_STE_V1_LU_TYPE_ETHL4_I                       = 0x000a,
  38        DR_STE_V1_LU_TYPE_IPV6_SRC_I                    = 0x010a,
  39        DR_STE_V1_LU_TYPE_ETHL2_SRC_DST_O               = 0x000b,
  40        DR_STE_V1_LU_TYPE_MPLS_O                        = 0x010b,
  41        DR_STE_V1_LU_TYPE_ETHL2_SRC_DST_I               = 0x000c,
  42        DR_STE_V1_LU_TYPE_MPLS_I                        = 0x010c,
  43        DR_STE_V1_LU_TYPE_ETHL3_IPV4_MISC_O             = 0x000d,
  44        DR_STE_V1_LU_TYPE_GRE                           = 0x010d,
  45        DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER        = 0x000e,
  46        DR_STE_V1_LU_TYPE_GENERAL_PURPOSE               = 0x010e,
  47        DR_STE_V1_LU_TYPE_ETHL3_IPV4_MISC_I             = 0x000f,
  48        DR_STE_V1_LU_TYPE_STEERING_REGISTERS_0          = 0x010f,
  49        DR_STE_V1_LU_TYPE_STEERING_REGISTERS_1          = 0x0110,
  50        DR_STE_V1_LU_TYPE_FLEX_PARSER_0                 = 0x0111,
  51        DR_STE_V1_LU_TYPE_FLEX_PARSER_1                 = 0x0112,
  52        DR_STE_V1_LU_TYPE_ETHL4_MISC_O                  = 0x0113,
  53        DR_STE_V1_LU_TYPE_ETHL4_MISC_I                  = 0x0114,
  54        DR_STE_V1_LU_TYPE_INVALID                       = 0x00ff,
  55        DR_STE_V1_LU_TYPE_DONT_CARE                     = MLX5DR_STE_LU_TYPE_DONT_CARE,
  56};
  57
  58enum dr_ste_v1_header_anchors {
  59        DR_STE_HEADER_ANCHOR_START_OUTER                = 0x00,
  60        DR_STE_HEADER_ANCHOR_1ST_VLAN                   = 0x02,
  61        DR_STE_HEADER_ANCHOR_IPV6_IPV4                  = 0x07,
  62        DR_STE_HEADER_ANCHOR_INNER_MAC                  = 0x13,
  63        DR_STE_HEADER_ANCHOR_INNER_IPV6_IPV4            = 0x19,
  64};
  65
  66enum dr_ste_v1_action_size {
  67        DR_STE_ACTION_SINGLE_SZ = 4,
  68        DR_STE_ACTION_DOUBLE_SZ = 8,
  69        DR_STE_ACTION_TRIPLE_SZ = 12,
  70};
  71
  72enum dr_ste_v1_action_insert_ptr_attr {
  73        DR_STE_V1_ACTION_INSERT_PTR_ATTR_NONE = 0,  /* Regular push header (e.g. push vlan) */
  74        DR_STE_V1_ACTION_INSERT_PTR_ATTR_ENCAP = 1, /* Encapsulation / Tunneling */
  75        DR_STE_V1_ACTION_INSERT_PTR_ATTR_ESP = 2,   /* IPsec */
  76};
  77
  78enum dr_ste_v1_action_id {
  79        DR_STE_V1_ACTION_ID_NOP                         = 0x00,
  80        DR_STE_V1_ACTION_ID_COPY                        = 0x05,
  81        DR_STE_V1_ACTION_ID_SET                         = 0x06,
  82        DR_STE_V1_ACTION_ID_ADD                         = 0x07,
  83        DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE              = 0x08,
  84        DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER     = 0x09,
  85        DR_STE_V1_ACTION_ID_INSERT_INLINE               = 0x0a,
  86        DR_STE_V1_ACTION_ID_INSERT_POINTER              = 0x0b,
  87        DR_STE_V1_ACTION_ID_FLOW_TAG                    = 0x0c,
  88        DR_STE_V1_ACTION_ID_QUEUE_ID_SEL                = 0x0d,
  89        DR_STE_V1_ACTION_ID_ACCELERATED_LIST            = 0x0e,
  90        DR_STE_V1_ACTION_ID_MODIFY_LIST                 = 0x0f,
  91        DR_STE_V1_ACTION_ID_TRAILER                     = 0x13,
  92        DR_STE_V1_ACTION_ID_COUNTER_ID                  = 0x14,
  93        DR_STE_V1_ACTION_ID_MAX                         = 0x21,
  94        /* use for special cases */
  95        DR_STE_V1_ACTION_ID_SPECIAL_ENCAP_L3            = 0x22,
  96};
  97
  98enum {
  99        DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_0              = 0x00,
 100        DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_1              = 0x01,
 101        DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_2              = 0x02,
 102        DR_STE_V1_ACTION_MDFY_FLD_SRC_L2_OUT_0          = 0x08,
 103        DR_STE_V1_ACTION_MDFY_FLD_SRC_L2_OUT_1          = 0x09,
 104        DR_STE_V1_ACTION_MDFY_FLD_L3_OUT_0              = 0x0e,
 105        DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0              = 0x18,
 106        DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_1              = 0x19,
 107        DR_STE_V1_ACTION_MDFY_FLD_IPV4_OUT_0            = 0x40,
 108        DR_STE_V1_ACTION_MDFY_FLD_IPV4_OUT_1            = 0x41,
 109        DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_0        = 0x44,
 110        DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_1        = 0x45,
 111        DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_2        = 0x46,
 112        DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_3        = 0x47,
 113        DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_0        = 0x4c,
 114        DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_1        = 0x4d,
 115        DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_2        = 0x4e,
 116        DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_3        = 0x4f,
 117        DR_STE_V1_ACTION_MDFY_FLD_TCP_MISC_0            = 0x5e,
 118        DR_STE_V1_ACTION_MDFY_FLD_TCP_MISC_1            = 0x5f,
 119        DR_STE_V1_ACTION_MDFY_FLD_METADATA_2_CQE        = 0x7b,
 120        DR_STE_V1_ACTION_MDFY_FLD_GNRL_PURPOSE          = 0x7c,
 121        DR_STE_V1_ACTION_MDFY_FLD_REGISTER_2            = 0x8c,
 122        DR_STE_V1_ACTION_MDFY_FLD_REGISTER_3            = 0x8d,
 123        DR_STE_V1_ACTION_MDFY_FLD_REGISTER_4            = 0x8e,
 124        DR_STE_V1_ACTION_MDFY_FLD_REGISTER_5            = 0x8f,
 125        DR_STE_V1_ACTION_MDFY_FLD_REGISTER_6            = 0x90,
 126        DR_STE_V1_ACTION_MDFY_FLD_REGISTER_7            = 0x91,
 127};
 128
 129static const struct mlx5dr_ste_action_modify_field dr_ste_v1_action_modify_field_arr[] = {
 130        [MLX5_ACTION_IN_FIELD_OUT_SMAC_47_16] = {
 131                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_SRC_L2_OUT_0, .start = 0, .end = 31,
 132        },
 133        [MLX5_ACTION_IN_FIELD_OUT_SMAC_15_0] = {
 134                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_SRC_L2_OUT_1, .start = 16, .end = 31,
 135        },
 136        [MLX5_ACTION_IN_FIELD_OUT_ETHERTYPE] = {
 137                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_1, .start = 0, .end = 15,
 138        },
 139        [MLX5_ACTION_IN_FIELD_OUT_DMAC_47_16] = {
 140                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_0, .start = 0, .end = 31,
 141        },
 142        [MLX5_ACTION_IN_FIELD_OUT_DMAC_15_0] = {
 143                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_1, .start = 16, .end = 31,
 144        },
 145        [MLX5_ACTION_IN_FIELD_OUT_IP_DSCP] = {
 146                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L3_OUT_0, .start = 18, .end = 23,
 147        },
 148        [MLX5_ACTION_IN_FIELD_OUT_TCP_FLAGS] = {
 149                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_1, .start = 16, .end = 24,
 150                .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP,
 151        },
 152        [MLX5_ACTION_IN_FIELD_OUT_TCP_SPORT] = {
 153                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0, .start = 16, .end = 31,
 154                .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP,
 155        },
 156        [MLX5_ACTION_IN_FIELD_OUT_TCP_DPORT] = {
 157                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0, .start = 0, .end = 15,
 158                .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_TCP,
 159        },
 160        [MLX5_ACTION_IN_FIELD_OUT_IP_TTL] = {
 161                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L3_OUT_0, .start = 8, .end = 15,
 162                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4,
 163        },
 164        [MLX5_ACTION_IN_FIELD_OUT_IPV6_HOPLIMIT] = {
 165                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L3_OUT_0, .start = 8, .end = 15,
 166                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 167        },
 168        [MLX5_ACTION_IN_FIELD_OUT_UDP_SPORT] = {
 169                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0, .start = 16, .end = 31,
 170                .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_UDP,
 171        },
 172        [MLX5_ACTION_IN_FIELD_OUT_UDP_DPORT] = {
 173                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L4_OUT_0, .start = 0, .end = 15,
 174                .l4_type = DR_STE_ACTION_MDFY_TYPE_L4_UDP,
 175        },
 176        [MLX5_ACTION_IN_FIELD_OUT_SIPV6_127_96] = {
 177                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_0, .start = 0, .end = 31,
 178                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 179        },
 180        [MLX5_ACTION_IN_FIELD_OUT_SIPV6_95_64] = {
 181                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_1, .start = 0, .end = 31,
 182                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 183        },
 184        [MLX5_ACTION_IN_FIELD_OUT_SIPV6_63_32] = {
 185                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_2, .start = 0, .end = 31,
 186                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 187        },
 188        [MLX5_ACTION_IN_FIELD_OUT_SIPV6_31_0] = {
 189                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_SRC_OUT_3, .start = 0, .end = 31,
 190                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 191        },
 192        [MLX5_ACTION_IN_FIELD_OUT_DIPV6_127_96] = {
 193                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_0, .start = 0, .end = 31,
 194                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 195        },
 196        [MLX5_ACTION_IN_FIELD_OUT_DIPV6_95_64] = {
 197                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_1, .start = 0, .end = 31,
 198                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 199        },
 200        [MLX5_ACTION_IN_FIELD_OUT_DIPV6_63_32] = {
 201                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_2, .start = 0, .end = 31,
 202                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 203        },
 204        [MLX5_ACTION_IN_FIELD_OUT_DIPV6_31_0] = {
 205                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV6_DST_OUT_3, .start = 0, .end = 31,
 206                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV6,
 207        },
 208        [MLX5_ACTION_IN_FIELD_OUT_SIPV4] = {
 209                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV4_OUT_0, .start = 0, .end = 31,
 210                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4,
 211        },
 212        [MLX5_ACTION_IN_FIELD_OUT_DIPV4] = {
 213                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_IPV4_OUT_1, .start = 0, .end = 31,
 214                .l3_type = DR_STE_ACTION_MDFY_TYPE_L3_IPV4,
 215        },
 216        [MLX5_ACTION_IN_FIELD_METADATA_REG_A] = {
 217                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_GNRL_PURPOSE, .start = 0, .end = 31,
 218        },
 219        [MLX5_ACTION_IN_FIELD_METADATA_REG_B] = {
 220                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_METADATA_2_CQE, .start = 0, .end = 31,
 221        },
 222        [MLX5_ACTION_IN_FIELD_METADATA_REG_C_0] = {
 223                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_6, .start = 0, .end = 31,
 224        },
 225        [MLX5_ACTION_IN_FIELD_METADATA_REG_C_1] = {
 226                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_7, .start = 0, .end = 31,
 227        },
 228        [MLX5_ACTION_IN_FIELD_METADATA_REG_C_2] = {
 229                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_4, .start = 0, .end = 31,
 230        },
 231        [MLX5_ACTION_IN_FIELD_METADATA_REG_C_3] = {
 232                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_5, .start = 0, .end = 31,
 233        },
 234        [MLX5_ACTION_IN_FIELD_METADATA_REG_C_4] = {
 235                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_2, .start = 0, .end = 31,
 236        },
 237        [MLX5_ACTION_IN_FIELD_METADATA_REG_C_5] = {
 238                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_REGISTER_3, .start = 0, .end = 31,
 239        },
 240        [MLX5_ACTION_IN_FIELD_OUT_TCP_SEQ_NUM] = {
 241                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_TCP_MISC_0, .start = 0, .end = 31,
 242        },
 243        [MLX5_ACTION_IN_FIELD_OUT_TCP_ACK_NUM] = {
 244                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_TCP_MISC_1, .start = 0, .end = 31,
 245        },
 246        [MLX5_ACTION_IN_FIELD_OUT_FIRST_VID] = {
 247                .hw_field = DR_STE_V1_ACTION_MDFY_FLD_L2_OUT_2, .start = 0, .end = 15,
 248        },
 249};
 250
 251static void dr_ste_v1_set_entry_type(u8 *hw_ste_p, u8 entry_type)
 252{
 253        MLX5_SET(ste_match_bwc_v1, hw_ste_p, entry_format, entry_type);
 254}
 255
 256static void dr_ste_v1_set_miss_addr(u8 *hw_ste_p, u64 miss_addr)
 257{
 258        u64 index = miss_addr >> 6;
 259
 260        MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32, index >> 26);
 261        MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6, index);
 262}
 263
 264static u64 dr_ste_v1_get_miss_addr(u8 *hw_ste_p)
 265{
 266        u64 index =
 267                ((u64)MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6) |
 268                 ((u64)MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32)) << 26);
 269
 270        return index << 6;
 271}
 272
 273static void dr_ste_v1_set_byte_mask(u8 *hw_ste_p, u16 byte_mask)
 274{
 275        MLX5_SET(ste_match_bwc_v1, hw_ste_p, byte_mask, byte_mask);
 276}
 277
 278static u16 dr_ste_v1_get_byte_mask(u8 *hw_ste_p)
 279{
 280        return MLX5_GET(ste_match_bwc_v1, hw_ste_p, byte_mask);
 281}
 282
 283static void dr_ste_v1_set_lu_type(u8 *hw_ste_p, u16 lu_type)
 284{
 285        MLX5_SET(ste_match_bwc_v1, hw_ste_p, entry_format, lu_type >> 8);
 286        MLX5_SET(ste_match_bwc_v1, hw_ste_p, match_definer_ctx_idx, lu_type & 0xFF);
 287}
 288
 289static void dr_ste_v1_set_next_lu_type(u8 *hw_ste_p, u16 lu_type)
 290{
 291        MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_entry_format, lu_type >> 8);
 292        MLX5_SET(ste_match_bwc_v1, hw_ste_p, hash_definer_ctx_idx, lu_type & 0xFF);
 293}
 294
 295static u16 dr_ste_v1_get_next_lu_type(u8 *hw_ste_p)
 296{
 297        u8 mode = MLX5_GET(ste_match_bwc_v1, hw_ste_p, next_entry_format);
 298        u8 index = MLX5_GET(ste_match_bwc_v1, hw_ste_p, hash_definer_ctx_idx);
 299
 300        return (mode << 8 | index);
 301}
 302
 303static void dr_ste_v1_set_hit_gvmi(u8 *hw_ste_p, u16 gvmi)
 304{
 305        MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_63_48, gvmi);
 306}
 307
 308static void dr_ste_v1_set_hit_addr(u8 *hw_ste_p, u64 icm_addr, u32 ht_size)
 309{
 310        u64 index = (icm_addr >> 5) | ht_size;
 311
 312        MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_39_32_size, index >> 27);
 313        MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_31_5_size, index);
 314}
 315
 316static void dr_ste_v1_init(u8 *hw_ste_p, u16 lu_type,
 317                           u8 entry_type, u16 gvmi)
 318{
 319        dr_ste_v1_set_lu_type(hw_ste_p, lu_type);
 320        dr_ste_v1_set_next_lu_type(hw_ste_p, MLX5DR_STE_LU_TYPE_DONT_CARE);
 321
 322        MLX5_SET(ste_match_bwc_v1, hw_ste_p, gvmi, gvmi);
 323        MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_63_48, gvmi);
 324        MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_63_48, gvmi);
 325}
 326
 327static void dr_ste_v1_prepare_for_postsend(u8 *hw_ste_p,
 328                                           u32 ste_size)
 329{
 330        u8 *tag = hw_ste_p + DR_STE_SIZE_CTRL;
 331        u8 *mask = tag + DR_STE_SIZE_TAG;
 332        u8 tmp_tag[DR_STE_SIZE_TAG] = {};
 333
 334        if (ste_size == DR_STE_SIZE_CTRL)
 335                return;
 336
 337        WARN_ON(ste_size != DR_STE_SIZE);
 338
 339        /* Backup tag */
 340        memcpy(tmp_tag, tag, DR_STE_SIZE_TAG);
 341
 342        /* Swap mask and tag  both are the same size */
 343        memcpy(tag, mask, DR_STE_SIZE_MASK);
 344        memcpy(mask, tmp_tag, DR_STE_SIZE_TAG);
 345}
 346
 347static void dr_ste_v1_set_rx_flow_tag(u8 *s_action, u32 flow_tag)
 348{
 349        MLX5_SET(ste_single_action_flow_tag_v1, s_action, action_id,
 350                 DR_STE_V1_ACTION_ID_FLOW_TAG);
 351        MLX5_SET(ste_single_action_flow_tag_v1, s_action, flow_tag, flow_tag);
 352}
 353
 354static void dr_ste_v1_set_counter_id(u8 *hw_ste_p, u32 ctr_id)
 355{
 356        MLX5_SET(ste_match_bwc_v1, hw_ste_p, counter_id, ctr_id);
 357}
 358
 359static void dr_ste_v1_set_reparse(u8 *hw_ste_p)
 360{
 361        MLX5_SET(ste_match_bwc_v1, hw_ste_p, reparse, 1);
 362}
 363
 364static void dr_ste_v1_set_tx_encap(u8 *hw_ste_p, u8 *d_action,
 365                                   u32 reformat_id, int size)
 366{
 367        MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, action_id,
 368                 DR_STE_V1_ACTION_ID_INSERT_POINTER);
 369        /* The hardware expects here size in words (2 byte) */
 370        MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, size, size / 2);
 371        MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, pointer, reformat_id);
 372        MLX5_SET(ste_double_action_insert_with_ptr_v1, d_action, attributes,
 373                 DR_STE_V1_ACTION_INSERT_PTR_ATTR_ENCAP);
 374        dr_ste_v1_set_reparse(hw_ste_p);
 375}
 376
 377static void dr_ste_v1_set_tx_push_vlan(u8 *hw_ste_p, u8 *d_action,
 378                                       u32 vlan_hdr)
 379{
 380        MLX5_SET(ste_double_action_insert_with_inline_v1, d_action,
 381                 action_id, DR_STE_V1_ACTION_ID_INSERT_INLINE);
 382        /* The hardware expects offset to vlan header in words (2 byte) */
 383        MLX5_SET(ste_double_action_insert_with_inline_v1, d_action,
 384                 start_offset, HDR_LEN_L2_MACS >> 1);
 385        MLX5_SET(ste_double_action_insert_with_inline_v1, d_action,
 386                 inline_data, vlan_hdr);
 387
 388        dr_ste_v1_set_reparse(hw_ste_p);
 389}
 390
 391static void dr_ste_v1_set_rx_pop_vlan(u8 *hw_ste_p, u8 *s_action, u8 vlans_num)
 392{
 393        MLX5_SET(ste_single_action_remove_header_size_v1, s_action,
 394                 action_id, DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE);
 395        MLX5_SET(ste_single_action_remove_header_size_v1, s_action,
 396                 start_anchor, DR_STE_HEADER_ANCHOR_1ST_VLAN);
 397        /* The hardware expects here size in words (2 byte) */
 398        MLX5_SET(ste_single_action_remove_header_size_v1, s_action,
 399                 remove_size, (HDR_LEN_L2_VLAN >> 1) * vlans_num);
 400
 401        dr_ste_v1_set_reparse(hw_ste_p);
 402}
 403
 404static void dr_ste_v1_set_tx_encap_l3(u8 *hw_ste_p,
 405                                      u8 *frst_s_action,
 406                                      u8 *scnd_d_action,
 407                                      u32 reformat_id,
 408                                      int size)
 409{
 410        /* Remove L2 headers */
 411        MLX5_SET(ste_single_action_remove_header_v1, frst_s_action, action_id,
 412                 DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER);
 413        MLX5_SET(ste_single_action_remove_header_v1, frst_s_action, end_anchor,
 414                 DR_STE_HEADER_ANCHOR_IPV6_IPV4);
 415
 416        /* Encapsulate with given reformat ID */
 417        MLX5_SET(ste_double_action_insert_with_ptr_v1, scnd_d_action, action_id,
 418                 DR_STE_V1_ACTION_ID_INSERT_POINTER);
 419        /* The hardware expects here size in words (2 byte) */
 420        MLX5_SET(ste_double_action_insert_with_ptr_v1, scnd_d_action, size, size / 2);
 421        MLX5_SET(ste_double_action_insert_with_ptr_v1, scnd_d_action, pointer, reformat_id);
 422        MLX5_SET(ste_double_action_insert_with_ptr_v1, scnd_d_action, attributes,
 423                 DR_STE_V1_ACTION_INSERT_PTR_ATTR_ENCAP);
 424
 425        dr_ste_v1_set_reparse(hw_ste_p);
 426}
 427
 428static void dr_ste_v1_set_rx_decap(u8 *hw_ste_p, u8 *s_action)
 429{
 430        MLX5_SET(ste_single_action_remove_header_v1, s_action, action_id,
 431                 DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER);
 432        MLX5_SET(ste_single_action_remove_header_v1, s_action, decap, 1);
 433        MLX5_SET(ste_single_action_remove_header_v1, s_action, vni_to_cqe, 1);
 434        MLX5_SET(ste_single_action_remove_header_v1, s_action, end_anchor,
 435                 DR_STE_HEADER_ANCHOR_INNER_MAC);
 436
 437        dr_ste_v1_set_reparse(hw_ste_p);
 438}
 439
 440static void dr_ste_v1_set_rewrite_actions(u8 *hw_ste_p,
 441                                          u8 *s_action,
 442                                          u16 num_of_actions,
 443                                          u32 re_write_index)
 444{
 445        MLX5_SET(ste_single_action_modify_list_v1, s_action, action_id,
 446                 DR_STE_V1_ACTION_ID_MODIFY_LIST);
 447        MLX5_SET(ste_single_action_modify_list_v1, s_action, num_of_modify_actions,
 448                 num_of_actions);
 449        MLX5_SET(ste_single_action_modify_list_v1, s_action, modify_actions_ptr,
 450                 re_write_index);
 451
 452        dr_ste_v1_set_reparse(hw_ste_p);
 453}
 454
 455static void dr_ste_v1_arr_init_next_match(u8 **last_ste,
 456                                          u32 *added_stes,
 457                                          u16 gvmi)
 458{
 459        u8 *action;
 460
 461        (*added_stes)++;
 462        *last_ste += DR_STE_SIZE;
 463        dr_ste_v1_init(*last_ste, MLX5DR_STE_LU_TYPE_DONT_CARE, 0, gvmi);
 464        dr_ste_v1_set_entry_type(*last_ste, DR_STE_V1_TYPE_MATCH);
 465
 466        action = MLX5_ADDR_OF(ste_mask_and_match_v1, *last_ste, action);
 467        memset(action, 0, MLX5_FLD_SZ_BYTES(ste_mask_and_match_v1, action));
 468}
 469
 470static void dr_ste_v1_set_actions_tx(struct mlx5dr_domain *dmn,
 471                                     u8 *action_type_set,
 472                                     u8 *last_ste,
 473                                     struct mlx5dr_ste_actions_attr *attr,
 474                                     u32 *added_stes)
 475{
 476        u8 *action = MLX5_ADDR_OF(ste_match_bwc_v1, last_ste, action);
 477        u8 action_sz = DR_STE_ACTION_DOUBLE_SZ;
 478        bool allow_encap = true;
 479
 480        if (action_type_set[DR_ACTION_TYP_CTR])
 481                dr_ste_v1_set_counter_id(last_ste, attr->ctr_id);
 482
 483        if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) {
 484                if (action_sz < DR_STE_ACTION_DOUBLE_SZ) {
 485                        dr_ste_v1_arr_init_next_match(&last_ste, added_stes,
 486                                                      attr->gvmi);
 487                        action = MLX5_ADDR_OF(ste_mask_and_match_v1,
 488                                              last_ste, action);
 489                        action_sz = DR_STE_ACTION_TRIPLE_SZ;
 490                }
 491                dr_ste_v1_set_rewrite_actions(last_ste, action,
 492                                              attr->modify_actions,
 493                                              attr->modify_index);
 494                action_sz -= DR_STE_ACTION_DOUBLE_SZ;
 495                action += DR_STE_ACTION_DOUBLE_SZ;
 496                allow_encap = false;
 497        }
 498
 499        if (action_type_set[DR_ACTION_TYP_PUSH_VLAN]) {
 500                int i;
 501
 502                for (i = 0; i < attr->vlans.count; i++) {
 503                        if (action_sz < DR_STE_ACTION_DOUBLE_SZ || !allow_encap) {
 504                                dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi);
 505                                action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action);
 506                                action_sz = DR_STE_ACTION_TRIPLE_SZ;
 507                                allow_encap = true;
 508                        }
 509                        dr_ste_v1_set_tx_push_vlan(last_ste, action, attr->vlans.headers[i]);
 510                        action_sz -= DR_STE_ACTION_DOUBLE_SZ;
 511                        action += DR_STE_ACTION_DOUBLE_SZ;
 512                }
 513        }
 514
 515        if (action_type_set[DR_ACTION_TYP_L2_TO_TNL_L2]) {
 516                if (!allow_encap || action_sz < DR_STE_ACTION_DOUBLE_SZ) {
 517                        dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi);
 518                        action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action);
 519                        action_sz = DR_STE_ACTION_TRIPLE_SZ;
 520                        allow_encap = true;
 521                }
 522                dr_ste_v1_set_tx_encap(last_ste, action,
 523                                       attr->reformat_id,
 524                                       attr->reformat_size);
 525                action_sz -= DR_STE_ACTION_DOUBLE_SZ;
 526                action += DR_STE_ACTION_DOUBLE_SZ;
 527        } else if (action_type_set[DR_ACTION_TYP_L2_TO_TNL_L3]) {
 528                u8 *d_action;
 529
 530                dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi);
 531                action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action);
 532                action_sz = DR_STE_ACTION_TRIPLE_SZ;
 533                d_action = action + DR_STE_ACTION_SINGLE_SZ;
 534
 535                dr_ste_v1_set_tx_encap_l3(last_ste,
 536                                          action, d_action,
 537                                          attr->reformat_id,
 538                                          attr->reformat_size);
 539                action_sz -= DR_STE_ACTION_TRIPLE_SZ;
 540                action += DR_STE_ACTION_TRIPLE_SZ;
 541        }
 542
 543        dr_ste_v1_set_hit_gvmi(last_ste, attr->hit_gvmi);
 544        dr_ste_v1_set_hit_addr(last_ste, attr->final_icm_addr, 1);
 545}
 546
 547static void dr_ste_v1_set_actions_rx(struct mlx5dr_domain *dmn,
 548                                     u8 *action_type_set,
 549                                     u8 *last_ste,
 550                                     struct mlx5dr_ste_actions_attr *attr,
 551                                     u32 *added_stes)
 552{
 553        u8 *action = MLX5_ADDR_OF(ste_match_bwc_v1, last_ste, action);
 554        u8 action_sz = DR_STE_ACTION_DOUBLE_SZ;
 555        bool allow_modify_hdr = true;
 556        bool allow_ctr = true;
 557
 558        if (action_type_set[DR_ACTION_TYP_TNL_L3_TO_L2]) {
 559                dr_ste_v1_set_rewrite_actions(last_ste, action,
 560                                              attr->decap_actions,
 561                                              attr->decap_index);
 562                action_sz -= DR_STE_ACTION_DOUBLE_SZ;
 563                action += DR_STE_ACTION_DOUBLE_SZ;
 564                allow_modify_hdr = false;
 565                allow_ctr = false;
 566        } else if (action_type_set[DR_ACTION_TYP_TNL_L2_TO_L2]) {
 567                dr_ste_v1_set_rx_decap(last_ste, action);
 568                action_sz -= DR_STE_ACTION_SINGLE_SZ;
 569                action += DR_STE_ACTION_SINGLE_SZ;
 570                allow_modify_hdr = false;
 571                allow_ctr = false;
 572        }
 573
 574        if (action_type_set[DR_ACTION_TYP_TAG]) {
 575                if (action_sz < DR_STE_ACTION_SINGLE_SZ) {
 576                        dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi);
 577                        action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action);
 578                        action_sz = DR_STE_ACTION_TRIPLE_SZ;
 579                        allow_modify_hdr = true;
 580                        allow_ctr = true;
 581                }
 582                dr_ste_v1_set_rx_flow_tag(action, attr->flow_tag);
 583                action_sz -= DR_STE_ACTION_SINGLE_SZ;
 584                action += DR_STE_ACTION_SINGLE_SZ;
 585        }
 586
 587        if (action_type_set[DR_ACTION_TYP_POP_VLAN]) {
 588                if (action_sz < DR_STE_ACTION_SINGLE_SZ ||
 589                    !allow_modify_hdr) {
 590                        dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi);
 591                        action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action);
 592                        action_sz = DR_STE_ACTION_TRIPLE_SZ;
 593                        allow_modify_hdr = false;
 594                        allow_ctr = false;
 595                }
 596
 597                dr_ste_v1_set_rx_pop_vlan(last_ste, action, attr->vlans.count);
 598                action_sz -= DR_STE_ACTION_SINGLE_SZ;
 599                action += DR_STE_ACTION_SINGLE_SZ;
 600        }
 601
 602        if (action_type_set[DR_ACTION_TYP_MODIFY_HDR]) {
 603                /* Modify header and decapsulation must use different STEs */
 604                if (!allow_modify_hdr || action_sz < DR_STE_ACTION_DOUBLE_SZ) {
 605                        dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi);
 606                        action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action);
 607                        action_sz = DR_STE_ACTION_TRIPLE_SZ;
 608                        allow_modify_hdr = true;
 609                        allow_ctr = true;
 610                }
 611                dr_ste_v1_set_rewrite_actions(last_ste, action,
 612                                              attr->modify_actions,
 613                                              attr->modify_index);
 614                action_sz -= DR_STE_ACTION_DOUBLE_SZ;
 615                action += DR_STE_ACTION_DOUBLE_SZ;
 616        }
 617
 618        if (action_type_set[DR_ACTION_TYP_CTR]) {
 619                /* Counter action set after decap to exclude decaped header */
 620                if (!allow_ctr) {
 621                        dr_ste_v1_arr_init_next_match(&last_ste, added_stes, attr->gvmi);
 622                        action = MLX5_ADDR_OF(ste_mask_and_match_v1, last_ste, action);
 623                        action_sz = DR_STE_ACTION_TRIPLE_SZ;
 624                        allow_modify_hdr = true;
 625                        allow_ctr = false;
 626                }
 627                dr_ste_v1_set_counter_id(last_ste, attr->ctr_id);
 628        }
 629
 630        dr_ste_v1_set_hit_gvmi(last_ste, attr->hit_gvmi);
 631        dr_ste_v1_set_hit_addr(last_ste, attr->final_icm_addr, 1);
 632}
 633
 634static void dr_ste_v1_set_action_set(u8 *d_action,
 635                                     u8 hw_field,
 636                                     u8 shifter,
 637                                     u8 length,
 638                                     u32 data)
 639{
 640        shifter += MLX5_MODIFY_HEADER_V1_QW_OFFSET;
 641        MLX5_SET(ste_double_action_set_v1, d_action, action_id, DR_STE_V1_ACTION_ID_SET);
 642        MLX5_SET(ste_double_action_set_v1, d_action, destination_dw_offset, hw_field);
 643        MLX5_SET(ste_double_action_set_v1, d_action, destination_left_shifter, shifter);
 644        MLX5_SET(ste_double_action_set_v1, d_action, destination_length, length);
 645        MLX5_SET(ste_double_action_set_v1, d_action, inline_data, data);
 646}
 647
 648static void dr_ste_v1_set_action_add(u8 *d_action,
 649                                     u8 hw_field,
 650                                     u8 shifter,
 651                                     u8 length,
 652                                     u32 data)
 653{
 654        shifter += MLX5_MODIFY_HEADER_V1_QW_OFFSET;
 655        MLX5_SET(ste_double_action_add_v1, d_action, action_id, DR_STE_V1_ACTION_ID_ADD);
 656        MLX5_SET(ste_double_action_add_v1, d_action, destination_dw_offset, hw_field);
 657        MLX5_SET(ste_double_action_add_v1, d_action, destination_left_shifter, shifter);
 658        MLX5_SET(ste_double_action_add_v1, d_action, destination_length, length);
 659        MLX5_SET(ste_double_action_add_v1, d_action, add_value, data);
 660}
 661
 662static void dr_ste_v1_set_action_copy(u8 *d_action,
 663                                      u8 dst_hw_field,
 664                                      u8 dst_shifter,
 665                                      u8 dst_len,
 666                                      u8 src_hw_field,
 667                                      u8 src_shifter)
 668{
 669        dst_shifter += MLX5_MODIFY_HEADER_V1_QW_OFFSET;
 670        src_shifter += MLX5_MODIFY_HEADER_V1_QW_OFFSET;
 671        MLX5_SET(ste_double_action_copy_v1, d_action, action_id, DR_STE_V1_ACTION_ID_COPY);
 672        MLX5_SET(ste_double_action_copy_v1, d_action, destination_dw_offset, dst_hw_field);
 673        MLX5_SET(ste_double_action_copy_v1, d_action, destination_left_shifter, dst_shifter);
 674        MLX5_SET(ste_double_action_copy_v1, d_action, destination_length, dst_len);
 675        MLX5_SET(ste_double_action_copy_v1, d_action, source_dw_offset, src_hw_field);
 676        MLX5_SET(ste_double_action_copy_v1, d_action, source_right_shifter, src_shifter);
 677}
 678
 679#define DR_STE_DECAP_L3_ACTION_NUM      8
 680#define DR_STE_L2_HDR_MAX_SZ            20
 681
 682static int dr_ste_v1_set_action_decap_l3_list(void *data,
 683                                              u32 data_sz,
 684                                              u8 *hw_action,
 685                                              u32 hw_action_sz,
 686                                              u16 *used_hw_action_num)
 687{
 688        u8 padded_data[DR_STE_L2_HDR_MAX_SZ] = {};
 689        void *data_ptr = padded_data;
 690        u16 used_actions = 0;
 691        u32 inline_data_sz;
 692        u32 i;
 693
 694        if (hw_action_sz / DR_STE_ACTION_DOUBLE_SZ < DR_STE_DECAP_L3_ACTION_NUM)
 695                return -EINVAL;
 696
 697        inline_data_sz =
 698                MLX5_FLD_SZ_BYTES(ste_double_action_insert_with_inline_v1, inline_data);
 699
 700        /* Add an alignment padding  */
 701        memcpy(padded_data + data_sz % inline_data_sz, data, data_sz);
 702
 703        /* Remove L2L3 outer headers */
 704        MLX5_SET(ste_single_action_remove_header_v1, hw_action, action_id,
 705                 DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER);
 706        MLX5_SET(ste_single_action_remove_header_v1, hw_action, decap, 1);
 707        MLX5_SET(ste_single_action_remove_header_v1, hw_action, vni_to_cqe, 1);
 708        MLX5_SET(ste_single_action_remove_header_v1, hw_action, end_anchor,
 709                 DR_STE_HEADER_ANCHOR_INNER_IPV6_IPV4);
 710        hw_action += DR_STE_ACTION_DOUBLE_SZ;
 711        used_actions++; /* Remove and NOP are a single double action */
 712
 713        /* Point to the last dword of the header */
 714        data_ptr += (data_sz / inline_data_sz) * inline_data_sz;
 715
 716        /* Add the new header using inline action 4Byte at a time, the header
 717         * is added in reversed order to the beginning of the packet to avoid
 718         * incorrect parsing by the HW. Since header is 14B or 18B an extra
 719         * two bytes are padded and later removed.
 720         */
 721        for (i = 0; i < data_sz / inline_data_sz + 1; i++) {
 722                void *addr_inline;
 723
 724                MLX5_SET(ste_double_action_insert_with_inline_v1, hw_action, action_id,
 725                         DR_STE_V1_ACTION_ID_INSERT_INLINE);
 726                /* The hardware expects here offset to words (2 bytes) */
 727                MLX5_SET(ste_double_action_insert_with_inline_v1, hw_action, start_offset, 0);
 728
 729                /* Copy bytes one by one to avoid endianness problem */
 730                addr_inline = MLX5_ADDR_OF(ste_double_action_insert_with_inline_v1,
 731                                           hw_action, inline_data);
 732                memcpy(addr_inline, data_ptr - i * inline_data_sz, inline_data_sz);
 733                hw_action += DR_STE_ACTION_DOUBLE_SZ;
 734                used_actions++;
 735        }
 736
 737        /* Remove first 2 extra bytes */
 738        MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, action_id,
 739                 DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE);
 740        MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, start_offset, 0);
 741        /* The hardware expects here size in words (2 bytes) */
 742        MLX5_SET(ste_single_action_remove_header_size_v1, hw_action, remove_size, 1);
 743        used_actions++;
 744
 745        *used_hw_action_num = used_actions;
 746
 747        return 0;
 748}
 749
 750static void dr_ste_v1_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value,
 751                                                    bool inner, u8 *bit_mask)
 752{
 753        struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
 754
 755        DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, dmac_47_16, mask, dmac_47_16);
 756        DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, dmac_15_0, mask, dmac_15_0);
 757
 758        DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, smac_47_16, mask, smac_47_16);
 759        DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, smac_15_0, mask, smac_15_0);
 760
 761        DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_vlan_id, mask, first_vid);
 762        DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_cfi, mask, first_cfi);
 763        DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_priority, mask, first_prio);
 764        DR_STE_SET_ONES(eth_l2_src_dst_v1, bit_mask, l3_type, mask, ip_version);
 765
 766        if (mask->cvlan_tag) {
 767                MLX5_SET(ste_eth_l2_src_dst_v1, bit_mask, first_vlan_qualifier, -1);
 768                mask->cvlan_tag = 0;
 769        } else if (mask->svlan_tag) {
 770                MLX5_SET(ste_eth_l2_src_dst_v1, bit_mask, first_vlan_qualifier, -1);
 771                mask->svlan_tag = 0;
 772        }
 773}
 774
 775static int dr_ste_v1_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value,
 776                                              struct mlx5dr_ste_build *sb,
 777                                              u8 *tag)
 778{
 779        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
 780
 781        DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, dmac_47_16, spec, dmac_47_16);
 782        DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, dmac_15_0, spec, dmac_15_0);
 783
 784        DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, smac_47_16, spec, smac_47_16);
 785        DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, smac_15_0, spec, smac_15_0);
 786
 787        if (spec->ip_version == IP_VERSION_IPV4) {
 788                MLX5_SET(ste_eth_l2_src_dst_v1, tag, l3_type, STE_IPV4);
 789                spec->ip_version = 0;
 790        } else if (spec->ip_version == IP_VERSION_IPV6) {
 791                MLX5_SET(ste_eth_l2_src_dst_v1, tag, l3_type, STE_IPV6);
 792                spec->ip_version = 0;
 793        } else if (spec->ip_version) {
 794                return -EINVAL;
 795        }
 796
 797        DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_vlan_id, spec, first_vid);
 798        DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_cfi, spec, first_cfi);
 799        DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_priority, spec, first_prio);
 800
 801        if (spec->cvlan_tag) {
 802                MLX5_SET(ste_eth_l2_src_dst_v1, tag, first_vlan_qualifier, DR_STE_CVLAN);
 803                spec->cvlan_tag = 0;
 804        } else if (spec->svlan_tag) {
 805                MLX5_SET(ste_eth_l2_src_dst_v1, tag, first_vlan_qualifier, DR_STE_SVLAN);
 806                spec->svlan_tag = 0;
 807        }
 808        return 0;
 809}
 810
 811static void dr_ste_v1_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb,
 812                                                struct mlx5dr_match_param *mask)
 813{
 814        dr_ste_v1_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask);
 815
 816        sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2_SRC_DST, sb->inner);
 817        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
 818        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_src_dst_tag;
 819}
 820
 821static int dr_ste_v1_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value,
 822                                               struct mlx5dr_ste_build *sb,
 823                                               u8 *tag)
 824{
 825        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
 826
 827        DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96);
 828        DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64);
 829        DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32);
 830        DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0);
 831
 832        return 0;
 833}
 834
 835static void dr_ste_v1_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb,
 836                                                 struct mlx5dr_match_param *mask)
 837{
 838        dr_ste_v1_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask);
 839
 840        sb->lu_type = DR_STE_CALC_DFNR_TYPE(IPV6_DES, sb->inner);
 841        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
 842        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv6_dst_tag;
 843}
 844
 845static int dr_ste_v1_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value,
 846                                               struct mlx5dr_ste_build *sb,
 847                                               u8 *tag)
 848{
 849        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
 850
 851        DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96);
 852        DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64);
 853        DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32);
 854        DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0);
 855
 856        return 0;
 857}
 858
 859static void dr_ste_v1_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb,
 860                                                 struct mlx5dr_match_param *mask)
 861{
 862        dr_ste_v1_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask);
 863
 864        sb->lu_type = DR_STE_CALC_DFNR_TYPE(IPV6_SRC, sb->inner);
 865        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
 866        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv6_src_tag;
 867}
 868
 869static int dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value,
 870                                                   struct mlx5dr_ste_build *sb,
 871                                                   u8 *tag)
 872{
 873        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
 874
 875        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_address, spec, dst_ip_31_0);
 876        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_address, spec, src_ip_31_0);
 877        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_port, spec, tcp_dport);
 878        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_port, spec, udp_dport);
 879        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_port, spec, tcp_sport);
 880        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_port, spec, udp_sport);
 881        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, protocol, spec, ip_protocol);
 882        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, fragmented, spec, frag);
 883        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, dscp, spec, ip_dscp);
 884        DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, ecn, spec, ip_ecn);
 885
 886        if (spec->tcp_flags) {
 887                DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple_v1, tag, spec);
 888                spec->tcp_flags = 0;
 889        }
 890
 891        return 0;
 892}
 893
 894static void dr_ste_v1_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb,
 895                                                     struct mlx5dr_match_param *mask)
 896{
 897        dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask);
 898
 899        sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL3_IPV4_5_TUPLE, sb->inner);
 900        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
 901        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag;
 902}
 903
 904static void dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value,
 905                                                       bool inner, u8 *bit_mask)
 906{
 907        struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
 908        struct mlx5dr_match_misc *misc_mask = &value->misc;
 909
 910        DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_vlan_id, mask, first_vid);
 911        DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_cfi, mask, first_cfi);
 912        DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_priority, mask, first_prio);
 913        DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, ip_fragmented, mask, frag); // ?
 914        DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, l3_ethertype, mask, ethertype); // ?
 915        DR_STE_SET_ONES(eth_l2_src_v1, bit_mask, l3_type, mask, ip_version);
 916
 917        if (mask->svlan_tag || mask->cvlan_tag) {
 918                MLX5_SET(ste_eth_l2_src_v1, bit_mask, first_vlan_qualifier, -1);
 919                mask->cvlan_tag = 0;
 920                mask->svlan_tag = 0;
 921        }
 922
 923        if (inner) {
 924                if (misc_mask->inner_second_cvlan_tag ||
 925                    misc_mask->inner_second_svlan_tag) {
 926                        MLX5_SET(ste_eth_l2_src_v1, bit_mask, second_vlan_qualifier, -1);
 927                        misc_mask->inner_second_cvlan_tag = 0;
 928                        misc_mask->inner_second_svlan_tag = 0;
 929                }
 930
 931                DR_STE_SET_TAG(eth_l2_src_v1, bit_mask,
 932                               second_vlan_id, misc_mask, inner_second_vid);
 933                DR_STE_SET_TAG(eth_l2_src_v1, bit_mask,
 934                               second_cfi, misc_mask, inner_second_cfi);
 935                DR_STE_SET_TAG(eth_l2_src_v1, bit_mask,
 936                               second_priority, misc_mask, inner_second_prio);
 937        } else {
 938                if (misc_mask->outer_second_cvlan_tag ||
 939                    misc_mask->outer_second_svlan_tag) {
 940                        MLX5_SET(ste_eth_l2_src_v1, bit_mask, second_vlan_qualifier, -1);
 941                        misc_mask->outer_second_cvlan_tag = 0;
 942                        misc_mask->outer_second_svlan_tag = 0;
 943                }
 944
 945                DR_STE_SET_TAG(eth_l2_src_v1, bit_mask,
 946                               second_vlan_id, misc_mask, outer_second_vid);
 947                DR_STE_SET_TAG(eth_l2_src_v1, bit_mask,
 948                               second_cfi, misc_mask, outer_second_cfi);
 949                DR_STE_SET_TAG(eth_l2_src_v1, bit_mask,
 950                               second_priority, misc_mask, outer_second_prio);
 951        }
 952}
 953
 954static int dr_ste_v1_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value,
 955                                                 bool inner, u8 *tag)
 956{
 957        struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer;
 958        struct mlx5dr_match_misc *misc_spec = &value->misc;
 959
 960        DR_STE_SET_TAG(eth_l2_src_v1, tag, first_vlan_id, spec, first_vid);
 961        DR_STE_SET_TAG(eth_l2_src_v1, tag, first_cfi, spec, first_cfi);
 962        DR_STE_SET_TAG(eth_l2_src_v1, tag, first_priority, spec, first_prio);
 963        DR_STE_SET_TAG(eth_l2_src_v1, tag, ip_fragmented, spec, frag);
 964        DR_STE_SET_TAG(eth_l2_src_v1, tag, l3_ethertype, spec, ethertype);
 965
 966        if (spec->ip_version == IP_VERSION_IPV4) {
 967                MLX5_SET(ste_eth_l2_src_v1, tag, l3_type, STE_IPV4);
 968                spec->ip_version = 0;
 969        } else if (spec->ip_version == IP_VERSION_IPV6) {
 970                MLX5_SET(ste_eth_l2_src_v1, tag, l3_type, STE_IPV6);
 971                spec->ip_version = 0;
 972        } else if (spec->ip_version) {
 973                return -EINVAL;
 974        }
 975
 976        if (spec->cvlan_tag) {
 977                MLX5_SET(ste_eth_l2_src_v1, tag, first_vlan_qualifier, DR_STE_CVLAN);
 978                spec->cvlan_tag = 0;
 979        } else if (spec->svlan_tag) {
 980                MLX5_SET(ste_eth_l2_src_v1, tag, first_vlan_qualifier, DR_STE_SVLAN);
 981                spec->svlan_tag = 0;
 982        }
 983
 984        if (inner) {
 985                if (misc_spec->inner_second_cvlan_tag) {
 986                        MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_CVLAN);
 987                        misc_spec->inner_second_cvlan_tag = 0;
 988                } else if (misc_spec->inner_second_svlan_tag) {
 989                        MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_SVLAN);
 990                        misc_spec->inner_second_svlan_tag = 0;
 991                }
 992
 993                DR_STE_SET_TAG(eth_l2_src_v1, tag, second_vlan_id, misc_spec, inner_second_vid);
 994                DR_STE_SET_TAG(eth_l2_src_v1, tag, second_cfi, misc_spec, inner_second_cfi);
 995                DR_STE_SET_TAG(eth_l2_src_v1, tag, second_priority, misc_spec, inner_second_prio);
 996        } else {
 997                if (misc_spec->outer_second_cvlan_tag) {
 998                        MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_CVLAN);
 999                        misc_spec->outer_second_cvlan_tag = 0;
1000                } else if (misc_spec->outer_second_svlan_tag) {
1001                        MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_SVLAN);
1002                        misc_spec->outer_second_svlan_tag = 0;
1003                }
1004                DR_STE_SET_TAG(eth_l2_src_v1, tag, second_vlan_id, misc_spec, outer_second_vid);
1005                DR_STE_SET_TAG(eth_l2_src_v1, tag, second_cfi, misc_spec, outer_second_cfi);
1006                DR_STE_SET_TAG(eth_l2_src_v1, tag, second_priority, misc_spec, outer_second_prio);
1007        }
1008
1009        return 0;
1010}
1011
1012static void dr_ste_v1_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value,
1013                                                bool inner, u8 *bit_mask)
1014{
1015        struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1016
1017        DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, smac_47_16, mask, smac_47_16);
1018        DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, smac_15_0, mask, smac_15_0);
1019
1020        dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask);
1021}
1022
1023static int dr_ste_v1_build_eth_l2_src_tag(struct mlx5dr_match_param *value,
1024                                          struct mlx5dr_ste_build *sb,
1025                                          u8 *tag)
1026{
1027        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1028
1029        DR_STE_SET_TAG(eth_l2_src_v1, tag, smac_47_16, spec, smac_47_16);
1030        DR_STE_SET_TAG(eth_l2_src_v1, tag, smac_15_0, spec, smac_15_0);
1031
1032        return dr_ste_v1_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
1033}
1034
1035static void dr_ste_v1_build_eth_l2_src_init(struct mlx5dr_ste_build *sb,
1036                                            struct mlx5dr_match_param *mask)
1037{
1038        dr_ste_v1_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask);
1039
1040        sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2_SRC, sb->inner);
1041        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1042        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_src_tag;
1043}
1044
1045static void dr_ste_v1_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value,
1046                                                bool inner, u8 *bit_mask)
1047{
1048        struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1049
1050        DR_STE_SET_TAG(eth_l2_dst_v1, bit_mask, dmac_47_16, mask, dmac_47_16);
1051        DR_STE_SET_TAG(eth_l2_dst_v1, bit_mask, dmac_15_0, mask, dmac_15_0);
1052
1053        dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask);
1054}
1055
1056static int dr_ste_v1_build_eth_l2_dst_tag(struct mlx5dr_match_param *value,
1057                                          struct mlx5dr_ste_build *sb,
1058                                          u8 *tag)
1059{
1060        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1061
1062        DR_STE_SET_TAG(eth_l2_dst_v1, tag, dmac_47_16, spec, dmac_47_16);
1063        DR_STE_SET_TAG(eth_l2_dst_v1, tag, dmac_15_0, spec, dmac_15_0);
1064
1065        return dr_ste_v1_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
1066}
1067
1068static void dr_ste_v1_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb,
1069                                            struct mlx5dr_match_param *mask)
1070{
1071        dr_ste_v1_build_eth_l2_dst_bit_mask(mask, sb->inner, sb->bit_mask);
1072
1073        sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2, sb->inner);
1074        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1075        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_dst_tag;
1076}
1077
1078static void dr_ste_v1_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value,
1079                                                bool inner, u8 *bit_mask)
1080{
1081        struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
1082        struct mlx5dr_match_misc *misc = &value->misc;
1083
1084        DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, dmac_47_16, mask, dmac_47_16);
1085        DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, dmac_15_0, mask, dmac_15_0);
1086        DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_vlan_id, mask, first_vid);
1087        DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_cfi, mask, first_cfi);
1088        DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_priority, mask, first_prio);
1089        DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, ip_fragmented, mask, frag);
1090        DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, l3_ethertype, mask, ethertype);
1091        DR_STE_SET_ONES(eth_l2_tnl_v1, bit_mask, l3_type, mask, ip_version);
1092
1093        if (misc->vxlan_vni) {
1094                MLX5_SET(ste_eth_l2_tnl_v1, bit_mask,
1095                         l2_tunneling_network_id, (misc->vxlan_vni << 8));
1096                misc->vxlan_vni = 0;
1097        }
1098
1099        if (mask->svlan_tag || mask->cvlan_tag) {
1100                MLX5_SET(ste_eth_l2_tnl_v1, bit_mask, first_vlan_qualifier, -1);
1101                mask->cvlan_tag = 0;
1102                mask->svlan_tag = 0;
1103        }
1104}
1105
1106static int dr_ste_v1_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value,
1107                                          struct mlx5dr_ste_build *sb,
1108                                          u8 *tag)
1109{
1110        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1111        struct mlx5dr_match_misc *misc = &value->misc;
1112
1113        DR_STE_SET_TAG(eth_l2_tnl_v1, tag, dmac_47_16, spec, dmac_47_16);
1114        DR_STE_SET_TAG(eth_l2_tnl_v1, tag, dmac_15_0, spec, dmac_15_0);
1115        DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_vlan_id, spec, first_vid);
1116        DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_cfi, spec, first_cfi);
1117        DR_STE_SET_TAG(eth_l2_tnl_v1, tag, ip_fragmented, spec, frag);
1118        DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_priority, spec, first_prio);
1119        DR_STE_SET_TAG(eth_l2_tnl_v1, tag, l3_ethertype, spec, ethertype);
1120
1121        if (misc->vxlan_vni) {
1122                MLX5_SET(ste_eth_l2_tnl_v1, tag, l2_tunneling_network_id,
1123                         (misc->vxlan_vni << 8));
1124                misc->vxlan_vni = 0;
1125        }
1126
1127        if (spec->cvlan_tag) {
1128                MLX5_SET(ste_eth_l2_tnl_v1, tag, first_vlan_qualifier, DR_STE_CVLAN);
1129                spec->cvlan_tag = 0;
1130        } else if (spec->svlan_tag) {
1131                MLX5_SET(ste_eth_l2_tnl_v1, tag, first_vlan_qualifier, DR_STE_SVLAN);
1132                spec->svlan_tag = 0;
1133        }
1134
1135        if (spec->ip_version == IP_VERSION_IPV4) {
1136                MLX5_SET(ste_eth_l2_tnl_v1, tag, l3_type, STE_IPV4);
1137                spec->ip_version = 0;
1138        } else if (spec->ip_version == IP_VERSION_IPV6) {
1139                MLX5_SET(ste_eth_l2_tnl_v1, tag, l3_type, STE_IPV6);
1140                spec->ip_version = 0;
1141        } else if (spec->ip_version) {
1142                return -EINVAL;
1143        }
1144
1145        return 0;
1146}
1147
1148static void dr_ste_v1_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb,
1149                                            struct mlx5dr_match_param *mask)
1150{
1151        dr_ste_v1_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask);
1152
1153        sb->lu_type = DR_STE_V1_LU_TYPE_ETHL2_TNL;
1154        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1155        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_tnl_tag;
1156}
1157
1158static int dr_ste_v1_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value,
1159                                                struct mlx5dr_ste_build *sb,
1160                                                u8 *tag)
1161{
1162        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1163
1164        DR_STE_SET_TAG(eth_l3_ipv4_misc_v1, tag, time_to_live, spec, ttl_hoplimit);
1165
1166        return 0;
1167}
1168
1169static void dr_ste_v1_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb,
1170                                                  struct mlx5dr_match_param *mask)
1171{
1172        dr_ste_v1_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask);
1173
1174        sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL3_IPV4_MISC, sb->inner);
1175        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1176        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv4_misc_tag;
1177}
1178
1179static int dr_ste_v1_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value,
1180                                              struct mlx5dr_ste_build *sb,
1181                                              u8 *tag)
1182{
1183        struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
1184        struct mlx5dr_match_misc *misc = &value->misc;
1185
1186        DR_STE_SET_TAG(eth_l4_v1, tag, dst_port, spec, tcp_dport);
1187        DR_STE_SET_TAG(eth_l4_v1, tag, src_port, spec, tcp_sport);
1188        DR_STE_SET_TAG(eth_l4_v1, tag, dst_port, spec, udp_dport);
1189        DR_STE_SET_TAG(eth_l4_v1, tag, src_port, spec, udp_sport);
1190        DR_STE_SET_TAG(eth_l4_v1, tag, protocol, spec, ip_protocol);
1191        DR_STE_SET_TAG(eth_l4_v1, tag, fragmented, spec, frag);
1192        DR_STE_SET_TAG(eth_l4_v1, tag, dscp, spec, ip_dscp);
1193        DR_STE_SET_TAG(eth_l4_v1, tag, ecn, spec, ip_ecn);
1194        DR_STE_SET_TAG(eth_l4_v1, tag, ipv6_hop_limit, spec, ttl_hoplimit);
1195
1196        if (sb->inner)
1197                DR_STE_SET_TAG(eth_l4_v1, tag, flow_label, misc, inner_ipv6_flow_label);
1198        else
1199                DR_STE_SET_TAG(eth_l4_v1, tag, flow_label, misc, outer_ipv6_flow_label);
1200
1201        if (spec->tcp_flags) {
1202                DR_STE_SET_TCP_FLAGS(eth_l4_v1, tag, spec);
1203                spec->tcp_flags = 0;
1204        }
1205
1206        return 0;
1207}
1208
1209static void dr_ste_v1_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb,
1210                                                struct mlx5dr_match_param *mask)
1211{
1212        dr_ste_v1_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask);
1213
1214        sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL4, sb->inner);
1215        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1216        sb->ste_build_tag_func = &dr_ste_v1_build_eth_ipv6_l3_l4_tag;
1217}
1218
1219static int dr_ste_v1_build_mpls_tag(struct mlx5dr_match_param *value,
1220                                    struct mlx5dr_ste_build *sb,
1221                                    u8 *tag)
1222{
1223        struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1224
1225        if (sb->inner)
1226                DR_STE_SET_MPLS(mpls_v1, misc2, inner, tag);
1227        else
1228                DR_STE_SET_MPLS(mpls_v1, misc2, outer, tag);
1229
1230        return 0;
1231}
1232
1233static void dr_ste_v1_build_mpls_init(struct mlx5dr_ste_build *sb,
1234                                      struct mlx5dr_match_param *mask)
1235{
1236        dr_ste_v1_build_mpls_tag(mask, sb, sb->bit_mask);
1237
1238        sb->lu_type = DR_STE_CALC_DFNR_TYPE(MPLS, sb->inner);
1239        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1240        sb->ste_build_tag_func = &dr_ste_v1_build_mpls_tag;
1241}
1242
1243static int dr_ste_v1_build_tnl_gre_tag(struct mlx5dr_match_param *value,
1244                                       struct mlx5dr_ste_build *sb,
1245                                       u8 *tag)
1246{
1247        struct  mlx5dr_match_misc *misc = &value->misc;
1248
1249        DR_STE_SET_TAG(gre_v1, tag, gre_protocol, misc, gre_protocol);
1250        DR_STE_SET_TAG(gre_v1, tag, gre_k_present, misc, gre_k_present);
1251        DR_STE_SET_TAG(gre_v1, tag, gre_key_h, misc, gre_key_h);
1252        DR_STE_SET_TAG(gre_v1, tag, gre_key_l, misc, gre_key_l);
1253
1254        DR_STE_SET_TAG(gre_v1, tag, gre_c_present, misc, gre_c_present);
1255        DR_STE_SET_TAG(gre_v1, tag, gre_s_present, misc, gre_s_present);
1256
1257        return 0;
1258}
1259
1260static void dr_ste_v1_build_tnl_gre_init(struct mlx5dr_ste_build *sb,
1261                                         struct mlx5dr_match_param *mask)
1262{
1263        dr_ste_v1_build_tnl_gre_tag(mask, sb, sb->bit_mask);
1264
1265        sb->lu_type = DR_STE_V1_LU_TYPE_GRE;
1266        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1267        sb->ste_build_tag_func = &dr_ste_v1_build_tnl_gre_tag;
1268}
1269
1270static int dr_ste_v1_build_tnl_mpls_tag(struct mlx5dr_match_param *value,
1271                                        struct mlx5dr_ste_build *sb,
1272                                        u8 *tag)
1273{
1274        struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1275
1276        if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc2)) {
1277                DR_STE_SET_TAG(mpls_v1, tag, mpls0_label,
1278                               misc2, outer_first_mpls_over_gre_label);
1279
1280                DR_STE_SET_TAG(mpls_v1, tag, mpls0_exp,
1281                               misc2, outer_first_mpls_over_gre_exp);
1282
1283                DR_STE_SET_TAG(mpls_v1, tag, mpls0_s_bos,
1284                               misc2, outer_first_mpls_over_gre_s_bos);
1285
1286                DR_STE_SET_TAG(mpls_v1, tag, mpls0_ttl,
1287                               misc2, outer_first_mpls_over_gre_ttl);
1288        } else {
1289                DR_STE_SET_TAG(mpls_v1, tag, mpls0_label,
1290                               misc2, outer_first_mpls_over_udp_label);
1291
1292                DR_STE_SET_TAG(mpls_v1, tag, mpls0_exp,
1293                               misc2, outer_first_mpls_over_udp_exp);
1294
1295                DR_STE_SET_TAG(mpls_v1, tag, mpls0_s_bos,
1296                               misc2, outer_first_mpls_over_udp_s_bos);
1297
1298                DR_STE_SET_TAG(mpls_v1, tag, mpls0_ttl,
1299                               misc2, outer_first_mpls_over_udp_ttl);
1300        }
1301
1302        return 0;
1303}
1304
1305static void dr_ste_v1_build_tnl_mpls_init(struct mlx5dr_ste_build *sb,
1306                                          struct mlx5dr_match_param *mask)
1307{
1308        dr_ste_v1_build_tnl_mpls_tag(mask, sb, sb->bit_mask);
1309
1310        sb->lu_type = DR_STE_V1_LU_TYPE_MPLS_I;
1311        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1312        sb->ste_build_tag_func = &dr_ste_v1_build_tnl_mpls_tag;
1313}
1314
1315static int dr_ste_v1_build_tnl_mpls_over_udp_tag(struct mlx5dr_match_param *value,
1316                                                 struct mlx5dr_ste_build *sb,
1317                                                 u8 *tag)
1318{
1319        struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1320        u8 *parser_ptr;
1321        u8 parser_id;
1322        u32 mpls_hdr;
1323
1324        mpls_hdr = misc2->outer_first_mpls_over_udp_label << HDR_MPLS_OFFSET_LABEL;
1325        misc2->outer_first_mpls_over_udp_label = 0;
1326        mpls_hdr |= misc2->outer_first_mpls_over_udp_exp << HDR_MPLS_OFFSET_EXP;
1327        misc2->outer_first_mpls_over_udp_exp = 0;
1328        mpls_hdr |= misc2->outer_first_mpls_over_udp_s_bos << HDR_MPLS_OFFSET_S_BOS;
1329        misc2->outer_first_mpls_over_udp_s_bos = 0;
1330        mpls_hdr |= misc2->outer_first_mpls_over_udp_ttl << HDR_MPLS_OFFSET_TTL;
1331        misc2->outer_first_mpls_over_udp_ttl = 0;
1332
1333        parser_id = sb->caps->flex_parser_id_mpls_over_udp;
1334        parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id);
1335        *(__be32 *)parser_ptr = cpu_to_be32(mpls_hdr);
1336
1337        return 0;
1338}
1339
1340static void dr_ste_v1_build_tnl_mpls_over_udp_init(struct mlx5dr_ste_build *sb,
1341                                                   struct mlx5dr_match_param *mask)
1342{
1343        dr_ste_v1_build_tnl_mpls_over_udp_tag(mask, sb, sb->bit_mask);
1344
1345        /* STEs with lookup type FLEX_PARSER_{0/1} includes
1346         * flex parsers_{0-3}/{4-7} respectively.
1347         */
1348        sb->lu_type = sb->caps->flex_parser_id_mpls_over_udp > DR_STE_MAX_FLEX_0_ID ?
1349                      DR_STE_V1_LU_TYPE_FLEX_PARSER_1 :
1350                      DR_STE_V1_LU_TYPE_FLEX_PARSER_0;
1351
1352        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1353        sb->ste_build_tag_func = &dr_ste_v1_build_tnl_mpls_over_udp_tag;
1354}
1355
1356static int dr_ste_v1_build_tnl_mpls_over_gre_tag(struct mlx5dr_match_param *value,
1357                                                 struct mlx5dr_ste_build *sb,
1358                                                 u8 *tag)
1359{
1360        struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1361        u8 *parser_ptr;
1362        u8 parser_id;
1363        u32 mpls_hdr;
1364
1365        mpls_hdr = misc2->outer_first_mpls_over_gre_label << HDR_MPLS_OFFSET_LABEL;
1366        misc2->outer_first_mpls_over_gre_label = 0;
1367        mpls_hdr |= misc2->outer_first_mpls_over_gre_exp << HDR_MPLS_OFFSET_EXP;
1368        misc2->outer_first_mpls_over_gre_exp = 0;
1369        mpls_hdr |= misc2->outer_first_mpls_over_gre_s_bos << HDR_MPLS_OFFSET_S_BOS;
1370        misc2->outer_first_mpls_over_gre_s_bos = 0;
1371        mpls_hdr |= misc2->outer_first_mpls_over_gre_ttl << HDR_MPLS_OFFSET_TTL;
1372        misc2->outer_first_mpls_over_gre_ttl = 0;
1373
1374        parser_id = sb->caps->flex_parser_id_mpls_over_gre;
1375        parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id);
1376        *(__be32 *)parser_ptr = cpu_to_be32(mpls_hdr);
1377
1378        return 0;
1379}
1380
1381static void dr_ste_v1_build_tnl_mpls_over_gre_init(struct mlx5dr_ste_build *sb,
1382                                                   struct mlx5dr_match_param *mask)
1383{
1384        dr_ste_v1_build_tnl_mpls_over_gre_tag(mask, sb, sb->bit_mask);
1385
1386        /* STEs with lookup type FLEX_PARSER_{0/1} includes
1387         * flex parsers_{0-3}/{4-7} respectively.
1388         */
1389        sb->lu_type = sb->caps->flex_parser_id_mpls_over_gre > DR_STE_MAX_FLEX_0_ID ?
1390                      DR_STE_V1_LU_TYPE_FLEX_PARSER_1 :
1391                      DR_STE_V1_LU_TYPE_FLEX_PARSER_0;
1392
1393        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1394        sb->ste_build_tag_func = &dr_ste_v1_build_tnl_mpls_over_gre_tag;
1395}
1396
1397static int dr_ste_v1_build_icmp_tag(struct mlx5dr_match_param *value,
1398                                    struct mlx5dr_ste_build *sb,
1399                                    u8 *tag)
1400{
1401        struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1402        bool is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc3);
1403        u32 *icmp_header_data;
1404        u8 *icmp_type;
1405        u8 *icmp_code;
1406
1407        if (is_ipv4) {
1408                icmp_header_data        = &misc3->icmpv4_header_data;
1409                icmp_type               = &misc3->icmpv4_type;
1410                icmp_code               = &misc3->icmpv4_code;
1411        } else {
1412                icmp_header_data        = &misc3->icmpv6_header_data;
1413                icmp_type               = &misc3->icmpv6_type;
1414                icmp_code               = &misc3->icmpv6_code;
1415        }
1416
1417        MLX5_SET(ste_icmp_v1, tag, icmp_header_data, *icmp_header_data);
1418        MLX5_SET(ste_icmp_v1, tag, icmp_type, *icmp_type);
1419        MLX5_SET(ste_icmp_v1, tag, icmp_code, *icmp_code);
1420
1421        *icmp_header_data = 0;
1422        *icmp_type = 0;
1423        *icmp_code = 0;
1424
1425        return 0;
1426}
1427
1428static void dr_ste_v1_build_icmp_init(struct mlx5dr_ste_build *sb,
1429                                      struct mlx5dr_match_param *mask)
1430{
1431        dr_ste_v1_build_icmp_tag(mask, sb, sb->bit_mask);
1432
1433        sb->lu_type = DR_STE_V1_LU_TYPE_ETHL4_MISC_O;
1434        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1435        sb->ste_build_tag_func = &dr_ste_v1_build_icmp_tag;
1436}
1437
1438static int dr_ste_v1_build_general_purpose_tag(struct mlx5dr_match_param *value,
1439                                               struct mlx5dr_ste_build *sb,
1440                                               u8 *tag)
1441{
1442        struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1443
1444        DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field,
1445                       misc2, metadata_reg_a);
1446
1447        return 0;
1448}
1449
1450static void dr_ste_v1_build_general_purpose_init(struct mlx5dr_ste_build *sb,
1451                                                 struct mlx5dr_match_param *mask)
1452{
1453        dr_ste_v1_build_general_purpose_tag(mask, sb, sb->bit_mask);
1454
1455        sb->lu_type = DR_STE_V1_LU_TYPE_GENERAL_PURPOSE;
1456        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1457        sb->ste_build_tag_func = &dr_ste_v1_build_general_purpose_tag;
1458}
1459
1460static int dr_ste_v1_build_eth_l4_misc_tag(struct mlx5dr_match_param *value,
1461                                           struct mlx5dr_ste_build *sb,
1462                                           u8 *tag)
1463{
1464        struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1465
1466        if (sb->inner) {
1467                DR_STE_SET_TAG(eth_l4_misc_v1, tag, seq_num, misc3, inner_tcp_seq_num);
1468                DR_STE_SET_TAG(eth_l4_misc_v1, tag, ack_num, misc3, inner_tcp_ack_num);
1469        } else {
1470                DR_STE_SET_TAG(eth_l4_misc_v1, tag, seq_num, misc3, outer_tcp_seq_num);
1471                DR_STE_SET_TAG(eth_l4_misc_v1, tag, ack_num, misc3, outer_tcp_ack_num);
1472        }
1473
1474        return 0;
1475}
1476
1477static void dr_ste_v1_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb,
1478                                             struct mlx5dr_match_param *mask)
1479{
1480        dr_ste_v1_build_eth_l4_misc_tag(mask, sb, sb->bit_mask);
1481
1482        sb->lu_type = DR_STE_V1_LU_TYPE_ETHL4_MISC_O;
1483        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1484        sb->ste_build_tag_func = &dr_ste_v1_build_eth_l4_misc_tag;
1485}
1486
1487static int
1488dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value,
1489                                              struct mlx5dr_ste_build *sb,
1490                                              u8 *tag)
1491{
1492        struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1493
1494        DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
1495                       outer_vxlan_gpe_flags, misc3,
1496                       outer_vxlan_gpe_flags);
1497        DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
1498                       outer_vxlan_gpe_next_protocol, misc3,
1499                       outer_vxlan_gpe_next_protocol);
1500        DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
1501                       outer_vxlan_gpe_vni, misc3,
1502                       outer_vxlan_gpe_vni);
1503
1504        return 0;
1505}
1506
1507static void
1508dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb,
1509                                               struct mlx5dr_match_param *mask)
1510{
1511        dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask);
1512
1513        sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER;
1514        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1515        sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag;
1516}
1517
1518static int
1519dr_ste_v1_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value,
1520                                           struct mlx5dr_ste_build *sb,
1521                                           u8 *tag)
1522{
1523        struct mlx5dr_match_misc *misc = &value->misc;
1524
1525        DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
1526                       geneve_protocol_type, misc, geneve_protocol_type);
1527        DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
1528                       geneve_oam, misc, geneve_oam);
1529        DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
1530                       geneve_opt_len, misc, geneve_opt_len);
1531        DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
1532                       geneve_vni, misc, geneve_vni);
1533
1534        return 0;
1535}
1536
1537static void
1538dr_ste_v1_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb,
1539                                            struct mlx5dr_match_param *mask)
1540{
1541        dr_ste_v1_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask);
1542
1543        sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER;
1544        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1545        sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_geneve_tag;
1546}
1547
1548static int dr_ste_v1_build_register_0_tag(struct mlx5dr_match_param *value,
1549                                          struct mlx5dr_ste_build *sb,
1550                                          u8 *tag)
1551{
1552        struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1553
1554        DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0);
1555        DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1);
1556        DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2);
1557        DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3);
1558
1559        return 0;
1560}
1561
1562static void dr_ste_v1_build_register_0_init(struct mlx5dr_ste_build *sb,
1563                                            struct mlx5dr_match_param *mask)
1564{
1565        dr_ste_v1_build_register_0_tag(mask, sb, sb->bit_mask);
1566
1567        sb->lu_type = DR_STE_V1_LU_TYPE_STEERING_REGISTERS_0;
1568        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1569        sb->ste_build_tag_func = &dr_ste_v1_build_register_0_tag;
1570}
1571
1572static int dr_ste_v1_build_register_1_tag(struct mlx5dr_match_param *value,
1573                                          struct mlx5dr_ste_build *sb,
1574                                          u8 *tag)
1575{
1576        struct mlx5dr_match_misc2 *misc2 = &value->misc2;
1577
1578        DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4);
1579        DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5);
1580        DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6);
1581        DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7);
1582
1583        return 0;
1584}
1585
1586static void dr_ste_v1_build_register_1_init(struct mlx5dr_ste_build *sb,
1587                                            struct mlx5dr_match_param *mask)
1588{
1589        dr_ste_v1_build_register_1_tag(mask, sb, sb->bit_mask);
1590
1591        sb->lu_type = DR_STE_V1_LU_TYPE_STEERING_REGISTERS_1;
1592        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1593        sb->ste_build_tag_func = &dr_ste_v1_build_register_1_tag;
1594}
1595
1596static void dr_ste_v1_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value,
1597                                                  u8 *bit_mask)
1598{
1599        struct mlx5dr_match_misc *misc_mask = &value->misc;
1600
1601        DR_STE_SET_ONES(src_gvmi_qp_v1, bit_mask, source_gvmi, misc_mask, source_port);
1602        DR_STE_SET_ONES(src_gvmi_qp_v1, bit_mask, source_qp, misc_mask, source_sqn);
1603        misc_mask->source_eswitch_owner_vhca_id = 0;
1604}
1605
1606static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
1607                                            struct mlx5dr_ste_build *sb,
1608                                            u8 *tag)
1609{
1610        struct mlx5dr_match_misc *misc = &value->misc;
1611        struct mlx5dr_cmd_vport_cap *vport_cap;
1612        struct mlx5dr_domain *dmn = sb->dmn;
1613        struct mlx5dr_cmd_caps *caps;
1614        u8 *bit_mask = sb->bit_mask;
1615
1616        DR_STE_SET_TAG(src_gvmi_qp_v1, tag, source_qp, misc, source_sqn);
1617
1618        if (sb->vhca_id_valid) {
1619                /* Find port GVMI based on the eswitch_owner_vhca_id */
1620                if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi)
1621                        caps = &dmn->info.caps;
1622                else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id ==
1623                                           dmn->peer_dmn->info.caps.gvmi))
1624                        caps = &dmn->peer_dmn->info.caps;
1625                else
1626                        return -EINVAL;
1627
1628                 misc->source_eswitch_owner_vhca_id = 0;
1629        } else {
1630                caps = &dmn->info.caps;
1631        }
1632
1633        if (!MLX5_GET(ste_src_gvmi_qp_v1, bit_mask, source_gvmi))
1634                return 0;
1635
1636        vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port);
1637        if (!vport_cap) {
1638                mlx5dr_err(dmn, "Vport 0x%x is disabled or invalid\n",
1639                           misc->source_port);
1640                return -EINVAL;
1641        }
1642
1643        if (vport_cap->vport_gvmi)
1644                MLX5_SET(ste_src_gvmi_qp_v1, tag, source_gvmi, vport_cap->vport_gvmi);
1645
1646        misc->source_port = 0;
1647        return 0;
1648}
1649
1650static void dr_ste_v1_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb,
1651                                              struct mlx5dr_match_param *mask)
1652{
1653        dr_ste_v1_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask);
1654
1655        sb->lu_type = DR_STE_V1_LU_TYPE_SRC_QP_GVMI;
1656        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1657        sb->ste_build_tag_func = &dr_ste_v1_build_src_gvmi_qpn_tag;
1658}
1659
1660static void dr_ste_v1_set_flex_parser(u32 *misc4_field_id,
1661                                      u32 *misc4_field_value,
1662                                      bool *parser_is_used,
1663                                      u8 *tag)
1664{
1665        u32 id = *misc4_field_id;
1666        u8 *parser_ptr;
1667
1668        if (parser_is_used[id])
1669                return;
1670
1671        parser_is_used[id] = true;
1672        parser_ptr = dr_ste_calc_flex_parser_offset(tag, id);
1673
1674        *(__be32 *)parser_ptr = cpu_to_be32(*misc4_field_value);
1675        *misc4_field_id = 0;
1676        *misc4_field_value = 0;
1677}
1678
1679static int dr_ste_v1_build_felx_parser_tag(struct mlx5dr_match_param *value,
1680                                           struct mlx5dr_ste_build *sb,
1681                                           u8 *tag)
1682{
1683        struct mlx5dr_match_misc4 *misc_4_mask = &value->misc4;
1684        bool parser_is_used[DR_NUM_OF_FLEX_PARSERS] = {};
1685
1686        dr_ste_v1_set_flex_parser(&misc_4_mask->prog_sample_field_id_0,
1687                                  &misc_4_mask->prog_sample_field_value_0,
1688                                  parser_is_used, tag);
1689
1690        dr_ste_v1_set_flex_parser(&misc_4_mask->prog_sample_field_id_1,
1691                                  &misc_4_mask->prog_sample_field_value_1,
1692                                  parser_is_used, tag);
1693
1694        dr_ste_v1_set_flex_parser(&misc_4_mask->prog_sample_field_id_2,
1695                                  &misc_4_mask->prog_sample_field_value_2,
1696                                  parser_is_used, tag);
1697
1698        dr_ste_v1_set_flex_parser(&misc_4_mask->prog_sample_field_id_3,
1699                                  &misc_4_mask->prog_sample_field_value_3,
1700                                  parser_is_used, tag);
1701
1702        return 0;
1703}
1704
1705static void dr_ste_v1_build_flex_parser_0_init(struct mlx5dr_ste_build *sb,
1706                                               struct mlx5dr_match_param *mask)
1707{
1708        sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_0;
1709        dr_ste_v1_build_felx_parser_tag(mask, sb, sb->bit_mask);
1710        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1711        sb->ste_build_tag_func = &dr_ste_v1_build_felx_parser_tag;
1712}
1713
1714static void dr_ste_v1_build_flex_parser_1_init(struct mlx5dr_ste_build *sb,
1715                                               struct mlx5dr_match_param *mask)
1716{
1717        sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_1;
1718        dr_ste_v1_build_felx_parser_tag(mask, sb, sb->bit_mask);
1719        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1720        sb->ste_build_tag_func = &dr_ste_v1_build_felx_parser_tag;
1721}
1722
1723static int
1724dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_tag(struct mlx5dr_match_param *value,
1725                                                   struct mlx5dr_ste_build *sb,
1726                                                   u8 *tag)
1727{
1728        struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1729        u8 parser_id = sb->caps->flex_parser_id_geneve_tlv_option_0;
1730        u8 *parser_ptr = dr_ste_calc_flex_parser_offset(tag, parser_id);
1731
1732        MLX5_SET(ste_flex_parser_0, parser_ptr, flex_parser_3,
1733                 misc3->geneve_tlv_option_0_data);
1734        misc3->geneve_tlv_option_0_data = 0;
1735
1736        return 0;
1737}
1738
1739static void
1740dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_init(struct mlx5dr_ste_build *sb,
1741                                                    struct mlx5dr_match_param *mask)
1742{
1743        dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_tag(mask, sb, sb->bit_mask);
1744
1745        /* STEs with lookup type FLEX_PARSER_{0/1} includes
1746         * flex parsers_{0-3}/{4-7} respectively.
1747         */
1748        sb->lu_type = sb->caps->flex_parser_id_geneve_tlv_option_0 > 3 ?
1749                      DR_STE_V1_LU_TYPE_FLEX_PARSER_1 :
1750                      DR_STE_V1_LU_TYPE_FLEX_PARSER_0;
1751
1752        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1753        sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_tag;
1754}
1755
1756static int dr_ste_v1_build_flex_parser_tnl_gtpu_tag(struct mlx5dr_match_param *value,
1757                                                    struct mlx5dr_ste_build *sb,
1758                                                    uint8_t *tag)
1759{
1760        struct mlx5dr_match_misc3 *misc3 = &value->misc3;
1761
1762        DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, gtpu_msg_flags, misc3, gtpu_msg_flags);
1763        DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, gtpu_msg_type, misc3, gtpu_msg_type);
1764        DR_STE_SET_TAG(flex_parser_tnl_gtpu, tag, gtpu_teid, misc3, gtpu_teid);
1765
1766        return 0;
1767}
1768
1769static void dr_ste_v1_build_flex_parser_tnl_gtpu_init(struct mlx5dr_ste_build *sb,
1770                                                      struct mlx5dr_match_param *mask)
1771{
1772        dr_ste_v1_build_flex_parser_tnl_gtpu_tag(mask, sb, sb->bit_mask);
1773
1774        sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER;
1775        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1776        sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_gtpu_tag;
1777}
1778
1779static int
1780dr_ste_v1_build_tnl_gtpu_flex_parser_0_tag(struct mlx5dr_match_param *value,
1781                                           struct mlx5dr_ste_build *sb,
1782                                           uint8_t *tag)
1783{
1784        if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_dw_0))
1785                DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_0, sb->caps, &value->misc3);
1786        if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_teid))
1787                DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_teid, sb->caps, &value->misc3);
1788        if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_dw_2))
1789                DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_2, sb->caps, &value->misc3);
1790        if (dr_is_flex_parser_0_id(sb->caps->flex_parser_id_gtpu_first_ext_dw_0))
1791                DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_first_ext_dw_0, sb->caps, &value->misc3);
1792        return 0;
1793}
1794
1795static void
1796dr_ste_v1_build_tnl_gtpu_flex_parser_0_init(struct mlx5dr_ste_build *sb,
1797                                            struct mlx5dr_match_param *mask)
1798{
1799        dr_ste_v1_build_tnl_gtpu_flex_parser_0_tag(mask, sb, sb->bit_mask);
1800
1801        sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_0;
1802        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1803        sb->ste_build_tag_func = &dr_ste_v1_build_tnl_gtpu_flex_parser_0_tag;
1804}
1805
1806static int
1807dr_ste_v1_build_tnl_gtpu_flex_parser_1_tag(struct mlx5dr_match_param *value,
1808                                           struct mlx5dr_ste_build *sb,
1809                                           uint8_t *tag)
1810{
1811        if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_dw_0))
1812                DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_0, sb->caps, &value->misc3);
1813        if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_teid))
1814                DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_teid, sb->caps, &value->misc3);
1815        if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_dw_2))
1816                DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_dw_2, sb->caps, &value->misc3);
1817        if (dr_is_flex_parser_1_id(sb->caps->flex_parser_id_gtpu_first_ext_dw_0))
1818                DR_STE_SET_FLEX_PARSER_FIELD(tag, gtpu_first_ext_dw_0, sb->caps, &value->misc3);
1819        return 0;
1820}
1821
1822static void
1823dr_ste_v1_build_tnl_gtpu_flex_parser_1_init(struct mlx5dr_ste_build *sb,
1824                                            struct mlx5dr_match_param *mask)
1825{
1826        dr_ste_v1_build_tnl_gtpu_flex_parser_1_tag(mask, sb, sb->bit_mask);
1827
1828        sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_1;
1829        sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
1830        sb->ste_build_tag_func = &dr_ste_v1_build_tnl_gtpu_flex_parser_1_tag;
1831}
1832
1833struct mlx5dr_ste_ctx ste_ctx_v1 = {
1834        /* Builders */
1835        .build_eth_l2_src_dst_init      = &dr_ste_v1_build_eth_l2_src_dst_init,
1836        .build_eth_l3_ipv6_src_init     = &dr_ste_v1_build_eth_l3_ipv6_src_init,
1837        .build_eth_l3_ipv6_dst_init     = &dr_ste_v1_build_eth_l3_ipv6_dst_init,
1838        .build_eth_l3_ipv4_5_tuple_init = &dr_ste_v1_build_eth_l3_ipv4_5_tuple_init,
1839        .build_eth_l2_src_init          = &dr_ste_v1_build_eth_l2_src_init,
1840        .build_eth_l2_dst_init          = &dr_ste_v1_build_eth_l2_dst_init,
1841        .build_eth_l2_tnl_init          = &dr_ste_v1_build_eth_l2_tnl_init,
1842        .build_eth_l3_ipv4_misc_init    = &dr_ste_v1_build_eth_l3_ipv4_misc_init,
1843        .build_eth_ipv6_l3_l4_init      = &dr_ste_v1_build_eth_ipv6_l3_l4_init,
1844        .build_mpls_init                = &dr_ste_v1_build_mpls_init,
1845        .build_tnl_gre_init             = &dr_ste_v1_build_tnl_gre_init,
1846        .build_tnl_mpls_init            = &dr_ste_v1_build_tnl_mpls_init,
1847        .build_tnl_mpls_over_udp_init   = &dr_ste_v1_build_tnl_mpls_over_udp_init,
1848        .build_tnl_mpls_over_gre_init   = &dr_ste_v1_build_tnl_mpls_over_gre_init,
1849        .build_icmp_init                = &dr_ste_v1_build_icmp_init,
1850        .build_general_purpose_init     = &dr_ste_v1_build_general_purpose_init,
1851        .build_eth_l4_misc_init         = &dr_ste_v1_build_eth_l4_misc_init,
1852        .build_tnl_vxlan_gpe_init       = &dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_init,
1853        .build_tnl_geneve_init          = &dr_ste_v1_build_flex_parser_tnl_geneve_init,
1854        .build_tnl_geneve_tlv_opt_init  = &dr_ste_v1_build_flex_parser_tnl_geneve_tlv_opt_init,
1855        .build_register_0_init          = &dr_ste_v1_build_register_0_init,
1856        .build_register_1_init          = &dr_ste_v1_build_register_1_init,
1857        .build_src_gvmi_qpn_init        = &dr_ste_v1_build_src_gvmi_qpn_init,
1858        .build_flex_parser_0_init       = &dr_ste_v1_build_flex_parser_0_init,
1859        .build_flex_parser_1_init       = &dr_ste_v1_build_flex_parser_1_init,
1860        .build_tnl_gtpu_init            = &dr_ste_v1_build_flex_parser_tnl_gtpu_init,
1861        .build_tnl_gtpu_flex_parser_0_init = &dr_ste_v1_build_tnl_gtpu_flex_parser_0_init,
1862        .build_tnl_gtpu_flex_parser_1_init = &dr_ste_v1_build_tnl_gtpu_flex_parser_1_init,
1863
1864        /* Getters and Setters */
1865        .ste_init                       = &dr_ste_v1_init,
1866        .set_next_lu_type               = &dr_ste_v1_set_next_lu_type,
1867        .get_next_lu_type               = &dr_ste_v1_get_next_lu_type,
1868        .set_miss_addr                  = &dr_ste_v1_set_miss_addr,
1869        .get_miss_addr                  = &dr_ste_v1_get_miss_addr,
1870        .set_hit_addr                   = &dr_ste_v1_set_hit_addr,
1871        .set_byte_mask                  = &dr_ste_v1_set_byte_mask,
1872        .get_byte_mask                  = &dr_ste_v1_get_byte_mask,
1873        /* Actions */
1874        .set_actions_rx                 = &dr_ste_v1_set_actions_rx,
1875        .set_actions_tx                 = &dr_ste_v1_set_actions_tx,
1876        .modify_field_arr_sz            = ARRAY_SIZE(dr_ste_v1_action_modify_field_arr),
1877        .modify_field_arr               = dr_ste_v1_action_modify_field_arr,
1878        .set_action_set                 = &dr_ste_v1_set_action_set,
1879        .set_action_add                 = &dr_ste_v1_set_action_add,
1880        .set_action_copy                = &dr_ste_v1_set_action_copy,
1881        .set_action_decap_l3_list       = &dr_ste_v1_set_action_decap_l3_list,
1882        /* Send */
1883        .prepare_for_postsend           = &dr_ste_v1_prepare_for_postsend,
1884};
1885