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 {
2826d688e3SAlex Vesker 	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
2926d688e3SAlex Vesker 	u8 masked[DR_STE_SIZE_TAG] = {};
3026d688e3SAlex Vesker 	u32 crc32, index;
3126d688e3SAlex Vesker 	u16 bit;
3226d688e3SAlex Vesker 	int i;
3326d688e3SAlex Vesker 
3426d688e3SAlex Vesker 	/* Don't calculate CRC if the result is predicted */
3526d688e3SAlex Vesker 	if (htbl->chunk->num_of_entries == 1 || htbl->byte_mask == 0)
3626d688e3SAlex Vesker 		return 0;
3726d688e3SAlex Vesker 
3826d688e3SAlex Vesker 	/* Mask tag using byte mask, bit per byte */
3926d688e3SAlex Vesker 	bit = 1 << (DR_STE_SIZE_TAG - 1);
4026d688e3SAlex Vesker 	for (i = 0; i < DR_STE_SIZE_TAG; i++) {
4126d688e3SAlex Vesker 		if (htbl->byte_mask & bit)
4226d688e3SAlex Vesker 			masked[i] = hw_ste->tag[i];
4326d688e3SAlex Vesker 
4426d688e3SAlex Vesker 		bit = bit >> 1;
4526d688e3SAlex Vesker 	}
4626d688e3SAlex Vesker 
4740416d8eSHamdan Igbaria 	crc32 = dr_ste_crc32_calc(masked, DR_STE_SIZE_TAG);
4826d688e3SAlex Vesker 	index = crc32 & (htbl->chunk->num_of_entries - 1);
4926d688e3SAlex Vesker 
5026d688e3SAlex Vesker 	return index;
5126d688e3SAlex Vesker }
5226d688e3SAlex Vesker 
535212f9c6SYevgeny Kliteynik u16 mlx5dr_ste_conv_bit_to_byte_mask(u8 *bit_mask)
5426d688e3SAlex Vesker {
5526d688e3SAlex Vesker 	u16 byte_mask = 0;
5626d688e3SAlex Vesker 	int i;
5726d688e3SAlex Vesker 
5826d688e3SAlex Vesker 	for (i = 0; i < DR_STE_SIZE_MASK; i++) {
5926d688e3SAlex Vesker 		byte_mask = byte_mask << 1;
6026d688e3SAlex Vesker 		if (bit_mask[i] == 0xff)
6126d688e3SAlex Vesker 			byte_mask |= 1;
6226d688e3SAlex Vesker 	}
6326d688e3SAlex Vesker 	return byte_mask;
6426d688e3SAlex Vesker }
6526d688e3SAlex Vesker 
6664c78942SYevgeny Kliteynik static u8 *dr_ste_get_tag(u8 *hw_ste_p)
67e6b69bf3SYevgeny Kliteynik {
68e6b69bf3SYevgeny Kliteynik 	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
69e6b69bf3SYevgeny Kliteynik 
70e6b69bf3SYevgeny Kliteynik 	return hw_ste->tag;
71e6b69bf3SYevgeny Kliteynik }
72e6b69bf3SYevgeny Kliteynik 
7326d688e3SAlex Vesker void mlx5dr_ste_set_bit_mask(u8 *hw_ste_p, u8 *bit_mask)
7426d688e3SAlex Vesker {
7526d688e3SAlex Vesker 	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
7626d688e3SAlex Vesker 
7726d688e3SAlex Vesker 	memcpy(hw_ste->mask, bit_mask, DR_STE_SIZE_MASK);
7826d688e3SAlex Vesker }
7926d688e3SAlex Vesker 
8026d688e3SAlex Vesker static void dr_ste_set_always_hit(struct dr_hw_ste_format *hw_ste)
8126d688e3SAlex Vesker {
8226d688e3SAlex Vesker 	memset(&hw_ste->tag, 0, sizeof(hw_ste->tag));
8326d688e3SAlex Vesker 	memset(&hw_ste->mask, 0, sizeof(hw_ste->mask));
8426d688e3SAlex Vesker }
8526d688e3SAlex Vesker 
8626d688e3SAlex Vesker static void dr_ste_set_always_miss(struct dr_hw_ste_format *hw_ste)
8726d688e3SAlex Vesker {
8826d688e3SAlex Vesker 	hw_ste->tag[0] = 0xdc;
8926d688e3SAlex Vesker 	hw_ste->mask[0] = 0;
9026d688e3SAlex Vesker }
9126d688e3SAlex Vesker 
926b93b400SYevgeny Kliteynik void mlx5dr_ste_set_miss_addr(struct mlx5dr_ste_ctx *ste_ctx,
936b93b400SYevgeny Kliteynik 			      u8 *hw_ste_p, u64 miss_addr)
9464c78942SYevgeny Kliteynik {
956b93b400SYevgeny Kliteynik 	ste_ctx->set_miss_addr(hw_ste_p, miss_addr);
9664c78942SYevgeny Kliteynik }
9764c78942SYevgeny Kliteynik 
986b93b400SYevgeny Kliteynik static void dr_ste_always_miss_addr(struct mlx5dr_ste_ctx *ste_ctx,
996b93b400SYevgeny Kliteynik 				    struct mlx5dr_ste *ste, u64 miss_addr)
10064c78942SYevgeny Kliteynik {
10164c78942SYevgeny Kliteynik 	u8 *hw_ste_p = ste->hw_ste;
10264c78942SYevgeny Kliteynik 
1036b93b400SYevgeny Kliteynik 	ste_ctx->set_next_lu_type(hw_ste_p, MLX5DR_STE_LU_TYPE_DONT_CARE);
1046b93b400SYevgeny Kliteynik 	ste_ctx->set_miss_addr(hw_ste_p, miss_addr);
10564c78942SYevgeny Kliteynik 	dr_ste_set_always_miss((struct dr_hw_ste_format *)ste->hw_ste);
10664c78942SYevgeny Kliteynik }
10764c78942SYevgeny Kliteynik 
1086b93b400SYevgeny Kliteynik void mlx5dr_ste_set_hit_addr(struct mlx5dr_ste_ctx *ste_ctx,
1096b93b400SYevgeny Kliteynik 			     u8 *hw_ste, u64 icm_addr, u32 ht_size)
11026d688e3SAlex Vesker {
1116b93b400SYevgeny Kliteynik 	ste_ctx->set_hit_addr(hw_ste, icm_addr, ht_size);
11226d688e3SAlex Vesker }
11326d688e3SAlex Vesker 
11426d688e3SAlex Vesker u64 mlx5dr_ste_get_icm_addr(struct mlx5dr_ste *ste)
11526d688e3SAlex Vesker {
11626d688e3SAlex Vesker 	u32 index = ste - ste->htbl->ste_arr;
11726d688e3SAlex Vesker 
11826d688e3SAlex Vesker 	return ste->htbl->chunk->icm_addr + DR_STE_SIZE * index;
11926d688e3SAlex Vesker }
12026d688e3SAlex Vesker 
12126d688e3SAlex Vesker u64 mlx5dr_ste_get_mr_addr(struct mlx5dr_ste *ste)
12226d688e3SAlex Vesker {
12326d688e3SAlex Vesker 	u32 index = ste - ste->htbl->ste_arr;
12426d688e3SAlex Vesker 
12526d688e3SAlex Vesker 	return ste->htbl->chunk->mr_addr + DR_STE_SIZE * index;
12626d688e3SAlex Vesker }
12726d688e3SAlex Vesker 
12826d688e3SAlex Vesker struct list_head *mlx5dr_ste_get_miss_list(struct mlx5dr_ste *ste)
12926d688e3SAlex Vesker {
13026d688e3SAlex Vesker 	u32 index = ste - ste->htbl->ste_arr;
13126d688e3SAlex Vesker 
13226d688e3SAlex Vesker 	return &ste->htbl->miss_list[index];
13326d688e3SAlex Vesker }
13426d688e3SAlex Vesker 
1356b93b400SYevgeny Kliteynik static void dr_ste_always_hit_htbl(struct mlx5dr_ste_ctx *ste_ctx,
1366b93b400SYevgeny Kliteynik 				   struct mlx5dr_ste *ste,
13726d688e3SAlex Vesker 				   struct mlx5dr_ste_htbl *next_htbl)
13826d688e3SAlex Vesker {
13926d688e3SAlex Vesker 	struct mlx5dr_icm_chunk *chunk = next_htbl->chunk;
14026d688e3SAlex Vesker 	u8 *hw_ste = ste->hw_ste;
14126d688e3SAlex Vesker 
1426b93b400SYevgeny Kliteynik 	ste_ctx->set_byte_mask(hw_ste, next_htbl->byte_mask);
1436b93b400SYevgeny Kliteynik 	ste_ctx->set_next_lu_type(hw_ste, next_htbl->lu_type);
1446b93b400SYevgeny Kliteynik 	ste_ctx->set_hit_addr(hw_ste, chunk->icm_addr, chunk->num_of_entries);
14526d688e3SAlex Vesker 
14626d688e3SAlex Vesker 	dr_ste_set_always_hit((struct dr_hw_ste_format *)ste->hw_ste);
14726d688e3SAlex Vesker }
14826d688e3SAlex Vesker 
14926d688e3SAlex Vesker bool mlx5dr_ste_is_last_in_rule(struct mlx5dr_matcher_rx_tx *nic_matcher,
15026d688e3SAlex Vesker 				u8 ste_location)
15126d688e3SAlex Vesker {
15226d688e3SAlex Vesker 	return ste_location == nic_matcher->num_of_builders;
15326d688e3SAlex Vesker }
15426d688e3SAlex Vesker 
15526d688e3SAlex Vesker /* Replace relevant fields, except of:
15626d688e3SAlex Vesker  * htbl - keep the origin htbl
15726d688e3SAlex Vesker  * miss_list + list - already took the src from the list.
15826d688e3SAlex Vesker  * icm_addr/mr_addr - depends on the hosting table.
15926d688e3SAlex Vesker  *
16026d688e3SAlex Vesker  * Before:
16126d688e3SAlex Vesker  * | a | -> | b | -> | c | ->
16226d688e3SAlex Vesker  *
16326d688e3SAlex Vesker  * After:
16426d688e3SAlex Vesker  * | a | -> | c | ->
16526d688e3SAlex Vesker  * While the data that was in b copied to a.
16626d688e3SAlex Vesker  */
16726d688e3SAlex Vesker static void dr_ste_replace(struct mlx5dr_ste *dst, struct mlx5dr_ste *src)
16826d688e3SAlex Vesker {
16926d688e3SAlex Vesker 	memcpy(dst->hw_ste, src->hw_ste, DR_STE_SIZE_REDUCED);
17026d688e3SAlex Vesker 	dst->next_htbl = src->next_htbl;
17126d688e3SAlex Vesker 	if (dst->next_htbl)
17226d688e3SAlex Vesker 		dst->next_htbl->pointing_ste = dst;
17326d688e3SAlex Vesker 
1744ce380caSYevgeny Kliteynik 	dst->refcount = src->refcount;
17526d688e3SAlex Vesker }
17626d688e3SAlex Vesker 
17726d688e3SAlex Vesker /* Free ste which is the head and the only one in miss_list */
17826d688e3SAlex Vesker static void
1796b93b400SYevgeny Kliteynik dr_ste_remove_head_ste(struct mlx5dr_ste_ctx *ste_ctx,
1806b93b400SYevgeny Kliteynik 		       struct mlx5dr_ste *ste,
18126d688e3SAlex Vesker 		       struct mlx5dr_matcher_rx_tx *nic_matcher,
18226d688e3SAlex Vesker 		       struct mlx5dr_ste_send_info *ste_info_head,
18326d688e3SAlex Vesker 		       struct list_head *send_ste_list,
18426d688e3SAlex Vesker 		       struct mlx5dr_ste_htbl *stats_tbl)
18526d688e3SAlex Vesker {
18626d688e3SAlex Vesker 	u8 tmp_data_ste[DR_STE_SIZE] = {};
18726d688e3SAlex Vesker 	struct mlx5dr_ste tmp_ste = {};
18826d688e3SAlex Vesker 	u64 miss_addr;
18926d688e3SAlex Vesker 
19026d688e3SAlex Vesker 	tmp_ste.hw_ste = tmp_data_ste;
19126d688e3SAlex Vesker 
19226d688e3SAlex Vesker 	/* Use temp ste because dr_ste_always_miss_addr
19326d688e3SAlex Vesker 	 * touches bit_mask area which doesn't exist at ste->hw_ste.
19426d688e3SAlex Vesker 	 */
19526d688e3SAlex Vesker 	memcpy(tmp_ste.hw_ste, ste->hw_ste, DR_STE_SIZE_REDUCED);
19626d688e3SAlex Vesker 	miss_addr = nic_matcher->e_anchor->chunk->icm_addr;
1976b93b400SYevgeny Kliteynik 	dr_ste_always_miss_addr(ste_ctx, &tmp_ste, miss_addr);
19826d688e3SAlex Vesker 	memcpy(ste->hw_ste, tmp_ste.hw_ste, DR_STE_SIZE_REDUCED);
19926d688e3SAlex Vesker 
20026d688e3SAlex Vesker 	list_del_init(&ste->miss_list_node);
20126d688e3SAlex Vesker 
20226d688e3SAlex Vesker 	/* Write full STE size in order to have "always_miss" */
20326d688e3SAlex Vesker 	mlx5dr_send_fill_and_append_ste_send_info(ste, DR_STE_SIZE,
20426d688e3SAlex Vesker 						  0, tmp_data_ste,
20526d688e3SAlex Vesker 						  ste_info_head,
20626d688e3SAlex Vesker 						  send_ste_list,
20726d688e3SAlex Vesker 						  true /* Copy data */);
20826d688e3SAlex Vesker 
20926d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_valid_entries--;
21026d688e3SAlex Vesker }
21126d688e3SAlex Vesker 
21226d688e3SAlex Vesker /* Free ste which is the head but NOT the only one in miss_list:
21326d688e3SAlex Vesker  * |_ste_| --> |_next_ste_| -->|__| -->|__| -->/0
21426d688e3SAlex Vesker  */
21526d688e3SAlex Vesker static void
2168fdac12aSYevgeny Kliteynik dr_ste_replace_head_ste(struct mlx5dr_matcher_rx_tx *nic_matcher,
2178fdac12aSYevgeny Kliteynik 			struct mlx5dr_ste *ste,
2188fdac12aSYevgeny Kliteynik 			struct mlx5dr_ste *next_ste,
21926d688e3SAlex Vesker 			struct mlx5dr_ste_send_info *ste_info_head,
22026d688e3SAlex Vesker 			struct list_head *send_ste_list,
22126d688e3SAlex Vesker 			struct mlx5dr_ste_htbl *stats_tbl)
22226d688e3SAlex Vesker 
22326d688e3SAlex Vesker {
22426d688e3SAlex Vesker 	struct mlx5dr_ste_htbl *next_miss_htbl;
2258fdac12aSYevgeny Kliteynik 	u8 hw_ste[DR_STE_SIZE] = {};
2268fdac12aSYevgeny Kliteynik 	int sb_idx;
22726d688e3SAlex Vesker 
22826d688e3SAlex Vesker 	next_miss_htbl = next_ste->htbl;
22926d688e3SAlex Vesker 
23026d688e3SAlex Vesker 	/* Remove from the miss_list the next_ste before copy */
23126d688e3SAlex Vesker 	list_del_init(&next_ste->miss_list_node);
23226d688e3SAlex Vesker 
23326d688e3SAlex Vesker 	/* Move data from next into ste */
23426d688e3SAlex Vesker 	dr_ste_replace(ste, next_ste);
23526d688e3SAlex Vesker 
2368a015baeSYevgeny Kliteynik 	/* Update the rule on STE change */
2378a015baeSYevgeny Kliteynik 	mlx5dr_rule_set_last_member(next_ste->rule_rx_tx, ste, false);
2388a015baeSYevgeny Kliteynik 
2398fdac12aSYevgeny Kliteynik 	/* Copy all 64 hw_ste bytes */
2408fdac12aSYevgeny Kliteynik 	memcpy(hw_ste, ste->hw_ste, DR_STE_SIZE_REDUCED);
2418fdac12aSYevgeny Kliteynik 	sb_idx = ste->ste_chain_location - 1;
2428fdac12aSYevgeny Kliteynik 	mlx5dr_ste_set_bit_mask(hw_ste,
2438fdac12aSYevgeny Kliteynik 				nic_matcher->ste_builder[sb_idx].bit_mask);
2448fdac12aSYevgeny Kliteynik 
24526d688e3SAlex Vesker 	/* Del the htbl that contains the next_ste.
24626d688e3SAlex Vesker 	 * The origin htbl stay with the same number of entries.
24726d688e3SAlex Vesker 	 */
24826d688e3SAlex Vesker 	mlx5dr_htbl_put(next_miss_htbl);
24926d688e3SAlex Vesker 
2508fdac12aSYevgeny Kliteynik 	mlx5dr_send_fill_and_append_ste_send_info(ste, DR_STE_SIZE,
2518fdac12aSYevgeny Kliteynik 						  0, hw_ste,
25226d688e3SAlex Vesker 						  ste_info_head,
25326d688e3SAlex Vesker 						  send_ste_list,
25426d688e3SAlex Vesker 						  true /* Copy data */);
25526d688e3SAlex Vesker 
25626d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_collisions--;
25726d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_valid_entries--;
25826d688e3SAlex Vesker }
25926d688e3SAlex Vesker 
26026d688e3SAlex Vesker /* Free ste that is located in the middle of the miss list:
26126d688e3SAlex Vesker  * |__| -->|_prev_ste_|->|_ste_|-->|_next_ste_|
26226d688e3SAlex Vesker  */
2636b93b400SYevgeny Kliteynik static void dr_ste_remove_middle_ste(struct mlx5dr_ste_ctx *ste_ctx,
2646b93b400SYevgeny Kliteynik 				     struct mlx5dr_ste *ste,
26526d688e3SAlex Vesker 				     struct mlx5dr_ste_send_info *ste_info,
26626d688e3SAlex Vesker 				     struct list_head *send_ste_list,
26726d688e3SAlex Vesker 				     struct mlx5dr_ste_htbl *stats_tbl)
26826d688e3SAlex Vesker {
26926d688e3SAlex Vesker 	struct mlx5dr_ste *prev_ste;
27026d688e3SAlex Vesker 	u64 miss_addr;
27126d688e3SAlex Vesker 
27248cbde4bSAlex Vesker 	prev_ste = list_prev_entry(ste, miss_list_node);
27348cbde4bSAlex Vesker 	if (WARN_ON(!prev_ste))
27426d688e3SAlex Vesker 		return;
27526d688e3SAlex Vesker 
2766b93b400SYevgeny Kliteynik 	miss_addr = ste_ctx->get_miss_addr(ste->hw_ste);
2776b93b400SYevgeny Kliteynik 	ste_ctx->set_miss_addr(prev_ste->hw_ste, miss_addr);
27826d688e3SAlex Vesker 
279f06d4969SYevgeny Kliteynik 	mlx5dr_send_fill_and_append_ste_send_info(prev_ste, DR_STE_SIZE_CTRL, 0,
28026d688e3SAlex Vesker 						  prev_ste->hw_ste, ste_info,
28126d688e3SAlex Vesker 						  send_ste_list, true /* Copy data*/);
28226d688e3SAlex Vesker 
28326d688e3SAlex Vesker 	list_del_init(&ste->miss_list_node);
28426d688e3SAlex Vesker 
28526d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_valid_entries--;
28626d688e3SAlex Vesker 	stats_tbl->ctrl.num_of_collisions--;
28726d688e3SAlex Vesker }
28826d688e3SAlex Vesker 
28926d688e3SAlex Vesker void mlx5dr_ste_free(struct mlx5dr_ste *ste,
29026d688e3SAlex Vesker 		     struct mlx5dr_matcher *matcher,
29126d688e3SAlex Vesker 		     struct mlx5dr_matcher_rx_tx *nic_matcher)
29226d688e3SAlex Vesker {
29326d688e3SAlex Vesker 	struct mlx5dr_ste_send_info *cur_ste_info, *tmp_ste_info;
29426d688e3SAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
2956b93b400SYevgeny Kliteynik 	struct mlx5dr_ste_ctx *ste_ctx = dmn->ste_ctx;
29626d688e3SAlex Vesker 	struct mlx5dr_ste_send_info ste_info_head;
29726d688e3SAlex Vesker 	struct mlx5dr_ste *next_ste, *first_ste;
29826d688e3SAlex Vesker 	bool put_on_origin_table = true;
29926d688e3SAlex Vesker 	struct mlx5dr_ste_htbl *stats_tbl;
30026d688e3SAlex Vesker 	LIST_HEAD(send_ste_list);
30126d688e3SAlex Vesker 
30248cbde4bSAlex Vesker 	first_ste = list_first_entry(mlx5dr_ste_get_miss_list(ste),
30326d688e3SAlex Vesker 				     struct mlx5dr_ste, miss_list_node);
30426d688e3SAlex Vesker 	stats_tbl = first_ste->htbl;
30526d688e3SAlex Vesker 
30626d688e3SAlex Vesker 	/* Two options:
30726d688e3SAlex Vesker 	 * 1. ste is head:
30826d688e3SAlex Vesker 	 *	a. head ste is the only ste in the miss list
30926d688e3SAlex Vesker 	 *	b. head ste is not the only ste in the miss-list
31026d688e3SAlex Vesker 	 * 2. ste is not head
31126d688e3SAlex Vesker 	 */
31226d688e3SAlex Vesker 	if (first_ste == ste) { /* Ste is the head */
31326d688e3SAlex Vesker 		struct mlx5dr_ste *last_ste;
31426d688e3SAlex Vesker 
31526d688e3SAlex Vesker 		last_ste = list_last_entry(mlx5dr_ste_get_miss_list(ste),
31626d688e3SAlex Vesker 					   struct mlx5dr_ste, miss_list_node);
31726d688e3SAlex Vesker 		if (last_ste == first_ste)
31826d688e3SAlex Vesker 			next_ste = NULL;
31926d688e3SAlex Vesker 		else
32048cbde4bSAlex Vesker 			next_ste = list_next_entry(ste, miss_list_node);
32126d688e3SAlex Vesker 
32226d688e3SAlex Vesker 		if (!next_ste) {
32326d688e3SAlex Vesker 			/* One and only entry in the list */
3246b93b400SYevgeny Kliteynik 			dr_ste_remove_head_ste(ste_ctx, ste,
3256b93b400SYevgeny Kliteynik 					       nic_matcher,
32626d688e3SAlex Vesker 					       &ste_info_head,
32726d688e3SAlex Vesker 					       &send_ste_list,
32826d688e3SAlex Vesker 					       stats_tbl);
32926d688e3SAlex Vesker 		} else {
33026d688e3SAlex Vesker 			/* First but not only entry in the list */
3318fdac12aSYevgeny Kliteynik 			dr_ste_replace_head_ste(nic_matcher, ste,
3328fdac12aSYevgeny Kliteynik 						next_ste, &ste_info_head,
33326d688e3SAlex Vesker 						&send_ste_list, stats_tbl);
33426d688e3SAlex Vesker 			put_on_origin_table = false;
33526d688e3SAlex Vesker 		}
33626d688e3SAlex Vesker 	} else { /* Ste in the middle of the list */
3376b93b400SYevgeny Kliteynik 		dr_ste_remove_middle_ste(ste_ctx, ste,
3386b93b400SYevgeny Kliteynik 					 &ste_info_head, &send_ste_list,
3396b93b400SYevgeny Kliteynik 					 stats_tbl);
34026d688e3SAlex Vesker 	}
34126d688e3SAlex Vesker 
34226d688e3SAlex Vesker 	/* Update HW */
34326d688e3SAlex Vesker 	list_for_each_entry_safe(cur_ste_info, tmp_ste_info,
34426d688e3SAlex Vesker 				 &send_ste_list, send_list) {
34526d688e3SAlex Vesker 		list_del(&cur_ste_info->send_list);
34626d688e3SAlex Vesker 		mlx5dr_send_postsend_ste(dmn, cur_ste_info->ste,
34726d688e3SAlex Vesker 					 cur_ste_info->data, cur_ste_info->size,
34826d688e3SAlex Vesker 					 cur_ste_info->offset);
34926d688e3SAlex Vesker 	}
35026d688e3SAlex Vesker 
35126d688e3SAlex Vesker 	if (put_on_origin_table)
35226d688e3SAlex Vesker 		mlx5dr_htbl_put(ste->htbl);
35326d688e3SAlex Vesker }
35426d688e3SAlex Vesker 
35526d688e3SAlex Vesker bool mlx5dr_ste_equal_tag(void *src, void *dst)
35626d688e3SAlex Vesker {
35726d688e3SAlex Vesker 	struct dr_hw_ste_format *s_hw_ste = (struct dr_hw_ste_format *)src;
35826d688e3SAlex Vesker 	struct dr_hw_ste_format *d_hw_ste = (struct dr_hw_ste_format *)dst;
35926d688e3SAlex Vesker 
36026d688e3SAlex Vesker 	return !memcmp(s_hw_ste->tag, d_hw_ste->tag, DR_STE_SIZE_TAG);
36126d688e3SAlex Vesker }
36226d688e3SAlex Vesker 
3636b93b400SYevgeny Kliteynik void mlx5dr_ste_set_hit_addr_by_next_htbl(struct mlx5dr_ste_ctx *ste_ctx,
3646b93b400SYevgeny Kliteynik 					  u8 *hw_ste,
36526d688e3SAlex Vesker 					  struct mlx5dr_ste_htbl *next_htbl)
36626d688e3SAlex Vesker {
36726d688e3SAlex Vesker 	struct mlx5dr_icm_chunk *chunk = next_htbl->chunk;
36826d688e3SAlex Vesker 
3696b93b400SYevgeny Kliteynik 	ste_ctx->set_hit_addr(hw_ste, chunk->icm_addr, chunk->num_of_entries);
37026d688e3SAlex Vesker }
37126d688e3SAlex Vesker 
3724fe45e1dSYevgeny Kliteynik void mlx5dr_ste_prepare_for_postsend(struct mlx5dr_ste_ctx *ste_ctx,
3734fe45e1dSYevgeny Kliteynik 				     u8 *hw_ste_p, u32 ste_size)
3744fe45e1dSYevgeny Kliteynik {
3754fe45e1dSYevgeny Kliteynik 	if (ste_ctx->prepare_for_postsend)
3764fe45e1dSYevgeny Kliteynik 		ste_ctx->prepare_for_postsend(hw_ste_p, ste_size);
3774fe45e1dSYevgeny Kliteynik }
3784fe45e1dSYevgeny Kliteynik 
37926d688e3SAlex Vesker /* Init one ste as a pattern for ste data array */
3806b93b400SYevgeny Kliteynik void mlx5dr_ste_set_formatted_ste(struct mlx5dr_ste_ctx *ste_ctx,
3816b93b400SYevgeny Kliteynik 				  u16 gvmi,
38246f2a8aeSYevgeny Kliteynik 				  enum mlx5dr_domain_nic_type nic_type,
38326d688e3SAlex Vesker 				  struct mlx5dr_ste_htbl *htbl,
38426d688e3SAlex Vesker 				  u8 *formatted_ste,
38526d688e3SAlex Vesker 				  struct mlx5dr_htbl_connect_info *connect_info)
38626d688e3SAlex Vesker {
38746f2a8aeSYevgeny Kliteynik 	bool is_rx = nic_type == DR_DOMAIN_NIC_TYPE_RX;
38826d688e3SAlex Vesker 	struct mlx5dr_ste ste = {};
38926d688e3SAlex Vesker 
39046f2a8aeSYevgeny Kliteynik 	ste_ctx->ste_init(formatted_ste, htbl->lu_type, is_rx, gvmi);
39126d688e3SAlex Vesker 	ste.hw_ste = formatted_ste;
39226d688e3SAlex Vesker 
39326d688e3SAlex Vesker 	if (connect_info->type == CONNECT_HIT)
3946b93b400SYevgeny Kliteynik 		dr_ste_always_hit_htbl(ste_ctx, &ste, connect_info->hit_next_htbl);
39526d688e3SAlex Vesker 	else
3966b93b400SYevgeny Kliteynik 		dr_ste_always_miss_addr(ste_ctx, &ste, connect_info->miss_icm_addr);
39726d688e3SAlex Vesker }
39826d688e3SAlex Vesker 
39926d688e3SAlex Vesker int mlx5dr_ste_htbl_init_and_postsend(struct mlx5dr_domain *dmn,
40026d688e3SAlex Vesker 				      struct mlx5dr_domain_rx_tx *nic_dmn,
40126d688e3SAlex Vesker 				      struct mlx5dr_ste_htbl *htbl,
40226d688e3SAlex Vesker 				      struct mlx5dr_htbl_connect_info *connect_info,
40326d688e3SAlex Vesker 				      bool update_hw_ste)
40426d688e3SAlex Vesker {
40526d688e3SAlex Vesker 	u8 formatted_ste[DR_STE_SIZE] = {};
40626d688e3SAlex Vesker 
4076b93b400SYevgeny Kliteynik 	mlx5dr_ste_set_formatted_ste(dmn->ste_ctx,
4086b93b400SYevgeny Kliteynik 				     dmn->info.caps.gvmi,
40946f2a8aeSYevgeny Kliteynik 				     nic_dmn->type,
41026d688e3SAlex Vesker 				     htbl,
41126d688e3SAlex Vesker 				     formatted_ste,
41226d688e3SAlex Vesker 				     connect_info);
41326d688e3SAlex Vesker 
41426d688e3SAlex Vesker 	return mlx5dr_send_postsend_formatted_htbl(dmn, htbl, formatted_ste, update_hw_ste);
41526d688e3SAlex Vesker }
41626d688e3SAlex Vesker 
41726d688e3SAlex Vesker int mlx5dr_ste_create_next_htbl(struct mlx5dr_matcher *matcher,
41826d688e3SAlex Vesker 				struct mlx5dr_matcher_rx_tx *nic_matcher,
41926d688e3SAlex Vesker 				struct mlx5dr_ste *ste,
42026d688e3SAlex Vesker 				u8 *cur_hw_ste,
42126d688e3SAlex Vesker 				enum mlx5dr_icm_chunk_size log_table_size)
42226d688e3SAlex Vesker {
42326d688e3SAlex Vesker 	struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn;
42426d688e3SAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
4256b93b400SYevgeny Kliteynik 	struct mlx5dr_ste_ctx *ste_ctx = dmn->ste_ctx;
42626d688e3SAlex Vesker 	struct mlx5dr_htbl_connect_info info;
42726d688e3SAlex Vesker 	struct mlx5dr_ste_htbl *next_htbl;
42826d688e3SAlex Vesker 
42926d688e3SAlex Vesker 	if (!mlx5dr_ste_is_last_in_rule(nic_matcher, ste->ste_chain_location)) {
430dd2d3c8dSYevgeny Kliteynik 		u16 next_lu_type;
43126d688e3SAlex Vesker 		u16 byte_mask;
43226d688e3SAlex Vesker 
4336b93b400SYevgeny Kliteynik 		next_lu_type = ste_ctx->get_next_lu_type(cur_hw_ste);
4346b93b400SYevgeny Kliteynik 		byte_mask = ste_ctx->get_byte_mask(cur_hw_ste);
43526d688e3SAlex Vesker 
43626d688e3SAlex Vesker 		next_htbl = mlx5dr_ste_htbl_alloc(dmn->ste_icm_pool,
43726d688e3SAlex Vesker 						  log_table_size,
43826d688e3SAlex Vesker 						  next_lu_type,
43926d688e3SAlex Vesker 						  byte_mask);
44026d688e3SAlex Vesker 		if (!next_htbl) {
44126d688e3SAlex Vesker 			mlx5dr_dbg(dmn, "Failed allocating table\n");
44226d688e3SAlex Vesker 			return -ENOMEM;
44326d688e3SAlex Vesker 		}
44426d688e3SAlex Vesker 
44526d688e3SAlex Vesker 		/* Write new table to HW */
44626d688e3SAlex Vesker 		info.type = CONNECT_MISS;
44726d688e3SAlex Vesker 		info.miss_icm_addr = nic_matcher->e_anchor->chunk->icm_addr;
44826d688e3SAlex Vesker 		if (mlx5dr_ste_htbl_init_and_postsend(dmn, nic_dmn, next_htbl,
44926d688e3SAlex Vesker 						      &info, false)) {
45026d688e3SAlex Vesker 			mlx5dr_info(dmn, "Failed writing table to HW\n");
45126d688e3SAlex Vesker 			goto free_table;
45226d688e3SAlex Vesker 		}
45326d688e3SAlex Vesker 
4546b93b400SYevgeny Kliteynik 		mlx5dr_ste_set_hit_addr_by_next_htbl(ste_ctx,
4556b93b400SYevgeny Kliteynik 						     cur_hw_ste, next_htbl);
45626d688e3SAlex Vesker 		ste->next_htbl = next_htbl;
45726d688e3SAlex Vesker 		next_htbl->pointing_ste = ste;
45826d688e3SAlex Vesker 	}
45926d688e3SAlex Vesker 
46026d688e3SAlex Vesker 	return 0;
46126d688e3SAlex Vesker 
46226d688e3SAlex Vesker free_table:
46326d688e3SAlex Vesker 	mlx5dr_ste_htbl_free(next_htbl);
46426d688e3SAlex Vesker 	return -ENOENT;
46526d688e3SAlex Vesker }
46626d688e3SAlex Vesker 
46726d688e3SAlex Vesker struct mlx5dr_ste_htbl *mlx5dr_ste_htbl_alloc(struct mlx5dr_icm_pool *pool,
46826d688e3SAlex Vesker 					      enum mlx5dr_icm_chunk_size chunk_size,
469dd2d3c8dSYevgeny Kliteynik 					      u16 lu_type, u16 byte_mask)
47026d688e3SAlex Vesker {
47126d688e3SAlex Vesker 	struct mlx5dr_icm_chunk *chunk;
47226d688e3SAlex Vesker 	struct mlx5dr_ste_htbl *htbl;
47326d688e3SAlex Vesker 	int i;
47426d688e3SAlex Vesker 
47526d688e3SAlex Vesker 	htbl = kzalloc(sizeof(*htbl), GFP_KERNEL);
47626d688e3SAlex Vesker 	if (!htbl)
47726d688e3SAlex Vesker 		return NULL;
47826d688e3SAlex Vesker 
47926d688e3SAlex Vesker 	chunk = mlx5dr_icm_alloc_chunk(pool, chunk_size);
48026d688e3SAlex Vesker 	if (!chunk)
48126d688e3SAlex Vesker 		goto out_free_htbl;
48226d688e3SAlex Vesker 
48326d688e3SAlex Vesker 	htbl->chunk = chunk;
48426d688e3SAlex Vesker 	htbl->lu_type = lu_type;
48526d688e3SAlex Vesker 	htbl->byte_mask = byte_mask;
48626d688e3SAlex Vesker 	htbl->ste_arr = chunk->ste_arr;
48726d688e3SAlex Vesker 	htbl->hw_ste_arr = chunk->hw_ste_arr;
48826d688e3SAlex Vesker 	htbl->miss_list = chunk->miss_list;
4894ce380caSYevgeny Kliteynik 	htbl->refcount = 0;
49026d688e3SAlex Vesker 
49126d688e3SAlex Vesker 	for (i = 0; i < chunk->num_of_entries; i++) {
49226d688e3SAlex Vesker 		struct mlx5dr_ste *ste = &htbl->ste_arr[i];
49326d688e3SAlex Vesker 
49426d688e3SAlex Vesker 		ste->hw_ste = htbl->hw_ste_arr + i * DR_STE_SIZE_REDUCED;
49526d688e3SAlex Vesker 		ste->htbl = htbl;
4964ce380caSYevgeny Kliteynik 		ste->refcount = 0;
49726d688e3SAlex Vesker 		INIT_LIST_HEAD(&ste->miss_list_node);
49826d688e3SAlex Vesker 		INIT_LIST_HEAD(&htbl->miss_list[i]);
49926d688e3SAlex Vesker 	}
50026d688e3SAlex Vesker 
50126d688e3SAlex Vesker 	htbl->chunk_size = chunk_size;
50226d688e3SAlex Vesker 	return htbl;
50326d688e3SAlex Vesker 
50426d688e3SAlex Vesker out_free_htbl:
50526d688e3SAlex Vesker 	kfree(htbl);
50626d688e3SAlex Vesker 	return NULL;
50726d688e3SAlex Vesker }
50826d688e3SAlex Vesker 
50926d688e3SAlex Vesker int mlx5dr_ste_htbl_free(struct mlx5dr_ste_htbl *htbl)
51026d688e3SAlex Vesker {
5114ce380caSYevgeny Kliteynik 	if (htbl->refcount)
51226d688e3SAlex Vesker 		return -EBUSY;
51326d688e3SAlex Vesker 
51426d688e3SAlex Vesker 	mlx5dr_icm_free_chunk(htbl->chunk);
51526d688e3SAlex Vesker 	kfree(htbl);
51626d688e3SAlex Vesker 	return 0;
51726d688e3SAlex Vesker }
51826d688e3SAlex Vesker 
5196b93b400SYevgeny Kliteynik void mlx5dr_ste_set_actions_tx(struct mlx5dr_ste_ctx *ste_ctx,
5206b93b400SYevgeny Kliteynik 			       struct mlx5dr_domain *dmn,
52164c78942SYevgeny Kliteynik 			       u8 *action_type_set,
522ad17dc8cSYevgeny Kliteynik 			       u8 *hw_ste_arr,
52364c78942SYevgeny Kliteynik 			       struct mlx5dr_ste_actions_attr *attr,
52464c78942SYevgeny Kliteynik 			       u32 *added_stes)
52564c78942SYevgeny Kliteynik {
526638a07f1SYevgeny Kliteynik 	ste_ctx->set_actions_tx(dmn, action_type_set, ste_ctx->actions_caps,
527638a07f1SYevgeny Kliteynik 				hw_ste_arr, attr, added_stes);
52864c78942SYevgeny Kliteynik }
52964c78942SYevgeny Kliteynik 
5306b93b400SYevgeny Kliteynik void mlx5dr_ste_set_actions_rx(struct mlx5dr_ste_ctx *ste_ctx,
5316b93b400SYevgeny Kliteynik 			       struct mlx5dr_domain *dmn,
53264c78942SYevgeny Kliteynik 			       u8 *action_type_set,
533ad17dc8cSYevgeny Kliteynik 			       u8 *hw_ste_arr,
53464c78942SYevgeny Kliteynik 			       struct mlx5dr_ste_actions_attr *attr,
53564c78942SYevgeny Kliteynik 			       u32 *added_stes)
53664c78942SYevgeny Kliteynik {
537638a07f1SYevgeny Kliteynik 	ste_ctx->set_actions_rx(dmn, action_type_set, ste_ctx->actions_caps,
538638a07f1SYevgeny Kliteynik 				hw_ste_arr, attr, added_stes);
53964c78942SYevgeny Kliteynik }
54064c78942SYevgeny Kliteynik 
5414781df92SYevgeny Kliteynik const struct mlx5dr_ste_action_modify_field *
5424781df92SYevgeny Kliteynik mlx5dr_ste_conv_modify_hdr_sw_field(struct mlx5dr_ste_ctx *ste_ctx, u16 sw_field)
5434781df92SYevgeny Kliteynik {
5444781df92SYevgeny Kliteynik 	const struct mlx5dr_ste_action_modify_field *hw_field;
5454781df92SYevgeny Kliteynik 
5464781df92SYevgeny Kliteynik 	if (sw_field >= ste_ctx->modify_field_arr_sz)
5474781df92SYevgeny Kliteynik 		return NULL;
5484781df92SYevgeny Kliteynik 
5494781df92SYevgeny Kliteynik 	hw_field = &ste_ctx->modify_field_arr[sw_field];
5504781df92SYevgeny Kliteynik 	if (!hw_field->end && !hw_field->start)
5514781df92SYevgeny Kliteynik 		return NULL;
5524781df92SYevgeny Kliteynik 
5534781df92SYevgeny Kliteynik 	return hw_field;
5544781df92SYevgeny Kliteynik }
5554781df92SYevgeny Kliteynik 
5564781df92SYevgeny Kliteynik void mlx5dr_ste_set_action_set(struct mlx5dr_ste_ctx *ste_ctx,
5574781df92SYevgeny Kliteynik 			       __be64 *hw_action,
5584781df92SYevgeny Kliteynik 			       u8 hw_field,
5594781df92SYevgeny Kliteynik 			       u8 shifter,
5604781df92SYevgeny Kliteynik 			       u8 length,
5614781df92SYevgeny Kliteynik 			       u32 data)
5624781df92SYevgeny Kliteynik {
5634781df92SYevgeny Kliteynik 	ste_ctx->set_action_set((u8 *)hw_action,
5644781df92SYevgeny Kliteynik 				hw_field, shifter, length, data);
5654781df92SYevgeny Kliteynik }
5664781df92SYevgeny Kliteynik 
5674781df92SYevgeny Kliteynik void mlx5dr_ste_set_action_add(struct mlx5dr_ste_ctx *ste_ctx,
5684781df92SYevgeny Kliteynik 			       __be64 *hw_action,
5694781df92SYevgeny Kliteynik 			       u8 hw_field,
5704781df92SYevgeny Kliteynik 			       u8 shifter,
5714781df92SYevgeny Kliteynik 			       u8 length,
5724781df92SYevgeny Kliteynik 			       u32 data)
5734781df92SYevgeny Kliteynik {
5744781df92SYevgeny Kliteynik 	ste_ctx->set_action_add((u8 *)hw_action,
5754781df92SYevgeny Kliteynik 				hw_field, shifter, length, data);
5764781df92SYevgeny Kliteynik }
5774781df92SYevgeny Kliteynik 
5784781df92SYevgeny Kliteynik void mlx5dr_ste_set_action_copy(struct mlx5dr_ste_ctx *ste_ctx,
5794781df92SYevgeny Kliteynik 				__be64 *hw_action,
5804781df92SYevgeny Kliteynik 				u8 dst_hw_field,
5814781df92SYevgeny Kliteynik 				u8 dst_shifter,
5824781df92SYevgeny Kliteynik 				u8 dst_len,
5834781df92SYevgeny Kliteynik 				u8 src_hw_field,
5844781df92SYevgeny Kliteynik 				u8 src_shifter)
5854781df92SYevgeny Kliteynik {
5864781df92SYevgeny Kliteynik 	ste_ctx->set_action_copy((u8 *)hw_action,
5874781df92SYevgeny Kliteynik 				 dst_hw_field, dst_shifter, dst_len,
5884781df92SYevgeny Kliteynik 				 src_hw_field, src_shifter);
5894781df92SYevgeny Kliteynik }
5904781df92SYevgeny Kliteynik 
5914781df92SYevgeny Kliteynik int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx,
5924781df92SYevgeny Kliteynik 					void *data, u32 data_sz,
5934781df92SYevgeny Kliteynik 					u8 *hw_action, u32 hw_action_sz,
5944781df92SYevgeny Kliteynik 					u16 *used_hw_action_num)
5954781df92SYevgeny Kliteynik {
5964781df92SYevgeny Kliteynik 	/* Only Ethernet frame is supported, with VLAN (18) or without (14) */
5974781df92SYevgeny Kliteynik 	if (data_sz != HDR_LEN_L2 && data_sz != HDR_LEN_L2_W_VLAN)
5984781df92SYevgeny Kliteynik 		return -EINVAL;
5994781df92SYevgeny Kliteynik 
6004781df92SYevgeny Kliteynik 	return ste_ctx->set_action_decap_l3_list(data, data_sz,
6014781df92SYevgeny Kliteynik 						 hw_action, hw_action_sz,
6024781df92SYevgeny Kliteynik 						 used_hw_action_num);
6034781df92SYevgeny Kliteynik }
6044781df92SYevgeny Kliteynik 
605ffb0753bSYevgeny Kliteynik static int dr_ste_build_pre_check_spec(struct mlx5dr_domain *dmn,
606ffb0753bSYevgeny Kliteynik 				       struct mlx5dr_match_spec *spec)
607ffb0753bSYevgeny Kliteynik {
608ffb0753bSYevgeny Kliteynik 	if (spec->ip_version) {
609ffb0753bSYevgeny Kliteynik 		if (spec->ip_version != 0xf) {
610ffb0753bSYevgeny Kliteynik 			mlx5dr_err(dmn,
611ffb0753bSYevgeny Kliteynik 				   "Partial ip_version mask with src/dst IP is not supported\n");
612ffb0753bSYevgeny Kliteynik 			return -EINVAL;
613ffb0753bSYevgeny Kliteynik 		}
614ffb0753bSYevgeny Kliteynik 	} else if (spec->ethertype != 0xffff &&
615ffb0753bSYevgeny Kliteynik 		   (DR_MASK_IS_SRC_IP_SET(spec) || DR_MASK_IS_DST_IP_SET(spec))) {
616ffb0753bSYevgeny Kliteynik 		mlx5dr_err(dmn,
617ffb0753bSYevgeny Kliteynik 			   "Partial/no ethertype mask with src/dst IP is not supported\n");
618ffb0753bSYevgeny Kliteynik 		return -EINVAL;
619ffb0753bSYevgeny Kliteynik 	}
620ffb0753bSYevgeny Kliteynik 
621ffb0753bSYevgeny Kliteynik 	return 0;
622ffb0753bSYevgeny Kliteynik }
623ffb0753bSYevgeny Kliteynik 
62426d688e3SAlex Vesker int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
62526d688e3SAlex Vesker 			       u8 match_criteria,
62626d688e3SAlex Vesker 			       struct mlx5dr_match_param *mask,
62726d688e3SAlex Vesker 			       struct mlx5dr_match_param *value)
62826d688e3SAlex Vesker {
629ffb0753bSYevgeny Kliteynik 	if (value)
630ffb0753bSYevgeny Kliteynik 		return 0;
631ffb0753bSYevgeny Kliteynik 
632ffb0753bSYevgeny Kliteynik 	if (match_criteria & DR_MATCHER_CRITERIA_MISC) {
63326d688e3SAlex Vesker 		if (mask->misc.source_port && mask->misc.source_port != 0xffff) {
63438a5c59dSYevgeny Kliteynik 			mlx5dr_err(dmn,
63538a5c59dSYevgeny Kliteynik 				   "Partial mask source_port is not supported\n");
63638a5c59dSYevgeny Kliteynik 			return -EINVAL;
63738a5c59dSYevgeny Kliteynik 		}
63838a5c59dSYevgeny Kliteynik 		if (mask->misc.source_eswitch_owner_vhca_id &&
63938a5c59dSYevgeny Kliteynik 		    mask->misc.source_eswitch_owner_vhca_id != 0xffff) {
64038a5c59dSYevgeny Kliteynik 			mlx5dr_err(dmn,
64138a5c59dSYevgeny Kliteynik 				   "Partial mask source_eswitch_owner_vhca_id is not supported\n");
64226d688e3SAlex Vesker 			return -EINVAL;
64326d688e3SAlex Vesker 		}
64426d688e3SAlex Vesker 	}
64526d688e3SAlex Vesker 
646ffb0753bSYevgeny Kliteynik 	if ((match_criteria & DR_MATCHER_CRITERIA_OUTER) &&
647ffb0753bSYevgeny Kliteynik 	    dr_ste_build_pre_check_spec(dmn, &mask->outer))
648ffb0753bSYevgeny Kliteynik 		return -EINVAL;
649ffb0753bSYevgeny Kliteynik 
650ffb0753bSYevgeny Kliteynik 	if ((match_criteria & DR_MATCHER_CRITERIA_INNER) &&
651ffb0753bSYevgeny Kliteynik 	    dr_ste_build_pre_check_spec(dmn, &mask->inner))
652ffb0753bSYevgeny Kliteynik 		return -EINVAL;
653ffb0753bSYevgeny Kliteynik 
65426d688e3SAlex Vesker 	return 0;
65526d688e3SAlex Vesker }
65626d688e3SAlex Vesker 
65726d688e3SAlex Vesker int mlx5dr_ste_build_ste_arr(struct mlx5dr_matcher *matcher,
65826d688e3SAlex Vesker 			     struct mlx5dr_matcher_rx_tx *nic_matcher,
65926d688e3SAlex Vesker 			     struct mlx5dr_match_param *value,
66026d688e3SAlex Vesker 			     u8 *ste_arr)
66126d688e3SAlex Vesker {
66226d688e3SAlex Vesker 	struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn;
66346f2a8aeSYevgeny Kliteynik 	bool is_rx = nic_dmn->type == DR_DOMAIN_NIC_TYPE_RX;
66426d688e3SAlex Vesker 	struct mlx5dr_domain *dmn = matcher->tbl->dmn;
6656b93b400SYevgeny Kliteynik 	struct mlx5dr_ste_ctx *ste_ctx = dmn->ste_ctx;
66626d688e3SAlex Vesker 	struct mlx5dr_ste_build *sb;
66726d688e3SAlex Vesker 	int ret, i;
66826d688e3SAlex Vesker 
66926d688e3SAlex Vesker 	ret = mlx5dr_ste_build_pre_check(dmn, matcher->match_criteria,
67026d688e3SAlex Vesker 					 &matcher->mask, value);
67126d688e3SAlex Vesker 	if (ret)
67226d688e3SAlex Vesker 		return ret;
67326d688e3SAlex Vesker 
67426d688e3SAlex Vesker 	sb = nic_matcher->ste_builder;
67526d688e3SAlex Vesker 	for (i = 0; i < nic_matcher->num_of_builders; i++) {
6766b93b400SYevgeny Kliteynik 		ste_ctx->ste_init(ste_arr,
67726d688e3SAlex Vesker 				  sb->lu_type,
67846f2a8aeSYevgeny Kliteynik 				  is_rx,
67926d688e3SAlex Vesker 				  dmn->info.caps.gvmi);
68026d688e3SAlex Vesker 
68126d688e3SAlex Vesker 		mlx5dr_ste_set_bit_mask(ste_arr, sb->bit_mask);
68226d688e3SAlex Vesker 
68364c78942SYevgeny Kliteynik 		ret = sb->ste_build_tag_func(value, sb, dr_ste_get_tag(ste_arr));
68426d688e3SAlex Vesker 		if (ret)
68526d688e3SAlex Vesker 			return ret;
68626d688e3SAlex Vesker 
68726d688e3SAlex Vesker 		/* Connect the STEs */
68826d688e3SAlex Vesker 		if (i < (nic_matcher->num_of_builders - 1)) {
68926d688e3SAlex Vesker 			/* Need the next builder for these fields,
69026d688e3SAlex Vesker 			 * not relevant for the last ste in the chain.
69126d688e3SAlex Vesker 			 */
69226d688e3SAlex Vesker 			sb++;
6936b93b400SYevgeny Kliteynik 			ste_ctx->set_next_lu_type(ste_arr, sb->lu_type);
6946b93b400SYevgeny Kliteynik 			ste_ctx->set_byte_mask(ste_arr, sb->byte_mask);
69526d688e3SAlex Vesker 		}
69626d688e3SAlex Vesker 		ste_arr += DR_STE_SIZE;
69726d688e3SAlex Vesker 	}
69826d688e3SAlex Vesker 	return 0;
69926d688e3SAlex Vesker }
70026d688e3SAlex Vesker 
701941f1979SMuhammad Sammar #define IFC_GET_CLR(typ, p, fld, clear) ({ \
702941f1979SMuhammad Sammar 	void *__p = (p); \
703941f1979SMuhammad Sammar 	u32 __t = MLX5_GET(typ, __p, fld); \
704941f1979SMuhammad Sammar 	if (clear) \
705941f1979SMuhammad Sammar 		MLX5_SET(typ, __p, fld, 0); \
706941f1979SMuhammad Sammar 	__t; \
707941f1979SMuhammad Sammar })
708941f1979SMuhammad Sammar 
709941f1979SMuhammad Sammar #define memcpy_and_clear(to, from, len, clear) ({ \
710941f1979SMuhammad Sammar 	void *__to = (to), *__from = (from); \
711941f1979SMuhammad Sammar 	size_t __len = (len); \
712941f1979SMuhammad Sammar 	memcpy(__to, __from, __len); \
713941f1979SMuhammad Sammar 	if (clear) \
714941f1979SMuhammad Sammar 		memset(__from, 0, __len); \
715941f1979SMuhammad Sammar })
716941f1979SMuhammad Sammar 
717941f1979SMuhammad Sammar static void dr_ste_copy_mask_misc(char *mask, struct mlx5dr_match_misc *spec, bool clr)
71826d688e3SAlex Vesker {
719941f1979SMuhammad Sammar 	spec->gre_c_present = IFC_GET_CLR(fte_match_set_misc, mask, gre_c_present, clr);
720941f1979SMuhammad Sammar 	spec->gre_k_present = IFC_GET_CLR(fte_match_set_misc, mask, gre_k_present, clr);
721941f1979SMuhammad Sammar 	spec->gre_s_present = IFC_GET_CLR(fte_match_set_misc, mask, gre_s_present, clr);
722941f1979SMuhammad Sammar 	spec->source_vhca_port = IFC_GET_CLR(fte_match_set_misc, mask, source_vhca_port, clr);
723941f1979SMuhammad Sammar 	spec->source_sqn = IFC_GET_CLR(fte_match_set_misc, mask, source_sqn, clr);
72426d688e3SAlex Vesker 
725941f1979SMuhammad Sammar 	spec->source_port = IFC_GET_CLR(fte_match_set_misc, mask, source_port, clr);
726941f1979SMuhammad Sammar 	spec->source_eswitch_owner_vhca_id =
727941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, source_eswitch_owner_vhca_id, clr);
72826d688e3SAlex Vesker 
729941f1979SMuhammad Sammar 	spec->outer_second_prio = IFC_GET_CLR(fte_match_set_misc, mask, outer_second_prio, clr);
730941f1979SMuhammad Sammar 	spec->outer_second_cfi = IFC_GET_CLR(fte_match_set_misc, mask, outer_second_cfi, clr);
731941f1979SMuhammad Sammar 	spec->outer_second_vid = IFC_GET_CLR(fte_match_set_misc, mask, outer_second_vid, clr);
732941f1979SMuhammad Sammar 	spec->inner_second_prio = IFC_GET_CLR(fte_match_set_misc, mask, inner_second_prio, clr);
733941f1979SMuhammad Sammar 	spec->inner_second_cfi = IFC_GET_CLR(fte_match_set_misc, mask, inner_second_cfi, clr);
734941f1979SMuhammad Sammar 	spec->inner_second_vid = IFC_GET_CLR(fte_match_set_misc, mask, inner_second_vid, clr);
73526d688e3SAlex Vesker 
73626d688e3SAlex Vesker 	spec->outer_second_cvlan_tag =
737941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, outer_second_cvlan_tag, clr);
73826d688e3SAlex Vesker 	spec->inner_second_cvlan_tag =
739941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, inner_second_cvlan_tag, clr);
74026d688e3SAlex Vesker 	spec->outer_second_svlan_tag =
741941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, outer_second_svlan_tag, clr);
74226d688e3SAlex Vesker 	spec->inner_second_svlan_tag =
743941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, inner_second_svlan_tag, clr);
744941f1979SMuhammad Sammar 	spec->gre_protocol = IFC_GET_CLR(fte_match_set_misc, mask, gre_protocol, clr);
74526d688e3SAlex Vesker 
746941f1979SMuhammad Sammar 	spec->gre_key_h = IFC_GET_CLR(fte_match_set_misc, mask, gre_key.nvgre.hi, clr);
747941f1979SMuhammad Sammar 	spec->gre_key_l = IFC_GET_CLR(fte_match_set_misc, mask, gre_key.nvgre.lo, clr);
74826d688e3SAlex Vesker 
749941f1979SMuhammad Sammar 	spec->vxlan_vni = IFC_GET_CLR(fte_match_set_misc, mask, vxlan_vni, clr);
75026d688e3SAlex Vesker 
751941f1979SMuhammad Sammar 	spec->geneve_vni = IFC_GET_CLR(fte_match_set_misc, mask, geneve_vni, clr);
752f59464e2SYevgeny Kliteynik 	spec->geneve_tlv_option_0_exist =
753f59464e2SYevgeny Kliteynik 		IFC_GET_CLR(fte_match_set_misc, mask, geneve_tlv_option_0_exist, clr);
754941f1979SMuhammad Sammar 	spec->geneve_oam = IFC_GET_CLR(fte_match_set_misc, mask, geneve_oam, clr);
75526d688e3SAlex Vesker 
75626d688e3SAlex Vesker 	spec->outer_ipv6_flow_label =
757941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, outer_ipv6_flow_label, clr);
75826d688e3SAlex Vesker 
75926d688e3SAlex Vesker 	spec->inner_ipv6_flow_label =
760941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, inner_ipv6_flow_label, clr);
76126d688e3SAlex Vesker 
762941f1979SMuhammad Sammar 	spec->geneve_opt_len = IFC_GET_CLR(fte_match_set_misc, mask, geneve_opt_len, clr);
76326d688e3SAlex Vesker 	spec->geneve_protocol_type =
764941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc, mask, geneve_protocol_type, clr);
76526d688e3SAlex Vesker 
766941f1979SMuhammad Sammar 	spec->bth_dst_qp = IFC_GET_CLR(fte_match_set_misc, mask, bth_dst_qp, clr);
76726d688e3SAlex Vesker }
76826d688e3SAlex Vesker 
769941f1979SMuhammad Sammar static void dr_ste_copy_mask_spec(char *mask, struct mlx5dr_match_spec *spec, bool clr)
77026d688e3SAlex Vesker {
771c2ba2c22SSaeed Mahameed 	__be32 raw_ip[4];
77226d688e3SAlex Vesker 
773941f1979SMuhammad Sammar 	spec->smac_47_16 = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, smac_47_16, clr);
77426d688e3SAlex Vesker 
775941f1979SMuhammad Sammar 	spec->smac_15_0 = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, smac_15_0, clr);
776941f1979SMuhammad Sammar 	spec->ethertype = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ethertype, clr);
77726d688e3SAlex Vesker 
778941f1979SMuhammad Sammar 	spec->dmac_47_16 = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, dmac_47_16, clr);
77926d688e3SAlex Vesker 
780941f1979SMuhammad Sammar 	spec->dmac_15_0 = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, dmac_15_0, clr);
781941f1979SMuhammad Sammar 	spec->first_prio = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, first_prio, clr);
782941f1979SMuhammad Sammar 	spec->first_cfi = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, first_cfi, clr);
783941f1979SMuhammad Sammar 	spec->first_vid = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, first_vid, clr);
78426d688e3SAlex Vesker 
785941f1979SMuhammad Sammar 	spec->ip_protocol = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ip_protocol, clr);
786941f1979SMuhammad Sammar 	spec->ip_dscp = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ip_dscp, clr);
787941f1979SMuhammad Sammar 	spec->ip_ecn = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ip_ecn, clr);
788941f1979SMuhammad Sammar 	spec->cvlan_tag = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, cvlan_tag, clr);
789941f1979SMuhammad Sammar 	spec->svlan_tag = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, svlan_tag, clr);
790941f1979SMuhammad Sammar 	spec->frag = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, frag, clr);
791941f1979SMuhammad Sammar 	spec->ip_version = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ip_version, clr);
792941f1979SMuhammad Sammar 	spec->tcp_flags = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, tcp_flags, clr);
793941f1979SMuhammad Sammar 	spec->tcp_sport = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, tcp_sport, clr);
794941f1979SMuhammad Sammar 	spec->tcp_dport = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, tcp_dport, clr);
79526d688e3SAlex Vesker 
7965c422bfaSYevgeny Kliteynik 	spec->ipv4_ihl = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ipv4_ihl, clr);
797941f1979SMuhammad Sammar 	spec->ttl_hoplimit = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, ttl_hoplimit, clr);
79826d688e3SAlex Vesker 
799941f1979SMuhammad Sammar 	spec->udp_sport = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, udp_sport, clr);
800941f1979SMuhammad Sammar 	spec->udp_dport = IFC_GET_CLR(fte_match_set_lyr_2_4, mask, udp_dport, clr);
80126d688e3SAlex Vesker 
802941f1979SMuhammad Sammar 	memcpy_and_clear(raw_ip, MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask,
80326d688e3SAlex Vesker 					      src_ipv4_src_ipv6.ipv6_layout.ipv6),
804941f1979SMuhammad Sammar 			 sizeof(raw_ip), clr);
80526d688e3SAlex Vesker 
80626d688e3SAlex Vesker 	spec->src_ip_127_96 = be32_to_cpu(raw_ip[0]);
80726d688e3SAlex Vesker 	spec->src_ip_95_64 = be32_to_cpu(raw_ip[1]);
80826d688e3SAlex Vesker 	spec->src_ip_63_32 = be32_to_cpu(raw_ip[2]);
80926d688e3SAlex Vesker 	spec->src_ip_31_0 = be32_to_cpu(raw_ip[3]);
81026d688e3SAlex Vesker 
811941f1979SMuhammad Sammar 	memcpy_and_clear(raw_ip, MLX5_ADDR_OF(fte_match_set_lyr_2_4, mask,
81226d688e3SAlex Vesker 					      dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
813941f1979SMuhammad Sammar 			 sizeof(raw_ip), clr);
81426d688e3SAlex Vesker 
81526d688e3SAlex Vesker 	spec->dst_ip_127_96 = be32_to_cpu(raw_ip[0]);
81626d688e3SAlex Vesker 	spec->dst_ip_95_64 = be32_to_cpu(raw_ip[1]);
81726d688e3SAlex Vesker 	spec->dst_ip_63_32 = be32_to_cpu(raw_ip[2]);
81826d688e3SAlex Vesker 	spec->dst_ip_31_0 = be32_to_cpu(raw_ip[3]);
81926d688e3SAlex Vesker }
82026d688e3SAlex Vesker 
821941f1979SMuhammad Sammar static void dr_ste_copy_mask_misc2(char *mask, struct mlx5dr_match_misc2 *spec, bool clr)
82226d688e3SAlex Vesker {
82326d688e3SAlex Vesker 	spec->outer_first_mpls_label =
824941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls.mpls_label, clr);
82526d688e3SAlex Vesker 	spec->outer_first_mpls_exp =
826941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls.mpls_exp, clr);
82726d688e3SAlex Vesker 	spec->outer_first_mpls_s_bos =
828941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls.mpls_s_bos, clr);
82926d688e3SAlex Vesker 	spec->outer_first_mpls_ttl =
830941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls.mpls_ttl, clr);
83126d688e3SAlex Vesker 	spec->inner_first_mpls_label =
832941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, inner_first_mpls.mpls_label, clr);
83326d688e3SAlex Vesker 	spec->inner_first_mpls_exp =
834941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, inner_first_mpls.mpls_exp, clr);
83526d688e3SAlex Vesker 	spec->inner_first_mpls_s_bos =
836941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, inner_first_mpls.mpls_s_bos, clr);
83726d688e3SAlex Vesker 	spec->inner_first_mpls_ttl =
838941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, inner_first_mpls.mpls_ttl, clr);
83926d688e3SAlex Vesker 	spec->outer_first_mpls_over_gre_label =
840941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_label, clr);
84126d688e3SAlex Vesker 	spec->outer_first_mpls_over_gre_exp =
842941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_exp, clr);
84326d688e3SAlex Vesker 	spec->outer_first_mpls_over_gre_s_bos =
844941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_s_bos, clr);
84526d688e3SAlex Vesker 	spec->outer_first_mpls_over_gre_ttl =
846941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_gre.mpls_ttl, clr);
84726d688e3SAlex Vesker 	spec->outer_first_mpls_over_udp_label =
848941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_label, clr);
84926d688e3SAlex Vesker 	spec->outer_first_mpls_over_udp_exp =
850941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_exp, clr);
85126d688e3SAlex Vesker 	spec->outer_first_mpls_over_udp_s_bos =
852941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_s_bos, clr);
85326d688e3SAlex Vesker 	spec->outer_first_mpls_over_udp_ttl =
854941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc2, mask, outer_first_mpls_over_udp.mpls_ttl, clr);
855941f1979SMuhammad Sammar 	spec->metadata_reg_c_7 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_7, clr);
856941f1979SMuhammad Sammar 	spec->metadata_reg_c_6 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_6, clr);
857941f1979SMuhammad Sammar 	spec->metadata_reg_c_5 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_5, clr);
858941f1979SMuhammad Sammar 	spec->metadata_reg_c_4 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_4, clr);
859941f1979SMuhammad Sammar 	spec->metadata_reg_c_3 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_3, clr);
860941f1979SMuhammad Sammar 	spec->metadata_reg_c_2 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_2, clr);
861941f1979SMuhammad Sammar 	spec->metadata_reg_c_1 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_1, clr);
862941f1979SMuhammad Sammar 	spec->metadata_reg_c_0 = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_c_0, clr);
863941f1979SMuhammad Sammar 	spec->metadata_reg_a = IFC_GET_CLR(fte_match_set_misc2, mask, metadata_reg_a, clr);
86426d688e3SAlex Vesker }
86526d688e3SAlex Vesker 
866941f1979SMuhammad Sammar static void dr_ste_copy_mask_misc3(char *mask, struct mlx5dr_match_misc3 *spec, bool clr)
86726d688e3SAlex Vesker {
868941f1979SMuhammad Sammar 	spec->inner_tcp_seq_num = IFC_GET_CLR(fte_match_set_misc3, mask, inner_tcp_seq_num, clr);
869941f1979SMuhammad Sammar 	spec->outer_tcp_seq_num = IFC_GET_CLR(fte_match_set_misc3, mask, outer_tcp_seq_num, clr);
870941f1979SMuhammad Sammar 	spec->inner_tcp_ack_num = IFC_GET_CLR(fte_match_set_misc3, mask, inner_tcp_ack_num, clr);
871941f1979SMuhammad Sammar 	spec->outer_tcp_ack_num = IFC_GET_CLR(fte_match_set_misc3, mask, outer_tcp_ack_num, clr);
87226d688e3SAlex Vesker 	spec->outer_vxlan_gpe_vni =
873941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, outer_vxlan_gpe_vni, clr);
87426d688e3SAlex Vesker 	spec->outer_vxlan_gpe_next_protocol =
875941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, outer_vxlan_gpe_next_protocol, clr);
87626d688e3SAlex Vesker 	spec->outer_vxlan_gpe_flags =
877941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, outer_vxlan_gpe_flags, clr);
878941f1979SMuhammad Sammar 	spec->icmpv4_header_data = IFC_GET_CLR(fte_match_set_misc3, mask, icmp_header_data, clr);
87926d688e3SAlex Vesker 	spec->icmpv6_header_data =
880941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, icmpv6_header_data, clr);
881941f1979SMuhammad Sammar 	spec->icmpv4_type = IFC_GET_CLR(fte_match_set_misc3, mask, icmp_type, clr);
882941f1979SMuhammad Sammar 	spec->icmpv4_code = IFC_GET_CLR(fte_match_set_misc3, mask, icmp_code, clr);
883941f1979SMuhammad Sammar 	spec->icmpv6_type = IFC_GET_CLR(fte_match_set_misc3, mask, icmpv6_type, clr);
884941f1979SMuhammad Sammar 	spec->icmpv6_code = IFC_GET_CLR(fte_match_set_misc3, mask, icmpv6_code, clr);
8853442e033SYevgeny Kliteynik 	spec->geneve_tlv_option_0_data =
886941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, geneve_tlv_option_0_data, clr);
887941f1979SMuhammad Sammar 	spec->gtpu_teid = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_teid, clr);
888941f1979SMuhammad Sammar 	spec->gtpu_msg_flags = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_msg_flags, clr);
889941f1979SMuhammad Sammar 	spec->gtpu_msg_type = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_msg_type, clr);
890941f1979SMuhammad Sammar 	spec->gtpu_dw_0 = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_dw_0, clr);
891941f1979SMuhammad Sammar 	spec->gtpu_dw_2 = IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_dw_2, clr);
892df9dd15aSYevgeny Kliteynik 	spec->gtpu_first_ext_dw_0 =
893941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc3, mask, gtpu_first_ext_dw_0, clr);
89426d688e3SAlex Vesker }
89526d688e3SAlex Vesker 
896941f1979SMuhammad Sammar static void dr_ste_copy_mask_misc4(char *mask, struct mlx5dr_match_misc4 *spec, bool clr)
897160e9cb3SYevgeny Kliteynik {
898160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_id_0 =
899941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_id_0, clr);
900160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_value_0 =
901941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_value_0, clr);
902160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_id_1 =
903941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_id_1, clr);
904160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_value_1 =
905941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_value_1, clr);
906160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_id_2 =
907941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_id_2, clr);
908160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_value_2 =
909941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_value_2, clr);
910160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_id_3 =
911941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_id_3, clr);
912160e9cb3SYevgeny Kliteynik 	spec->prog_sample_field_value_3 =
913941f1979SMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc4, mask, prog_sample_field_value_3, clr);
914160e9cb3SYevgeny Kliteynik }
915160e9cb3SYevgeny Kliteynik 
9168c2b4feeSMuhammad Sammar static void dr_ste_copy_mask_misc5(char *mask, struct mlx5dr_match_misc5 *spec, bool clr)
9178c2b4feeSMuhammad Sammar {
9188c2b4feeSMuhammad Sammar 	spec->macsec_tag_0 =
9198c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, macsec_tag_0, clr);
9208c2b4feeSMuhammad Sammar 	spec->macsec_tag_1 =
9218c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, macsec_tag_1, clr);
9228c2b4feeSMuhammad Sammar 	spec->macsec_tag_2 =
9238c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, macsec_tag_2, clr);
9248c2b4feeSMuhammad Sammar 	spec->macsec_tag_3 =
9258c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, macsec_tag_3, clr);
9268c2b4feeSMuhammad Sammar 	spec->tunnel_header_0 =
9278c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, tunnel_header_0, clr);
9288c2b4feeSMuhammad Sammar 	spec->tunnel_header_1 =
9298c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, tunnel_header_1, clr);
9308c2b4feeSMuhammad Sammar 	spec->tunnel_header_2 =
9318c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, tunnel_header_2, clr);
9328c2b4feeSMuhammad Sammar 	spec->tunnel_header_3 =
9338c2b4feeSMuhammad Sammar 		IFC_GET_CLR(fte_match_set_misc5, mask, tunnel_header_3, clr);
9348c2b4feeSMuhammad Sammar }
9358c2b4feeSMuhammad Sammar 
93626d688e3SAlex Vesker void mlx5dr_ste_copy_param(u8 match_criteria,
93726d688e3SAlex Vesker 			   struct mlx5dr_match_param *set_param,
938941f1979SMuhammad Sammar 			   struct mlx5dr_match_parameters *mask,
939941f1979SMuhammad Sammar 			   bool clr)
94026d688e3SAlex Vesker {
94126d688e3SAlex Vesker 	u8 tail_param[MLX5_ST_SZ_BYTES(fte_match_set_lyr_2_4)] = {};
94226d688e3SAlex Vesker 	u8 *data = (u8 *)mask->match_buf;
94326d688e3SAlex Vesker 	size_t param_location;
94426d688e3SAlex Vesker 	void *buff;
94526d688e3SAlex Vesker 
94626d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_OUTER) {
94726d688e3SAlex Vesker 		if (mask->match_sz < sizeof(struct mlx5dr_match_spec)) {
94826d688e3SAlex Vesker 			memcpy(tail_param, data, mask->match_sz);
94926d688e3SAlex Vesker 			buff = tail_param;
95026d688e3SAlex Vesker 		} else {
95126d688e3SAlex Vesker 			buff = mask->match_buf;
95226d688e3SAlex Vesker 		}
953941f1979SMuhammad Sammar 		dr_ste_copy_mask_spec(buff, &set_param->outer, clr);
95426d688e3SAlex Vesker 	}
95526d688e3SAlex Vesker 	param_location = sizeof(struct mlx5dr_match_spec);
95626d688e3SAlex Vesker 
95726d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_MISC) {
95826d688e3SAlex Vesker 		if (mask->match_sz < param_location +
95926d688e3SAlex Vesker 		    sizeof(struct mlx5dr_match_misc)) {
96026d688e3SAlex Vesker 			memcpy(tail_param, data + param_location,
96126d688e3SAlex Vesker 			       mask->match_sz - param_location);
96226d688e3SAlex Vesker 			buff = tail_param;
96326d688e3SAlex Vesker 		} else {
96426d688e3SAlex Vesker 			buff = data + param_location;
96526d688e3SAlex Vesker 		}
966941f1979SMuhammad Sammar 		dr_ste_copy_mask_misc(buff, &set_param->misc, clr);
96726d688e3SAlex Vesker 	}
96826d688e3SAlex Vesker 	param_location += sizeof(struct mlx5dr_match_misc);
96926d688e3SAlex Vesker 
97026d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_INNER) {
97126d688e3SAlex Vesker 		if (mask->match_sz < param_location +
97226d688e3SAlex Vesker 		    sizeof(struct mlx5dr_match_spec)) {
97326d688e3SAlex Vesker 			memcpy(tail_param, data + param_location,
97426d688e3SAlex Vesker 			       mask->match_sz - param_location);
97526d688e3SAlex Vesker 			buff = tail_param;
97626d688e3SAlex Vesker 		} else {
97726d688e3SAlex Vesker 			buff = data + param_location;
97826d688e3SAlex Vesker 		}
979941f1979SMuhammad Sammar 		dr_ste_copy_mask_spec(buff, &set_param->inner, clr);
98026d688e3SAlex Vesker 	}
98126d688e3SAlex Vesker 	param_location += sizeof(struct mlx5dr_match_spec);
98226d688e3SAlex Vesker 
98326d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_MISC2) {
98426d688e3SAlex Vesker 		if (mask->match_sz < param_location +
98526d688e3SAlex Vesker 		    sizeof(struct mlx5dr_match_misc2)) {
98626d688e3SAlex Vesker 			memcpy(tail_param, data + param_location,
98726d688e3SAlex Vesker 			       mask->match_sz - param_location);
98826d688e3SAlex Vesker 			buff = tail_param;
98926d688e3SAlex Vesker 		} else {
99026d688e3SAlex Vesker 			buff = data + param_location;
99126d688e3SAlex Vesker 		}
992941f1979SMuhammad Sammar 		dr_ste_copy_mask_misc2(buff, &set_param->misc2, clr);
99326d688e3SAlex Vesker 	}
99426d688e3SAlex Vesker 
99526d688e3SAlex Vesker 	param_location += sizeof(struct mlx5dr_match_misc2);
99626d688e3SAlex Vesker 
99726d688e3SAlex Vesker 	if (match_criteria & DR_MATCHER_CRITERIA_MISC3) {
99826d688e3SAlex Vesker 		if (mask->match_sz < param_location +
99926d688e3SAlex Vesker 		    sizeof(struct mlx5dr_match_misc3)) {
100026d688e3SAlex Vesker 			memcpy(tail_param, data + param_location,
100126d688e3SAlex Vesker 			       mask->match_sz - param_location);
100226d688e3SAlex Vesker 			buff = tail_param;
100326d688e3SAlex Vesker 		} else {
100426d688e3SAlex Vesker 			buff = data + param_location;
100526d688e3SAlex Vesker 		}
1006941f1979SMuhammad Sammar 		dr_ste_copy_mask_misc3(buff, &set_param->misc3, clr);
100726d688e3SAlex Vesker 	}
1008160e9cb3SYevgeny Kliteynik 
1009160e9cb3SYevgeny Kliteynik 	param_location += sizeof(struct mlx5dr_match_misc3);
1010160e9cb3SYevgeny Kliteynik 
1011160e9cb3SYevgeny Kliteynik 	if (match_criteria & DR_MATCHER_CRITERIA_MISC4) {
1012160e9cb3SYevgeny Kliteynik 		if (mask->match_sz < param_location +
1013160e9cb3SYevgeny Kliteynik 		    sizeof(struct mlx5dr_match_misc4)) {
1014160e9cb3SYevgeny Kliteynik 			memcpy(tail_param, data + param_location,
1015160e9cb3SYevgeny Kliteynik 			       mask->match_sz - param_location);
1016160e9cb3SYevgeny Kliteynik 			buff = tail_param;
1017160e9cb3SYevgeny Kliteynik 		} else {
1018160e9cb3SYevgeny Kliteynik 			buff = data + param_location;
1019160e9cb3SYevgeny Kliteynik 		}
1020941f1979SMuhammad Sammar 		dr_ste_copy_mask_misc4(buff, &set_param->misc4, clr);
1021160e9cb3SYevgeny Kliteynik 	}
10228c2b4feeSMuhammad Sammar 
10238c2b4feeSMuhammad Sammar 	param_location += sizeof(struct mlx5dr_match_misc4);
10248c2b4feeSMuhammad Sammar 
10258c2b4feeSMuhammad Sammar 	if (match_criteria & DR_MATCHER_CRITERIA_MISC5) {
10268c2b4feeSMuhammad Sammar 		if (mask->match_sz < param_location +
10278c2b4feeSMuhammad Sammar 		    sizeof(struct mlx5dr_match_misc5)) {
10288c2b4feeSMuhammad Sammar 			memcpy(tail_param, data + param_location,
10298c2b4feeSMuhammad Sammar 			       mask->match_sz - param_location);
10308c2b4feeSMuhammad Sammar 			buff = tail_param;
10318c2b4feeSMuhammad Sammar 		} else {
10328c2b4feeSMuhammad Sammar 			buff = data + param_location;
10338c2b4feeSMuhammad Sammar 		}
10348c2b4feeSMuhammad Sammar 		dr_ste_copy_mask_misc5(buff, &set_param->misc5, clr);
10358c2b4feeSMuhammad Sammar 	}
103626d688e3SAlex Vesker }
103726d688e3SAlex Vesker 
10385212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l2_src_dst(struct mlx5dr_ste_ctx *ste_ctx,
10395212f9c6SYevgeny Kliteynik 				     struct mlx5dr_ste_build *sb,
104026d688e3SAlex Vesker 				     struct mlx5dr_match_param *mask,
104126d688e3SAlex Vesker 				     bool inner, bool rx)
104226d688e3SAlex Vesker {
104326d688e3SAlex Vesker 	sb->rx = rx;
104426d688e3SAlex Vesker 	sb->inner = inner;
10455212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l2_src_dst_init(sb, mask);
104626d688e3SAlex Vesker }
104726d688e3SAlex Vesker 
10485212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l3_ipv6_dst(struct mlx5dr_ste_ctx *ste_ctx,
10495212f9c6SYevgeny Kliteynik 				      struct mlx5dr_ste_build *sb,
105026d688e3SAlex Vesker 				      struct mlx5dr_match_param *mask,
105126d688e3SAlex Vesker 				      bool inner, bool rx)
105226d688e3SAlex Vesker {
105326d688e3SAlex Vesker 	sb->rx = rx;
105426d688e3SAlex Vesker 	sb->inner = inner;
10555212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l3_ipv6_dst_init(sb, mask);
105626d688e3SAlex Vesker }
105726d688e3SAlex Vesker 
10585212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l3_ipv6_src(struct mlx5dr_ste_ctx *ste_ctx,
10595212f9c6SYevgeny Kliteynik 				      struct mlx5dr_ste_build *sb,
106026d688e3SAlex Vesker 				      struct mlx5dr_match_param *mask,
106126d688e3SAlex Vesker 				      bool inner, bool rx)
106226d688e3SAlex Vesker {
106326d688e3SAlex Vesker 	sb->rx = rx;
106426d688e3SAlex Vesker 	sb->inner = inner;
10655212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l3_ipv6_src_init(sb, mask);
106626d688e3SAlex Vesker }
106726d688e3SAlex Vesker 
10685212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l3_ipv4_5_tuple(struct mlx5dr_ste_ctx *ste_ctx,
10695212f9c6SYevgeny Kliteynik 					  struct mlx5dr_ste_build *sb,
107026d688e3SAlex Vesker 					  struct mlx5dr_match_param *mask,
107126d688e3SAlex Vesker 					  bool inner, bool rx)
107226d688e3SAlex Vesker {
107326d688e3SAlex Vesker 	sb->rx = rx;
107426d688e3SAlex Vesker 	sb->inner = inner;
10755212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l3_ipv4_5_tuple_init(sb, mask);
107626d688e3SAlex Vesker }
107726d688e3SAlex Vesker 
10785212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l2_src(struct mlx5dr_ste_ctx *ste_ctx,
10795212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
108026d688e3SAlex Vesker 				 struct mlx5dr_match_param *mask,
108126d688e3SAlex Vesker 				 bool inner, bool rx)
108226d688e3SAlex Vesker {
108326d688e3SAlex Vesker 	sb->rx = rx;
108426d688e3SAlex Vesker 	sb->inner = inner;
10855212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l2_src_init(sb, mask);
108626d688e3SAlex Vesker }
108726d688e3SAlex Vesker 
10885212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l2_dst(struct mlx5dr_ste_ctx *ste_ctx,
10895212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
109026d688e3SAlex Vesker 				 struct mlx5dr_match_param *mask,
109126d688e3SAlex Vesker 				 bool inner, bool rx)
109226d688e3SAlex Vesker {
109326d688e3SAlex Vesker 	sb->rx = rx;
109426d688e3SAlex Vesker 	sb->inner = inner;
10955212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l2_dst_init(sb, mask);
109626d688e3SAlex Vesker }
109726d688e3SAlex Vesker 
10985212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l2_tnl(struct mlx5dr_ste_ctx *ste_ctx,
10995212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
11005212f9c6SYevgeny Kliteynik 				 struct mlx5dr_match_param *mask, bool inner, bool rx)
11015212f9c6SYevgeny Kliteynik {
11025212f9c6SYevgeny Kliteynik 	sb->rx = rx;
11035212f9c6SYevgeny Kliteynik 	sb->inner = inner;
11045212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l2_tnl_init(sb, mask);
11055212f9c6SYevgeny Kliteynik }
11065212f9c6SYevgeny Kliteynik 
11075212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l3_ipv4_misc(struct mlx5dr_ste_ctx *ste_ctx,
11085212f9c6SYevgeny Kliteynik 				       struct mlx5dr_ste_build *sb,
110926d688e3SAlex Vesker 				       struct mlx5dr_match_param *mask,
111026d688e3SAlex Vesker 				       bool inner, bool rx)
111126d688e3SAlex Vesker {
111226d688e3SAlex Vesker 	sb->rx = rx;
111326d688e3SAlex Vesker 	sb->inner = inner;
11145212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l3_ipv4_misc_init(sb, mask);
111526d688e3SAlex Vesker }
111626d688e3SAlex Vesker 
11175212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_ipv6_l3_l4(struct mlx5dr_ste_ctx *ste_ctx,
11185212f9c6SYevgeny Kliteynik 				     struct mlx5dr_ste_build *sb,
111926d688e3SAlex Vesker 				     struct mlx5dr_match_param *mask,
112026d688e3SAlex Vesker 				     bool inner, bool rx)
112126d688e3SAlex Vesker {
112226d688e3SAlex Vesker 	sb->rx = rx;
112326d688e3SAlex Vesker 	sb->inner = inner;
11245212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_ipv6_l3_l4_init(sb, mask);
112526d688e3SAlex Vesker }
112626d688e3SAlex Vesker 
112726d688e3SAlex Vesker static int dr_ste_build_empty_always_hit_tag(struct mlx5dr_match_param *value,
112826d688e3SAlex Vesker 					     struct mlx5dr_ste_build *sb,
1129e6b69bf3SYevgeny Kliteynik 					     u8 *tag)
113026d688e3SAlex Vesker {
113126d688e3SAlex Vesker 	return 0;
113226d688e3SAlex Vesker }
113326d688e3SAlex Vesker 
113426d688e3SAlex Vesker void mlx5dr_ste_build_empty_always_hit(struct mlx5dr_ste_build *sb, bool rx)
113526d688e3SAlex Vesker {
113626d688e3SAlex Vesker 	sb->rx = rx;
113726d688e3SAlex Vesker 	sb->lu_type = MLX5DR_STE_LU_TYPE_DONT_CARE;
113826d688e3SAlex Vesker 	sb->byte_mask = 0;
113926d688e3SAlex Vesker 	sb->ste_build_tag_func = &dr_ste_build_empty_always_hit_tag;
114026d688e3SAlex Vesker }
114126d688e3SAlex Vesker 
11425212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_mpls(struct mlx5dr_ste_ctx *ste_ctx,
11435212f9c6SYevgeny Kliteynik 			   struct mlx5dr_ste_build *sb,
114426d688e3SAlex Vesker 			   struct mlx5dr_match_param *mask,
114526d688e3SAlex Vesker 			   bool inner, bool rx)
114626d688e3SAlex Vesker {
114726d688e3SAlex Vesker 	sb->rx = rx;
114826d688e3SAlex Vesker 	sb->inner = inner;
11495212f9c6SYevgeny Kliteynik 	ste_ctx->build_mpls_init(sb, mask);
115026d688e3SAlex Vesker }
115126d688e3SAlex Vesker 
11525212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_tnl_gre(struct mlx5dr_ste_ctx *ste_ctx,
11535212f9c6SYevgeny Kliteynik 			      struct mlx5dr_ste_build *sb,
11545212f9c6SYevgeny Kliteynik 			      struct mlx5dr_match_param *mask,
11555212f9c6SYevgeny Kliteynik 			      bool inner, bool rx)
11565212f9c6SYevgeny Kliteynik {
11575212f9c6SYevgeny Kliteynik 	sb->rx = rx;
11585212f9c6SYevgeny Kliteynik 	sb->inner = inner;
11595212f9c6SYevgeny Kliteynik 	ste_ctx->build_tnl_gre_init(sb, mask);
11605212f9c6SYevgeny Kliteynik }
11615212f9c6SYevgeny Kliteynik 
116235ba005dSYevgeny Kliteynik void mlx5dr_ste_build_tnl_mpls_over_gre(struct mlx5dr_ste_ctx *ste_ctx,
11635212f9c6SYevgeny Kliteynik 					struct mlx5dr_ste_build *sb,
116426d688e3SAlex Vesker 					struct mlx5dr_match_param *mask,
116535ba005dSYevgeny Kliteynik 					struct mlx5dr_cmd_caps *caps,
116626d688e3SAlex Vesker 					bool inner, bool rx)
116726d688e3SAlex Vesker {
116826d688e3SAlex Vesker 	sb->rx = rx;
116926d688e3SAlex Vesker 	sb->inner = inner;
117035ba005dSYevgeny Kliteynik 	sb->caps = caps;
117135ba005dSYevgeny Kliteynik 	return ste_ctx->build_tnl_mpls_over_gre_init(sb, mask);
117235ba005dSYevgeny Kliteynik }
117335ba005dSYevgeny Kliteynik 
117435ba005dSYevgeny Kliteynik void mlx5dr_ste_build_tnl_mpls_over_udp(struct mlx5dr_ste_ctx *ste_ctx,
117535ba005dSYevgeny Kliteynik 					struct mlx5dr_ste_build *sb,
117635ba005dSYevgeny Kliteynik 					struct mlx5dr_match_param *mask,
117735ba005dSYevgeny Kliteynik 					struct mlx5dr_cmd_caps *caps,
117835ba005dSYevgeny Kliteynik 					bool inner, bool rx)
117935ba005dSYevgeny Kliteynik {
118035ba005dSYevgeny Kliteynik 	sb->rx = rx;
118135ba005dSYevgeny Kliteynik 	sb->inner = inner;
118235ba005dSYevgeny Kliteynik 	sb->caps = caps;
118335ba005dSYevgeny Kliteynik 	return ste_ctx->build_tnl_mpls_over_udp_init(sb, mask);
118426d688e3SAlex Vesker }
118526d688e3SAlex Vesker 
11864923938dSYevgeny Kliteynik void mlx5dr_ste_build_icmp(struct mlx5dr_ste_ctx *ste_ctx,
11875212f9c6SYevgeny Kliteynik 			   struct mlx5dr_ste_build *sb,
11885212f9c6SYevgeny Kliteynik 			   struct mlx5dr_match_param *mask,
11895212f9c6SYevgeny Kliteynik 			   struct mlx5dr_cmd_caps *caps,
11905212f9c6SYevgeny Kliteynik 			   bool inner, bool rx)
11915212f9c6SYevgeny Kliteynik {
11925212f9c6SYevgeny Kliteynik 	sb->rx = rx;
11935212f9c6SYevgeny Kliteynik 	sb->inner = inner;
11945212f9c6SYevgeny Kliteynik 	sb->caps = caps;
11954923938dSYevgeny Kliteynik 	ste_ctx->build_icmp_init(sb, mask);
11965212f9c6SYevgeny Kliteynik }
11975212f9c6SYevgeny Kliteynik 
11985212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_general_purpose(struct mlx5dr_ste_ctx *ste_ctx,
11995212f9c6SYevgeny Kliteynik 				      struct mlx5dr_ste_build *sb,
120026d688e3SAlex Vesker 				      struct mlx5dr_match_param *mask,
120126d688e3SAlex Vesker 				      bool inner, bool rx)
120226d688e3SAlex Vesker {
120326d688e3SAlex Vesker 	sb->rx = rx;
120426d688e3SAlex Vesker 	sb->inner = inner;
12055212f9c6SYevgeny Kliteynik 	ste_ctx->build_general_purpose_init(sb, mask);
120626d688e3SAlex Vesker }
120726d688e3SAlex Vesker 
12085212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_eth_l4_misc(struct mlx5dr_ste_ctx *ste_ctx,
12095212f9c6SYevgeny Kliteynik 				  struct mlx5dr_ste_build *sb,
121026d688e3SAlex Vesker 				  struct mlx5dr_match_param *mask,
121126d688e3SAlex Vesker 				  bool inner, bool rx)
121226d688e3SAlex Vesker {
121326d688e3SAlex Vesker 	sb->rx = rx;
121426d688e3SAlex Vesker 	sb->inner = inner;
12155212f9c6SYevgeny Kliteynik 	ste_ctx->build_eth_l4_misc_init(sb, mask);
121626d688e3SAlex Vesker }
121726d688e3SAlex Vesker 
12185212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_tnl_vxlan_gpe(struct mlx5dr_ste_ctx *ste_ctx,
12195212f9c6SYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
122026d688e3SAlex Vesker 				    struct mlx5dr_match_param *mask,
122126d688e3SAlex Vesker 				    bool inner, bool rx)
122226d688e3SAlex Vesker {
122326d688e3SAlex Vesker 	sb->rx = rx;
122426d688e3SAlex Vesker 	sb->inner = inner;
12255212f9c6SYevgeny Kliteynik 	ste_ctx->build_tnl_vxlan_gpe_init(sb, mask);
122626d688e3SAlex Vesker }
122726d688e3SAlex Vesker 
12285212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_tnl_geneve(struct mlx5dr_ste_ctx *ste_ctx,
12295212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
1230b6d12238SYevgeny Kliteynik 				 struct mlx5dr_match_param *mask,
1231b6d12238SYevgeny Kliteynik 				 bool inner, bool rx)
1232b6d12238SYevgeny Kliteynik {
1233b6d12238SYevgeny Kliteynik 	sb->rx = rx;
1234b6d12238SYevgeny Kliteynik 	sb->inner = inner;
12355212f9c6SYevgeny Kliteynik 	ste_ctx->build_tnl_geneve_init(sb, mask);
123626d688e3SAlex Vesker }
123726d688e3SAlex Vesker 
12383442e033SYevgeny Kliteynik void mlx5dr_ste_build_tnl_geneve_tlv_opt(struct mlx5dr_ste_ctx *ste_ctx,
12393442e033SYevgeny Kliteynik 					 struct mlx5dr_ste_build *sb,
12403442e033SYevgeny Kliteynik 					 struct mlx5dr_match_param *mask,
12413442e033SYevgeny Kliteynik 					 struct mlx5dr_cmd_caps *caps,
12423442e033SYevgeny Kliteynik 					 bool inner, bool rx)
12433442e033SYevgeny Kliteynik {
12443442e033SYevgeny Kliteynik 	sb->rx = rx;
12453442e033SYevgeny Kliteynik 	sb->caps = caps;
12463442e033SYevgeny Kliteynik 	sb->inner = inner;
12473442e033SYevgeny Kliteynik 	ste_ctx->build_tnl_geneve_tlv_opt_init(sb, mask);
12483442e033SYevgeny Kliteynik }
12493442e033SYevgeny Kliteynik 
1250f59464e2SYevgeny Kliteynik void mlx5dr_ste_build_tnl_geneve_tlv_opt_exist(struct mlx5dr_ste_ctx *ste_ctx,
1251f59464e2SYevgeny Kliteynik 					       struct mlx5dr_ste_build *sb,
1252f59464e2SYevgeny Kliteynik 					       struct mlx5dr_match_param *mask,
1253f59464e2SYevgeny Kliteynik 					       struct mlx5dr_cmd_caps *caps,
1254f59464e2SYevgeny Kliteynik 					       bool inner, bool rx)
1255f59464e2SYevgeny Kliteynik {
1256f59464e2SYevgeny Kliteynik 	if (!ste_ctx->build_tnl_geneve_tlv_opt_exist_init)
1257f59464e2SYevgeny Kliteynik 		return;
1258f59464e2SYevgeny Kliteynik 
1259f59464e2SYevgeny Kliteynik 	sb->rx = rx;
1260f59464e2SYevgeny Kliteynik 	sb->caps = caps;
1261f59464e2SYevgeny Kliteynik 	sb->inner = inner;
1262f59464e2SYevgeny Kliteynik 	ste_ctx->build_tnl_geneve_tlv_opt_exist_init(sb, mask);
1263f59464e2SYevgeny Kliteynik }
1264f59464e2SYevgeny Kliteynik 
1265df9dd15aSYevgeny Kliteynik void mlx5dr_ste_build_tnl_gtpu(struct mlx5dr_ste_ctx *ste_ctx,
1266df9dd15aSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
1267df9dd15aSYevgeny Kliteynik 			       struct mlx5dr_match_param *mask,
1268df9dd15aSYevgeny Kliteynik 			       bool inner, bool rx)
1269df9dd15aSYevgeny Kliteynik {
1270df9dd15aSYevgeny Kliteynik 	sb->rx = rx;
1271df9dd15aSYevgeny Kliteynik 	sb->inner = inner;
1272df9dd15aSYevgeny Kliteynik 	ste_ctx->build_tnl_gtpu_init(sb, mask);
1273df9dd15aSYevgeny Kliteynik }
1274df9dd15aSYevgeny Kliteynik 
1275df9dd15aSYevgeny Kliteynik void mlx5dr_ste_build_tnl_gtpu_flex_parser_0(struct mlx5dr_ste_ctx *ste_ctx,
1276df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_ste_build *sb,
1277df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_match_param *mask,
1278df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_cmd_caps *caps,
1279df9dd15aSYevgeny Kliteynik 					     bool inner, bool rx)
1280df9dd15aSYevgeny Kliteynik {
1281df9dd15aSYevgeny Kliteynik 	sb->rx = rx;
1282df9dd15aSYevgeny Kliteynik 	sb->caps = caps;
1283df9dd15aSYevgeny Kliteynik 	sb->inner = inner;
1284df9dd15aSYevgeny Kliteynik 	ste_ctx->build_tnl_gtpu_flex_parser_0_init(sb, mask);
1285df9dd15aSYevgeny Kliteynik }
1286df9dd15aSYevgeny Kliteynik 
1287df9dd15aSYevgeny Kliteynik void mlx5dr_ste_build_tnl_gtpu_flex_parser_1(struct mlx5dr_ste_ctx *ste_ctx,
1288df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_ste_build *sb,
1289df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_match_param *mask,
1290df9dd15aSYevgeny Kliteynik 					     struct mlx5dr_cmd_caps *caps,
1291df9dd15aSYevgeny Kliteynik 					     bool inner, bool rx)
1292df9dd15aSYevgeny Kliteynik {
1293df9dd15aSYevgeny Kliteynik 	sb->rx = rx;
1294df9dd15aSYevgeny Kliteynik 	sb->caps = caps;
1295df9dd15aSYevgeny Kliteynik 	sb->inner = inner;
1296df9dd15aSYevgeny Kliteynik 	ste_ctx->build_tnl_gtpu_flex_parser_1_init(sb, mask);
1297df9dd15aSYevgeny Kliteynik }
1298df9dd15aSYevgeny Kliteynik 
12995212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_register_0(struct mlx5dr_ste_ctx *ste_ctx,
13005212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
130126d688e3SAlex Vesker 				 struct mlx5dr_match_param *mask,
130226d688e3SAlex Vesker 				 bool inner, bool rx)
130326d688e3SAlex Vesker {
130426d688e3SAlex Vesker 	sb->rx = rx;
130526d688e3SAlex Vesker 	sb->inner = inner;
13065212f9c6SYevgeny Kliteynik 	ste_ctx->build_register_0_init(sb, mask);
130726d688e3SAlex Vesker }
130826d688e3SAlex Vesker 
13095212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_register_1(struct mlx5dr_ste_ctx *ste_ctx,
13105212f9c6SYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
131126d688e3SAlex Vesker 				 struct mlx5dr_match_param *mask,
131226d688e3SAlex Vesker 				 bool inner, bool rx)
131326d688e3SAlex Vesker {
131426d688e3SAlex Vesker 	sb->rx = rx;
131526d688e3SAlex Vesker 	sb->inner = inner;
13165212f9c6SYevgeny Kliteynik 	ste_ctx->build_register_1_init(sb, mask);
131726d688e3SAlex Vesker }
131826d688e3SAlex Vesker 
13195212f9c6SYevgeny Kliteynik void mlx5dr_ste_build_src_gvmi_qpn(struct mlx5dr_ste_ctx *ste_ctx,
13205212f9c6SYevgeny Kliteynik 				   struct mlx5dr_ste_build *sb,
132126d688e3SAlex Vesker 				   struct mlx5dr_match_param *mask,
1322640bdb1fSAlaa Hleihel 				   struct mlx5dr_domain *dmn,
132326d688e3SAlex Vesker 				   bool inner, bool rx)
132426d688e3SAlex Vesker {
1325640bdb1fSAlaa Hleihel 	/* Set vhca_id_valid before we reset source_eswitch_owner_vhca_id */
1326640bdb1fSAlaa Hleihel 	sb->vhca_id_valid = mask->misc.source_eswitch_owner_vhca_id;
1327640bdb1fSAlaa Hleihel 
132826d688e3SAlex Vesker 	sb->rx = rx;
1329640bdb1fSAlaa Hleihel 	sb->dmn = dmn;
133026d688e3SAlex Vesker 	sb->inner = inner;
13315212f9c6SYevgeny Kliteynik 	ste_ctx->build_src_gvmi_qpn_init(sb, mask);
13325212f9c6SYevgeny Kliteynik }
13335212f9c6SYevgeny Kliteynik 
1334160e9cb3SYevgeny Kliteynik void mlx5dr_ste_build_flex_parser_0(struct mlx5dr_ste_ctx *ste_ctx,
1335160e9cb3SYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
1336160e9cb3SYevgeny Kliteynik 				    struct mlx5dr_match_param *mask,
1337160e9cb3SYevgeny Kliteynik 				    bool inner, bool rx)
1338160e9cb3SYevgeny Kliteynik {
1339160e9cb3SYevgeny Kliteynik 	sb->rx = rx;
1340160e9cb3SYevgeny Kliteynik 	sb->inner = inner;
1341160e9cb3SYevgeny Kliteynik 	ste_ctx->build_flex_parser_0_init(sb, mask);
1342160e9cb3SYevgeny Kliteynik }
1343160e9cb3SYevgeny Kliteynik 
1344160e9cb3SYevgeny Kliteynik void mlx5dr_ste_build_flex_parser_1(struct mlx5dr_ste_ctx *ste_ctx,
1345160e9cb3SYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
1346160e9cb3SYevgeny Kliteynik 				    struct mlx5dr_match_param *mask,
1347160e9cb3SYevgeny Kliteynik 				    bool inner, bool rx)
1348160e9cb3SYevgeny Kliteynik {
1349160e9cb3SYevgeny Kliteynik 	sb->rx = rx;
1350160e9cb3SYevgeny Kliteynik 	sb->inner = inner;
1351160e9cb3SYevgeny Kliteynik 	ste_ctx->build_flex_parser_1_init(sb, mask);
1352160e9cb3SYevgeny Kliteynik }
1353160e9cb3SYevgeny Kliteynik 
135409753babSMuhammad Sammar void mlx5dr_ste_build_tnl_header_0_1(struct mlx5dr_ste_ctx *ste_ctx,
135509753babSMuhammad Sammar 				     struct mlx5dr_ste_build *sb,
135609753babSMuhammad Sammar 				     struct mlx5dr_match_param *mask,
135709753babSMuhammad Sammar 				     bool inner, bool rx)
135809753babSMuhammad Sammar {
135909753babSMuhammad Sammar 	sb->rx = rx;
136009753babSMuhammad Sammar 	sb->inner = inner;
136109753babSMuhammad Sammar 	ste_ctx->build_tnl_header_0_1_init(sb, mask);
136209753babSMuhammad Sammar }
136309753babSMuhammad Sammar 
13645212f9c6SYevgeny Kliteynik struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx(u8 version)
13655212f9c6SYevgeny Kliteynik {
1366638a07f1SYevgeny Kliteynik 	if (version == MLX5_STEERING_FORMAT_CONNECTX_5)
1367638a07f1SYevgeny Kliteynik 		return mlx5dr_ste_get_ctx_v0();
1368638a07f1SYevgeny Kliteynik 	else if (version == MLX5_STEERING_FORMAT_CONNECTX_6DX)
1369638a07f1SYevgeny Kliteynik 		return mlx5dr_ste_get_ctx_v1();
1370*6862c787SYevgeny Kliteynik 	else if (version == MLX5_STEERING_FORMAT_CONNECTX_7)
1371*6862c787SYevgeny Kliteynik 		return mlx5dr_ste_get_ctx_v2();
13725212f9c6SYevgeny Kliteynik 
1373638a07f1SYevgeny Kliteynik 	return NULL;
137426d688e3SAlex Vesker }
1375