linux/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
   2/* Copyright (c) 2019, Mellanox Technologies */
   3
   4#ifndef _DR_TYPES_
   5#define _DR_TYPES_
   6
   7#include <linux/mlx5/driver.h>
   8#include <linux/refcount.h>
   9#include "fs_core.h"
  10#include "wq.h"
  11#include "lib/mlx5.h"
  12#include "mlx5_ifc_dr.h"
  13#include "mlx5dr.h"
  14
  15#define DR_RULE_MAX_STES 17
  16#define DR_ACTION_MAX_STES 5
  17#define WIRE_PORT 0xFFFF
  18#define DR_STE_SVLAN 0x1
  19#define DR_STE_CVLAN 0x2
  20#define DR_SZ_MATCH_PARAM (MLX5_ST_SZ_DW_MATCH_PARAM * 4)
  21
  22#define mlx5dr_err(dmn, arg...) mlx5_core_err((dmn)->mdev, ##arg)
  23#define mlx5dr_info(dmn, arg...) mlx5_core_info((dmn)->mdev, ##arg)
  24#define mlx5dr_dbg(dmn, arg...) mlx5_core_dbg((dmn)->mdev, ##arg)
  25
  26enum mlx5dr_icm_chunk_size {
  27        DR_CHUNK_SIZE_1,
  28        DR_CHUNK_SIZE_MIN = DR_CHUNK_SIZE_1, /* keep updated when changing */
  29        DR_CHUNK_SIZE_2,
  30        DR_CHUNK_SIZE_4,
  31        DR_CHUNK_SIZE_8,
  32        DR_CHUNK_SIZE_16,
  33        DR_CHUNK_SIZE_32,
  34        DR_CHUNK_SIZE_64,
  35        DR_CHUNK_SIZE_128,
  36        DR_CHUNK_SIZE_256,
  37        DR_CHUNK_SIZE_512,
  38        DR_CHUNK_SIZE_1K,
  39        DR_CHUNK_SIZE_2K,
  40        DR_CHUNK_SIZE_4K,
  41        DR_CHUNK_SIZE_8K,
  42        DR_CHUNK_SIZE_16K,
  43        DR_CHUNK_SIZE_32K,
  44        DR_CHUNK_SIZE_64K,
  45        DR_CHUNK_SIZE_128K,
  46        DR_CHUNK_SIZE_256K,
  47        DR_CHUNK_SIZE_512K,
  48        DR_CHUNK_SIZE_1024K,
  49        DR_CHUNK_SIZE_2048K,
  50        DR_CHUNK_SIZE_MAX,
  51};
  52
  53enum mlx5dr_icm_type {
  54        DR_ICM_TYPE_STE,
  55        DR_ICM_TYPE_MODIFY_ACTION,
  56};
  57
  58static inline enum mlx5dr_icm_chunk_size
  59mlx5dr_icm_next_higher_chunk(enum mlx5dr_icm_chunk_size chunk)
  60{
  61        chunk += 2;
  62        if (chunk < DR_CHUNK_SIZE_MAX)
  63                return chunk;
  64
  65        return DR_CHUNK_SIZE_MAX;
  66}
  67
  68enum {
  69        DR_STE_SIZE = 64,
  70        DR_STE_SIZE_CTRL = 32,
  71        DR_STE_SIZE_TAG = 16,
  72        DR_STE_SIZE_MASK = 16,
  73};
  74
  75enum {
  76        DR_STE_SIZE_REDUCED = DR_STE_SIZE - DR_STE_SIZE_MASK,
  77};
  78
  79enum {
  80        DR_MODIFY_ACTION_SIZE = 8,
  81};
  82
  83enum mlx5dr_matcher_criteria {
  84        DR_MATCHER_CRITERIA_EMPTY = 0,
  85        DR_MATCHER_CRITERIA_OUTER = 1 << 0,
  86        DR_MATCHER_CRITERIA_MISC = 1 << 1,
  87        DR_MATCHER_CRITERIA_INNER = 1 << 2,
  88        DR_MATCHER_CRITERIA_MISC2 = 1 << 3,
  89        DR_MATCHER_CRITERIA_MISC3 = 1 << 4,
  90        DR_MATCHER_CRITERIA_MAX = 1 << 5,
  91};
  92
  93enum mlx5dr_action_type {
  94        DR_ACTION_TYP_TNL_L2_TO_L2,
  95        DR_ACTION_TYP_L2_TO_TNL_L2,
  96        DR_ACTION_TYP_TNL_L3_TO_L2,
  97        DR_ACTION_TYP_L2_TO_TNL_L3,
  98        DR_ACTION_TYP_DROP,
  99        DR_ACTION_TYP_QP,
 100        DR_ACTION_TYP_FT,
 101        DR_ACTION_TYP_CTR,
 102        DR_ACTION_TYP_TAG,
 103        DR_ACTION_TYP_MODIFY_HDR,
 104        DR_ACTION_TYP_VPORT,
 105        DR_ACTION_TYP_POP_VLAN,
 106        DR_ACTION_TYP_PUSH_VLAN,
 107        DR_ACTION_TYP_MAX,
 108};
 109
 110enum mlx5dr_ipv {
 111        DR_RULE_IPV4,
 112        DR_RULE_IPV6,
 113        DR_RULE_IPV_MAX,
 114};
 115
 116struct mlx5dr_icm_pool;
 117struct mlx5dr_icm_chunk;
 118struct mlx5dr_icm_buddy_mem;
 119struct mlx5dr_ste_htbl;
 120struct mlx5dr_match_param;
 121struct mlx5dr_cmd_caps;
 122struct mlx5dr_matcher_rx_tx;
 123struct mlx5dr_ste_ctx;
 124
 125struct mlx5dr_ste {
 126        u8 *hw_ste;
 127        /* refcount: indicates the num of rules that using this ste */
 128        u32 refcount;
 129
 130        /* attached to the miss_list head at each htbl entry */
 131        struct list_head miss_list_node;
 132
 133        /* each rule member that uses this ste attached here */
 134        struct list_head rule_list;
 135
 136        /* this ste is member of htbl */
 137        struct mlx5dr_ste_htbl *htbl;
 138
 139        struct mlx5dr_ste_htbl *next_htbl;
 140
 141        /* this ste is part of a rule, located in ste's chain */
 142        u8 ste_chain_location;
 143};
 144
 145struct mlx5dr_ste_htbl_ctrl {
 146        /* total number of valid entries belonging to this hash table. This
 147         * includes the non collision and collision entries
 148         */
 149        unsigned int num_of_valid_entries;
 150
 151        /* total number of collisions entries attached to this table */
 152        unsigned int num_of_collisions;
 153        unsigned int increase_threshold;
 154        u8 may_grow:1;
 155};
 156
 157struct mlx5dr_ste_htbl {
 158        u16 lu_type;
 159        u16 byte_mask;
 160        u32 refcount;
 161        struct mlx5dr_icm_chunk *chunk;
 162        struct mlx5dr_ste *ste_arr;
 163        u8 *hw_ste_arr;
 164
 165        struct list_head *miss_list;
 166
 167        enum mlx5dr_icm_chunk_size chunk_size;
 168        struct mlx5dr_ste *pointing_ste;
 169
 170        struct mlx5dr_ste_htbl_ctrl ctrl;
 171};
 172
 173struct mlx5dr_ste_send_info {
 174        struct mlx5dr_ste *ste;
 175        struct list_head send_list;
 176        u16 size;
 177        u16 offset;
 178        u8 data_cont[DR_STE_SIZE];
 179        u8 *data;
 180};
 181
 182void mlx5dr_send_fill_and_append_ste_send_info(struct mlx5dr_ste *ste, u16 size,
 183                                               u16 offset, u8 *data,
 184                                               struct mlx5dr_ste_send_info *ste_info,
 185                                               struct list_head *send_list,
 186                                               bool copy_data);
 187
 188struct mlx5dr_ste_build {
 189        u8 inner:1;
 190        u8 rx:1;
 191        u8 vhca_id_valid:1;
 192        struct mlx5dr_domain *dmn;
 193        struct mlx5dr_cmd_caps *caps;
 194        u16 lu_type;
 195        u16 byte_mask;
 196        u8 bit_mask[DR_STE_SIZE_MASK];
 197        int (*ste_build_tag_func)(struct mlx5dr_match_param *spec,
 198                                  struct mlx5dr_ste_build *sb,
 199                                  u8 *tag);
 200};
 201
 202struct mlx5dr_ste_htbl *
 203mlx5dr_ste_htbl_alloc(struct mlx5dr_icm_pool *pool,
 204                      enum mlx5dr_icm_chunk_size chunk_size,
 205                      u16 lu_type, u16 byte_mask);
 206
 207int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl);
 208
 209static inline void mlx5dr_htbl_put(struct mlx5dr_ste_htbl *htbl)
 210{
 211        htbl->refcount--;
 212        if (!htbl->refcount)
 213                mlx5dr_ste_htbl_free(htbl);
 214}
 215
 216static inline void mlx5dr_htbl_get(struct mlx5dr_ste_htbl *htbl)
 217{
 218        htbl->refcount++;
 219}
 220
 221/* STE utils */
 222u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl);
 223void mlx5dr_ste_set_miss_addr(struct mlx5dr_ste_ctx *ste_ctx,
 224                              u8 *hw_ste, u64 miss_addr);
 225void mlx5dr_ste_set_hit_addr(struct mlx5dr_ste_ctx *ste_ctx,
 226                             u8 *hw_ste, u64 icm_addr, u32 ht_size);
 227void mlx5dr_ste_set_hit_addr_by_next_htbl(struct mlx5dr_ste_ctx *ste_ctx,
 228                                          u8 *hw_ste,
 229                                          struct mlx5dr_ste_htbl *next_htbl);
 230void mlx5dr_ste_set_bit_mask(u8 *hw_ste_p, u8 *bit_mask);
 231bool mlx5dr_ste_is_last_in_rule(struct mlx5dr_matcher_rx_tx *nic_matcher,
 232                                u8 ste_location);
 233u64 mlx5dr_ste_get_icm_addr(struct mlx5dr_ste *ste);
 234u64 mlx5dr_ste_get_mr_addr(struct mlx5dr_ste *ste);
 235struct list_head *mlx5dr_ste_get_miss_list(struct mlx5dr_ste *ste);
 236
 237#define MLX5DR_MAX_VLANS 2
 238
 239struct mlx5dr_ste_actions_attr {
 240        u32     modify_index;
 241        u16     modify_actions;
 242        u32     decap_index;
 243        u16     decap_actions;
 244        u8      decap_with_vlan:1;
 245        u64     final_icm_addr;
 246        u32     flow_tag;
 247        u32     ctr_id;
 248        u16     gvmi;
 249        u16     hit_gvmi;
 250        u32     reformat_id;
 251        u32     reformat_size;
 252        struct {
 253                int     count;
 254                u32     headers[MLX5DR_MAX_VLANS];
 255        } vlans;
 256};
 257
 258void mlx5dr_ste_set_actions_rx(struct mlx5dr_ste_ctx *ste_ctx,
 259                               struct mlx5dr_domain *dmn,
 260                               u8 *action_type_set,
 261                               u8 *last_ste,
 262                               struct mlx5dr_ste_actions_attr *attr,
 263                               u32 *added_stes);
 264void mlx5dr_ste_set_actions_tx(struct mlx5dr_ste_ctx *ste_ctx,
 265                               struct mlx5dr_domain *dmn,
 266                               u8 *action_type_set,
 267                               u8 *last_ste,
 268                               struct mlx5dr_ste_actions_attr *attr,
 269                               u32 *added_stes);
 270
 271void mlx5dr_ste_set_action_set(struct mlx5dr_ste_ctx *ste_ctx,
 272                               __be64 *hw_action,
 273                               u8 hw_field,
 274                               u8 shifter,
 275                               u8 length,
 276                               u32 data);
 277void mlx5dr_ste_set_action_add(struct mlx5dr_ste_ctx *ste_ctx,
 278                               __be64 *hw_action,
 279                               u8 hw_field,
 280                               u8 shifter,
 281                               u8 length,
 282                               u32 data);
 283void mlx5dr_ste_set_action_copy(struct mlx5dr_ste_ctx *ste_ctx,
 284                                __be64 *hw_action,
 285                                u8 dst_hw_field,
 286                                u8 dst_shifter,
 287                                u8 dst_len,
 288                                u8 src_hw_field,
 289                                u8 src_shifter);
 290int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx,
 291                                        void *data,
 292                                        u32 data_sz,
 293                                        u8 *hw_action,
 294                                        u32 hw_action_sz,
 295                                        u16 *used_hw_action_num);
 296
 297const struct mlx5dr_ste_action_modify_field *
 298mlx5dr_ste_conv_modify_hdr_sw_field(struct mlx5dr_ste_ctx *ste_ctx, u16 sw_field);
 299
 300struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx(u8 version);
 301void mlx5dr_ste_free(struct mlx5dr_ste *ste,
 302                     struct mlx5dr_matcher *matcher,
 303                     struct mlx5dr_matcher_rx_tx *nic_matcher);
 304static inline void mlx5dr_ste_put(struct mlx5dr_ste *ste,
 305                                  struct mlx5dr_matcher *matcher,
 306                                  struct mlx5dr_matcher_rx_tx *nic_matcher)
 307{
 308        ste->refcount--;
 309        if (!ste->refcount)
 310                mlx5dr_ste_free(ste, matcher, nic_matcher);
 311}
 312
 313/* initial as 0, increased only when ste appears in a new rule */
 314static inline void mlx5dr_ste_get(struct mlx5dr_ste *ste)
 315{
 316        ste->refcount++;
 317}
 318
 319static inline bool mlx5dr_ste_is_not_used(struct mlx5dr_ste *ste)
 320{
 321        return !ste->refcount;
 322}
 323
 324bool mlx5dr_ste_equal_tag(void *src, void *dst);
 325int mlx5dr_ste_create_next_htbl(struct mlx5dr_matcher *matcher,
 326                                struct mlx5dr_matcher_rx_tx *nic_matcher,
 327                                struct mlx5dr_ste *ste,
 328                                u8 *cur_hw_ste,
 329                                enum mlx5dr_icm_chunk_size log_table_size);
 330
 331/* STE build functions */
 332int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
 333                               u8 match_criteria,
 334                               struct mlx5dr_match_param *mask,
 335                               struct mlx5dr_match_param *value);
 336int mlx5dr_ste_build_ste_arr(struct mlx5dr_matcher *matcher,
 337                             struct mlx5dr_matcher_rx_tx *nic_matcher,
 338                             struct mlx5dr_match_param *value,
 339                             u8 *ste_arr);
 340void mlx5dr_ste_build_eth_l2_src_dst(struct mlx5dr_ste_ctx *ste_ctx,
 341                                     struct mlx5dr_ste_build *builder,
 342                                     struct mlx5dr_match_param *mask,
 343                                     bool inner, bool rx);
 344void mlx5dr_ste_build_eth_l3_ipv4_5_tuple(struct mlx5dr_ste_ctx *ste_ctx,
 345                                          struct mlx5dr_ste_build *sb,
 346                                          struct mlx5dr_match_param *mask,
 347                                          bool inner, bool rx);
 348void mlx5dr_ste_build_eth_l3_ipv4_misc(struct mlx5dr_ste_ctx *ste_ctx,
 349                                       struct mlx5dr_ste_build *sb,
 350                                       struct mlx5dr_match_param *mask,
 351                                       bool inner, bool rx);
 352void mlx5dr_ste_build_eth_l3_ipv6_dst(struct mlx5dr_ste_ctx *ste_ctx,
 353                                      struct mlx5dr_ste_build *sb,
 354                                      struct mlx5dr_match_param *mask,
 355                                      bool inner, bool rx);
 356void mlx5dr_ste_build_eth_l3_ipv6_src(struct mlx5dr_ste_ctx *ste_ctx,
 357                                      struct mlx5dr_ste_build *sb,
 358                                      struct mlx5dr_match_param *mask,
 359                                      bool inner, bool rx);
 360void mlx5dr_ste_build_eth_l2_src(struct mlx5dr_ste_ctx *ste_ctx,
 361                                 struct mlx5dr_ste_build *sb,
 362                                 struct mlx5dr_match_param *mask,
 363                                 bool inner, bool rx);
 364void mlx5dr_ste_build_eth_l2_dst(struct mlx5dr_ste_ctx *ste_ctx,
 365                                 struct mlx5dr_ste_build *sb,
 366                                 struct mlx5dr_match_param *mask,
 367                                 bool inner, bool rx);
 368void mlx5dr_ste_build_eth_l2_tnl(struct mlx5dr_ste_ctx *ste_ctx,
 369                                 struct mlx5dr_ste_build *sb,
 370                                 struct mlx5dr_match_param *mask,
 371                                 bool inner, bool rx);
 372void mlx5dr_ste_build_eth_ipv6_l3_l4(struct mlx5dr_ste_ctx *ste_ctx,
 373                                     struct mlx5dr_ste_build *sb,
 374                                     struct mlx5dr_match_param *mask,
 375                                     bool inner, bool rx);
 376void mlx5dr_ste_build_eth_l4_misc(struct mlx5dr_ste_ctx *ste_ctx,
 377                                  struct mlx5dr_ste_build *sb,
 378                                  struct mlx5dr_match_param *mask,
 379                                  bool inner, bool rx);
 380void mlx5dr_ste_build_tnl_gre(struct mlx5dr_ste_ctx *ste_ctx,
 381                              struct mlx5dr_ste_build *sb,
 382                              struct mlx5dr_match_param *mask,
 383                              bool inner, bool rx);
 384void mlx5dr_ste_build_mpls(struct mlx5dr_ste_ctx *ste_ctx,
 385                           struct mlx5dr_ste_build *sb,
 386                           struct mlx5dr_match_param *mask,
 387                           bool inner, bool rx);
 388void mlx5dr_ste_build_tnl_mpls(struct mlx5dr_ste_ctx *ste_ctx,
 389                               struct mlx5dr_ste_build *sb,
 390                               struct mlx5dr_match_param *mask,
 391                               bool inner, bool rx);
 392int mlx5dr_ste_build_icmp(struct mlx5dr_ste_ctx *ste_ctx,
 393                          struct mlx5dr_ste_build *sb,
 394                          struct mlx5dr_match_param *mask,
 395                          struct mlx5dr_cmd_caps *caps,
 396                          bool inner, bool rx);
 397void mlx5dr_ste_build_tnl_vxlan_gpe(struct mlx5dr_ste_ctx *ste_ctx,
 398                                    struct mlx5dr_ste_build *sb,
 399                                    struct mlx5dr_match_param *mask,
 400                                    bool inner, bool rx);
 401void mlx5dr_ste_build_tnl_geneve(struct mlx5dr_ste_ctx *ste_ctx,
 402                                 struct mlx5dr_ste_build *sb,
 403                                 struct mlx5dr_match_param *mask,
 404                                 bool inner, bool rx);
 405void mlx5dr_ste_build_general_purpose(struct mlx5dr_ste_ctx *ste_ctx,
 406                                      struct mlx5dr_ste_build *sb,
 407                                      struct mlx5dr_match_param *mask,
 408                                      bool inner, bool rx);
 409void mlx5dr_ste_build_register_0(struct mlx5dr_ste_ctx *ste_ctx,
 410                                 struct mlx5dr_ste_build *sb,
 411                                 struct mlx5dr_match_param *mask,
 412                                 bool inner, bool rx);
 413void mlx5dr_ste_build_register_1(struct mlx5dr_ste_ctx *ste_ctx,
 414                                 struct mlx5dr_ste_build *sb,
 415                                 struct mlx5dr_match_param *mask,
 416                                 bool inner, bool rx);
 417void mlx5dr_ste_build_src_gvmi_qpn(struct mlx5dr_ste_ctx *ste_ctx,
 418                                   struct mlx5dr_ste_build *sb,
 419                                   struct mlx5dr_match_param *mask,
 420                                   struct mlx5dr_domain *dmn,
 421                                   bool inner, bool rx);
 422void mlx5dr_ste_build_empty_always_hit(struct mlx5dr_ste_build *sb, bool rx);
 423
 424/* Actions utils */
 425int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher,
 426                                 struct mlx5dr_matcher_rx_tx *nic_matcher,
 427                                 struct mlx5dr_action *actions[],
 428                                 u32 num_actions,
 429                                 u8 *ste_arr,
 430                                 u32 *new_hw_ste_arr_sz);
 431
 432struct mlx5dr_match_spec {
 433        u32 smac_47_16;         /* Source MAC address of incoming packet */
 434        /* Incoming packet Ethertype - this is the Ethertype
 435         * following the last VLAN tag of the packet
 436         */
 437        u32 ethertype:16;
 438        u32 smac_15_0:16;       /* Source MAC address of incoming packet */
 439        u32 dmac_47_16;         /* Destination MAC address of incoming packet */
 440        /* VLAN ID of first VLAN tag in the incoming packet.
 441         * Valid only when cvlan_tag==1 or svlan_tag==1
 442         */
 443        u32 first_vid:12;
 444        /* CFI bit of first VLAN tag in the incoming packet.
 445         * Valid only when cvlan_tag==1 or svlan_tag==1
 446         */
 447        u32 first_cfi:1;
 448        /* Priority of first VLAN tag in the incoming packet.
 449         * Valid only when cvlan_tag==1 or svlan_tag==1
 450         */
 451        u32 first_prio:3;
 452        u32 dmac_15_0:16;       /* Destination MAC address of incoming packet */
 453        /* TCP flags. ;Bit 0: FIN;Bit 1: SYN;Bit 2: RST;Bit 3: PSH;Bit 4: ACK;
 454         *             Bit 5: URG;Bit 6: ECE;Bit 7: CWR;Bit 8: NS
 455         */
 456        u32 tcp_flags:9;
 457        u32 ip_version:4;       /* IP version */
 458        u32 frag:1;             /* Packet is an IP fragment */
 459        /* The first vlan in the packet is s-vlan (0x8a88).
 460         * cvlan_tag and svlan_tag cannot be set together
 461         */
 462        u32 svlan_tag:1;
 463        /* The first vlan in the packet is c-vlan (0x8100).
 464         * cvlan_tag and svlan_tag cannot be set together
 465         */
 466        u32 cvlan_tag:1;
 467        /* Explicit Congestion Notification derived from
 468         * Traffic Class/TOS field of IPv6/v4
 469         */
 470        u32 ip_ecn:2;
 471        /* Differentiated Services Code Point derived from
 472         * Traffic Class/TOS field of IPv6/v4
 473         */
 474        u32 ip_dscp:6;
 475        u32 ip_protocol:8;      /* IP protocol */
 476        /* TCP destination port.
 477         * tcp and udp sport/dport are mutually exclusive
 478         */
 479        u32 tcp_dport:16;
 480        /* TCP source port.;tcp and udp sport/dport are mutually exclusive */
 481        u32 tcp_sport:16;
 482        u32 ttl_hoplimit:8;
 483        u32 reserved:24;
 484        /* UDP destination port.;tcp and udp sport/dport are mutually exclusive */
 485        u32 udp_dport:16;
 486        /* UDP source port.;tcp and udp sport/dport are mutually exclusive */
 487        u32 udp_sport:16;
 488        /* IPv6 source address of incoming packets
 489         * For IPv4 address use bits 31:0 (rest of the bits are reserved)
 490         * This field should be qualified by an appropriate ethertype
 491         */
 492        u32 src_ip_127_96;
 493        /* IPv6 source address of incoming packets
 494         * For IPv4 address use bits 31:0 (rest of the bits are reserved)
 495         * This field should be qualified by an appropriate ethertype
 496         */
 497        u32 src_ip_95_64;
 498        /* IPv6 source address of incoming packets
 499         * For IPv4 address use bits 31:0 (rest of the bits are reserved)
 500         * This field should be qualified by an appropriate ethertype
 501         */
 502        u32 src_ip_63_32;
 503        /* IPv6 source address of incoming packets
 504         * For IPv4 address use bits 31:0 (rest of the bits are reserved)
 505         * This field should be qualified by an appropriate ethertype
 506         */
 507        u32 src_ip_31_0;
 508        /* IPv6 destination address of incoming packets
 509         * For IPv4 address use bits 31:0 (rest of the bits are reserved)
 510         * This field should be qualified by an appropriate ethertype
 511         */
 512        u32 dst_ip_127_96;
 513        /* IPv6 destination address of incoming packets
 514         * For IPv4 address use bits 31:0 (rest of the bits are reserved)
 515         * This field should be qualified by an appropriate ethertype
 516         */
 517        u32 dst_ip_95_64;
 518        /* IPv6 destination address of incoming packets
 519         * For IPv4 address use bits 31:0 (rest of the bits are reserved)
 520         * This field should be qualified by an appropriate ethertype
 521         */
 522        u32 dst_ip_63_32;
 523        /* IPv6 destination address of incoming packets
 524         * For IPv4 address use bits 31:0 (rest of the bits are reserved)
 525         * This field should be qualified by an appropriate ethertype
 526         */
 527        u32 dst_ip_31_0;
 528};
 529
 530struct mlx5dr_match_misc {
 531        u32 source_sqn:24;              /* Source SQN */
 532        u32 source_vhca_port:4;
 533        /* used with GRE, sequence number exist when gre_s_present == 1 */
 534        u32 gre_s_present:1;
 535        /* used with GRE, key exist when gre_k_present == 1 */
 536        u32 gre_k_present:1;
 537        u32 reserved_auto1:1;
 538        /* used with GRE, checksum exist when gre_c_present == 1 */
 539        u32 gre_c_present:1;
 540        /* Source port.;0xffff determines wire port */
 541        u32 source_port:16;
 542        u32 source_eswitch_owner_vhca_id:16;
 543        /* VLAN ID of first VLAN tag the inner header of the incoming packet.
 544         * Valid only when inner_second_cvlan_tag ==1 or inner_second_svlan_tag ==1
 545         */
 546        u32 inner_second_vid:12;
 547        /* CFI bit of first VLAN tag in the inner header of the incoming packet.
 548         * Valid only when inner_second_cvlan_tag ==1 or inner_second_svlan_tag ==1
 549         */
 550        u32 inner_second_cfi:1;
 551        /* Priority of second VLAN tag in the inner header of the incoming packet.
 552         * Valid only when inner_second_cvlan_tag ==1 or inner_second_svlan_tag ==1
 553         */
 554        u32 inner_second_prio:3;
 555        /* VLAN ID of first VLAN tag the outer header of the incoming packet.
 556         * Valid only when outer_second_cvlan_tag ==1 or outer_second_svlan_tag ==1
 557         */
 558        u32 outer_second_vid:12;
 559        /* CFI bit of first VLAN tag in the outer header of the incoming packet.
 560         * Valid only when outer_second_cvlan_tag ==1 or outer_second_svlan_tag ==1
 561         */
 562        u32 outer_second_cfi:1;
 563        /* Priority of second VLAN tag in the outer header of the incoming packet.
 564         * Valid only when outer_second_cvlan_tag ==1 or outer_second_svlan_tag ==1
 565         */
 566        u32 outer_second_prio:3;
 567        u32 gre_protocol:16;            /* GRE Protocol (outer) */
 568        u32 reserved_auto3:12;
 569        /* The second vlan in the inner header of the packet is s-vlan (0x8a88).
 570         * inner_second_cvlan_tag and inner_second_svlan_tag cannot be set together
 571         */
 572        u32 inner_second_svlan_tag:1;
 573        /* The second vlan in the outer header of the packet is s-vlan (0x8a88).
 574         * outer_second_cvlan_tag and outer_second_svlan_tag cannot be set together
 575         */
 576        u32 outer_second_svlan_tag:1;
 577        /* The second vlan in the inner header of the packet is c-vlan (0x8100).
 578         * inner_second_cvlan_tag and inner_second_svlan_tag cannot be set together
 579         */
 580        u32 inner_second_cvlan_tag:1;
 581        /* The second vlan in the outer header of the packet is c-vlan (0x8100).
 582         * outer_second_cvlan_tag and outer_second_svlan_tag cannot be set together
 583         */
 584        u32 outer_second_cvlan_tag:1;
 585        u32 gre_key_l:8;                /* GRE Key [7:0] (outer) */
 586        u32 gre_key_h:24;               /* GRE Key[31:8] (outer) */
 587        u32 reserved_auto4:8;
 588        u32 vxlan_vni:24;               /* VXLAN VNI (outer) */
 589        u32 geneve_oam:1;               /* GENEVE OAM field (outer) */
 590        u32 reserved_auto5:7;
 591        u32 geneve_vni:24;              /* GENEVE VNI field (outer) */
 592        u32 outer_ipv6_flow_label:20;   /* Flow label of incoming IPv6 packet (outer) */
 593        u32 reserved_auto6:12;
 594        u32 inner_ipv6_flow_label:20;   /* Flow label of incoming IPv6 packet (inner) */
 595        u32 reserved_auto7:12;
 596        u32 geneve_protocol_type:16;    /* GENEVE protocol type (outer) */
 597        u32 geneve_opt_len:6;           /* GENEVE OptLen (outer) */
 598        u32 reserved_auto8:10;
 599        u32 bth_dst_qp:24;              /* Destination QP in BTH header */
 600        u32 reserved_auto9:8;
 601        u8 reserved_auto10[20];
 602};
 603
 604struct mlx5dr_match_misc2 {
 605        u32 outer_first_mpls_ttl:8;             /* First MPLS TTL (outer) */
 606        u32 outer_first_mpls_s_bos:1;           /* First MPLS S_BOS (outer) */
 607        u32 outer_first_mpls_exp:3;             /* First MPLS EXP (outer) */
 608        u32 outer_first_mpls_label:20;          /* First MPLS LABEL (outer) */
 609        u32 inner_first_mpls_ttl:8;             /* First MPLS TTL (inner) */
 610        u32 inner_first_mpls_s_bos:1;           /* First MPLS S_BOS (inner) */
 611        u32 inner_first_mpls_exp:3;             /* First MPLS EXP (inner) */
 612        u32 inner_first_mpls_label:20;          /* First MPLS LABEL (inner) */
 613        u32 outer_first_mpls_over_gre_ttl:8;    /* last MPLS TTL (outer) */
 614        u32 outer_first_mpls_over_gre_s_bos:1;  /* last MPLS S_BOS (outer) */
 615        u32 outer_first_mpls_over_gre_exp:3;    /* last MPLS EXP (outer) */
 616        u32 outer_first_mpls_over_gre_label:20; /* last MPLS LABEL (outer) */
 617        u32 outer_first_mpls_over_udp_ttl:8;    /* last MPLS TTL (outer) */
 618        u32 outer_first_mpls_over_udp_s_bos:1;  /* last MPLS S_BOS (outer) */
 619        u32 outer_first_mpls_over_udp_exp:3;    /* last MPLS EXP (outer) */
 620        u32 outer_first_mpls_over_udp_label:20; /* last MPLS LABEL (outer) */
 621        u32 metadata_reg_c_7;                   /* metadata_reg_c_7 */
 622        u32 metadata_reg_c_6;                   /* metadata_reg_c_6 */
 623        u32 metadata_reg_c_5;                   /* metadata_reg_c_5 */
 624        u32 metadata_reg_c_4;                   /* metadata_reg_c_4 */
 625        u32 metadata_reg_c_3;                   /* metadata_reg_c_3 */
 626        u32 metadata_reg_c_2;                   /* metadata_reg_c_2 */
 627        u32 metadata_reg_c_1;                   /* metadata_reg_c_1 */
 628        u32 metadata_reg_c_0;                   /* metadata_reg_c_0 */
 629        u32 metadata_reg_a;                     /* metadata_reg_a */
 630        u8 reserved_auto2[12];
 631};
 632
 633struct mlx5dr_match_misc3 {
 634        u32 inner_tcp_seq_num;
 635        u32 outer_tcp_seq_num;
 636        u32 inner_tcp_ack_num;
 637        u32 outer_tcp_ack_num;
 638        u32 outer_vxlan_gpe_vni:24;
 639        u32 reserved_auto1:8;
 640        u32 reserved_auto2:16;
 641        u32 outer_vxlan_gpe_flags:8;
 642        u32 outer_vxlan_gpe_next_protocol:8;
 643        u32 icmpv4_header_data;
 644        u32 icmpv6_header_data;
 645        u8 icmpv6_code;
 646        u8 icmpv6_type;
 647        u8 icmpv4_code;
 648        u8 icmpv4_type;
 649        u8 reserved_auto3[0x1c];
 650};
 651
 652struct mlx5dr_match_param {
 653        struct mlx5dr_match_spec outer;
 654        struct mlx5dr_match_misc misc;
 655        struct mlx5dr_match_spec inner;
 656        struct mlx5dr_match_misc2 misc2;
 657        struct mlx5dr_match_misc3 misc3;
 658};
 659
 660#define DR_MASK_IS_ICMPV4_SET(_misc3) ((_misc3)->icmpv4_type || \
 661                                       (_misc3)->icmpv4_code || \
 662                                       (_misc3)->icmpv4_header_data)
 663
 664struct mlx5dr_esw_caps {
 665        u64 drop_icm_address_rx;
 666        u64 drop_icm_address_tx;
 667        u64 uplink_icm_address_rx;
 668        u64 uplink_icm_address_tx;
 669        u8 sw_owner:1;
 670        u8 sw_owner_v2:1;
 671};
 672
 673struct mlx5dr_cmd_vport_cap {
 674        u16 vport_gvmi;
 675        u16 vhca_gvmi;
 676        u64 icm_address_rx;
 677        u64 icm_address_tx;
 678        u32 num;
 679};
 680
 681struct mlx5dr_cmd_caps {
 682        u16 gvmi;
 683        u64 nic_rx_drop_address;
 684        u64 nic_tx_drop_address;
 685        u64 nic_tx_allow_address;
 686        u64 esw_rx_drop_address;
 687        u64 esw_tx_drop_address;
 688        u32 log_icm_size;
 689        u64 hdr_modify_icm_addr;
 690        u32 flex_protocols;
 691        u8 flex_parser_id_icmp_dw0;
 692        u8 flex_parser_id_icmp_dw1;
 693        u8 flex_parser_id_icmpv6_dw0;
 694        u8 flex_parser_id_icmpv6_dw1;
 695        u8 max_ft_level;
 696        u16 roce_min_src_udp;
 697        u8 num_esw_ports;
 698        u8 sw_format_ver;
 699        bool eswitch_manager;
 700        bool rx_sw_owner;
 701        bool tx_sw_owner;
 702        bool fdb_sw_owner;
 703        u8 rx_sw_owner_v2:1;
 704        u8 tx_sw_owner_v2:1;
 705        u8 fdb_sw_owner_v2:1;
 706        u32 num_vports;
 707        struct mlx5dr_esw_caps esw_caps;
 708        struct mlx5dr_cmd_vport_cap *vports_caps;
 709        bool prio_tag_required;
 710};
 711
 712struct mlx5dr_domain_rx_tx {
 713        u64 drop_icm_addr;
 714        u64 default_icm_addr;
 715        enum mlx5dr_ste_entry_type ste_type;
 716        struct mutex mutex; /* protect rx/tx domain */
 717};
 718
 719struct mlx5dr_domain_info {
 720        bool supp_sw_steering;
 721        u32 max_inline_size;
 722        u32 max_send_wr;
 723        u32 max_log_sw_icm_sz;
 724        u32 max_log_action_icm_sz;
 725        struct mlx5dr_domain_rx_tx rx;
 726        struct mlx5dr_domain_rx_tx tx;
 727        struct mlx5dr_cmd_caps caps;
 728};
 729
 730struct mlx5dr_domain_cache {
 731        struct mlx5dr_fw_recalc_cs_ft **recalc_cs_ft;
 732};
 733
 734struct mlx5dr_domain {
 735        struct mlx5dr_domain *peer_dmn;
 736        struct mlx5_core_dev *mdev;
 737        u32 pdn;
 738        struct mlx5_uars_page *uar;
 739        enum mlx5dr_domain_type type;
 740        refcount_t refcount;
 741        struct mlx5dr_icm_pool *ste_icm_pool;
 742        struct mlx5dr_icm_pool *action_icm_pool;
 743        struct mlx5dr_send_ring *send_ring;
 744        struct mlx5dr_domain_info info;
 745        struct mlx5dr_domain_cache cache;
 746        struct mlx5dr_ste_ctx *ste_ctx;
 747};
 748
 749struct mlx5dr_table_rx_tx {
 750        struct mlx5dr_ste_htbl *s_anchor;
 751        struct mlx5dr_domain_rx_tx *nic_dmn;
 752        u64 default_icm_addr;
 753};
 754
 755struct mlx5dr_table {
 756        struct mlx5dr_domain *dmn;
 757        struct mlx5dr_table_rx_tx rx;
 758        struct mlx5dr_table_rx_tx tx;
 759        u32 level;
 760        u32 table_type;
 761        u32 table_id;
 762        u32 flags;
 763        struct list_head matcher_list;
 764        struct mlx5dr_action *miss_action;
 765        refcount_t refcount;
 766};
 767
 768struct mlx5dr_matcher_rx_tx {
 769        struct mlx5dr_ste_htbl *s_htbl;
 770        struct mlx5dr_ste_htbl *e_anchor;
 771        struct mlx5dr_ste_build *ste_builder;
 772        struct mlx5dr_ste_build ste_builder_arr[DR_RULE_IPV_MAX]
 773                                               [DR_RULE_IPV_MAX]
 774                                               [DR_RULE_MAX_STES];
 775        u8 num_of_builders;
 776        u8 num_of_builders_arr[DR_RULE_IPV_MAX][DR_RULE_IPV_MAX];
 777        u64 default_icm_addr;
 778        struct mlx5dr_table_rx_tx *nic_tbl;
 779};
 780
 781struct mlx5dr_matcher {
 782        struct mlx5dr_table *tbl;
 783        struct mlx5dr_matcher_rx_tx rx;
 784        struct mlx5dr_matcher_rx_tx tx;
 785        struct list_head matcher_list;
 786        u32 prio;
 787        struct mlx5dr_match_param mask;
 788        u8 match_criteria;
 789        refcount_t refcount;
 790        struct mlx5dv_flow_matcher *dv_matcher;
 791};
 792
 793struct mlx5dr_rule_member {
 794        struct mlx5dr_ste *ste;
 795        /* attached to mlx5dr_rule via this */
 796        struct list_head list;
 797        /* attached to mlx5dr_ste via this */
 798        struct list_head use_ste_list;
 799};
 800
 801struct mlx5dr_ste_action_modify_field {
 802        u16 hw_field;
 803        u8 start;
 804        u8 end;
 805        u8 l3_type;
 806        u8 l4_type;
 807};
 808
 809struct mlx5dr_action {
 810        enum mlx5dr_action_type action_type;
 811        refcount_t refcount;
 812        union {
 813                struct {
 814                        struct mlx5dr_domain *dmn;
 815                        struct mlx5dr_icm_chunk *chunk;
 816                        u8 *data;
 817                        u16 num_of_actions;
 818                        u32 index;
 819                        u8 allow_rx:1;
 820                        u8 allow_tx:1;
 821                        u8 modify_ttl:1;
 822                } rewrite;
 823                struct {
 824                        struct mlx5dr_domain *dmn;
 825                        u32 reformat_id;
 826                        u32 reformat_size;
 827                } reformat;
 828                struct {
 829                        u8 is_fw_tbl:1;
 830                        union {
 831                                struct mlx5dr_table *tbl;
 832                                struct {
 833                                        struct mlx5dr_domain *dmn;
 834                                        u32 id;
 835                                        u32 group_id;
 836                                        enum fs_flow_table_type type;
 837                                        u64 rx_icm_addr;
 838                                        u64 tx_icm_addr;
 839                                        struct mlx5dr_action **ref_actions;
 840                                        u32 num_of_ref_actions;
 841                                } fw_tbl;
 842                        };
 843                } dest_tbl;
 844                struct {
 845                        u32 ctr_id;
 846                        u32 offeset;
 847                } ctr;
 848                struct {
 849                        struct mlx5dr_domain *dmn;
 850                        struct mlx5dr_cmd_vport_cap *caps;
 851                } vport;
 852                struct {
 853                        u32 vlan_hdr; /* tpid_pcp_dei_vid */
 854                } push_vlan;
 855                u32 flow_tag;
 856        };
 857};
 858
 859enum mlx5dr_connect_type {
 860        CONNECT_HIT     = 1,
 861        CONNECT_MISS    = 2,
 862};
 863
 864struct mlx5dr_htbl_connect_info {
 865        enum mlx5dr_connect_type type;
 866        union {
 867                struct mlx5dr_ste_htbl *hit_next_htbl;
 868                u64 miss_icm_addr;
 869        };
 870};
 871
 872struct mlx5dr_rule_rx_tx {
 873        struct list_head rule_members_list;
 874        struct mlx5dr_matcher_rx_tx *nic_matcher;
 875};
 876
 877struct mlx5dr_rule {
 878        struct mlx5dr_matcher *matcher;
 879        struct mlx5dr_rule_rx_tx rx;
 880        struct mlx5dr_rule_rx_tx tx;
 881        struct list_head rule_actions_list;
 882        u32 flow_source;
 883};
 884
 885void mlx5dr_rule_update_rule_member(struct mlx5dr_ste *new_ste,
 886                                    struct mlx5dr_ste *ste);
 887
 888struct mlx5dr_icm_chunk {
 889        struct mlx5dr_icm_buddy_mem *buddy_mem;
 890        struct list_head chunk_list;
 891        u32 rkey;
 892        u32 num_of_entries;
 893        u32 byte_size;
 894        u64 icm_addr;
 895        u64 mr_addr;
 896
 897        /* indicates the index of this chunk in the whole memory,
 898         * used for deleting the chunk from the buddy
 899         */
 900        unsigned int seg;
 901
 902        /* Memory optimisation */
 903        struct mlx5dr_ste *ste_arr;
 904        u8 *hw_ste_arr;
 905        struct list_head *miss_list;
 906};
 907
 908static inline void mlx5dr_domain_nic_lock(struct mlx5dr_domain_rx_tx *nic_dmn)
 909{
 910        mutex_lock(&nic_dmn->mutex);
 911}
 912
 913static inline void mlx5dr_domain_nic_unlock(struct mlx5dr_domain_rx_tx *nic_dmn)
 914{
 915        mutex_unlock(&nic_dmn->mutex);
 916}
 917
 918static inline void mlx5dr_domain_lock(struct mlx5dr_domain *dmn)
 919{
 920        mlx5dr_domain_nic_lock(&dmn->info.rx);
 921        mlx5dr_domain_nic_lock(&dmn->info.tx);
 922}
 923
 924static inline void mlx5dr_domain_unlock(struct mlx5dr_domain *dmn)
 925{
 926        mlx5dr_domain_nic_unlock(&dmn->info.tx);
 927        mlx5dr_domain_nic_unlock(&dmn->info.rx);
 928}
 929
 930int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher,
 931                                   struct mlx5dr_matcher_rx_tx *nic_matcher,
 932                                   enum mlx5dr_ipv outer_ipv,
 933                                   enum mlx5dr_ipv inner_ipv);
 934
 935static inline int
 936mlx5dr_icm_pool_dm_type_to_entry_size(enum mlx5dr_icm_type icm_type)
 937{
 938        if (icm_type == DR_ICM_TYPE_STE)
 939                return DR_STE_SIZE;
 940
 941        return DR_MODIFY_ACTION_SIZE;
 942}
 943
 944static inline u32
 945mlx5dr_icm_pool_chunk_size_to_entries(enum mlx5dr_icm_chunk_size chunk_size)
 946{
 947        return 1 << chunk_size;
 948}
 949
 950static inline int
 951mlx5dr_icm_pool_chunk_size_to_byte(enum mlx5dr_icm_chunk_size chunk_size,
 952                                   enum mlx5dr_icm_type icm_type)
 953{
 954        int num_of_entries;
 955        int entry_size;
 956
 957        entry_size = mlx5dr_icm_pool_dm_type_to_entry_size(icm_type);
 958        num_of_entries = mlx5dr_icm_pool_chunk_size_to_entries(chunk_size);
 959
 960        return entry_size * num_of_entries;
 961}
 962
 963static inline struct mlx5dr_cmd_vport_cap *
 964mlx5dr_get_vport_cap(struct mlx5dr_cmd_caps *caps, u32 vport)
 965{
 966        if (!caps->vports_caps ||
 967            (vport >= caps->num_vports && vport != WIRE_PORT))
 968                return NULL;
 969
 970        if (vport == WIRE_PORT)
 971                vport = caps->num_vports;
 972
 973        return &caps->vports_caps[vport];
 974}
 975
 976struct mlx5dr_cmd_query_flow_table_details {
 977        u8 status;
 978        u8 level;
 979        u64 sw_owner_icm_root_1;
 980        u64 sw_owner_icm_root_0;
 981};
 982
 983struct mlx5dr_cmd_create_flow_table_attr {
 984        u32 table_type;
 985        u64 icm_addr_rx;
 986        u64 icm_addr_tx;
 987        u8 level;
 988        bool sw_owner;
 989        bool term_tbl;
 990        bool decap_en;
 991        bool reformat_en;
 992};
 993
 994/* internal API functions */
 995int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev,
 996                            struct mlx5dr_cmd_caps *caps);
 997int mlx5dr_cmd_query_esw_vport_context(struct mlx5_core_dev *mdev,
 998                                       bool other_vport, u16 vport_number,
 999                                       u64 *icm_address_rx,
1000                                       u64 *icm_address_tx);
1001int mlx5dr_cmd_query_gvmi(struct mlx5_core_dev *mdev,
1002                          bool other_vport, u16 vport_number, u16 *gvmi);
1003int mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev *mdev,
1004                              struct mlx5dr_esw_caps *caps);
1005int mlx5dr_cmd_sync_steering(struct mlx5_core_dev *mdev);
1006int mlx5dr_cmd_set_fte_modify_and_vport(struct mlx5_core_dev *mdev,
1007                                        u32 table_type,
1008                                        u32 table_id,
1009                                        u32 group_id,
1010                                        u32 modify_header_id,
1011                                        u32 vport_id);
1012int mlx5dr_cmd_del_flow_table_entry(struct mlx5_core_dev *mdev,
1013                                    u32 table_type,
1014                                    u32 table_id);
1015int mlx5dr_cmd_alloc_modify_header(struct mlx5_core_dev *mdev,
1016                                   u32 table_type,
1017                                   u8 num_of_actions,
1018                                   u64 *actions,
1019                                   u32 *modify_header_id);
1020int mlx5dr_cmd_dealloc_modify_header(struct mlx5_core_dev *mdev,
1021                                     u32 modify_header_id);
1022int mlx5dr_cmd_create_empty_flow_group(struct mlx5_core_dev *mdev,
1023                                       u32 table_type,
1024                                       u32 table_id,
1025                                       u32 *group_id);
1026int mlx5dr_cmd_destroy_flow_group(struct mlx5_core_dev *mdev,
1027                                  u32 table_type,
1028                                  u32 table_id,
1029                                  u32 group_id);
1030int mlx5dr_cmd_create_flow_table(struct mlx5_core_dev *mdev,
1031                                 struct mlx5dr_cmd_create_flow_table_attr *attr,
1032                                 u64 *fdb_rx_icm_addr,
1033                                 u32 *table_id);
1034int mlx5dr_cmd_destroy_flow_table(struct mlx5_core_dev *mdev,
1035                                  u32 table_id,
1036                                  u32 table_type);
1037int mlx5dr_cmd_query_flow_table(struct mlx5_core_dev *dev,
1038                                enum fs_flow_table_type type,
1039                                u32 table_id,
1040                                struct mlx5dr_cmd_query_flow_table_details *output);
1041int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev,
1042                                   enum mlx5_reformat_ctx_type rt,
1043                                   size_t reformat_size,
1044                                   void *reformat_data,
1045                                   u32 *reformat_id);
1046void mlx5dr_cmd_destroy_reformat_ctx(struct mlx5_core_dev *mdev,
1047                                     u32 reformat_id);
1048
1049struct mlx5dr_cmd_gid_attr {
1050        u8 gid[16];
1051        u8 mac[6];
1052        u32 roce_ver;
1053};
1054
1055struct mlx5dr_cmd_qp_create_attr {
1056        u32 page_id;
1057        u32 pdn;
1058        u32 cqn;
1059        u32 pm_state;
1060        u32 service_type;
1061        u32 buff_umem_id;
1062        u32 db_umem_id;
1063        u32 sq_wqe_cnt;
1064        u32 rq_wqe_cnt;
1065        u32 rq_wqe_shift;
1066};
1067
1068int mlx5dr_cmd_query_gid(struct mlx5_core_dev *mdev, u8 vhca_port_num,
1069                         u16 index, struct mlx5dr_cmd_gid_attr *attr);
1070
1071struct mlx5dr_icm_pool *mlx5dr_icm_pool_create(struct mlx5dr_domain *dmn,
1072                                               enum mlx5dr_icm_type icm_type);
1073void mlx5dr_icm_pool_destroy(struct mlx5dr_icm_pool *pool);
1074
1075struct mlx5dr_icm_chunk *
1076mlx5dr_icm_alloc_chunk(struct mlx5dr_icm_pool *pool,
1077                       enum mlx5dr_icm_chunk_size chunk_size);
1078void mlx5dr_icm_free_chunk(struct mlx5dr_icm_chunk *chunk);
1079
1080void mlx5dr_ste_prepare_for_postsend(struct mlx5dr_ste_ctx *ste_ctx,
1081                                     u8 *hw_ste_p, u32 ste_size);
1082int mlx5dr_ste_htbl_init_and_postsend(struct mlx5dr_domain *dmn,
1083                                      struct mlx5dr_domain_rx_tx *nic_dmn,
1084                                      struct mlx5dr_ste_htbl *htbl,
1085                                      struct mlx5dr_htbl_connect_info *connect_info,
1086                                      bool update_hw_ste);
1087void mlx5dr_ste_set_formatted_ste(struct mlx5dr_ste_ctx *ste_ctx,
1088                                  u16 gvmi,
1089                                  struct mlx5dr_domain_rx_tx *nic_dmn,
1090                                  struct mlx5dr_ste_htbl *htbl,
1091                                  u8 *formatted_ste,
1092                                  struct mlx5dr_htbl_connect_info *connect_info);
1093void mlx5dr_ste_copy_param(u8 match_criteria,
1094                           struct mlx5dr_match_param *set_param,
1095                           struct mlx5dr_match_parameters *mask);
1096
1097struct mlx5dr_qp {
1098        struct mlx5_core_dev *mdev;
1099        struct mlx5_wq_qp wq;
1100        struct mlx5_uars_page *uar;
1101        struct mlx5_wq_ctrl wq_ctrl;
1102        u32 qpn;
1103        struct {
1104                unsigned int pc;
1105                unsigned int cc;
1106                unsigned int size;
1107                unsigned int *wqe_head;
1108                unsigned int wqe_cnt;
1109        } sq;
1110        struct {
1111                unsigned int pc;
1112                unsigned int cc;
1113                unsigned int size;
1114                unsigned int wqe_cnt;
1115        } rq;
1116        int max_inline_data;
1117};
1118
1119struct mlx5dr_cq {
1120        struct mlx5_core_dev *mdev;
1121        struct mlx5_cqwq wq;
1122        struct mlx5_wq_ctrl wq_ctrl;
1123        struct mlx5_core_cq mcq;
1124        struct mlx5dr_qp *qp;
1125};
1126
1127struct mlx5dr_mr {
1128        struct mlx5_core_dev *mdev;
1129        struct mlx5_core_mkey mkey;
1130        dma_addr_t dma_addr;
1131        void *addr;
1132        size_t size;
1133};
1134
1135#define MAX_SEND_CQE            64
1136#define MIN_READ_SYNC           64
1137
1138struct mlx5dr_send_ring {
1139        struct mlx5dr_cq *cq;
1140        struct mlx5dr_qp *qp;
1141        struct mlx5dr_mr *mr;
1142        /* How much wqes are waiting for completion */
1143        u32 pending_wqe;
1144        /* Signal request per this trash hold value */
1145        u16 signal_th;
1146        /* Each post_send_size less than max_post_send_size */
1147        u32 max_post_send_size;
1148        /* manage the send queue */
1149        u32 tx_head;
1150        void *buf;
1151        u32 buf_size;
1152        struct ib_wc wc[MAX_SEND_CQE];
1153        u8 sync_buff[MIN_READ_SYNC];
1154        struct mlx5dr_mr *sync_mr;
1155        spinlock_t lock; /* Protect the data path of the send ring */
1156};
1157
1158int mlx5dr_send_ring_alloc(struct mlx5dr_domain *dmn);
1159void mlx5dr_send_ring_free(struct mlx5dr_domain *dmn,
1160                           struct mlx5dr_send_ring *send_ring);
1161int mlx5dr_send_ring_force_drain(struct mlx5dr_domain *dmn);
1162int mlx5dr_send_postsend_ste(struct mlx5dr_domain *dmn,
1163                             struct mlx5dr_ste *ste,
1164                             u8 *data,
1165                             u16 size,
1166                             u16 offset);
1167int mlx5dr_send_postsend_htbl(struct mlx5dr_domain *dmn,
1168                              struct mlx5dr_ste_htbl *htbl,
1169                              u8 *formatted_ste, u8 *mask);
1170int mlx5dr_send_postsend_formatted_htbl(struct mlx5dr_domain *dmn,
1171                                        struct mlx5dr_ste_htbl *htbl,
1172                                        u8 *ste_init_data,
1173                                        bool update_hw_ste);
1174int mlx5dr_send_postsend_action(struct mlx5dr_domain *dmn,
1175                                struct mlx5dr_action *action);
1176
1177struct mlx5dr_cmd_ft_info {
1178        u32 id;
1179        u16 vport;
1180        enum fs_flow_table_type type;
1181};
1182
1183struct mlx5dr_cmd_flow_destination_hw_info {
1184        enum mlx5_flow_destination_type type;
1185        union {
1186                u32 tir_num;
1187                u32 ft_num;
1188                u32 ft_id;
1189                u32 counter_id;
1190                struct {
1191                        u16 num;
1192                        u16 vhca_id;
1193                        u32 reformat_id;
1194                        u8 flags;
1195                } vport;
1196        };
1197};
1198
1199struct mlx5dr_cmd_fte_info {
1200        u32 dests_size;
1201        u32 index;
1202        struct mlx5_flow_context flow_context;
1203        u32 *val;
1204        struct mlx5_flow_act action;
1205        struct mlx5dr_cmd_flow_destination_hw_info *dest_arr;
1206};
1207
1208int mlx5dr_cmd_set_fte(struct mlx5_core_dev *dev,
1209                       int opmod, int modify_mask,
1210                       struct mlx5dr_cmd_ft_info *ft,
1211                       u32 group_id,
1212                       struct mlx5dr_cmd_fte_info *fte);
1213
1214bool mlx5dr_ste_supp_ttl_cs_recalc(struct mlx5dr_cmd_caps *caps);
1215
1216struct mlx5dr_fw_recalc_cs_ft {
1217        u64 rx_icm_addr;
1218        u32 table_id;
1219        u32 group_id;
1220        u32 modify_hdr_id;
1221};
1222
1223struct mlx5dr_fw_recalc_cs_ft *
1224mlx5dr_fw_create_recalc_cs_ft(struct mlx5dr_domain *dmn, u32 vport_num);
1225void mlx5dr_fw_destroy_recalc_cs_ft(struct mlx5dr_domain *dmn,
1226                                    struct mlx5dr_fw_recalc_cs_ft *recalc_cs_ft);
1227int mlx5dr_domain_cache_get_recalc_cs_ft_addr(struct mlx5dr_domain *dmn,
1228                                              u32 vport_num,
1229                                              u64 *rx_icm_addr);
1230int mlx5dr_fw_create_md_tbl(struct mlx5dr_domain *dmn,
1231                            struct mlx5dr_cmd_flow_destination_hw_info *dest,
1232                            int num_dest,
1233                            bool reformat_req,
1234                            u32 *tbl_id,
1235                            u32 *group_id);
1236void mlx5dr_fw_destroy_md_tbl(struct mlx5dr_domain *dmn, u32 tbl_id,
1237                              u32 group_id);
1238#endif  /* _DR_TYPES_H_ */
1239