126d688e3SAlex Vesker // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
226d688e3SAlex Vesker /* Copyright (c) 2019 Mellanox Technologies. */
326d688e3SAlex Vesker 
426d688e3SAlex Vesker #include <linux/types.h>
540416d8eSHamdan Igbaria #include <linux/crc32.h>
64bdba39bSYevgeny Kliteynik #include "dr_ste.h"
726d688e3SAlex Vesker 
826d688e3SAlex Vesker struct dr_hw_ste_format {
926d688e3SAlex Vesker 	u8 ctrl[DR_STE_SIZE_CTRL];
1026d688e3SAlex Vesker 	u8 tag[DR_STE_SIZE_TAG];
1126d688e3SAlex Vesker 	u8 mask[DR_STE_SIZE_MASK];
1226d688e3SAlex Vesker };
1326d688e3SAlex Vesker 
1440416d8eSHamdan Igbaria static u32 dr_ste_crc32_calc(const void *input_data, size_t length)
1540416d8eSHamdan Igbaria {
1640416d8eSHamdan Igbaria 	u32 crc = crc32(0, input_data, length);
1740416d8eSHamdan Igbaria 
189ff2e92cSSaeed Mahameed 	return (__force u32)htonl(crc);
1940416d8eSHamdan Igbaria }
2040416d8eSHamdan Igbaria 
21a283ea1bSYevgeny Kliteynik bool mlx5dr_ste_supp_ttl_cs_recalc(struct mlx5dr_cmd_caps *caps)
22a283ea1bSYevgeny Kliteynik {
23a283ea1bSYevgeny Kliteynik 	return caps->sw_format_ver > MLX5_STEERING_FORMAT_CONNECTX_5;
24a283ea1bSYevgeny Kliteynik }
25a283ea1bSYevgeny Kliteynik 
2626d688e3SAlex Vesker u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl)
2726d688e3SAlex Vesker {
28f51bb517SRongwei Liu 	u32 num_entries = mlx5dr_icm_pool_get_chunk_num_of_entries(htbl->chunk);
2926d688e3SAlex Vesker 	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
3026d688e3SAlex Vesker 	u8 masked[DR_STE_SIZE_TAG] = {};
3126d688e3SAlex Vesker 	u32 crc32, index;
3226d688e3SAlex Vesker 	u16 bit;
3326d688e3SAlex Vesker 	int i;
3426d688e3SAlex Vesker 
3526d688e3SAlex Vesker 	/* Don't calculate CRC if the result is predicted */
36f51bb517SRongwei Liu 	if (num_entries == 1 || htbl->byte_mask == 0)
3726d688e3SAlex Vesker 		return 0;
3826d688e3SAlex Vesker 
3926d688e3SAlex Vesker 	/* Mask tag using byte mask, bit per byte */
4026d688e3SAlex Vesker 	bit = 1 << (DR_STE_SIZE_TAG - 1);
4126d688e3SAlex Vesker 	for (i = 0; i < DR_STE_SIZE_TAG; i++) {
4226d688e3SAlex Vesker 		if (htbl->byte_mask & bit)
4326d688e3SAlex Vesker 			masked[i] = hw_ste->tag[i];
4426d688e3SAlex Vesker 
4526d688e3SAlex Vesker 		bit = bit >> 1;
4626d688e3SAlex Vesker 	}
4726d688e3SAlex Vesker 
4840416d8eSHamdan Igbaria 	crc32 = dr_ste_crc32_calc(masked, DR_STE_SIZE_TAG);
49f51bb517SRongwei Liu 	index = crc32 & (num_entries - 1);
5026d688e3SAlex Vesker 
5126d688e3SAlex Vesker 	return index;
5226d688e3SAlex Vesker }
5326d688e3SAlex Vesker 
545212f9c6SYevgeny Kliteynik u16 mlx5dr_ste_conv_bit_to_byte_mask(u8 *bit_mask)
5526d688e3SAlex Vesker {
5626d688e3SAlex Vesker 	u16 byte_mask = 0;
5726d688e3SAlex Vesker 	int i;
5826d688e3SAlex Vesker 
5926d688e3SAlex Vesker 	for (i = 0; i < DR_STE_SIZE_MASK; i++) {
6026d688e3SAlex Vesker 		byte_mask = byte_mask << 1;
6126d688e3SAlex Vesker 		if (bit_mask[i] == 0xff)
6226d688e3SAlex Vesker 			byte_mask |= 1;
6326d688e3SAlex Vesker 	}
6426d688e3SAlex Vesker 	return byte_mask;
6526d688e3SAlex Vesker }
6626d688e3SAlex Vesker 
6764c78942SYevgeny Kliteynik static u8 *dr_ste_get_tag(u8 *hw_ste_p)
68e6b69bf3SYevgeny Kliteynik {
69e6b69bf3SYevgeny Kliteynik 	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
70e6b69bf3SYevgeny Kliteynik 
71e6b69bf3SYevgeny Kliteynik 	return hw_ste->tag;
72e6b69bf3SYevgeny Kliteynik }
73e6b69bf3SYevgeny Kliteynik 
7426d688e3SAlex Vesker void mlx5dr_ste_set_bit_mask(u8 *hw_ste_p, u8 *bit_mask)
7526d688e3SAlex Vesker {
7626d688e3SAlex Vesker 	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
7726d688e3SAlex Vesker 
7826d688e3SAlex Vesker 	memcpy(hw_ste->mask, bit_mask, DR_STE_SIZE_MASK);
7926d688e3SAlex Vesker }
8026d688e3SAlex Vesker 
8126d688e3SAlex Vesker static void dr_ste_set_always_hit(struct dr_hw_ste_format *hw_ste)
8226d688e3SAlex Vesker {
8326d688e3SAlex Vesker 	memset(&hw_ste->tag, 0, sizeof(hw_ste->tag));
8426d688e3SAlex Vesker 	memset(&hw_ste->mask, 0, sizeof(hw_ste->mask));
8526d688e3SAlex Vesker }
8626d688e3SAlex Vesker 
8726d688e3SAlex Vesker static void dr_ste_set_always_miss(struct dr_hw_ste_format *hw_ste)
8826d688e3SAlex Vesker {
8926d688e3SAlex Vesker 	hw_ste->tag[0] = 0xdc;
9026d688e3SAlex Vesker 	hw_ste->mask[0] = 0;
9126d688e3SAlex Vesker }
9226d688e3SAlex Vesker 
936b93b400SYevgeny Kliteynik void mlx5dr_ste_set_miss_addr(struct mlx5dr_ste_ctx *ste_ctx,
946b93b400SYevgeny Kliteynik 			      u8 *hw_ste_p, u64 miss_addr)
9564c78942SYevgeny Kliteynik {
966b93b400SYevgeny Kliteynik 	ste_ctx->set_miss_addr(hw_ste_p, miss_addr);
9764c78942SYevgeny Kliteynik }
9864c78942SYevgeny Kliteynik 
996b93b400SYevgeny Kliteynik static void dr_ste_always_miss_addr(struct mlx5dr_ste_ctx *ste_ctx,
1006b93b400SYevgeny Kliteynik 				    struct mlx5dr_ste *ste, u64 miss_addr)
10164c78942SYevgeny Kliteynik {
10264c78942SYevgeny Kliteynik 	u8 *hw_ste_p = ste->hw_ste;
10364c78942SYevgeny Kliteynik 
1046b93b400SYevgeny Kliteynik 	ste_ctx->set_next_lu_type(hw_ste_p, MLX5DR_STE_LU_TYPE_DONT_CARE);
1056b93b400SYevgeny Kliteynik 	ste_ctx->set_miss_addr(hw_ste_p, miss_addr);
10664c78942SYevgeny Kliteynik 	dr_ste_set_always_miss((struct dr_hw_ste_format *)ste->hw_ste);
10764c78942SYevgeny Kliteynik }
10864c78942SYevgeny Kliteynik 
1096b93b400SYevgeny Kliteynik void mlx5dr_ste_set_hit_addr(struct mlx5dr_ste_ctx *ste_ctx,
1106b93b400SYevgeny Kliteynik 			     u8 *hw_ste, u64 icm_addr, u32 ht_size)
11126d688e3SAlex Vesker {
1126b93b400SYevgeny Kliteynik 	ste_ctx->set_hit_addr(hw_ste, icm_addr, ht_size);
11326d688e3SAlex Vesker }
11426d688e3SAlex Vesker 
11526d688e3SAlex Vesker u64 mlx5dr_ste_get_icm_addr(struct mlx5dr_ste *ste)
11626d688e3SAlex Vesker {
1175c4f9b6eSRongwei Liu 	u64 base_icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(ste->htbl->chunk);
118*597534bdSRongwei Liu 	u32 index = ste - ste->htbl->chunk->ste_arr;
11926d688e3SAlex Vesker 
1205c4f9b6eSRongwei Liu 	return base_icm_addr + DR_STE_SIZE * index;
12126d688e3SAlex Vesker }
12226d688e3SAlex Vesker 
12326d688e3SAlex Vesker u64 mlx5dr_ste_get_mr_addr(struct mlx5dr_ste *ste)
12426d688e3SAlex Vesker {
125*597534bdSRongwei Liu 	u32 index = ste - ste->htbl->chunk->ste_arr;
12626d688e3SAlex Vesker 
127003f4f9aSRongwei Liu 	return mlx5dr_icm_pool_get_chunk_mr_addr(ste->htbl->chunk) + DR_STE_SIZE * index;
12826d688e3SAlex Vesker }
12926d688e3SAlex Vesker 
13026d688e3SAlex Vesker struct list_head *mlx5dr_ste_get_miss_list(struct mlx5dr_ste *ste)
13126d688e3SAlex Vesker {
132*597534bdSRongwei Liu 	u32 index = ste - ste->htbl->chunk->ste_arr;
13326d688e3SAlex Vesker 
134*597534bdSRongwei Liu 	return &ste->htbl->chunk->miss_list[index];
13526d688e3SAlex Vesker }
13626d688e3SAlex Vesker 
1376b93b400SYevgeny Kliteynik static void dr_ste_always_hit_htbl(struct mlx5dr_ste_ctx *ste_ctx,
1386b93b400SYevgeny Kliteynik 				   struct mlx5dr_ste *ste,
13926d688e3SAlex Vesker 				   struct mlx5dr_ste_htbl *next_htbl)
14026d688e3SAlex Vesker {
14126d688e3SAlex Vesker 	struct mlx5dr_icm_chunk *chunk = next_htbl->chunk;
14226d688e3SAlex Vesker 	u8 *hw_ste = ste->hw_ste;
14326d688e3SAlex Vesker 
1446b93b400SYevgeny Kliteynik 	ste_ctx->set_byte_mask(hw_ste, next_htbl->byte_mask);
1456b93b400SYevgeny Kliteynik 	ste_ctx->set_next_lu_type(hw_ste, next_htbl->lu_type);
1465c4f9b6eSRongwei Liu 	ste_ctx->set_hit_addr(hw_ste, mlx5dr_icm_pool_get_chunk_icm_addr(chunk),
147f51bb517SRongwei Liu 			      mlx5dr_icm_pool_get_chunk_num_of_entries(chunk));
14826d688e3SAlex Vesker 
14926d688e3SAlex Vesker 	dr_ste_set_always_hit((struct dr_hw_ste_format *)ste->hw_ste);
15026d688e3SAlex Vesker }
15126d688e3SAlex Vesker 
15226d688e3SAlex Vesker bool mlx5dr_ste_is_last_in_rule(struct mlx5dr_matcher_rx_tx *nic_matcher,
15326d688e3SAlex Vesker 				u8 ste_location)
15426d688e3SAlex Vesker {
15526d688e3SAlex Vesker 	return ste_location == nic_matcher->num_of_builders;
15626d688e3SAlex Vesker }
15726d688e3SAlex Vesker 
15826d688e3SAlex Vesker /* Replace relevant fields, except of:
15926d688e3SAlex Vesker  * htbl - keep the origin htbl
16026d688e3SAlex Vesker  * miss_list + list - already took the src from the list.
16126d688e3SAlex Vesker  * icm_addr/mr_addr - depends on the hosting table.
16226d688e3SAlex Vesker  *
16326d688e3SAlex Vesker  * Before:
16426d688e3SAlex Vesker  * | a | -> | b | -> | c | ->
16526d688e3SAlex Vesker  *
16626d688e3SAlex Vesker  * After:
16726d688e3SAlex Vesker  * | a | -> | c | ->
16826d688e3SAlex Vesker  * While the data that was in b copied to a.
16926d688e3SAlex Vesker  */
17026d688e3SAlex Vesker static void dr_ste_replace(struct mlx5dr_ste *dst, struct mlx5dr_ste *src)
17126d688e3SAlex Vesker {
17226d688e3SAlex Vesker 	memcpy(dst->hw_ste, src->hw_ste, DR_STE_SIZE_REDUCED);
17326d688e3SAlex Vesker 	dst->next_htbl = src->next_htbl;
17426d688e3SAlex Vesker 	if (dst->next_htbl)
17526d688e3SAlex Vesker 		dst->next_htbl->pointing_ste = dst;
17626d688e3SAlex Vesker 
1774ce380caSYevgeny Kliteynik 	dst->refcount = src->refcount;
17826d688e3SAlex Vesker }
17926d688e3SAlex Vesker 
18026d688e3SAlex Vesker /* Free ste which is the head and the only one in miss_list */
18126d688e3SAlex Vesker static void
1826b93b400SYevgeny Kliteynik dr_ste_remove_head_ste(struct mlx5dr_ste_ctx *ste_ctx,
1836b93b400SYevgeny Kliteynik 		       struct mlx5dr_ste *ste,
18426d688e3SAlex Vesker 		       struct mlx5dr_matcher_rx_tx *nic_matcher,
18526d688e3SAlex Vesker 		       struct mlx5dr_ste_send_info *ste_info_head,
18626d688e3SAlex Vesker 		       struct list_head *send_ste_list,
18726d688e3SAlex Vesker 		       struct mlx5dr_ste_htbl *stats_tbl)
18826d688e3SAlex Vesker {
18926d688e3SAlex Vesker 	u8 tmp_data_ste[DR_STE_SIZE] = {};
19026d688e3SAlex Vesker 	struct mlx5dr_ste tmp_ste = {};
19126d688e3SAlex Vesker 	u64 miss_addr;
19226d688e3SAlex Vesker 
19326d688e3SAlex Vesker 	tmp_ste.hw_ste = tmp_data_ste;
19426d688e3SAlex Vesker 
19526d688e3SAlex Vesker 	/* Use temp ste because dr_ste_always_miss_addr
19626d688e3SAlex Vesker 	 * touches bit_mask area which doesn't exist at ste->hw_ste.
19726d688e3SAlex Vesker 	 */
19826d688e3SAlex Vesker 	memcpy(tmp_ste.hw_ste, ste->hw_ste, DR_STE_SIZE_REDUCED);
1995c4f9b6eSRongwei Liu 	miss_addr = mlx5dr_icm_pool_get_chunk_icm_addr(nic_matcher->e_anchor->chunk);
2006b93b400SYevgeny Kliteynik 	dr_ste_always_miss_addr(ste_ctx, &tmp_ste, miss_addr);
20126d688e3SAlex Vesker 	memcpy(ste->hw_ste, tmp_ste.hw_ste, DR_STE_SIZE_REDUCED);
20226d688e3SAlex Vesker 
20326d688e3SAlex Vesker 	list_del_init(&ste->miss_list_node);
20426d688e3SAlex Vesker 
20526d688e3SAlex Vesker 	/* Write full STE size in order to have "always_miss" */
20626d688e3SAlex Vesker 	mlx5dr_send_fill_and_append_ste_send_info(ste, DR_STE_SIZE,
20726d688e3SAlex Vesker 						  0, tmp_data_ste,
20826d688e3SAlex Vesker 						  ste_info_head,
20926d688e3SAlex Vesker 						  send_ste_list,
21026d688e3SAlex Vesker 						  true /* Copy data */);
21126d688e3SAlex Vesker 
21226d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_valid_entries--;
21326d688e3SAlex Vesker }
21426d688e3SAlex Vesker 
21526d688e3SAlex Vesker /* Free ste which is the head but NOT the only one in miss_list:
21626d688e3SAlex Vesker  * |_ste_| --> |_next_ste_| -->|__| -->|__| -->/0
21726d688e3SAlex Vesker  */
21826d688e3SAlex Vesker static void
2198fdac12aSYevgeny Kliteynik dr_ste_replace_head_ste(struct mlx5dr_matcher_rx_tx *nic_matcher,
2208fdac12aSYevgeny Kliteynik 			struct mlx5dr_ste *ste,
2218fdac12aSYevgeny Kliteynik 			struct mlx5dr_ste *next_ste,
22226d688e3SAlex Vesker 			struct mlx5dr_ste_send_info *ste_info_head,
22326d688e3SAlex Vesker 			struct list_head *send_ste_list,
22426d688e3SAlex Vesker 			struct mlx5dr_ste_htbl *stats_tbl)
22526d688e3SAlex Vesker 
22626d688e3SAlex Vesker {
22726d688e3SAlex Vesker 	struct mlx5dr_ste_htbl *next_miss_htbl;
2288fdac12aSYevgeny Kliteynik 	u8 hw_ste[DR_STE_SIZE] = {};
2298fdac12aSYevgeny Kliteynik 	int sb_idx;
23026d688e3SAlex Vesker 
23126d688e3SAlex Vesker 	next_miss_htbl = next_ste->htbl;
23226d688e3SAlex Vesker 
23326d688e3SAlex Vesker 	/* Remove from the miss_list the next_ste before copy */
23426d688e3SAlex Vesker 	list_del_init(&next_ste->miss_list_node);
23526d688e3SAlex Vesker 
23626d688e3SAlex Vesker 	/* Move data from next into ste */
23726d688e3SAlex Vesker 	dr_ste_replace(ste, next_ste);
23826d688e3SAlex Vesker 
2398a015baeSYevgeny Kliteynik 	/* Update the rule on STE change */
2408a015baeSYevgeny Kliteynik 	mlx5dr_rule_set_last_member(next_ste->rule_rx_tx, ste, false);
2418a015baeSYevgeny Kliteynik 
2428fdac12aSYevgeny Kliteynik 	/* Copy all 64 hw_ste bytes */
2438fdac12aSYevgeny Kliteynik 	memcpy(hw_ste, ste->hw_ste, DR_STE_SIZE_REDUCED);
2448fdac12aSYevgeny Kliteynik 	sb_idx = ste->ste_chain_location - 1;
2458fdac12aSYevgeny Kliteynik 	mlx5dr_ste_set_bit_mask(hw_ste,
2468fdac12aSYevgeny Kliteynik 				nic_matcher->ste_builder[sb_idx].bit_mask);
2478fdac12aSYevgeny Kliteynik 
24826d688e3SAlex Vesker 	/* Del the htbl that contains the next_ste.
24926d688e3SAlex Vesker 	 * The origin htbl stay with the same number of entries.
25026d688e3SAlex Vesker 	 */
25126d688e3SAlex Vesker 	mlx5dr_htbl_put(next_miss_htbl);
25226d688e3SAlex Vesker 
2538fdac12aSYevgeny Kliteynik 	mlx5dr_send_fill_and_append_ste_send_info(ste, DR_STE_SIZE,
2548fdac12aSYevgeny Kliteynik 						  0, hw_ste,
25526d688e3SAlex Vesker 						  ste_info_head,
25626d688e3SAlex Vesker 						  send_ste_list,
25726d688e3SAlex Vesker 						  true /* Copy data */);
25826d688e3SAlex Vesker 
25926d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_collisions--;
26026d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_valid_entries--;
26126d688e3SAlex Vesker }
26226d688e3SAlex Vesker 
26326d688e3SAlex Vesker /* Free ste that is located in the middle of the miss list:
26426d688e3SAlex Vesker  * |__| -->|_prev_ste_|->|_ste_|-->|_next_ste_|
26526d688e3SAlex Vesker  */
2666b93b400SYevgeny Kliteynik static void dr_ste_remove_middle_ste(struct mlx5dr_ste_ctx *ste_ctx,
2676b93b400SYevgeny Kliteynik 				     struct mlx5dr_ste *ste,
26826d688e3SAlex Vesker 				     struct mlx5dr_ste_send_info *ste_info,
26926d688e3SAlex Vesker 				     struct list_head *send_ste_list,
27026d688e3SAlex Vesker 				     struct mlx5dr_ste_htbl *stats_tbl)
27126d688e3SAlex Vesker {
27226d688e3SAlex Vesker 	struct mlx5dr_ste *prev_ste;
27326d688e3SAlex Vesker 	u64 miss_addr;
27426d688e3SAlex Vesker 
27548cbde4bSAlex Vesker 	prev_ste = list_prev_entry(ste, miss_list_node);
27648cbde4bSAlex Vesker 	if (WARN_ON(!prev_ste))
27726d688e3SAlex Vesker 		return;
27826d688e3SAlex Vesker 
2796b93b400SYevgeny Kliteynik 	miss_addr = ste_ctx->get_miss_addr(ste->hw_ste);
2806b93b400SYevgeny Kliteynik 	ste_ctx->set_miss_addr(prev_ste->hw_ste, miss_addr);
28126d688e3SAlex Vesker 
282f06d4969SYevgeny Kliteynik 	mlx5dr_send_fill_and_append_ste_send_info(prev_ste, DR_STE_SIZE_CTRL, 0,
28326d688e3SAlex Vesker 						  prev_ste->hw_ste, ste_info,
28426d688e3SAlex Vesker 						  send_ste_list, true /* Copy data*/);
28526d688e3SAlex Vesker 
28626d688e3SAlex Vesker 	list_del_init(&ste->miss_list_node);
28726d688e3SAlex Vesker 
28826d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_valid_entries--;
28926d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_collisions--;
29026d688e3SAlex Vesker }
29126d688e3SAlex Vesker 
29226d688e3SAlex Vesker void mlx5dr_ste_free(struct mlx5dr_ste *ste,
29326d688e3SAlex Vesker 		     struct mlx5dr_matcher *matcher,
29426d688e3SAlex Vesker 		     struct mlx5dr_matcher_rx_tx *nic_matcher)
29526d688e3SAlex Vesker {
29626d688e3SAlex Vesker 	struct mlx5dr_ste_send_info *cur_ste_info, *tmp_ste_info;
29726d688e3SAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
2986b93b400SYevgeny Kliteynik 	struct mlx5dr_ste_ctx *ste_ctx = dmn->ste_ctx;
29926d688e3SAlex Vesker 	struct mlx5dr_ste_send_info ste_info_head;
30026d688e3SAlex Vesker 	struct mlx5dr_ste *next_ste, *first_ste;
30126d688e3SAlex Vesker 	bool put_on_origin_table = true;
30226d688e3SAlex Vesker 	struct mlx5dr_ste_htbl *stats_tbl;
30326d688e3SAlex Vesker 	LIST_HEAD(send_ste_list);
30426d688e3SAlex Vesker 
30548cbde4bSAlex Vesker 	first_ste = list_first_entry(mlx5dr_ste_get_miss_list(ste),
30626d688e3SAlex Vesker 				     struct mlx5dr_ste, miss_list_node);
30726d688e3SAlex Vesker 	stats_tbl = first_ste->htbl;
30826d688e3SAlex Vesker 
30926d688e3SAlex Vesker 	/* Two options:
31026d688e3SAlex Vesker 	 * 1. ste is head:
31126d688e3SAlex Vesker 	 *	a. head ste is the only ste in the miss list
31226d688e3SAlex Vesker 	 *	b. head ste is not the only ste in the miss-list
31326d688e3SAlex Vesker 	 * 2. ste is not head
31426d688e3SAlex Vesker 	 */
31526d688e3SAlex Vesker 	if (first_ste == ste) { /* Ste is the head */
31626d688e3SAlex Vesker 		struct mlx5dr_ste *last_ste;
31726d688e3SAlex Vesker 
31826d688e3SAlex Vesker 		last_ste = list_last_entry(mlx5dr_ste_get_miss_list(ste),
31926d688e3SAlex Vesker 					   struct mlx5dr_ste, miss_list_node);
32026d688e3SAlex Vesker 		if (last_ste == first_ste)
32126d688e3SAlex Vesker 			next_ste = NULL;
32226d688e3SAlex Vesker 		else
32348cbde4bSAlex Vesker 			next_ste = list_next_entry(ste, miss_list_node);
32426d688e3SAlex Vesker 
32526d688e3SAlex Vesker 		if (!next_ste) {
32626d688e3SAlex Vesker 			/* One and only entry in the list */
3276b93b400SYevgeny Kliteynik 			dr_ste_remove_head_ste(ste_ctx, ste,
3286b93b400SYevgeny Kliteynik 					       nic_matcher,
32926d688e3SAlex Vesker 					       &ste_info_head,
33026d688e3SAlex Vesker 					       &send_ste_list,
33126d688e3SAlex Vesker 					       stats_tbl);
33226d688e3SAlex Vesker 		} else {
33326d688e3SAlex Vesker 			/* First but not only entry in the list */
3348fdac12aSYevgeny Kliteynik 			dr_ste_replace_head_ste(nic_matcher, ste,
3358fdac12aSYevgeny Kliteynik 						next_ste, &ste_info_head,
33626d688e3SAlex Vesker 						&send_ste_list, stats_tbl);
33726d688e3SAlex Vesker 			put_on_origin_table = false;
33826d688e3SAlex Vesker 		}
33926d688e3SAlex Vesker 	} else { /* Ste in the middle of the list */
3406b93b400SYevgeny Kliteynik 		dr_ste_remove_middle_ste(ste_ctx, ste,
3416b93b400SYevgeny Kliteynik 					 &ste_info_head, &send_ste_list,
3426b93b400SYevgeny Kliteynik 					 stats_tbl);
34326d688e3SAlex Vesker 	}
34426d688e3SAlex Vesker 
34526d688e3SAlex Vesker 	/* Update HW */
34626d688e3SAlex Vesker 	list_for_each_entry_safe(cur_ste_info, tmp_ste_info,
34726d688e3SAlex Vesker 				 &send_ste_list, send_list) {
34826d688e3SAlex Vesker 		list_del(&cur_ste_info->send_list);
34926d688e3SAlex Vesker 		mlx5dr_send_postsend_ste(dmn, cur_ste_info->ste,
35026d688e3SAlex Vesker 					 cur_ste_info->data, cur_ste_info->size,
35126d688e3SAlex Vesker 					 cur_ste_info->offset);
35226d688e3SAlex Vesker 	}
35326d688e3SAlex Vesker 
35426d688e3SAlex Vesker 	if (put_on_origin_table)
35526d688e3SAlex Vesker 		mlx5dr_htbl_put(ste->htbl);
35626d688e3SAlex Vesker }
35726d688e3SAlex Vesker 
35826d688e3SAlex Vesker bool mlx5dr_ste_equal_tag(void *src, void *dst)
35926d688e3SAlex Vesker {
36026d688e3SAlex Vesker 	struct dr_hw_ste_format *s_hw_ste = (struct dr_hw_ste_format *)src;
36126d688e3SAlex Vesker 	struct dr_hw_ste_format *d_hw_ste = (struct dr_hw_ste_format *)dst;
36226d688e3SAlex Vesker 
36326d688e3SAlex Vesker 	return !memcmp(s_hw_ste->tag, d_hw_ste->tag, DR_STE_SIZE_TAG);
36426d688e3SAlex Vesker }
36526d688e3SAlex Vesker 
3666b93b400SYevgeny Kliteynik void mlx5dr_ste_set_hit_addr_by_next_htbl(struct mlx5dr_ste_ctx *ste_ctx,
3676b93b400SYevgeny Kliteynik 					  u8 *hw_ste,
36826d688e3SAlex Vesker 					  struct mlx5dr_ste_htbl *next_htbl)
36926d688e3SAlex Vesker {
3705c4f9b6eSRongwei Liu 	u64 icm_addr = mlx5dr_icm_pool_get_chunk_icm_addr(next_htbl->chunk);
371f51bb517SRongwei Liu 	u32 num_entries =
372f51bb517SRongwei Liu 		mlx5dr_icm_pool_get_chunk_num_of_entries(next_htbl->chunk);
37326d688e3SAlex Vesker 
374f51bb517SRongwei Liu 	ste_ctx->set_hit_addr(hw_ste, icm_addr, num_entries);
37526d688e3SAlex Vesker }
37626d688e3SAlex Vesker 
3774fe45e1dSYevgeny Kliteynik void mlx5dr_ste_prepare_for_postsend(struct mlx5dr_ste_ctx *ste_ctx,
3784fe45e1dSYevgeny Kliteynik 				     u8 *hw_ste_p, u32 ste_size)
3794fe45e1dSYevgeny Kliteynik {
3804fe45e1dSYevgeny Kliteynik 	if (ste_ctx->prepare_for_postsend)
3814fe45e1dSYevgeny Kliteynik 		ste_ctx->prepare_for_postsend(hw_ste_p, ste_size);
3824fe45e1dSYevgeny Kliteynik }
3834fe45e1dSYevgeny Kliteynik 
38426d688e3SAlex Vesker /* Init one ste as a pattern for ste data array */
3856b93b400SYevgeny Kliteynik void mlx5dr_ste_set_formatted_ste(struct mlx5dr_ste_ctx *ste_ctx,
3866b93b400SYevgeny Kliteynik 				  u16 gvmi,
38746f2a8aeSYevgeny Kliteynik 				  enum mlx5dr_domain_nic_type nic_type,
38826d688e3SAlex Vesker 				  struct mlx5dr_ste_htbl *htbl,
38926d688e3SAlex Vesker 				  u8 *formatted_ste,
39026d688e3SAlex Vesker 				  struct mlx5dr_htbl_connect_info *connect_info)
39126d688e3SAlex Vesker {
39246f2a8aeSYevgeny Kliteynik 	bool is_rx = nic_type == DR_DOMAIN_NIC_TYPE_RX;
39326d688e3SAlex Vesker 	struct mlx5dr_ste ste = {};
39426d688e3SAlex Vesker 
39546f2a8aeSYevgeny Kliteynik 	ste_ctx->ste_init(formatted_ste, htbl->lu_type, is_rx, gvmi);
39626d688e3SAlex Vesker 	ste.hw_ste = formatted_ste;
39726d688e3SAlex Vesker 
39826d688e3SAlex Vesker 	if (connect_info->type == CONNECT_HIT)
3996b93b400SYevgeny Kliteynik 		dr_ste_always_hit_htbl(ste_ctx, &ste, connect_info->hit_next_htbl);
40026d688e3SAlex Vesker 	else
4016b93b400SYevgeny Kliteynik 		dr_ste_always_miss_addr(ste_ctx, &ste, connect_info->miss_icm_addr);
40226d688e3SAlex Vesker }
40326d688e3SAlex Vesker 
40426d688e3SAlex Vesker int mlx5dr_ste_htbl_init_and_postsend(struct mlx5dr_domain *dmn,
40526d688e3SAlex Vesker 				      struct mlx5dr_domain_rx_tx *nic_dmn,
40626d688e3SAlex Vesker 				      struct mlx5dr_ste_htbl *htbl,
40726d688e3SAlex Vesker 				      struct mlx5dr_htbl_connect_info *connect_info,
40826d688e3SAlex Vesker 				      bool update_hw_ste)
40926d688e3SAlex Vesker {
41026d688e3SAlex Vesker 	u8 formatted_ste[DR_STE_SIZE] = {};
41126d688e3SAlex Vesker 
4126b93b400SYevgeny Kliteynik 	mlx5dr_ste_set_formatted_ste(dmn->ste_ctx,
4136b93b400SYevgeny Kliteynik 				     dmn->info.caps.gvmi,
41446f2a8aeSYevgeny Kliteynik 				     nic_dmn->type,
41526d688e3SAlex Vesker 				     htbl,
41626d688e3SAlex Vesker 				     formatted_ste,
41726d688e3SAlex Vesker 				     connect_info);
41826d688e3SAlex Vesker 
41926d688e3SAlex Vesker 	return mlx5dr_send_postsend_formatted_htbl(dmn, htbl, formatted_ste, update_hw_ste);
42026d688e3SAlex Vesker }
42126d688e3SAlex Vesker 
42226d688e3SAlex Vesker int mlx5dr_ste_create_next_htbl(struct mlx5dr_matcher *matcher,
42326d688e3SAlex Vesker 				struct mlx5dr_matcher_rx_tx *nic_matcher,
42426d688e3SAlex Vesker 				struct mlx5dr_ste *ste,
42526d688e3SAlex Vesker 				u8 *cur_hw_ste,
42626d688e3SAlex Vesker 				enum mlx5dr_icm_chunk_size log_table_size)
42726d688e3SAlex Vesker {
42826d688e3SAlex Vesker 	struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn;
42926d688e3SAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
4306b93b400SYevgeny Kliteynik 	struct mlx5dr_ste_ctx *ste_ctx = dmn->ste_ctx;
43126d688e3SAlex Vesker 	struct mlx5dr_htbl_connect_info info;
43226d688e3SAlex Vesker 	struct mlx5dr_ste_htbl *next_htbl;
43326d688e3SAlex Vesker 
43426d688e3SAlex Vesker 	if (!mlx5dr_ste_is_last_in_rule(nic_matcher, ste->ste_chain_location)) {
435dd2d3c8dSYevgeny Kliteynik 		u16 next_lu_type;
43626d688e3SAlex Vesker 		u16 byte_mask;
43726d688e3SAlex Vesker 
4386b93b400SYevgeny Kliteynik 		next_lu_type = ste_ctx->get_next_lu_type(cur_hw_ste);
4396b93b400SYevgeny Kliteynik 		byte_mask = ste_ctx->get_byte_mask(cur_hw_ste);
44026d688e3SAlex Vesker 
44126d688e3SAlex Vesker 		next_htbl = mlx5dr_ste_htbl_alloc(dmn->ste_icm_pool,
44226d688e3SAlex Vesker 						  log_table_size,
44326d688e3SAlex Vesker 						  next_lu_type,
44426d688e3SAlex Vesker 						  byte_mask);
44526d688e3SAlex Vesker 		if (!next_htbl) {
44626d688e3SAlex Vesker 			mlx5dr_dbg(dmn, "Failed allocating table\n");
44726d688e3SAlex Vesker 			return -ENOMEM;
44826d688e3SAlex Vesker 		}
44926d688e3SAlex Vesker 
45026d688e3SAlex Vesker 		/* Write new table to HW */
45126d688e3SAlex Vesker 		info.type = CONNECT_MISS;
4525c4f9b6eSRongwei Liu 		info.miss_icm_addr =
4535c4f9b6eSRongwei Liu 			mlx5dr_icm_pool_get_chunk_icm_addr(nic_matcher->e_anchor->chunk);
45426d688e3SAlex Vesker 		if (mlx5dr_ste_htbl_init_and_postsend(dmn, nic_dmn, next_htbl,
45526d688e3SAlex Vesker 						      &info, false)) {
45626d688e3SAlex Vesker 			mlx5dr_info(dmn, "Failed writing table to HW\n");
45726d688e3SAlex Vesker 			goto free_table;
45826d688e3SAlex Vesker 		}
45926d688e3SAlex Vesker 
4606b93b400SYevgeny Kliteynik 		mlx5dr_ste_set_hit_addr_by_next_htbl(ste_ctx,
4616b93b400SYevgeny Kliteynik 						     cur_hw_ste, next_htbl);
46226d688e3SAlex Vesker 		ste->next_htbl = next_htbl;
46326d688e3SAlex Vesker 		next_htbl->pointing_ste = ste;
46426d688e3SAlex Vesker 	}
46526d688e3SAlex Vesker 
46626d688e3SAlex Vesker 	return 0;
46726d688e3SAlex Vesker 
46826d688e3SAlex Vesker free_table:
46926d688e3SAlex Vesker 	mlx5dr_ste_htbl_free(next_htbl);
47026d688e3SAlex Vesker 	return -ENOENT;
47126d688e3SAlex Vesker }
47226d688e3SAlex Vesker 
47326d688e3SAlex Vesker struct mlx5dr_ste_htbl *mlx5dr_ste_htbl_alloc(struct mlx5dr_icm_pool *pool,
47426d688e3SAlex Vesker 					      enum mlx5dr_icm_chunk_size chunk_size,
475dd2d3c8dSYevgeny Kliteynik 					      u16 lu_type, u16 byte_mask)
47626d688e3SAlex Vesker {
47726d688e3SAlex Vesker 	struct mlx5dr_icm_chunk *chunk;
47826d688e3SAlex Vesker 	struct mlx5dr_ste_htbl *htbl;
479f51bb517SRongwei Liu 	u32 num_entries;
48026d688e3SAlex Vesker 	int i;
48126d688e3SAlex Vesker 
48226d688e3SAlex Vesker 	htbl = kzalloc(sizeof(*htbl), GFP_KERNEL);
48326d688e3SAlex Vesker 	if (!htbl)
48426d688e3SAlex Vesker 		return NULL;
48526d688e3SAlex Vesker 
48626d688e3SAlex Vesker 	chunk = mlx5dr_icm_alloc_chunk(pool, chunk_size);
48726d688e3SAlex Vesker 	if (!chunk)
48826d688e3SAlex Vesker 		goto out_free_htbl;
48926d688e3SAlex Vesker 
49026d688e3SAlex Vesker 	htbl->chunk = chunk;
49126d688e3SAlex Vesker 	htbl->lu_type = lu_type;
49226d688e3SAlex Vesker 	htbl->byte_mask = byte_mask;
4934ce380caSYevgeny Kliteynik 	htbl->refcount = 0;
494f51bb517SRongwei Liu 	num_entries = mlx5dr_icm_pool_get_chunk_num_of_entries(chunk);
49526d688e3SAlex Vesker 
496f51bb517SRongwei Liu 	for (i = 0; i < num_entries; i++) {
497*597534bdSRongwei Liu 		struct mlx5dr_ste *ste = &chunk->ste_arr[i];
49826d688e3SAlex Vesker 
499*597534bdSRongwei Liu 		ste->hw_ste = chunk->hw_ste_arr + i * DR_STE_SIZE_REDUCED;
50026d688e3SAlex Vesker 		ste->htbl = htbl;
5014ce380caSYevgeny Kliteynik 		ste->refcount = 0;
50226d688e3SAlex Vesker 		INIT_LIST_HEAD(&ste->miss_list_node);
503*597534bdSRongwei Liu 		INIT_LIST_HEAD(&chunk->miss_list[i]);
50426d688e3SAlex Vesker 	}
50526d688e3SAlex Vesker 
50626d688e3SAlex Vesker 	return htbl;
50726d688e3SAlex Vesker 
50826d688e3SAlex Vesker out_free_htbl:
50926d688e3SAlex Vesker 	kfree(htbl);
51026d688e3SAlex Vesker 	return NULL;
51126d688e3SAlex Vesker }
51226d688e3SAlex Vesker 
51326d688e3SAlex Vesker int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl)
51426d688e3SAlex Vesker {
5154ce380caSYevgeny Kliteynik 	if (htbl->refcount)
51626d688e3SAlex Vesker 		return -EBUSY;
51726d688e3SAlex Vesker 
51826d688e3SAlex Vesker 	mlx5dr_icm_free_chunk(htbl->chunk);
51926d688e3SAlex Vesker 	kfree(htbl);
52026d688e3SAlex Vesker 	return 0;
52126d688e3SAlex Vesker }
52226d688e3SAlex Vesker 
5236b93b400SYevgeny Kliteynik void mlx5dr_ste_set_actions_tx(struct mlx5dr_ste_ctx *ste_ctx,
5246b93b400SYevgeny Kliteynik 			       struct mlx5dr_domain *dmn,
52564c78942SYevgeny Kliteynik 			       u8 *action_type_set,
526ad17dc8cSYevgeny Kliteynik 			       u8 *hw_ste_arr,
52764c78942SYevgeny Kliteynik 			       struct mlx5dr_ste_actions_attr *attr,
52864c78942SYevgeny Kliteynik 			       u32 *added_stes)
52964c78942SYevgeny Kliteynik {
530638a07f1SYevgeny Kliteynik 	ste_ctx->set_actions_tx(dmn, action_type_set, ste_ctx->actions_caps,
531638a07f1SYevgeny Kliteynik 				hw_ste_arr, attr, added_stes);
53264c78942SYevgeny Kliteynik }
53364c78942SYevgeny Kliteynik 
5346b93b400SYevgeny Kliteynik void mlx5dr_ste_set_actions_rx(struct mlx5dr_ste_ctx *ste_ctx,
5356b93b400SYevgeny Kliteynik 			       struct mlx5dr_domain *dmn,
53664c78942SYevgeny Kliteynik 			       u8 *action_type_set,
537ad17dc8cSYevgeny Kliteynik 			       u8 *hw_ste_arr,
53864c78942SYevgeny Kliteynik 			       struct mlx5dr_ste_actions_attr *attr,
53964c78942SYevgeny Kliteynik 			       u32 *added_stes)
54064c78942SYevgeny Kliteynik {
541638a07f1SYevgeny Kliteynik 	ste_ctx->set_actions_rx(dmn, action_type_set, ste_ctx->actions_caps,
542638a07f1SYevgeny Kliteynik 				hw_ste_arr, attr, added_stes);
54364c78942SYevgeny Kliteynik }
54464c78942SYevgeny Kliteynik 
5454781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field *
5464781df92SYevgeny Kliteynik mlx5dr_ste_conv_modify_hdr_sw_field(struct mlx5dr_ste_ctx *ste_ctx, u16 sw_field)
5474781df92SYevgeny Kliteynik {
5484781df92SYevgeny Kliteynik 	const struct mlx5dr_ste_action_modify_field *hw_field;
5494781df92SYevgeny Kliteynik 
5504781df92SYevgeny Kliteynik 	if (sw_field >= ste_ctx->modify_field_arr_sz)
5514781df92SYevgeny Kliteynik 		return NULL;
5524781df92SYevgeny Kliteynik 
5534781df92SYevgeny Kliteynik 	hw_field = &ste_ctx->modify_field_arr[sw_field];
5544781df92SYevgeny Kliteynik 	if (!hw_field->end && !hw_field->start)
5554781df92SYevgeny Kliteynik 		return NULL;
5564781df92SYevgeny Kliteynik 
5574781df92SYevgeny Kliteynik 	return hw_field;
5584781df92SYevgeny Kliteynik }
5594781df92SYevgeny Kliteynik 
5604781df92SYevgeny Kliteynik void mlx5dr_ste_set_action_set(struct mlx5dr_ste_ctx *ste_ctx,
5614781df92SYevgeny Kliteynik 			       __be64 *hw_action,
5624781df92SYevgeny Kliteynik 			       u8 hw_field,
5634781df92SYevgeny Kliteynik 			       u8 shifter,
5644781df92SYevgeny Kliteynik 			       u8 length,
5654781df92SYevgeny Kliteynik 			       u32 data)
5664781df92SYevgeny Kliteynik {
5674781df92SYevgeny Kliteynik 	ste_ctx->set_action_set((u8 *)hw_action,
5684781df92SYevgeny Kliteynik 				hw_field, shifter, length, data);
5694781df92SYevgeny Kliteynik }
5704781df92SYevgeny Kliteynik 
5714781df92SYevgeny Kliteynik void mlx5dr_ste_set_action_add(struct mlx5dr_ste_ctx *ste_ctx,
5724781df92SYevgeny Kliteynik 			       __be64 *hw_action,
5734781df92SYevgeny Kliteynik 			       u8 hw_field,
5744781df92SYevgeny Kliteynik 			       u8 shifter,
5754781df92SYevgeny Kliteynik 			       u8 length,
5764781df92SYevgeny Kliteynik 			       u32 data)
5774781df92SYevgeny Kliteynik {
5784781df92SYevgeny Kliteynik 	ste_ctx->set_action_add((u8 *)hw_action,
5794781df92SYevgeny Kliteynik 				hw_field, shifter, length, data);
5804781df92SYevgeny Kliteynik }
5814781df92SYevgeny Kliteynik 
5824781df92SYevgeny Kliteynik void mlx5dr_ste_set_action_copy(struct mlx5dr_ste_ctx *ste_ctx,
5834781df92SYevgeny Kliteynik 				__be64 *hw_action,
5844781df92SYevgeny Kliteynik 				u8 dst_hw_field,
5854781df92SYevgeny Kliteynik 				u8 dst_shifter,
5864781df92SYevgeny Kliteynik 				u8 dst_len,
5874781df92SYevgeny Kliteynik 				u8 src_hw_field,
5884781df92SYevgeny Kliteynik 				u8 src_shifter)
5894781df92SYevgeny Kliteynik {
5904781df92SYevgeny Kliteynik 	ste_ctx->set_action_copy((u8 *)hw_action,
5914781df92SYevgeny Kliteynik 				 dst_hw_field, dst_shifter, dst_len,
5924781df92SYevgeny Kliteynik 				 src_hw_field, src_shifter);
5934781df92SYevgeny Kliteynik }
5944781df92SYevgeny Kliteynik 
5954781df92SYevgeny Kliteynik int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx,
5964781df92SYevgeny Kliteynik 					void *data, u32 data_sz,
5974781df92SYevgeny Kliteynik 					u8 *hw_action, u32 hw_action_sz,
5984781df92SYevgeny Kliteynik 					u16 *used_hw_action_num)
5994781df92SYevgeny Kliteynik {
6004781df92SYevgeny Kliteynik 	/* Only Ethernet frame is supported, with VLAN (18) or without (14) */
6014781df92SYevgeny Kliteynik 	if (data_sz != HDR_LEN_L2 && data_sz != HDR_LEN_L2_W_VLAN)
6024781df92SYevgeny Kliteynik 		return -EINVAL;
6034781df92SYevgeny Kliteynik 
6044781df92SYevgeny Kliteynik 	return ste_ctx->set_action_decap_l3_list(data, data_sz,
6054781df92SYevgeny Kliteynik 						 hw_action, hw_action_sz,
6064781df92SYevgeny Kliteynik 						 used_hw_action_num);
6074781df92SYevgeny Kliteynik }
6084781df92SYevgeny Kliteynik 
609ffb0753bSYevgeny Kliteynik static int dr_ste_build_pre_check_spec(struct mlx5dr_domain *dmn,
610ffb0753bSYevgeny Kliteynik 				       struct mlx5dr_match_spec *spec)
611ffb0753bSYevgeny Kliteynik {
612ffb0753bSYevgeny Kliteynik 	if (spec->ip_version) {
613ffb0753bSYevgeny Kliteynik 		if (spec->ip_version != 0xf) {
614ffb0753bSYevgeny Kliteynik 			mlx5dr_err(dmn,
615ffb0753bSYevgeny Kliteynik 				   "Partial ip_version mask with src/dst IP is not supported\n");
616ffb0753bSYevgeny Kliteynik 			return -EINVAL;
617ffb0753bSYevgeny Kliteynik 		}
618ffb0753bSYevgeny Kliteynik 	} else if (spec->ethertype != 0xffff &&
619ffb0753bSYevgeny Kliteynik 		   (DR_MASK_IS_SRC_IP_SET(spec) || DR_MASK_IS_DST_IP_SET(spec))) {
620ffb0753bSYevgeny Kliteynik 		mlx5dr_err(dmn,
621ffb0753bSYevgeny Kliteynik 			   "Partial/no ethertype mask with src/dst IP is not supported\n");
622ffb0753bSYevgeny Kliteynik 		return -EINVAL;
623ffb0753bSYevgeny Kliteynik 	}
624ffb0753bSYevgeny Kliteynik 
625ffb0753bSYevgeny Kliteynik 	return 0;
626ffb0753bSYevgeny Kliteynik }
627ffb0753bSYevgeny Kliteynik 
62826d688e3SAlex Vesker int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
62926d688e3SAlex Vesker 			       u8 match_criteria,
63026d688e3SAlex Vesker 			       struct mlx5dr_match_param *mask,
63126d688e3SAlex Vesker 			       struct mlx5dr_match_param *value)
63226d688e3SAlex Vesker {
633ffb0753bSYevgeny Kliteynik 	if (value)
634ffb0753bSYevgeny Kliteynik 		return 0;
635ffb0753bSYevgeny Kliteynik 
636ffb0753bSYevgeny Kliteynik 	if (match_criteria & DR_MATCHER_CRITERIA_MISC) {
63726d688e3SAlex Vesker 		if (mask->misc.source_port && mask->misc.source_port != 0xffff) {
63838a5c59dSYevgeny Kliteynik 			mlx5dr_err(dmn,
63938a5c59dSYevgeny Kliteynik 				   "Partial mask source_port is not supported\n");
64038a5c59dSYevgeny Kliteynik 			return -EINVAL;
64138a5c59dSYevgeny Kliteynik 		}
64238a5c59dSYevgeny Kliteynik 		if (mask->misc.source_eswitch_owner_vhca_id &&
64338a5c59dSYevgeny Kliteynik 		    mask->misc.source_eswitch_owner_vhca_id != 0xffff) {
64438a5c59dSYevgeny Kliteynik 			mlx5dr_err(dmn,
64538a5c59dSYevgeny Kliteynik 				   "Partial mask source_eswitch_owner_vhca_id is not supported\n");
64626d688e3SAlex Vesker 			return -EINVAL;
64726d688e3SAlex Vesker 		}
64826d688e3SAlex Vesker 	}
64926d688e3SAlex Vesker 
650ffb0753bSYevgeny Kliteynik 	if ((match_criteria & DR_MATCHER_CRITERIA_OUTER) &&
651ffb0753bSYevgeny Kliteynik 	    dr_ste_build_pre_check_spec(dmn, &mask->outer))
652ffb0753bSYevgeny Kliteynik 		return -EINVAL;
653ffb0753bSYevgeny Kliteynik 
654ffb0753bSYevgeny Kliteynik 	if ((match_criteria & DR_MATCHER_CRITERIA_INNER) &&
655ffb0753bSYevgeny Kliteynik 	    dr_ste_build_pre_check_spec(dmn, &mask->inner))
656ffb0753bSYevgeny Kliteynik 		return -EINVAL;
657ffb0753bSYevgeny Kliteynik 
65826d688e3SAlex Vesker 	return 0;
65926d688e3SAlex Vesker }
66026d688e3SAlex Vesker 
66126d688e3SAlex Vesker int mlx5dr_ste_build_ste_arr(struct mlx5dr_matcher *matcher,
66226d688e3SAlex Vesker 			     struct mlx5dr_matcher_rx_tx *nic_matcher,
66326d688e3SAlex Vesker 			     struct mlx5dr_match_param *value,
66426d688e3SAlex Vesker 			     u8 *ste_arr)
66526d688e3SAlex Vesker {
66626d688e3SAlex Vesker 	struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn;
66746f2a8aeSYevgeny Kliteynik 	bool is_rx = nic_dmn->type == DR_DOMAIN_NIC_TYPE_RX;
66826d688e3SAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
6696b93b400SYevgeny Kliteynik 	struct mlx5dr_ste_ctx *ste_ctx = dmn->ste_ctx;
67026d688e3SAlex Vesker 	struct mlx5dr_ste_build *sb;
67126d688e3SAlex Vesker 	int ret, i;
67226d688e3SAlex Vesker 
67326d688e3SAlex Vesker 	ret = mlx5dr_ste_build_pre_check(dmn, matcher->match_criteria,
67426d688e3SAlex Vesker 					 &matcher->mask, value);
67526d688e3SAlex Vesker 	if (ret)
67626d688e3SAlex Vesker 		return ret;
67726d688e3SAlex Vesker 
67826d688e3SAlex Vesker 	sb = nic_matcher->ste_builder;
67926d688e3SAlex Vesker 	for (i = 0; i < nic_matcher->num_of_builders; i++) {
6806b93b400SYevgeny Kliteynik 		ste_ctx->ste_init(ste_arr,
68126d688e3SAlex Vesker 				  sb->lu_type,
68246f2a8aeSYevgeny Kliteynik 				  is_rx,
68326d688e3SAlex Vesker 				  dmn->info.caps.gvmi);
68426d688e3SAlex Vesker 
68526d688e3SAlex Vesker 		mlx5dr_ste_set_bit_mask(ste_arr, sb->bit_mask);
68626d688e3SAlex Vesker 
68764c78942SYevgeny Kliteynik 		ret = sb->ste_build_tag_func(value, sb, dr_ste_get_tag(ste_arr));
68826d688e3SAlex Vesker 		if (ret)
68926d688e3SAlex Vesker 			return ret;
69026d688e3SAlex Vesker 
69126d688e3SAlex Vesker 		/* Connect the STEs */
69226d688e3SAlex Vesker 		if (i < (nic_matcher->num_of_builders - 1)) {
69326d688e3SAlex Vesker 			/* Need the next builder for these fields,
69426d688e3SAlex Vesker 			 * not relevant for the last ste in the chain.
69526d688e3SAlex Vesker 			 */
69626d688e3SAlex Vesker 			sb++;
6976b93b400SYevgeny Kliteynik 			ste_ctx->set_next_lu_type(ste_arr, sb->lu_type);
6986b93b400SYevgeny Kliteynik 			ste_ctx->set_byte_mask(ste_arr, sb->byte_mask);
69926d688e3SAlex Vesker 		}
70026d688e3SAlex Vesker 		ste_arr += DR_STE_SIZE;
70126d688e3SAlex Vesker 	}
70226d688e3SAlex Vesker 	return 0;
70326d688e3SAlex Vesker }
70426d688e3SAlex Vesker 
705941f1979SMuhammad Sammar #define IFC_GET_CLR(typ, p, fld, clear) ({ \
706941f1979SMuhammad Sammar 	void *__p = (p); \
707941f1979SMuhammad Sammar 	u32 __t = MLX5_GET(typ, __p, fld); \
708941f1979SMuhammad Sammar 	if (clear) \
709941f1979SMuhammad Sammar 		MLX5_SET(typ, __p, fld, 0); \
710941f1979SMuhammad Sammar 	__t; \
711941f1979SMuhammad Sammar })
712941f1979SMuhammad Sammar 
713941f1979SMuhammad Sammar #define memcpy_and_clear(to, from, len, clear) ({ \
714941f1979SMuhammad Sammar 	void *__to = (to), *__from = (from); \
715941f1979SMuhammad Sammar 	size_t __len = (len); \
716941f1979SMuhammad Sammar 	memcpy(__to, __from, __len); \
717941f1979SMuhammad Sammar 	if (clear) \
718941f1979SMuhammad Sammar 		memset(__from, 0, __len); \
719941f1979SMuhammad Sammar })
720941f1979SMuhammad Sammar 
721941f1979SMuhammad Sammar static void dr_ste_copy_mask_misc(char *mask, struct mlx5dr_match_misc *spec, bool clr)
72226d688e3SAlex Vesker {
723941f1979SMuhammad Sammar 	spec->gre_c_present = IFC_GET_CLR(fte_match_set_misc, mask, gre_c_present, clr);
724941f1979SMuhammad Sammar 	spec->gre_k_present = IFC_GET_CLR(fte_match_set_misc, mask, gre_k_present, clr);
725941f1979SMuhammad Sammar 	spec->gre_s_present = IFC_GET_CLR(fte_match_set_misc, mask, gre_s_present, clr);
726941f1979SMuhammad Sammar 	spec->source_vhca_port = IFC_GET_CLR(fte_match_set_misc, mask, source_vhca_port, clr);
727941f1979SMuhammad Sammar 	spec->source_sqn = IFC_GET_CLR(fte_match_set_misc, mask, source_sqn, clr);
72826d688e3SAlex Vesker 
729941f1979SMuhammad Sammar 	spec->source_port = IFC_GET_CLR(fte_match_set_misc, mask, source_port, clr);
730941f1979SMuhammad Sammar 	spec->source_eswitch_owner_vhca_id =
731941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, source_eswitch_owner_vhca_id, clr);
73226d688e3SAlex Vesker 
733941f1979SMuhammad Sammar 	spec->outer_second_prio = IFC_GET_CLR(fte_match_set_misc, mask, outer_second_prio, clr);
734941f1979SMuhammad Sammar 	spec->outer_second_cfi = IFC_GET_CLR(fte_match_set_misc, mask, outer_second_cfi, clr);
735941f1979SMuhammad Sammar 	spec->outer_second_vid = IFC_GET_CLR(fte_match_set_misc, mask, outer_second_vid, clr);
736941f1979SMuhammad Sammar 	spec->inner_second_prio = IFC_GET_CLR(fte_match_set_misc, mask, inner_second_prio, clr);
737941f1979SMuhammad Sammar 	spec->inner_second_cfi = IFC_GET_CLR(fte_match_set_misc, mask, inner_second_cfi, clr);
738941f1979SMuhammad Sammar 	spec->inner_second_vid = IFC_GET_CLR(fte_match_set_misc, mask, inner_second_vid, clr);
73926d688e3SAlex Vesker 
74026d688e3SAlex Vesker 	spec->outer_second_cvlan_tag =
741941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, outer_second_cvlan_tag, clr);
74226d688e3SAlex Vesker 	spec->inner_second_cvlan_tag =
743941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, inner_second_cvlan_tag, clr);
74426d688e3SAlex Vesker 	spec->outer_second_svlan_tag =
745941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, outer_second_svlan_tag, clr);
74626d688e3SAlex Vesker 	spec->inner_second_svlan_tag =
747941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, inner_second_svlan_tag, clr);
748941f1979SMuhammad Sammar 	spec->gre_protocol = IFC_GET_CLR(fte_match_set_misc, mask, gre_protocol, clr);
74926d688e3SAlex Vesker 
750941f1979SMuhammad Sammar 	spec->gre_key_h = IFC_GET_CLR(fte_match_set_misc, mask, gre_key.nvgre.hi, clr);
751941f1979SMuhammad Sammar 	spec->gre_key_l = IFC_GET_CLR(fte_match_set_misc, mask, gre_key.nvgre.lo, clr);
75226d688e3SAlex Vesker 
753941f1979SMuhammad Sammar 	spec->vxlan_vni = IFC_GET_CLR(fte_match_set_misc, mask, vxlan_vni, clr);
75426d688e3SAlex Vesker 
755941f1979SMuhammad Sammar 	spec->geneve_vni = IFC_GET_CLR(fte_match_set_misc, mask, geneve_vni, clr);
756f59464e2SYevgeny Kliteynik 	spec->geneve_tlv_option_0_exist =
757f59464e2SYevgeny Kliteynik 		IFC_GET_CLR(fte_match_set_misc, mask, geneve_tlv_option_0_exist, clr);
758941f1979SMuhammad Sammar 	spec->geneve_oam = IFC_GET_CLR(fte_match_set_misc, mask, geneve_oam, clr);
75926d688e3SAlex Vesker 
76026d688e3SAlex Vesker 	spec->outer_ipv6_flow_label =
761941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, outer_ipv6_flow_label, clr);
76226d688e3SAlex Vesker 
76326d688e3SAlex Vesker 	spec->inner_ipv6_flow_label =
764941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, inner_ipv6_flow_label, clr);
76526d688e3SAlex Vesker 
766941f1979SMuhammad Sammar 	spec->geneve_opt_len = IFC_GET_CLR(fte_match_set_misc, mask, geneve_opt_len, clr);
76726d688e3SAlex Vesker 	spec->geneve_protocol_type =
768941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, geneve_protocol_type, clr);
76926d688e3SAlex Vesker 
770941f1979SMuhammad Sammar 	spec->bth_dst_qp = IFC_GET_CLR(fte_match_set_misc, mask, bth_dst_qp, clr);
77126d688e3SAlex Vesker }
77226d688e3SAlex Vesker 
773941f1979SMuhammad Sammar static void dr_ste_copy_mask_spec(char *mask, struct mlx5dr_match_spec *spec, bool clr)
77426d688e3SAlex Vesker {
775c2ba2c22SSaeed Mahameed 	__be32 raw_ip[4];
77626d688e3SAlex Vesker 
777941f1979SMuhammad Sammar 	spec->smac_47_16 = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, smac_47_16, clr);
77826d688e3SAlex Vesker 
779941f1979SMuhammad Sammar 	spec->smac_15_0 = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, smac_15_0, clr);
780941f1979SMuhammad Sammar 	spec->ethertype = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ethertype, clr);
78126d688e3SAlex Vesker 
782941f1979SMuhammad Sammar 	spec->dmac_47_16 = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, dmac_47_16, clr);
78326d688e3SAlex Vesker 
784941f1979SMuhammad Sammar 	spec->dmac_15_0 = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, dmac_15_0, clr);
785941f1979SMuhammad Sammar 	spec->first_prio = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, first_prio, clr);
786941f1979SMuhammad Sammar 	spec->first_cfi = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, first_cfi, clr);
787941f1979SMuhammad Sammar 	spec->first_vid = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, first_vid, clr);
78826d688e3SAlex Vesker 
789941f1979SMuhammad Sammar 	spec->ip_protocol = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ip_protocol, clr);
790941f1979SMuhammad Sammar 	spec->ip_dscp = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ip_dscp, clr);
791941f1979SMuhammad Sammar 	spec->ip_ecn = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ip_ecn, clr);
792941f1979SMuhammad Sammar 	spec->cvlan_tag = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, cvlan_tag, clr);
793941f1979SMuhammad Sammar 	spec->svlan_tag = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, svlan_tag, clr);
794941f1979SMuhammad Sammar 	spec->frag = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, frag, clr);
795941f1979SMuhammad Sammar 	spec->ip_version = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ip_version, clr);
796941f1979SMuhammad Sammar 	spec->tcp_flags = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, tcp_flags, clr);
797941f1979SMuhammad Sammar 	spec->tcp_sport = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, tcp_sport, clr);
798941f1979SMuhammad Sammar 	spec->tcp_dport = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, tcp_dport, clr);
79926d688e3SAlex Vesker 
8005c422bfaSYevgeny Kliteynik 	spec->ipv4_ihl = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ipv4_ihl, clr);
801941f1979SMuhammad Sammar 	spec->ttl_hoplimit = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ttl_hoplimit, clr);
80226d688e3SAlex Vesker 
803941f1979SMuhammad Sammar 	spec->udp_sport = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, udp_sport, clr);
804941f1979SMuhammad Sammar 	spec->udp_dport = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, udp_dport, clr);
80526d688e3SAlex Vesker 
806941f1979SMuhammad Sammar 	memcpy_and_clear(raw_ip, MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask,
80726d688e3SAlex Vesker 					      src_ipv4_src_ipv6.ipv6_layout.ipv6),
808941f1979SMuhammad Sammar 			 sizeof(raw_ip), clr);
80926d688e3SAlex Vesker 
81026d688e3SAlex Vesker 	spec->src_ip_127_96 = be32_to_cpu(raw_ip[0]);
81126d688e3SAlex Vesker 	spec->src_ip_95_64 = be32_to_cpu(raw_ip[1]);
81226d688e3SAlex Vesker 	spec->src_ip_63_32 = be32_to_cpu(raw_ip[2]);
81326d688e3SAlex Vesker 	spec->src_ip_31_0 = be32_to_cpu(raw_ip[3]);
81426d688e3SAlex Vesker 
815941f1979SMuhammad Sammar 	memcpy_and_clear(raw_ip, MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask,
81626d688e3SAlex Vesker 					      dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
817941f1979SMuhammad Sammar 			 sizeof(raw_ip), clr);
81826d688e3SAlex Vesker 
81926d688e3SAlex Vesker 	spec->dst_ip_127_96 = be32_to_cpu(raw_ip[0]);
82026d688e3SAlex Vesker 	spec->dst_ip_95_64 = be32_to_cpu(raw_ip[1]);
82126d688e3SAlex Vesker 	spec->dst_ip_63_32 = be32_to_cpu(raw_ip[2]);
82226d688e3SAlex Vesker 	spec->dst_ip_31_0 = be32_to_cpu(raw_ip[3]);
82326d688e3SAlex Vesker }
82426d688e3SAlex Vesker 
825941f1979SMuhammad Sammar static void dr_ste_copy_mask_misc2(char *mask, struct mlx5dr_match_misc2 *spec, bool clr)
82626d688e3SAlex Vesker {
82726d688e3SAlex Vesker 	spec->outer_first_mpls_label =
828941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls.mpls_label, clr);
82926d688e3SAlex Vesker 	spec->outer_first_mpls_exp =
830941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls.mpls_exp, clr);
83126d688e3SAlex Vesker 	spec->outer_first_mpls_s_bos =
832941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls.mpls_s_bos, clr);
83326d688e3SAlex Vesker 	spec->outer_first_mpls_ttl =
834941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls.mpls_ttl, clr);
83526d688e3SAlex Vesker 	spec->inner_first_mpls_label =
836941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, inner_first_mpls.mpls_label, clr);
83726d688e3SAlex Vesker 	spec->inner_first_mpls_exp =
838941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, inner_first_mpls.mpls_exp, clr);
83926d688e3SAlex Vesker 	spec->inner_first_mpls_s_bos =
840941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, inner_first_mpls.mpls_s_bos, clr);
84126d688e3SAlex Vesker 	spec->inner_first_mpls_ttl =
842941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, inner_first_mpls.mpls_ttl, clr);
84326d688e3SAlex Vesker 	spec->outer_first_mpls_over_gre_label =
844941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_label, clr);
84526d688e3SAlex Vesker 	spec->outer_first_mpls_over_gre_exp =
846941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_exp, clr);
84726d688e3SAlex Vesker 	spec->outer_first_mpls_over_gre_s_bos =
848941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_s_bos, clr);
84926d688e3SAlex Vesker 	spec->outer_first_mpls_over_gre_ttl =
850941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_ttl, clr);
85126d688e3SAlex Vesker 	spec->outer_first_mpls_over_udp_label =
852941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_label, clr);
85326d688e3SAlex Vesker 	spec->outer_first_mpls_over_udp_exp =
854941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_exp, clr);
85526d688e3SAlex Vesker 	spec->outer_first_mpls_over_udp_s_bos =
856941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_s_bos, clr);
85726d688e3SAlex Vesker 	spec->outer_first_mpls_over_udp_ttl =
858941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_ttl, clr);
859941f1979SMuhammad Sammar 	spec->metadata_reg_c_7 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_7, clr);
860941f1979SMuhammad Sammar 	spec->metadata_reg_c_6 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_6, clr);
861941f1979SMuhammad Sammar 	spec->metadata_reg_c_5 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_5, clr);
862941f1979SMuhammad Sammar 	spec->metadata_reg_c_4 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_4, clr);
863941f1979SMuhammad Sammar 	spec->metadata_reg_c_3 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_3, clr);
864941f1979SMuhammad Sammar 	spec->metadata_reg_c_2 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_2, clr);
865941f1979SMuhammad Sammar 	spec->metadata_reg_c_1 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_1, clr);
866941f1979SMuhammad Sammar 	spec->metadata_reg_c_0 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_0, clr);
867941f1979SMuhammad Sammar 	spec->metadata_reg_a = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_a, clr);
86826d688e3SAlex Vesker }
86926d688e3SAlex Vesker 
870941f1979SMuhammad Sammar static void dr_ste_copy_mask_misc3(char *mask, struct mlx5dr_match_misc3 *spec, bool clr)
87126d688e3SAlex Vesker {
872941f1979SMuhammad Sammar 	spec->inner_tcp_seq_num = IFC_GET_CLR(fte_match_set_misc3, mask, inner_tcp_seq_num, clr);
873941f1979SMuhammad Sammar 	spec->outer_tcp_seq_num = IFC_GET_CLR(fte_match_set_misc3, mask, outer_tcp_seq_num, clr);
874941f1979SMuhammad Sammar 	spec->inner_tcp_ack_num = IFC_GET_CLR(fte_match_set_misc3, mask, inner_tcp_ack_num, clr);
875941f1979SMuhammad Sammar 	spec->outer_tcp_ack_num = IFC_GET_CLR(fte_match_set_misc3, mask, outer_tcp_ack_num, clr);
87626d688e3SAlex Vesker 	spec->outer_vxlan_gpe_vni =
877941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, outer_vxlan_gpe_vni, clr);
87826d688e3SAlex Vesker 	spec->outer_vxlan_gpe_next_protocol =
879941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, outer_vxlan_gpe_next_protocol, clr);
88026d688e3SAlex Vesker 	spec->outer_vxlan_gpe_flags =
881941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, outer_vxlan_gpe_flags, clr);
882941f1979SMuhammad Sammar 	spec->icmpv4_header_data = IFC_GET_CLR(fte_match_set_misc3, mask, icmp_header_data, clr);
88326d688e3SAlex Vesker 	spec->icmpv6_header_data =
884941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, icmpv6_header_data, clr);
885941f1979SMuhammad Sammar 	spec->icmpv4_type = IFC_GET_CLR(fte_match_set_misc3, mask, icmp_type, clr);
886941f1979SMuhammad Sammar 	spec->icmpv4_code = IFC_GET_CLR(fte_match_set_misc3, mask, icmp_code, clr);
887941f1979SMuhammad Sammar 	spec->icmpv6_type = IFC_GET_CLR(fte_match_set_misc3, mask, icmpv6_type, clr);
888941f1979SMuhammad Sammar 	spec->icmpv6_code = IFC_GET_CLR(fte_match_set_misc3, mask, icmpv6_code, clr);
8893442e033SYevgeny Kliteynik 	spec->geneve_tlv_option_0_data =
890941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, geneve_tlv_option_0_data, clr);
891941f1979SMuhammad Sammar 	spec->gtpu_teid = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_teid, clr);
892941f1979SMuhammad Sammar 	spec->gtpu_msg_flags = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_msg_flags, clr);
893941f1979SMuhammad Sammar 	spec->gtpu_msg_type = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_msg_type, clr);
894941f1979SMuhammad Sammar 	spec->gtpu_dw_0 = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_dw_0, clr);
895941f1979SMuhammad Sammar 	spec->gtpu_dw_2 = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_dw_2, clr);
896df9dd15aSYevgeny Kliteynik 	spec->gtpu_first_ext_dw_0 =
897941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_first_ext_dw_0, clr);
89826d688e3SAlex Vesker }
89926d688e3SAlex Vesker 
900941f1979SMuhammad Sammar static void dr_ste_copy_mask_misc4(char *mask, struct mlx5dr_match_misc4 *spec, bool clr)
901160e9cb3SYevgeny Kliteynik {
902160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_id_0 =
903941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_id_0, clr);
904160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_value_0 =
905941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_value_0, clr);
906160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_id_1 =
907941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_id_1, clr);
908160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_value_1 =
909941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_value_1, clr);
910160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_id_2 =
911941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_id_2, clr);
912160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_value_2 =
913941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_value_2, clr);
914160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_id_3 =
915941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_id_3, clr);
916160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_value_3 =
917941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_value_3, clr);
918160e9cb3SYevgeny Kliteynik }
919160e9cb3SYevgeny Kliteynik 
9208c2b4feeSMuhammad Sammar static void dr_ste_copy_mask_misc5(char *mask, struct mlx5dr_match_misc5 *spec, bool clr)
9218c2b4feeSMuhammad Sammar {
9228c2b4feeSMuhammad Sammar 	spec->macsec_tag_0 =
9238c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, macsec_tag_0, clr);
9248c2b4feeSMuhammad Sammar 	spec->macsec_tag_1 =
9258c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, macsec_tag_1, clr);
9268c2b4feeSMuhammad Sammar 	spec->macsec_tag_2 =
9278c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, macsec_tag_2, clr);
9288c2b4feeSMuhammad Sammar 	spec->macsec_tag_3 =
9298c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, macsec_tag_3, clr);
9308c2b4feeSMuhammad Sammar 	spec->tunnel_header_0 =
9318c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, tunnel_header_0, clr);
9328c2b4feeSMuhammad Sammar 	spec->tunnel_header_1 =
9338c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, tunnel_header_1, clr);
9348c2b4feeSMuhammad Sammar 	spec->tunnel_header_2 =
9358c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, tunnel_header_2, clr);
9368c2b4feeSMuhammad Sammar 	spec->tunnel_header_3 =
9378c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, tunnel_header_3, clr);
9388c2b4feeSMuhammad Sammar }
9398c2b4feeSMuhammad Sammar 
94026d688e3SAlex Vesker void mlx5dr_ste_copy_param(u8 match_criteria,
94126d688e3SAlex Vesker 			   struct mlx5dr_match_param *set_param,
942941f1979SMuhammad Sammar 			   struct mlx5dr_match_parameters *mask,
943941f1979SMuhammad Sammar 			   bool clr)
94426d688e3SAlex Vesker {
94526d688e3SAlex Vesker 	u8 tail_param[MLX5_ST_SZ_BYTES(fte_match_set_lyr_2_4)] = {};
94626d688e3SAlex Vesker 	u8 *data = (u8 *)mask->match_buf;
94726d688e3SAlex Vesker 	size_t param_location;
94826d688e3SAlex Vesker 	void *buff;
94926d688e3SAlex Vesker 
95026d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_OUTER) {
95126d688e3SAlex Vesker 		if (mask->match_sz < sizeof(struct mlx5dr_match_spec)) {
95226d688e3SAlex Vesker 			memcpy(tail_param, data, mask->match_sz);
95326d688e3SAlex Vesker 			buff = tail_param;
95426d688e3SAlex Vesker 		} else {
95526d688e3SAlex Vesker 			buff = mask->match_buf;
95626d688e3SAlex Vesker 		}
957941f1979SMuhammad Sammar 		dr_ste_copy_mask_spec(buff, &set_param->outer, clr);
95826d688e3SAlex Vesker 	}
95926d688e3SAlex Vesker 	param_location = sizeof(struct mlx5dr_match_spec);
96026d688e3SAlex Vesker 
96126d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_MISC) {
96226d688e3SAlex Vesker 		if (mask->match_sz < param_location +
96326d688e3SAlex Vesker 		    sizeof(struct mlx5dr_match_misc)) {
96426d688e3SAlex Vesker 			memcpy(tail_param, data + param_location,
96526d688e3SAlex Vesker 			       mask->match_sz - param_location);
96626d688e3SAlex Vesker 			buff = tail_param;
96726d688e3SAlex Vesker 		} else {
96826d688e3SAlex Vesker 			buff = data + param_location;
96926d688e3SAlex Vesker 		}
970941f1979SMuhammad Sammar 		dr_ste_copy_mask_misc(buff, &set_param->misc, clr);
97126d688e3SAlex Vesker 	}
97226d688e3SAlex Vesker 	param_location += sizeof(struct mlx5dr_match_misc);
97326d688e3SAlex Vesker 
97426d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_INNER) {
97526d688e3SAlex Vesker 		if (mask->match_sz < param_location +
97626d688e3SAlex Vesker 		    sizeof(struct mlx5dr_match_spec)) {
97726d688e3SAlex Vesker 			memcpy(tail_param, data + param_location,
97826d688e3SAlex Vesker 			       mask->match_sz - param_location);
97926d688e3SAlex Vesker 			buff = tail_param;
98026d688e3SAlex Vesker 		} else {
98126d688e3SAlex Vesker 			buff = data + param_location;
98226d688e3SAlex Vesker 		}
983941f1979SMuhammad Sammar 		dr_ste_copy_mask_spec(buff, &set_param->inner, clr);
98426d688e3SAlex Vesker 	}
98526d688e3SAlex Vesker 	param_location += sizeof(struct mlx5dr_match_spec);
98626d688e3SAlex Vesker 
98726d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_MISC2) {
98826d688e3SAlex Vesker 		if (mask->match_sz < param_location +
98926d688e3SAlex Vesker 		    sizeof(struct mlx5dr_match_misc2)) {
99026d688e3SAlex Vesker 			memcpy(tail_param, data + param_location,
99126d688e3SAlex Vesker 			       mask->match_sz - param_location);
99226d688e3SAlex Vesker 			buff = tail_param;
99326d688e3SAlex Vesker 		} else {
99426d688e3SAlex Vesker 			buff = data + param_location;
99526d688e3SAlex Vesker 		}
996941f1979SMuhammad Sammar 		dr_ste_copy_mask_misc2(buff, &set_param->misc2, clr);
99726d688e3SAlex Vesker 	}
99826d688e3SAlex Vesker 
99926d688e3SAlex Vesker 	param_location += sizeof(struct mlx5dr_match_misc2);
100026d688e3SAlex Vesker 
100126d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_MISC3) {
100226d688e3SAlex Vesker 		if (mask->match_sz < param_location +
100326d688e3SAlex Vesker 		    sizeof(struct mlx5dr_match_misc3)) {
100426d688e3SAlex Vesker 			memcpy(tail_param, data + param_location,
100526d688e3SAlex Vesker 			       mask->match_sz - param_location);
100626d688e3SAlex Vesker 			buff = tail_param;
100726d688e3SAlex Vesker 		} else {
100826d688e3SAlex Vesker 			buff = data + param_location;
100926d688e3SAlex Vesker 		}
1010941f1979SMuhammad Sammar 		dr_ste_copy_mask_misc3(buff, &set_param->misc3, clr);
101126d688e3SAlex Vesker 	}
1012160e9cb3SYevgeny Kliteynik 
1013160e9cb3SYevgeny Kliteynik 	param_location += sizeof(struct mlx5dr_match_misc3);
1014160e9cb3SYevgeny Kliteynik 
1015160e9cb3SYevgeny Kliteynik 	if (match_criteria & DR_MATCHER_CRITERIA_MISC4) {
1016160e9cb3SYevgeny Kliteynik 		if (mask->match_sz < param_location +
1017160e9cb3SYevgeny Kliteynik 		    sizeof(struct mlx5dr_match_misc4)) {
1018160e9cb3SYevgeny Kliteynik 			memcpy(tail_param, data + param_location,
1019160e9cb3SYevgeny Kliteynik 			       mask->match_sz - param_location);
1020160e9cb3SYevgeny Kliteynik 			buff = tail_param;
1021160e9cb3SYevgeny Kliteynik 		} else {
1022160e9cb3SYevgeny Kliteynik 			buff = data + param_location;
1023160e9cb3SYevgeny Kliteynik 		}
1024941f1979SMuhammad Sammar 		dr_ste_copy_mask_misc4(buff, &set_param->misc4, clr);
1025160e9cb3SYevgeny Kliteynik 	}
10268c2b4feeSMuhammad Sammar 
10278c2b4feeSMuhammad Sammar 	param_location += sizeof(struct mlx5dr_match_misc4);
10288c2b4feeSMuhammad Sammar 
10298c2b4feeSMuhammad Sammar 	if (match_criteria & DR_MATCHER_CRITERIA_MISC5) {
10308c2b4feeSMuhammad Sammar 		if (mask->match_sz < param_location +
10318c2b4feeSMuhammad Sammar 		    sizeof(struct mlx5dr_match_misc5)) {
10328c2b4feeSMuhammad Sammar 			memcpy(tail_param, data + param_location,
10338c2b4feeSMuhammad Sammar 			       mask->match_sz - param_location);
10348c2b4feeSMuhammad Sammar 			buff = tail_param;
10358c2b4feeSMuhammad Sammar 		} else {
10368c2b4feeSMuhammad Sammar 			buff = data + param_location;
10378c2b4feeSMuhammad Sammar 		}
10388c2b4feeSMuhammad Sammar 		dr_ste_copy_mask_misc5(buff, &set_param->misc5, clr);
10398c2b4feeSMuhammad Sammar 	}
104026d688e3SAlex Vesker }
104126d688e3SAlex Vesker 
10425212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l2_src_dst(struct mlx5dr_ste_ctx *ste_ctx,
10435212f9c6SYevgeny Kliteynik 				     struct mlx5dr_ste_build *sb,
104426d688e3SAlex Vesker 				     struct mlx5dr_match_param *mask,
104526d688e3SAlex Vesker 				     bool inner, bool rx)
104626d688e3SAlex Vesker {
104726d688e3SAlex Vesker 	sb->rx = rx;
104826d688e3SAlex Vesker 	sb->inner = inner;
10495212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l2_src_dst_init(sb, mask);
105026d688e3SAlex Vesker }
105126d688e3SAlex Vesker 
10525212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l3_ipv6_dst(struct mlx5dr_ste_ctx *ste_ctx,
10535212f9c6SYevgeny Kliteynik 				      struct mlx5dr_ste_build *sb,
105426d688e3SAlex Vesker 				      struct mlx5dr_match_param *mask,
105526d688e3SAlex Vesker 				      bool inner, bool rx)
105626d688e3SAlex Vesker {
105726d688e3SAlex Vesker 	sb->rx = rx;
105826d688e3SAlex Vesker 	sb->inner = inner;
10595212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l3_ipv6_dst_init(sb, mask);
106026d688e3SAlex Vesker }
106126d688e3SAlex Vesker 
10625212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l3_ipv6_src(struct mlx5dr_ste_ctx *ste_ctx,
10635212f9c6SYevgeny Kliteynik 				      struct mlx5dr_ste_build *sb,
106426d688e3SAlex Vesker 				      struct mlx5dr_match_param *mask,
106526d688e3SAlex Vesker 				      bool inner, bool rx)
106626d688e3SAlex Vesker {
106726d688e3SAlex Vesker 	sb->rx = rx;
106826d688e3SAlex Vesker 	sb->inner = inner;
10695212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l3_ipv6_src_init(sb, mask);
107026d688e3SAlex Vesker }
107126d688e3SAlex Vesker 
10725212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l3_ipv4_5_tuple(struct mlx5dr_ste_ctx *ste_ctx,
10735212f9c6SYevgeny Kliteynik 					  struct mlx5dr_ste_build *sb,
107426d688e3SAlex Vesker 					  struct mlx5dr_match_param *mask,
107526d688e3SAlex Vesker 					  bool inner, bool rx)
107626d688e3SAlex Vesker {
107726d688e3SAlex Vesker 	sb->rx = rx;
107826d688e3SAlex Vesker 	sb->inner = inner;
10795212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l3_ipv4_5_tuple_init(sb, mask);
108026d688e3SAlex Vesker }
108126d688e3SAlex Vesker 
10825212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l2_src(struct mlx5dr_ste_ctx *ste_ctx,
10835212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
108426d688e3SAlex Vesker 				 struct mlx5dr_match_param *mask,
108526d688e3SAlex Vesker 				 bool inner, bool rx)
108626d688e3SAlex Vesker {
108726d688e3SAlex Vesker 	sb->rx = rx;
108826d688e3SAlex Vesker 	sb->inner = inner;
10895212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l2_src_init(sb, mask);
109026d688e3SAlex Vesker }
109126d688e3SAlex Vesker 
10925212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l2_dst(struct mlx5dr_ste_ctx *ste_ctx,
10935212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
109426d688e3SAlex Vesker 				 struct mlx5dr_match_param *mask,
109526d688e3SAlex Vesker 				 bool inner, bool rx)
109626d688e3SAlex Vesker {
109726d688e3SAlex Vesker 	sb->rx = rx;
109826d688e3SAlex Vesker 	sb->inner = inner;
10995212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l2_dst_init(sb, mask);
110026d688e3SAlex Vesker }
110126d688e3SAlex Vesker 
11025212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l2_tnl(struct mlx5dr_ste_ctx *ste_ctx,
11035212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
11045212f9c6SYevgeny Kliteynik 				 struct mlx5dr_match_param *mask, bool inner, bool rx)
11055212f9c6SYevgeny Kliteynik {
11065212f9c6SYevgeny Kliteynik 	sb->rx = rx;
11075212f9c6SYevgeny Kliteynik 	sb->inner = inner;
11085212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l2_tnl_init(sb, mask);
11095212f9c6SYevgeny Kliteynik }
11105212f9c6SYevgeny Kliteynik 
11115212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l3_ipv4_misc(struct mlx5dr_ste_ctx *ste_ctx,
11125212f9c6SYevgeny Kliteynik 				       struct mlx5dr_ste_build *sb,
111326d688e3SAlex Vesker 				       struct mlx5dr_match_param *mask,
111426d688e3SAlex Vesker 				       bool inner, bool rx)
111526d688e3SAlex Vesker {
111626d688e3SAlex Vesker 	sb->rx = rx;
111726d688e3SAlex Vesker 	sb->inner = inner;
11185212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l3_ipv4_misc_init(sb, mask);
111926d688e3SAlex Vesker }
112026d688e3SAlex Vesker 
11215212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_ipv6_l3_l4(struct mlx5dr_ste_ctx *ste_ctx,
11225212f9c6SYevgeny Kliteynik 				     struct mlx5dr_ste_build *sb,
112326d688e3SAlex Vesker 				     struct mlx5dr_match_param *mask,
112426d688e3SAlex Vesker 				     bool inner, bool rx)
112526d688e3SAlex Vesker {
112626d688e3SAlex Vesker 	sb->rx = rx;
112726d688e3SAlex Vesker 	sb->inner = inner;
11285212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_ipv6_l3_l4_init(sb, mask);
112926d688e3SAlex Vesker }
113026d688e3SAlex Vesker 
113126d688e3SAlex Vesker static int dr_ste_build_empty_always_hit_tag(struct mlx5dr_match_param *value,
113226d688e3SAlex Vesker 					     struct mlx5dr_ste_build *sb,
1133e6b69bf3SYevgeny Kliteynik 					     u8 *tag)
113426d688e3SAlex Vesker {
113526d688e3SAlex Vesker 	return 0;
113626d688e3SAlex Vesker }
113726d688e3SAlex Vesker 
113826d688e3SAlex Vesker void mlx5dr_ste_build_empty_always_hit(struct mlx5dr_ste_build *sb, bool rx)
113926d688e3SAlex Vesker {
114026d688e3SAlex Vesker 	sb->rx = rx;
114126d688e3SAlex Vesker 	sb->lu_type = MLX5DR_STE_LU_TYPE_DONT_CARE;
114226d688e3SAlex Vesker 	sb->byte_mask = 0;
114326d688e3SAlex Vesker 	sb->ste_build_tag_func = &dr_ste_build_empty_always_hit_tag;
114426d688e3SAlex Vesker }
114526d688e3SAlex Vesker 
11465212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_mpls(struct mlx5dr_ste_ctx *ste_ctx,
11475212f9c6SYevgeny Kliteynik 			   struct mlx5dr_ste_build *sb,
114826d688e3SAlex Vesker 			   struct mlx5dr_match_param *mask,
114926d688e3SAlex Vesker 			   bool inner, bool rx)
115026d688e3SAlex Vesker {
115126d688e3SAlex Vesker 	sb->rx = rx;
115226d688e3SAlex Vesker 	sb->inner = inner;
11535212f9c6SYevgeny Kliteynik 	ste_ctx->build_mpls_init(sb, mask);
115426d688e3SAlex Vesker }
115526d688e3SAlex Vesker 
11565212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_tnl_gre(struct mlx5dr_ste_ctx *ste_ctx,
11575212f9c6SYevgeny Kliteynik 			      struct mlx5dr_ste_build *sb,
11585212f9c6SYevgeny Kliteynik 			      struct mlx5dr_match_param *mask,
11595212f9c6SYevgeny Kliteynik 			      bool inner, bool rx)
11605212f9c6SYevgeny Kliteynik {
11615212f9c6SYevgeny Kliteynik 	sb->rx = rx;
11625212f9c6SYevgeny Kliteynik 	sb->inner = inner;
11635212f9c6SYevgeny Kliteynik 	ste_ctx->build_tnl_gre_init(sb, mask);
11645212f9c6SYevgeny Kliteynik }
11655212f9c6SYevgeny Kliteynik 
116635ba005dSYevgeny Kliteynik void mlx5dr_ste_build_tnl_mpls_over_gre(struct mlx5dr_ste_ctx *ste_ctx,
11675212f9c6SYevgeny Kliteynik 					struct mlx5dr_ste_build *sb,
116826d688e3SAlex Vesker 					struct mlx5dr_match_param *mask,
116935ba005dSYevgeny Kliteynik 					struct mlx5dr_cmd_caps *caps,
117026d688e3SAlex Vesker 					bool inner, bool rx)
117126d688e3SAlex Vesker {
117226d688e3SAlex Vesker 	sb->rx = rx;
117326d688e3SAlex Vesker 	sb->inner = inner;
117435ba005dSYevgeny Kliteynik 	sb->caps = caps;
117535ba005dSYevgeny Kliteynik 	return ste_ctx->build_tnl_mpls_over_gre_init(sb, mask);
117635ba005dSYevgeny Kliteynik }
117735ba005dSYevgeny Kliteynik 
117835ba005dSYevgeny Kliteynik void mlx5dr_ste_build_tnl_mpls_over_udp(struct mlx5dr_ste_ctx *ste_ctx,
117935ba005dSYevgeny Kliteynik 					struct mlx5dr_ste_build *sb,
118035ba005dSYevgeny Kliteynik 					struct mlx5dr_match_param *mask,
118135ba005dSYevgeny Kliteynik 					struct mlx5dr_cmd_caps *caps,
118235ba005dSYevgeny Kliteynik 					bool inner, bool rx)
118335ba005dSYevgeny Kliteynik {
118435ba005dSYevgeny Kliteynik 	sb->rx = rx;
118535ba005dSYevgeny Kliteynik 	sb->inner = inner;
118635ba005dSYevgeny Kliteynik 	sb->caps = caps;
118735ba005dSYevgeny Kliteynik 	return ste_ctx->build_tnl_mpls_over_udp_init(sb, mask);
118826d688e3SAlex Vesker }
118926d688e3SAlex Vesker 
11904923938dSYevgeny Kliteynik void mlx5dr_ste_build_icmp(struct mlx5dr_ste_ctx *ste_ctx,
11915212f9c6SYevgeny Kliteynik 			   struct mlx5dr_ste_build *sb,
11925212f9c6SYevgeny Kliteynik 			   struct mlx5dr_match_param *mask,
11935212f9c6SYevgeny Kliteynik 			   struct mlx5dr_cmd_caps *caps,
11945212f9c6SYevgeny Kliteynik 			   bool inner, bool rx)
11955212f9c6SYevgeny Kliteynik {
11965212f9c6SYevgeny Kliteynik 	sb->rx = rx;
11975212f9c6SYevgeny Kliteynik 	sb->inner = inner;
11985212f9c6SYevgeny Kliteynik 	sb->caps = caps;
11994923938dSYevgeny Kliteynik 	ste_ctx->build_icmp_init(sb, mask);
12005212f9c6SYevgeny Kliteynik }
12015212f9c6SYevgeny Kliteynik 
12025212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_general_purpose(struct mlx5dr_ste_ctx *ste_ctx,
12035212f9c6SYevgeny Kliteynik 				      struct mlx5dr_ste_build *sb,
120426d688e3SAlex Vesker 				      struct mlx5dr_match_param *mask,
120526d688e3SAlex Vesker 				      bool inner, bool rx)
120626d688e3SAlex Vesker {
120726d688e3SAlex Vesker 	sb->rx = rx;
120826d688e3SAlex Vesker 	sb->inner = inner;
12095212f9c6SYevgeny Kliteynik 	ste_ctx->build_general_purpose_init(sb, mask);
121026d688e3SAlex Vesker }
121126d688e3SAlex Vesker 
12125212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l4_misc(struct mlx5dr_ste_ctx *ste_ctx,
12135212f9c6SYevgeny Kliteynik 				  struct mlx5dr_ste_build *sb,
121426d688e3SAlex Vesker 				  struct mlx5dr_match_param *mask,
121526d688e3SAlex Vesker 				  bool inner, bool rx)
121626d688e3SAlex Vesker {
121726d688e3SAlex Vesker 	sb->rx = rx;
121826d688e3SAlex Vesker 	sb->inner = inner;
12195212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l4_misc_init(sb, mask);
122026d688e3SAlex Vesker }
122126d688e3SAlex Vesker 
12225212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_tnl_vxlan_gpe(struct mlx5dr_ste_ctx *ste_ctx,
12235212f9c6SYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
122426d688e3SAlex Vesker 				    struct mlx5dr_match_param *mask,
122526d688e3SAlex Vesker 				    bool inner, bool rx)
122626d688e3SAlex Vesker {
122726d688e3SAlex Vesker 	sb->rx = rx;
122826d688e3SAlex Vesker 	sb->inner = inner;
12295212f9c6SYevgeny Kliteynik 	ste_ctx->build_tnl_vxlan_gpe_init(sb, mask);
123026d688e3SAlex Vesker }
123126d688e3SAlex Vesker 
12325212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_tnl_geneve(struct mlx5dr_ste_ctx *ste_ctx,
12335212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
1234b6d12238SYevgeny Kliteynik 				 struct mlx5dr_match_param *mask,
1235b6d12238SYevgeny Kliteynik 				 bool inner, bool rx)
1236b6d12238SYevgeny Kliteynik {
1237b6d12238SYevgeny Kliteynik 	sb->rx = rx;
1238b6d12238SYevgeny Kliteynik 	sb->inner = inner;
12395212f9c6SYevgeny Kliteynik 	ste_ctx->build_tnl_geneve_init(sb, mask);
124026d688e3SAlex Vesker }
124126d688e3SAlex Vesker 
12423442e033SYevgeny Kliteynik void mlx5dr_ste_build_tnl_geneve_tlv_opt(struct mlx5dr_ste_ctx *ste_ctx,
12433442e033SYevgeny Kliteynik 					 struct mlx5dr_ste_build *sb,
12443442e033SYevgeny Kliteynik 					 struct mlx5dr_match_param *mask,
12453442e033SYevgeny Kliteynik 					 struct mlx5dr_cmd_caps *caps,
12463442e033SYevgeny Kliteynik 					 bool inner, bool rx)
12473442e033SYevgeny Kliteynik {
12483442e033SYevgeny Kliteynik 	sb->rx = rx;
12493442e033SYevgeny Kliteynik 	sb->caps = caps;
12503442e033SYevgeny Kliteynik 	sb->inner = inner;
12513442e033SYevgeny Kliteynik 	ste_ctx->build_tnl_geneve_tlv_opt_init(sb, mask);
12523442e033SYevgeny Kliteynik }
12533442e033SYevgeny Kliteynik 
1254f59464e2SYevgeny Kliteynik void mlx5dr_ste_build_tnl_geneve_tlv_opt_exist(struct mlx5dr_ste_ctx *ste_ctx,
1255f59464e2SYevgeny Kliteynik 					       struct mlx5dr_ste_build *sb,
1256f59464e2SYevgeny Kliteynik 					       struct mlx5dr_match_param *mask,
1257f59464e2SYevgeny Kliteynik 					       struct mlx5dr_cmd_caps *caps,
1258f59464e2SYevgeny Kliteynik 					       bool inner, bool rx)
1259f59464e2SYevgeny Kliteynik {
1260f59464e2SYevgeny Kliteynik 	if (!ste_ctx->build_tnl_geneve_tlv_opt_exist_init)
1261f59464e2SYevgeny Kliteynik 		return;
1262f59464e2SYevgeny Kliteynik 
1263f59464e2SYevgeny Kliteynik 	sb->rx = rx;
1264f59464e2SYevgeny Kliteynik 	sb->caps = caps;
1265f59464e2SYevgeny Kliteynik 	sb->inner = inner;
1266f59464e2SYevgeny Kliteynik 	ste_ctx->build_tnl_geneve_tlv_opt_exist_init(sb, mask);
1267f59464e2SYevgeny Kliteynik }
1268f59464e2SYevgeny Kliteynik 
1269df9dd15aSYevgeny Kliteynik void mlx5dr_ste_build_tnl_gtpu(struct mlx5dr_ste_ctx *ste_ctx,
1270df9dd15aSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
1271df9dd15aSYevgeny Kliteynik 			       struct mlx5dr_match_param *mask,
1272df9dd15aSYevgeny Kliteynik 			       bool inner, bool rx)
1273df9dd15aSYevgeny Kliteynik {
1274df9dd15aSYevgeny Kliteynik 	sb->rx = rx;
1275df9dd15aSYevgeny Kliteynik 	sb->inner = inner;
1276df9dd15aSYevgeny Kliteynik 	ste_ctx->build_tnl_gtpu_init(sb, mask);
1277df9dd15aSYevgeny Kliteynik }
1278df9dd15aSYevgeny Kliteynik 
1279df9dd15aSYevgeny Kliteynik void mlx5dr_ste_build_tnl_gtpu_flex_parser_0(struct mlx5dr_ste_ctx *ste_ctx,
1280df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_ste_build *sb,
1281df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_match_param *mask,
1282df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_cmd_caps *caps,
1283df9dd15aSYevgeny Kliteynik 					     bool inner, bool rx)
1284df9dd15aSYevgeny Kliteynik {
1285df9dd15aSYevgeny Kliteynik 	sb->rx = rx;
1286df9dd15aSYevgeny Kliteynik 	sb->caps = caps;
1287df9dd15aSYevgeny Kliteynik 	sb->inner = inner;
1288df9dd15aSYevgeny Kliteynik 	ste_ctx->build_tnl_gtpu_flex_parser_0_init(sb, mask);
1289df9dd15aSYevgeny Kliteynik }
1290df9dd15aSYevgeny Kliteynik 
1291df9dd15aSYevgeny Kliteynik void mlx5dr_ste_build_tnl_gtpu_flex_parser_1(struct mlx5dr_ste_ctx *ste_ctx,
1292df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_ste_build *sb,
1293df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_match_param *mask,
1294df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_cmd_caps *caps,
1295df9dd15aSYevgeny Kliteynik 					     bool inner, bool rx)
1296df9dd15aSYevgeny Kliteynik {
1297df9dd15aSYevgeny Kliteynik 	sb->rx = rx;
1298df9dd15aSYevgeny Kliteynik 	sb->caps = caps;
1299df9dd15aSYevgeny Kliteynik 	sb->inner = inner;
1300df9dd15aSYevgeny Kliteynik 	ste_ctx->build_tnl_gtpu_flex_parser_1_init(sb, mask);
1301df9dd15aSYevgeny Kliteynik }
1302df9dd15aSYevgeny Kliteynik 
13035212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_register_0(struct mlx5dr_ste_ctx *ste_ctx,
13045212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
130526d688e3SAlex Vesker 				 struct mlx5dr_match_param *mask,
130626d688e3SAlex Vesker 				 bool inner, bool rx)
130726d688e3SAlex Vesker {
130826d688e3SAlex Vesker 	sb->rx = rx;
130926d688e3SAlex Vesker 	sb->inner = inner;
13105212f9c6SYevgeny Kliteynik 	ste_ctx->build_register_0_init(sb, mask);
131126d688e3SAlex Vesker }
131226d688e3SAlex Vesker 
13135212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_register_1(struct mlx5dr_ste_ctx *ste_ctx,
13145212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
131526d688e3SAlex Vesker 				 struct mlx5dr_match_param *mask,
131626d688e3SAlex Vesker 				 bool inner, bool rx)
131726d688e3SAlex Vesker {
131826d688e3SAlex Vesker 	sb->rx = rx;
131926d688e3SAlex Vesker 	sb->inner = inner;
13205212f9c6SYevgeny Kliteynik 	ste_ctx->build_register_1_init(sb, mask);
132126d688e3SAlex Vesker }
132226d688e3SAlex Vesker 
13235212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_src_gvmi_qpn(struct mlx5dr_ste_ctx *ste_ctx,
13245212f9c6SYevgeny Kliteynik 				   struct mlx5dr_ste_build *sb,
132526d688e3SAlex Vesker 				   struct mlx5dr_match_param *mask,
1326640bdb1fSAlaa Hleihel 				   struct mlx5dr_domain *dmn,
132726d688e3SAlex Vesker 				   bool inner, bool rx)
132826d688e3SAlex Vesker {
1329640bdb1fSAlaa Hleihel 	/* Set vhca_id_valid before we reset source_eswitch_owner_vhca_id */
1330640bdb1fSAlaa Hleihel 	sb->vhca_id_valid = mask->misc.source_eswitch_owner_vhca_id;
1331640bdb1fSAlaa Hleihel 
133226d688e3SAlex Vesker 	sb->rx = rx;
1333640bdb1fSAlaa Hleihel 	sb->dmn = dmn;
133426d688e3SAlex Vesker 	sb->inner = inner;
13355212f9c6SYevgeny Kliteynik 	ste_ctx->build_src_gvmi_qpn_init(sb, mask);
13365212f9c6SYevgeny Kliteynik }
13375212f9c6SYevgeny Kliteynik 
1338160e9cb3SYevgeny Kliteynik void mlx5dr_ste_build_flex_parser_0(struct mlx5dr_ste_ctx *ste_ctx,
1339160e9cb3SYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
1340160e9cb3SYevgeny Kliteynik 				    struct mlx5dr_match_param *mask,
1341160e9cb3SYevgeny Kliteynik 				    bool inner, bool rx)
1342160e9cb3SYevgeny Kliteynik {
1343160e9cb3SYevgeny Kliteynik 	sb->rx = rx;
1344160e9cb3SYevgeny Kliteynik 	sb->inner = inner;
1345160e9cb3SYevgeny Kliteynik 	ste_ctx->build_flex_parser_0_init(sb, mask);
1346160e9cb3SYevgeny Kliteynik }
1347160e9cb3SYevgeny Kliteynik 
1348160e9cb3SYevgeny Kliteynik void mlx5dr_ste_build_flex_parser_1(struct mlx5dr_ste_ctx *ste_ctx,
1349160e9cb3SYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
1350160e9cb3SYevgeny Kliteynik 				    struct mlx5dr_match_param *mask,
1351160e9cb3SYevgeny Kliteynik 				    bool inner, bool rx)
1352160e9cb3SYevgeny Kliteynik {
1353160e9cb3SYevgeny Kliteynik 	sb->rx = rx;
1354160e9cb3SYevgeny Kliteynik 	sb->inner = inner;
1355160e9cb3SYevgeny Kliteynik 	ste_ctx->build_flex_parser_1_init(sb, mask);
1356160e9cb3SYevgeny Kliteynik }
1357160e9cb3SYevgeny Kliteynik 
135809753babSMuhammad Sammar void mlx5dr_ste_build_tnl_header_0_1(struct mlx5dr_ste_ctx *ste_ctx,
135909753babSMuhammad Sammar 				     struct mlx5dr_ste_build *sb,
136009753babSMuhammad Sammar 				     struct mlx5dr_match_param *mask,
136109753babSMuhammad Sammar 				     bool inner, bool rx)
136209753babSMuhammad Sammar {
136309753babSMuhammad Sammar 	sb->rx = rx;
136409753babSMuhammad Sammar 	sb->inner = inner;
136509753babSMuhammad Sammar 	ste_ctx->build_tnl_header_0_1_init(sb, mask);
136609753babSMuhammad Sammar }
136709753babSMuhammad Sammar 
13685212f9c6SYevgeny Kliteynik struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx(u8 version)
13695212f9c6SYevgeny Kliteynik {
1370638a07f1SYevgeny Kliteynik 	if (version == MLX5_STEERING_FORMAT_CONNECTX_5)
1371638a07f1SYevgeny Kliteynik 		return mlx5dr_ste_get_ctx_v0();
1372638a07f1SYevgeny Kliteynik 	else if (version == MLX5_STEERING_FORMAT_CONNECTX_6DX)
1373638a07f1SYevgeny Kliteynik 		return mlx5dr_ste_get_ctx_v1();
13746862c787SYevgeny Kliteynik 	else if (version == MLX5_STEERING_FORMAT_CONNECTX_7)
13756862c787SYevgeny Kliteynik 		return mlx5dr_ste_get_ctx_v2();
13765212f9c6SYevgeny Kliteynik 
1377638a07f1SYevgeny Kliteynik 	return NULL;
137826d688e3SAlex Vesker }
1379