Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2019, Mellanox Technologies */

#ifndef	_DR_TYPES_
#define	_DR_TYPES_

#include <linux/mlx5/driver.h>
#include <linux/refcount.h>
#include "fs_core.h"
#include "wq.h"
#include "lib/mlx5.h"
#include "mlx5_ifc_dr.h"
#include "mlx5dr.h"

#define DR_RULE_MAX_STES 17
#define DR_ACTION_MAX_STES 5
#define WIRE_PORT 0xFFFF
#define DR_STE_SVLAN 0x1
#define DR_STE_CVLAN 0x2

#define mlx5dr_err(dmn, arg...) mlx5_core_err((dmn)->mdev, ##arg)
#define mlx5dr_info(dmn, arg...) mlx5_core_info((dmn)->mdev, ##arg)
#define mlx5dr_dbg(dmn, arg...) mlx5_core_dbg((dmn)->mdev, ##arg)

enum mlx5dr_icm_chunk_size {
	DR_CHUNK_SIZE_1,
	DR_CHUNK_SIZE_MIN = DR_CHUNK_SIZE_1, /* keep updated when changing */
	DR_CHUNK_SIZE_2,
	DR_CHUNK_SIZE_4,
	DR_CHUNK_SIZE_8,
	DR_CHUNK_SIZE_16,
	DR_CHUNK_SIZE_32,
	DR_CHUNK_SIZE_64,
	DR_CHUNK_SIZE_128,
	DR_CHUNK_SIZE_256,
	DR_CHUNK_SIZE_512,
	DR_CHUNK_SIZE_1K,
	DR_CHUNK_SIZE_2K,
	DR_CHUNK_SIZE_4K,
	DR_CHUNK_SIZE_8K,
	DR_CHUNK_SIZE_16K,
	DR_CHUNK_SIZE_32K,
	DR_CHUNK_SIZE_64K,
	DR_CHUNK_SIZE_128K,
	DR_CHUNK_SIZE_256K,
	DR_CHUNK_SIZE_512K,
	DR_CHUNK_SIZE_1024K,
	DR_CHUNK_SIZE_2048K,
	DR_CHUNK_SIZE_MAX,
};

enum mlx5dr_icm_type {
	DR_ICM_TYPE_STE,
	DR_ICM_TYPE_MODIFY_ACTION,
};

static inline enum mlx5dr_icm_chunk_size
mlx5dr_icm_next_higher_chunk(enum mlx5dr_icm_chunk_size chunk)
{
	chunk += 2;
	if (chunk < DR_CHUNK_SIZE_MAX)
		return chunk;

	return DR_CHUNK_SIZE_MAX;
}

enum {
	DR_STE_SIZE = 64,
	DR_STE_SIZE_CTRL = 32,
	DR_STE_SIZE_TAG = 16,
	DR_STE_SIZE_MASK = 16,
};

enum {
	DR_STE_SIZE_REDUCED = DR_STE_SIZE - DR_STE_SIZE_MASK,
};

enum {
	DR_MODIFY_ACTION_SIZE = 8,
};

enum mlx5dr_matcher_criteria {
	DR_MATCHER_CRITERIA_EMPTY = 0,
	DR_MATCHER_CRITERIA_OUTER = 1 << 0,
	DR_MATCHER_CRITERIA_MISC = 1 << 1,
	DR_MATCHER_CRITERIA_INNER = 1 << 2,
	DR_MATCHER_CRITERIA_MISC2 = 1 << 3,
	DR_MATCHER_CRITERIA_MISC3 = 1 << 4,
	DR_MATCHER_CRITERIA_MAX = 1 << 5,
};

enum mlx5dr_action_type {
	DR_ACTION_TYP_TNL_L2_TO_L2,
	DR_ACTION_TYP_L2_TO_TNL_L2,
	DR_ACTION_TYP_TNL_L3_TO_L2,
	DR_ACTION_TYP_L2_TO_TNL_L3,
	DR_ACTION_TYP_DROP,
	DR_ACTION_TYP_QP,
	DR_ACTION_TYP_FT,
	DR_ACTION_TYP_CTR,
	DR_ACTION_TYP_TAG,
	DR_ACTION_TYP_MODIFY_HDR,
	DR_ACTION_TYP_VPORT,
	DR_ACTION_TYP_POP_VLAN,
	DR_ACTION_TYP_PUSH_VLAN,
	DR_ACTION_TYP_MAX,
};

struct mlx5dr_icm_pool;
struct mlx5dr_icm_chunk;
struct mlx5dr_icm_bucket;
struct mlx5dr_ste_htbl;
struct mlx5dr_match_param;
struct mlx5dr_cmd_caps;
struct mlx5dr_matcher_rx_tx;

struct mlx5dr_ste {
	u8 *hw_ste;
	/* refcount: indicates the num of rules that using this ste */
	refcount_t refcount;

	/* attached to the miss_list head at each htbl entry */
	struct list_head miss_list_node;

	/* each rule member that uses this ste attached here */
	struct list_head rule_list;

	/* this ste is member of htbl */
	struct mlx5dr_ste_htbl *htbl;

	struct mlx5dr_ste_htbl *next_htbl;

	/* this ste is part of a rule, located in ste's chain */
	u8 ste_chain_location;
};

struct mlx5dr_ste_htbl_ctrl {
	/* total number of valid entries belonging to this hash table. This
	 * includes the non collision and collision entries
	 */
	unsigned int num_of_valid_entries;

	/* total number of collisions entries attached to this table */
	unsigned int num_of_collisions;
	unsigned int increase_threshold;
	u8 may_grow:1;
};

struct mlx5dr_ste_htbl {
	u8 lu_type;
	u16 byte_mask;
	refcount_t refcount;
	struct mlx5dr_icm_chunk *chunk;
	struct mlx5dr_ste *ste_arr;
	u8 *hw_ste_arr;

	struct list_head *miss_list;

	enum mlx5dr_icm_chunk_size chunk_size;
	struct mlx5dr_ste *pointing_ste;

	struct mlx5dr_ste_htbl_ctrl ctrl;
};

struct mlx5dr_ste_send_info {
	struct mlx5dr_ste *ste;
	struct list_head send_list;
	u16 size;
	u16 offset;
	u8 data_cont[DR_STE_SIZE];
	u8 *data;
};

void mlx5dr_send_fill_and_append_ste_send_info(struct mlx5dr_ste *ste, u16 size,
					       u16 offset, u8 *data,
					       struct mlx5dr_ste_send_info *ste_info,
					       struct list_head *send_list,
					       bool copy_data);

struct mlx5dr_ste_build {
	u8 inner:1;
	u8 rx:1;
	u8 vhca_id_valid:1;
	struct mlx5dr_domain *dmn;
	struct mlx5dr_cmd_caps *caps;
	u8 lu_type;
	u16 byte_mask;
	u8 bit_mask[DR_STE_SIZE_MASK];
	int (*ste_build_tag_func)(struct mlx5dr_match_param *spec,
				  struct mlx5dr_ste_build *sb,
				  u8 *hw_ste_p);
};

struct mlx5dr_ste_htbl *
mlx5dr_ste_htbl_alloc(struct mlx5dr_icm_pool *pool,
		      enum mlx5dr_icm_chunk_size chunk_size,
		      u8 lu_type, u16 byte_mask);

int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl);

static inline void mlx5dr_htbl_put(struct mlx5dr_ste_htbl *htbl)
{
	if (refcount_dec_and_test(&htbl->refcount))
		mlx5dr_ste_htbl_free(htbl);
}

static inline void mlx5dr_htbl_get(struct mlx5dr_ste_htbl *htbl)
{
	refcount_inc(&htbl->refcount);
}

/* STE utils */
u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl);
void mlx5dr_ste_init(u8 *hw_ste_p, u8 lu_type, u8 entry_type, u16 gvmi);
void mlx5dr_ste_always_hit_htbl(struct mlx5dr_ste *ste,
				struct mlx5dr_ste_htbl *next_htbl);
void mlx5dr_ste_set_miss_addr(u8 *hw_ste, u64 miss_addr);
u64 mlx5dr_ste_get_miss_addr(u8 *hw_ste);
void mlx5dr_ste_set_hit_gvmi(u8 *hw_ste_p, u16 gvmi);
void mlx5dr_ste_set_hit_addr(u8 *hw_ste, u64 icm_addr, u32 ht_size);
void mlx5dr_ste_always_miss_addr(struct mlx5dr_ste *ste, u64 miss_addr);
void mlx5dr_ste_set_bit_mask(u8 *hw_ste_p, u8 *bit_mask);
bool mlx5dr_ste_not_used_ste(struct mlx5dr_ste *ste);
bool mlx5dr_ste_is_last_in_rule(struct mlx5dr_matcher_rx_tx *nic_matcher,
				u8 ste_location);
void mlx5dr_ste_rx_set_flow_tag(u8 *hw_ste_p, u32 flow_tag);
void mlx5dr_ste_set_counter_id(u8 *hw_ste_p, u32 ctr_id);
void mlx5dr_ste_set_tx_encap(void *hw_ste_p, u32 reformat_id,
			     int size, bool encap_l3);
void mlx5dr_ste_set_rx_decap(u8 *hw_ste_p);
void mlx5dr_ste_set_rx_decap_l3(u8 *hw_ste_p, bool vlan);
void mlx5dr_ste_set_rx_pop_vlan(u8 *hw_ste_p);
void mlx5dr_ste_set_tx_push_vlan(u8 *hw_ste_p, u32 vlan_tpid_pcp_dei_vid,
				 bool go_back);
void mlx5dr_ste_set_entry_type(u8 *hw_ste_p, u8 entry_type);
u8 mlx5dr_ste_get_entry_type(u8 *hw_ste_p);
void mlx5dr_ste_set_rewrite_actions(u8 *hw_ste_p, u16 num_of_actions,
				    u32 re_write_index);
void mlx5dr_ste_set_go_back_bit(u8 *hw_ste_p);
u64 mlx5dr_ste_get_icm_addr(struct mlx5dr_ste *ste);
u64 mlx5dr_ste_get_mr_addr(struct mlx5dr_ste *ste);
struct list_head *mlx5dr_ste_get_miss_list(struct mlx5dr_ste *ste);

void mlx5dr_ste_free(struct mlx5dr_ste *ste,
		     struct mlx5dr_matcher *matcher,
		     struct mlx5dr_matcher_rx_tx *nic_matcher);
static inline void mlx5dr_ste_put(struct mlx5dr_ste *ste,
				  struct mlx5dr_matcher *matcher,
				  struct mlx5dr_matcher_rx_tx *nic_matcher)
{
	if (refcount_dec_and_test(&ste->refcount))
		mlx5dr_ste_free(ste, matcher, nic_matcher);
}

/* initial as 0, increased only when ste appears in a new rule */
static inline void mlx5dr_ste_get(struct mlx5dr_ste *ste)
{
	refcount_inc(&ste->refcount);
}

void mlx5dr_ste_set_hit_addr_by_next_htbl(u8 *hw_ste,
					  struct mlx5dr_ste_htbl *next_htbl);
bool mlx5dr_ste_equal_tag(void *src, void *dst);
int mlx5dr_ste_create_next_htbl(struct mlx5dr_matcher *matcher,
				struct mlx5dr_matcher_rx_tx *nic_matcher,
				struct mlx5dr_ste *ste,
				u8 *cur_hw_ste,
				enum mlx5dr_icm_chunk_size log_table_size);

/* STE build functions */
int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
			       u8 match_criteria,
			       struct mlx5dr_match_param *mask,
			       struct mlx5dr_match_param *value);
int mlx5dr_ste_build_ste_arr(struct mlx5dr_matcher *matcher,
			     struct mlx5dr_matcher_rx_tx *nic_matcher,
			     struct mlx5dr_match_param *value,
			     u8 *ste_arr);
int mlx5dr_ste_build_eth_l2_src_des(struct mlx5dr_ste_build *builder,
				    struct mlx5dr_match_param *mask,
				    bool inner, bool rx);
void mlx5dr_ste_build_eth_l3_ipv4_5_tuple(struct mlx5dr_ste_build *sb,
					  struct mlx5dr_match_param *mask,
					  bool inner, bool rx);
void mlx5dr_ste_build_eth_l3_ipv4_misc(struct mlx5dr_ste_build *sb,
				       struct mlx5dr_match_param *mask,
				       bool inner, bool rx);
void mlx5dr_ste_build_eth_l3_ipv6_dst(struct mlx5dr_ste_build *sb,
				      struct mlx5dr_match_param *mask,
				      bool inner, bool rx);
void mlx5dr_ste_build_eth_l3_ipv6_src(struct mlx5dr_ste_build *sb,
				      struct mlx5dr_match_param *mask,
				      bool inner, bool rx);
void mlx5dr_ste_build_eth_l2_src(struct mlx5dr_ste_build *sb,
				 struct mlx5dr_match_param *mask,
				 bool inner, bool rx);
void mlx5dr_ste_build_eth_l2_dst(struct mlx5dr_ste_build *sb,
				 struct mlx5dr_match_param *mask,
				 bool inner, bool rx);
void mlx5dr_ste_build_eth_l2_tnl(struct mlx5dr_ste_build *sb,
				 struct mlx5dr_match_param *mask,
				 bool inner, bool rx);
void mlx5dr_ste_build_ipv6_l3_l4(struct mlx5dr_ste_build *sb,
				 struct mlx5dr_match_param *mask,
				 bool inner, bool rx);
void mlx5dr_ste_build_eth_l4_misc(struct mlx5dr_ste_build *sb,
				  struct mlx5dr_match_param *mask,
				  bool inner, bool rx);
void mlx5dr_ste_build_gre(struct mlx5dr_ste_build *sb,
			  struct mlx5dr_match_param *mask,
			  bool inner, bool rx);
void mlx5dr_ste_build_mpls(struct mlx5dr_ste_build *sb,
			   struct mlx5dr_match_param *mask,
			   bool inner, bool rx);
void mlx5dr_ste_build_flex_parser_0(struct mlx5dr_ste_build *sb,
				    struct mlx5dr_match_param *mask,
				    bool inner, bool rx);
int mlx5dr_ste_build_flex_parser_1(struct mlx5dr_ste_build *sb,
				   struct mlx5dr_match_param *mask,
				   struct mlx5dr_cmd_caps *caps,
				   bool inner, bool rx);
void mlx5dr_ste_build_flex_parser_tnl(struct mlx5dr_ste_build *sb,
				      struct mlx5dr_match_param *mask,
				      bool inner, bool rx);
void mlx5dr_ste_build_general_purpose(struct mlx5dr_ste_build *sb,
				      struct mlx5dr_match_param *mask,
				      bool inner, bool rx);
void mlx5dr_ste_build_register_0(struct mlx5dr_ste_build *sb,
				 struct mlx5dr_match_param *mask,
				 bool inner, bool rx);
void mlx5dr_ste_build_register_1(struct mlx5dr_ste_build *sb,
				 struct mlx5dr_match_param *mask,
				 bool inner, bool rx);
int mlx5dr_ste_build_src_gvmi_qpn(struct mlx5dr_ste_build *sb,
				  struct mlx5dr_match_param *mask,
				  struct mlx5dr_domain *dmn,
				  bool inner, bool rx);
void mlx5dr_ste_build_empty_always_hit(struct mlx5dr_ste_build *sb, bool rx);

/* Actions utils */
int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher,
				 struct mlx5dr_matcher_rx_tx *nic_matcher,
				 struct mlx5dr_action *actions[],
				 u32 num_actions,
				 u8 *ste_arr,
				 u32 *new_hw_ste_arr_sz);

struct mlx5dr_match_spec {
	u32 smac_47_16;		/* Source MAC address of incoming packet */
	/* Incoming packet Ethertype - this is the Ethertype
	 * following the last VLAN tag of the packet
	 */
	u32 ethertype:16;
	u32 smac_15_0:16;	/* Source MAC address of incoming packet */
	u32 dmac_47_16;		/* Destination MAC address of incoming packet */
	/* VLAN ID of first VLAN tag in the incoming packet.
	 * Valid only when cvlan_tag==1 or svlan_tag==1
	 */
	u32 first_vid:12;
	/* CFI bit of first VLAN tag in the incoming packet.
	 * Valid only when cvlan_tag==1 or svlan_tag==1
	 */
	u32 first_cfi:1;
	/* Priority of first VLAN tag in the incoming packet.
	 * Valid only when cvlan_tag==1 or svlan_tag==1
	 */
	u32 first_prio:3;
	u32 dmac_15_0:16;	/* Destination MAC address of incoming packet */
	/* TCP flags. ;Bit 0: FIN;Bit 1: SYN;Bit 2: RST;Bit 3: PSH;Bit 4: ACK;
	 *             Bit 5: URG;Bit 6: ECE;Bit 7: CWR;Bit 8: NS
	 */
	u32 tcp_flags:9;
	u32 ip_version:4;	/* IP version */
	u32 frag:1;		/* Packet is an IP fragment */
	/* The first vlan in the packet is s-vlan (0x8a88).
	 * cvlan_tag and svlan_tag cannot be set together
	 */
	u32 svlan_tag:1;
	/* The first vlan in the packet is c-vlan (0x8100).
	 * cvlan_tag and svlan_tag cannot be set together
	 */
	u32 cvlan_tag:1;
	/* Explicit Congestion Notification derived from
	 * Traffic Class/TOS field of IPv6/v4
	 */
	u32 ip_ecn:2;
	/* Differentiated Services Code Point derived from
	 * Traffic Class/TOS field of IPv6/v4
	 */
	u32 ip_dscp:6;
	u32 ip_protocol:8;	/* IP protocol */
	/* TCP destination port.
	 * tcp and udp sport/dport are mutually exclusive
	 */
	u32 tcp_dport:16;
	/* TCP source port.;tcp and udp sport/dport are mutually exclusive */
	u32 tcp_sport:16;
	u32 ttl_hoplimit:8;
	u32 reserved:24;
	/* UDP destination port.;tcp and udp sport/dport are mutually exclusive */
	u32 udp_dport:16;
	/* UDP source port.;tcp and udp sport/dport are mutually exclusive */
	u32 udp_sport:16;
	/* IPv6 source address of incoming packets
	 * For IPv4 address use bits 31:0 (rest of the bits are reserved)
	 * This field should be qualified by an appropriate ethertype
	 */
	u32 src_ip_127_96;
	/* IPv6 source address of incoming packets
	 * For IPv4 address use bits 31:0 (rest of the bits are reserved)
	 * This field should be qualified by an appropriate ethertype
	 */
	u32 src_ip_95_64;
	/* IPv6 source address of incoming packets
	 * For IPv4 address use bits 31:0 (rest of the bits are reserved)
	 * This field should be qualified by an appropriate ethertype
	 */
	u32 src_ip_63_32;
	/* IPv6 source address of incoming packets
	 * For IPv4 address use bits 31:0 (rest of the bits are reserved)
	 * This field should be qualified by an appropriate ethertype
	 */
	u32 src_ip_31_0;
	/* IPv6 destination address of incoming packets
	 * For IPv4 address use bits 31:0 (rest of the bits are reserved)
	 * This field should be qualified by an appropriate ethertype
	 */
	u32 dst_ip_127_96;
	/* IPv6 destination address of incoming packets
	 * For IPv4 address use bits 31:0 (rest of the bits are reserved)
	 * This field should be qualified by an appropriate ethertype
	 */
	u32 dst_ip_95_64;
	/* IPv6 destination address of incoming packets
	 * For IPv4 address use bits 31:0 (rest of the bits are reserved)
	 * This field should be qualified by an appropriate ethertype
	 */
	u32 dst_ip_63_32;
	/* IPv6 destination address of incoming packets
	 * For IPv4 address use bits 31:0 (rest of the bits are reserved)
	 * This field should be qualified by an appropriate ethertype
	 */
	u32 dst_ip_31_0;
};

struct mlx5dr_match_misc {
	u32 source_sqn:24;		/* Source SQN */
	u32 source_vhca_port:4;
	/* used with GRE, sequence number exist when gre_s_present == 1 */
	u32 gre_s_present:1;
	/* used with GRE, key exist when gre_k_present == 1 */
	u32 gre_k_present:1;
	u32 reserved_auto1:1;
	/* used with GRE, checksum exist when gre_c_present == 1 */
	u32 gre_c_present:1;
	/* Source port.;0xffff determines wire port */
	u32 source_port:16;
	u32 source_eswitch_owner_vhca_id:16;
	/* VLAN ID of first VLAN tag the inner header of the incoming packet.
	 * Valid only when inner_second_cvlan_tag ==1 or inner_second_svlan_tag ==1
	 */
	u32 inner_second_vid:12;
	/* CFI bit of first VLAN tag in the inner header of the incoming packet.
	 * Valid only when inner_second_cvlan_tag ==1 or inner_second_svlan_tag ==1
	 */
	u32 inner_second_cfi:1;
	/* Priority of second VLAN tag in the inner header of the incoming packet.
	 * Valid only when inner_second_cvlan_tag ==1 or inner_second_svlan_tag ==1
	 */
	u32 inner_second_prio:3;
	/* VLAN ID of first VLAN tag the outer header of the incoming packet.
	 * Valid only when outer_second_cvlan_tag ==1 or outer_second_svlan_tag ==1
	 */
	u32 outer_second_vid:12;
	/* CFI bit of first VLAN tag in the outer header of the incoming packet.
	 * Valid only when outer_second_cvlan_tag ==1 or outer_second_svlan_tag ==1
	 */
	u32 outer_second_cfi:1;
	/* Priority of second VLAN tag in the outer header of the incoming packet.
	 * Valid only when outer_second_cvlan_tag ==1 or outer_second_svlan_tag ==1
	 */
	u32 outer_second_prio:3;
	u32 gre_protocol:16;		/* GRE Protocol (outer) */
	u32 reserved_auto3:12;
	/* The second vlan in the inner header of the packet is s-vlan (0x8a88).
	 * inner_second_cvlan_tag and inner_second_svlan_tag cannot be set together
	 */
	u32 inner_second_svlan_tag:1;
	/* The second vlan in the outer header of the packet is s-vlan (0x8a88).
	 * outer_second_cvlan_tag and outer_second_svlan_tag cannot be set together
	 */
	u32 outer_second_svlan_tag:1;
	/* The second vlan in the inner header of the packet is c-vlan (0x8100).
	 * inner_second_cvlan_tag and inner_second_svlan_tag cannot be set together
	 */
	u32 inner_second_cvlan_tag:1;
	/* The second vlan in the outer header of the packet is c-vlan (0x8100).
	 * outer_second_cvlan_tag and outer_second_svlan_tag cannot be set together
	 */
	u32 outer_second_cvlan_tag:1;
	u32 gre_key_l:8;		/* GRE Key [7:0] (outer) */
	u32 gre_key_h:24;		/* GRE Key[31:8] (outer) */
	u32 reserved_auto4:8;
	u32 vxlan_vni:24;		/* VXLAN VNI (outer) */
	u32 geneve_oam:1;		/* GENEVE OAM field (outer) */
	u32 reserved_auto5:7;
	u32 geneve_vni:24;		/* GENEVE VNI field (outer) */
	u32 outer_ipv6_flow_label:20;	/* Flow label of incoming IPv6 packet (outer) */
	u32 reserved_auto6:12;
	u32 inner_ipv6_flow_label:20;	/* Flow label of incoming IPv6 packet (inner) */
	u32 reserved_auto7:12;
	u32 geneve_protocol_type:16;	/* GENEVE protocol type (outer) */
	u32 geneve_opt_len:6;		/* GENEVE OptLen (outer) */
	u32 reserved_auto8:10;
	u32 bth_dst_qp:24;		/* Destination QP in BTH header */
	u32 reserved_auto9:8;
	u8 reserved_auto10[20];
};

struct mlx5dr_match_misc2 {
	u32 outer_first_mpls_ttl:8;		/* First MPLS TTL (outer) */
	u32 outer_first_mpls_s_bos:1;		/* First MPLS S_BOS (outer) */
	u32 outer_first_mpls_exp:3;		/* First MPLS EXP (outer) */
	u32 outer_first_mpls_label:20;		/* First MPLS LABEL (outer) */
	u32 inner_first_mpls_ttl:8;		/* First MPLS TTL (inner) */
	u32 inner_first_mpls_s_bos:1;		/* First MPLS S_BOS (inner) */
	u32 inner_first_mpls_exp:3;		/* First MPLS EXP (inner) */
	u32 inner_first_mpls_label:20;		/* First MPLS LABEL (inner) */
	u32 outer_first_mpls_over_gre_ttl:8;	/* last MPLS TTL (outer) */
	u32 outer_first_mpls_over_gre_s_bos:1;	/* last MPLS S_BOS (outer) */
	u32 outer_first_mpls_over_gre_exp:3;	/* last MPLS EXP (outer) */
	u32 outer_first_mpls_over_gre_label:20;	/* last MPLS LABEL (outer) */
	u32 outer_first_mpls_over_udp_ttl:8;	/* last MPLS TTL (outer) */
	u32 outer_first_mpls_over_udp_s_bos:1;	/* last MPLS S_BOS (outer) */
	u32 outer_first_mpls_over_udp_exp:3;	/* last MPLS EXP (outer) */
	u32 outer_first_mpls_over_udp_label:20;	/* last MPLS LABEL (outer) */
	u32 metadata_reg_c_7;			/* metadata_reg_c_7 */
	u32 metadata_reg_c_6;			/* metadata_reg_c_6 */
	u32 metadata_reg_c_5;			/* metadata_reg_c_5 */
	u32 metadata_reg_c_4;			/* metadata_reg_c_4 */
	u32 metadata_reg_c_3;			/* metadata_reg_c_3 */
	u32 metadata_reg_c_2;			/* metadata_reg_c_2 */
	u32 metadata_reg_c_1;			/* metadata_reg_c_1 */
	u32 metadata_reg_c_0;			/* metadata_reg_c_0 */
	u32 metadata_reg_a;			/* metadata_reg_a */
	u32 metadata_reg_b;			/* metadata_reg_b */
	u8 reserved_auto2[8];
};

struct mlx5dr_match_misc3 {
	u32 inner_tcp_seq_num;
	u32 outer_tcp_seq_num;
	u32 inner_tcp_ack_num;
	u32 outer_tcp_ack_num;
	u32 outer_vxlan_gpe_vni:24;
	u32 reserved_auto1:8;
	u32 reserved_auto2:16;
	u32 outer_vxlan_gpe_flags:8;
	u32 outer_vxlan_gpe_next_protocol:8;
	u32 icmpv4_header_data;
	u32 icmpv6_header_data;
	u32 icmpv6_code:8;
	u32 icmpv6_type:8;
	u32 icmpv4_code:8;
	u32 icmpv4_type:8;
	u8 reserved_auto3[0x1c];
};

struct mlx5dr_match_param {
	struct mlx5dr_match_spec outer;
	struct mlx5dr_match_misc misc;
	struct mlx5dr_match_spec inner;
	struct mlx5dr_match_misc2 misc2;
	struct mlx5dr_match_misc3 misc3;
};

#define DR_MASK_IS_FLEX_PARSER_ICMPV4_SET(_misc3) ((_misc3)->icmpv4_type || \
						   (_misc3)->icmpv4_code || \
						   (_misc3)->icmpv4_header_data)

struct mlx5dr_esw_caps {
	u64 drop_icm_address_rx;
	u64 drop_icm_address_tx;
	u64 uplink_icm_address_rx;
	u64 uplink_icm_address_tx;
	bool sw_owner;
};

struct mlx5dr_cmd_vport_cap {
	u16 vport_gvmi;
	u16 vhca_gvmi;
	u64 icm_address_rx;
	u64 icm_address_tx;
	u32 num;
};

struct mlx5dr_cmd_caps {
	u16 gvmi;
	u64 nic_rx_drop_address;
	u64 nic_tx_drop_address;
	u64 nic_tx_allow_address;
	u64 esw_rx_drop_address;
	u64 esw_tx_drop_address;
	u32 log_icm_size;
	u64 hdr_modify_icm_addr;
	u32 flex_protocols;
	u8 flex_parser_id_icmp_dw0;
	u8 flex_parser_id_icmp_dw1;
	u8 flex_parser_id_icmpv6_dw0;
	u8 flex_parser_id_icmpv6_dw1;
	u8 max_ft_level;
	u16 roce_min_src_udp;
	u8 num_esw_ports;
	bool eswitch_manager;
	bool rx_sw_owner;
	bool tx_sw_owner;
	bool fdb_sw_owner;
	u32 num_vports;
	struct mlx5dr_esw_caps esw_caps;
	struct mlx5dr_cmd_vport_cap *vports_caps;
	bool prio_tag_required;
};

struct mlx5dr_domain_rx_tx {
	u64 drop_icm_addr;
	u64 default_icm_addr;
	enum mlx5dr_ste_entry_type ste_type;
};

struct mlx5dr_domain_info {
	bool supp_sw_steering;
	u32 max_inline_size;
	u32 max_send_wr;
	u32 max_log_sw_icm_sz;
	u32 max_log_action_icm_sz;
	struct mlx5dr_domain_rx_tx rx;
	struct mlx5dr_domain_rx_tx tx;
	struct mlx5dr_cmd_caps caps;
};

struct mlx5dr_domain_cache {
	struct mlx5dr_fw_recalc_cs_ft **recalc_cs_ft;
};

struct mlx5dr_domain {
	struct mlx5dr_domain *peer_dmn;
	struct mlx5_core_dev *mdev;
	u32 pdn;
	struct mlx5_uars_page *uar;
	enum mlx5dr_domain_type type;
	refcount_t refcount;
	struct mutex mutex; /* protect domain */
	struct mlx5dr_icm_pool *ste_icm_pool;
	struct mlx5dr_icm_pool *action_icm_pool;
	struct mlx5dr_send_ring *send_ring;
	struct mlx5dr_domain_info info;
	struct mlx5dr_domain_cache cache;
};

struct mlx5dr_table_rx_tx {
	struct mlx5dr_ste_htbl *s_anchor;
	struct mlx5dr_domain_rx_tx *nic_dmn;
	u64 default_icm_addr;
};

struct mlx5dr_table {
	struct mlx5dr_domain *dmn;
	struct mlx5dr_table_rx_tx rx;
	struct mlx5dr_table_rx_tx tx;
	u32 level;
	u32 table_type;
	u32 table_id;
	struct list_head matcher_list;
	struct mlx5dr_action *miss_action;
	refcount_t refcount;
};

struct mlx5dr_matcher_rx_tx {
	struct mlx5dr_ste_htbl *s_htbl;
	struct mlx5dr_ste_htbl *e_anchor;
	struct mlx5dr_ste_build *ste_builder;
	struct mlx5dr_ste_build ste_builder4[DR_RULE_MAX_STES];
	struct mlx5dr_ste_build ste_builder6[DR_RULE_MAX_STES];
	u8 num_of_builders;
	u8 num_of_builders4;
	u8 num_of_builders6;
	u64 default_icm_addr;
	struct mlx5dr_table_rx_tx *nic_tbl;
};

struct mlx5dr_matcher {
	struct mlx5dr_table *tbl;
	struct mlx5dr_matcher_rx_tx rx;
	struct mlx5dr_matcher_rx_tx tx;
	struct list_head matcher_list;
	u16 prio;
	struct mlx5dr_match_param mask;
	u8 match_criteria;
	refcount_t refcount;
	struct mlx5dv_flow_matcher *dv_matcher;
};

struct mlx5dr_rule_member {
	struct mlx5dr_ste *ste;
	/* attached to mlx5dr_rule via this */
	struct list_head list;
	/* attached to mlx5dr_ste via this */
	struct list_head use_ste_list;
};

struct mlx5dr_action {
	enum mlx5dr_action_type action_type;
	refcount_t refcount;
	union {
		struct {
			struct mlx5dr_domain *dmn;
			struct mlx5dr_icm_chunk *chunk;
			u8 *data;
			u32 data_size;
			u16 num_of_actions;
			u32 index;
			u8 allow_rx:1;
			u8 allow_tx:1;
			u8 modify_ttl:1;
		} rewrite;
		struct {
			struct mlx5dr_domain *dmn;
			u32 reformat_id;
			u32 reformat_size;
		} reformat;
		struct {
			u8 is_fw_tbl:1;
			union {
				struct mlx5dr_table *tbl;
				struct {
					struct mlx5_flow_table *ft;
					u64 rx_icm_addr;
					u64 tx_icm_addr;
					struct mlx5_core_dev *mdev;
				} fw_tbl;
			};
		} dest_tbl;
		struct {
			u32 ctr_id;
			u32 offeset;
		} ctr;
		struct {
			struct mlx5dr_domain *dmn;
			struct mlx5dr_cmd_vport_cap *caps;
		} vport;
		struct {
			u32 vlan_hdr; /* tpid_pcp_dei_vid */
		} push_vlan;
		u32 flow_tag;
	};
};

enum mlx5dr_connect_type {
	CONNECT_HIT	= 1,
	CONNECT_MISS	= 2,
};

struct mlx5dr_htbl_connect_info {
	enum mlx5dr_connect_type type;
	union {
		struct mlx5dr_ste_htbl *hit_next_htbl;
		u64 miss_icm_addr;
	};
};

struct mlx5dr_rule_rx_tx {
	struct list_head rule_members_list;
	struct mlx5dr_matcher_rx_tx *nic_matcher;
};

struct mlx5dr_rule {
	struct mlx5dr_matcher *matcher;
	struct mlx5dr_rule_rx_tx rx;
	struct mlx5dr_rule_rx_tx tx;
	struct list_head rule_actions_list;
};

void mlx5dr_rule_update_rule_member(struct mlx5dr_ste *new_ste,
				    struct mlx5dr_ste *ste);

struct mlx5dr_icm_chunk {
	struct mlx5dr_icm_bucket *bucket;
	struct list_head chunk_list;
	u32 rkey;
	u32 num_of_entries;
	u32 byte_size;
	u64 icm_addr;
	u64 mr_addr;

	/* Memory optimisation */
	struct mlx5dr_ste *ste_arr;
	u8 *hw_ste_arr;
	struct list_head *miss_list;
};

static inline int
mlx5dr_matcher_supp_flex_parser_icmp_v4(struct mlx5dr_cmd_caps *caps)
{
	return caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED;
}

static inline int
mlx5dr_matcher_supp_flex_parser_icmp_v6(struct mlx5dr_cmd_caps *caps)
{
	return caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED;
}

int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher,
				   struct mlx5dr_matcher_rx_tx *nic_matcher,
				   bool ipv6);

static inline u32
mlx5dr_icm_pool_chunk_size_to_entries(enum mlx5dr_icm_chunk_size chunk_size)
{
	return 1 << chunk_size;
}

static inline int
mlx5dr_icm_pool_chunk_size_to_byte(enum mlx5dr_icm_chunk_size chunk_size,
				   enum mlx5dr_icm_type icm_type)
{
	int num_of_entries;
	int entry_size;

	if (icm_type == DR_ICM_TYPE_STE)
		entry_size = DR_STE_SIZE;
	else
		entry_size = DR_MODIFY_ACTION_SIZE;

	num_of_entries = mlx5dr_icm_pool_chunk_size_to_entries(chunk_size);

	return entry_size * num_of_entries;
}

static inline struct mlx5dr_cmd_vport_cap *
mlx5dr_get_vport_cap(struct mlx5dr_cmd_caps *caps, u32 vport)
{
	if (!caps->vports_caps ||
	    (vport >= caps->num_vports && vport != WIRE_PORT))
		return NULL;

	if (vport == WIRE_PORT)
		vport = caps->num_vports;

	return &caps->vports_caps[vport];
}

struct mlx5dr_cmd_query_flow_table_details {
	u8 status;
	u8 level;
	u64 sw_owner_icm_root_1;
	u64 sw_owner_icm_root_0;
};

/* internal API functions */
int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev,
			    struct mlx5dr_cmd_caps *caps);
int mlx5dr_cmd_query_esw_vport_context(struct mlx5_core_dev *mdev,
				       bool other_vport, u16 vport_number,
				       u64 *icm_address_rx,
				       u64 *icm_address_tx);
int mlx5dr_cmd_query_gvmi(struct mlx5_core_dev *mdev,
			  bool other_vport, u16 vport_number, u16 *gvmi);
int mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev *mdev,
			      struct mlx5dr_esw_caps *caps);
int mlx5dr_cmd_sync_steering(struct mlx5_core_dev *mdev);
int mlx5dr_cmd_set_fte_modify_and_vport(struct mlx5_core_dev *mdev,
					u32 table_type,
					u32 table_id,
					u32 group_id,
					u32 modify_header_id,
					u32 vport_id);
int mlx5dr_cmd_del_flow_table_entry(struct mlx5_core_dev *mdev,
				    u32 table_type,
				    u32 table_id);
int mlx5dr_cmd_alloc_modify_header(struct mlx5_core_dev *mdev,
				   u32 table_type,
				   u8 num_of_actions,
				   u64 *actions,
				   u32 *modify_header_id);
int mlx5dr_cmd_dealloc_modify_header(struct mlx5_core_dev *mdev,
				     u32 modify_header_id);
int mlx5dr_cmd_create_empty_flow_group(struct mlx5_core_dev *mdev,
				       u32 table_type,
				       u32 table_id,
				       u32 *group_id);
int mlx5dr_cmd_destroy_flow_group(struct mlx5_core_dev *mdev,
				  u32 table_type,
				  u32 table_id,
				  u32 group_id);
int mlx5dr_cmd_create_flow_table(struct mlx5_core_dev *mdev,
				 u32 table_type,
				 u64 icm_addr_rx,
				 u64 icm_addr_tx,
				 u8 level,
				 bool sw_owner,
				 bool term_tbl,
				 u64 *fdb_rx_icm_addr,
				 u32 *table_id);
int mlx5dr_cmd_destroy_flow_table(struct mlx5_core_dev *mdev,
				  u32 table_id,
				  u32 table_type);
int mlx5dr_cmd_query_flow_table(struct mlx5_core_dev *dev,
				enum fs_flow_table_type type,
				u32 table_id,
				struct mlx5dr_cmd_query_flow_table_details *output);
int mlx5dr_cmd_create_reformat_ctx(struct mlx5_core_dev *mdev,
				   enum mlx5_reformat_ctx_type rt,
				   size_t reformat_size,
				   void *reformat_data,
				   u32 *reformat_id);
void mlx5dr_cmd_destroy_reformat_ctx(struct mlx5_core_dev *mdev,
				     u32 reformat_id);

struct mlx5dr_cmd_gid_attr {
	u8 gid[16];
	u8 mac[6];
	u32 roce_ver;
};

struct mlx5dr_cmd_qp_create_attr {
	u32 page_id;
	u32 pdn;
	u32 cqn;
	u32 pm_state;
	u32 service_type;
	u32 buff_umem_id;
	u32 db_umem_id;
	u32 sq_wqe_cnt;
	u32 rq_wqe_cnt;
	u32 rq_wqe_shift;
};

int mlx5dr_cmd_query_gid(struct mlx5_core_dev *mdev, u8 vhca_port_num,
			 u16 index, struct mlx5dr_cmd_gid_attr *attr);

struct mlx5dr_icm_pool *mlx5dr_icm_pool_create(struct mlx5dr_domain *dmn,
					       enum mlx5dr_icm_type icm_type);
void mlx5dr_icm_pool_destroy(struct mlx5dr_icm_pool *pool);

struct mlx5dr_icm_chunk *
mlx5dr_icm_alloc_chunk(struct mlx5dr_icm_pool *pool,
		       enum mlx5dr_icm_chunk_size chunk_size);
void mlx5dr_icm_free_chunk(struct mlx5dr_icm_chunk *chunk);
bool mlx5dr_ste_is_not_valid_entry(u8 *p_hw_ste);
int mlx5dr_ste_htbl_init_and_postsend(struct mlx5dr_domain *dmn,
				      struct mlx5dr_domain_rx_tx *nic_dmn,
				      struct mlx5dr_ste_htbl *htbl,
				      struct mlx5dr_htbl_connect_info *connect_info,
				      bool update_hw_ste);
void mlx5dr_ste_set_formatted_ste(u16 gvmi,
				  struct mlx5dr_domain_rx_tx *nic_dmn,
				  struct mlx5dr_ste_htbl *htbl,
				  u8 *formatted_ste,
				  struct mlx5dr_htbl_connect_info *connect_info);
void mlx5dr_ste_copy_param(u8 match_criteria,
			   struct mlx5dr_match_param *set_param,
			   struct mlx5dr_match_parameters *mask);

void mlx5dr_crc32_init_table(void);
u32 mlx5dr_crc32_slice8_calc(const void *input_data, size_t length);

struct mlx5dr_qp {
	struct mlx5_core_dev *mdev;
	struct mlx5_wq_qp wq;
	struct mlx5_uars_page *uar;
	struct mlx5_wq_ctrl wq_ctrl;
	struct mlx5_core_qp mqp;
	struct {
		unsigned int pc;
		unsigned int cc;
		unsigned int size;
		unsigned int *wqe_head;
		unsigned int wqe_cnt;
	} sq;
	struct {
		unsigned int pc;
		unsigned int cc;
		unsigned int size;
		unsigned int wqe_cnt;
	} rq;
	int max_inline_data;
};

struct mlx5dr_cq {
	struct mlx5_core_dev *mdev;
	struct mlx5_cqwq wq;
	struct mlx5_wq_ctrl wq_ctrl;
	struct mlx5_core_cq mcq;
	struct mlx5dr_qp *qp;
};

struct mlx5dr_mr {
	struct mlx5_core_dev *mdev;
	struct mlx5_core_mkey mkey;
	dma_addr_t dma_addr;
	void *addr;
	size_t size;
};

#define MAX_SEND_CQE		64
#define MIN_READ_SYNC		64

struct mlx5dr_send_ring {
	struct mlx5dr_cq *cq;
	struct mlx5dr_qp *qp;
	struct mlx5dr_mr *mr;
	/* How much wqes are waiting for completion */
	u32 pending_wqe;
	/* Signal request per this trash hold value */
	u16 signal_th;
	/* Each post_send_size less than max_post_send_size */
	u32 max_post_send_size;
	/* manage the send queue */
	u32 tx_head;
	void *buf;
	u32 buf_size;
	struct ib_wc wc[MAX_SEND_CQE];
	u8 sync_buff[MIN_READ_SYNC];
	struct mlx5dr_mr *sync_mr;
};

int mlx5dr_send_ring_alloc(struct mlx5dr_domain *dmn);
void mlx5dr_send_ring_free(struct mlx5dr_domain *dmn,
			   struct mlx5dr_send_ring *send_ring);
int mlx5dr_send_ring_force_drain(struct mlx5dr_domain *dmn);
int mlx5dr_send_postsend_ste(struct mlx5dr_domain *dmn,
			     struct mlx5dr_ste *ste,
			     u8 *data,
			     u16 size,
			     u16 offset);
int mlx5dr_send_postsend_htbl(struct mlx5dr_domain *dmn,
			      struct mlx5dr_ste_htbl *htbl,
			      u8 *formatted_ste, u8 *mask);
int mlx5dr_send_postsend_formatted_htbl(struct mlx5dr_domain *dmn,
					struct mlx5dr_ste_htbl *htbl,
					u8 *ste_init_data,
					bool update_hw_ste);
int mlx5dr_send_postsend_action(struct mlx5dr_domain *dmn,
				struct mlx5dr_action *action);

struct mlx5dr_fw_recalc_cs_ft {
	u64 rx_icm_addr;
	u32 table_id;
	u32 group_id;
	u32 modify_hdr_id;
};

struct mlx5dr_fw_recalc_cs_ft *
mlx5dr_fw_create_recalc_cs_ft(struct mlx5dr_domain *dmn, u32 vport_num);
void mlx5dr_fw_destroy_recalc_cs_ft(struct mlx5dr_domain *dmn,
				    struct mlx5dr_fw_recalc_cs_ft *recalc_cs_ft);
int mlx5dr_domain_cache_get_recalc_cs_ft_addr(struct mlx5dr_domain *dmn,
					      u32 vport_num,
					      u64 *rx_icm_addr);
#endif  /* _DR_TYPES_H_ */