165d6b6e5SMaxim Mikityanskiy // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
265d6b6e5SMaxim Mikityanskiy /* Copyright (c) 2021, Mellanox Technologies inc. All rights reserved. */
365d6b6e5SMaxim Mikityanskiy 
465d6b6e5SMaxim Mikityanskiy #include "rx_res.h"
543ec0f41SMaxim Mikityanskiy #include "channels.h"
643ec0f41SMaxim Mikityanskiy #include "params.h"
765d6b6e5SMaxim Mikityanskiy 
8f01cc58cSTariq Toukan #define MLX5E_MAX_NUM_RSS 16
9f01cc58cSTariq Toukan 
1043ec0f41SMaxim Mikityanskiy struct mlx5e_rx_res {
1143ec0f41SMaxim Mikityanskiy 	struct mlx5_core_dev *mdev;
1243ec0f41SMaxim Mikityanskiy 	enum mlx5e_rx_res_features features;
1343ec0f41SMaxim Mikityanskiy 	unsigned int max_nch;
1443ec0f41SMaxim Mikityanskiy 	u32 drop_rqn;
1543ec0f41SMaxim Mikityanskiy 
164cce2ccfSTariq Toukan 	struct mlx5e_packet_merge_param pkt_merge_param;
174cce2ccfSTariq Toukan 	struct rw_semaphore pkt_merge_param_sem;
184cce2ccfSTariq Toukan 
19f01cc58cSTariq Toukan 	struct mlx5e_rss *rss[MLX5E_MAX_NUM_RSS];
2043ec0f41SMaxim Mikityanskiy 	bool rss_active;
2143ec0f41SMaxim Mikityanskiy 	u32 rss_rqns[MLX5E_INDIR_RQT_SIZE];
2243ec0f41SMaxim Mikityanskiy 	unsigned int rss_nch;
2343ec0f41SMaxim Mikityanskiy 
2443ec0f41SMaxim Mikityanskiy 	struct {
2543ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt direct_rqt;
2643ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir direct_tir;
273ac90decSMaxim Mikityanskiy 	} *channels;
2843ec0f41SMaxim Mikityanskiy 
2943ec0f41SMaxim Mikityanskiy 	struct {
3043ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt rqt;
3143ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir tir;
3243ec0f41SMaxim Mikityanskiy 	} ptp;
3343ec0f41SMaxim Mikityanskiy };
3443ec0f41SMaxim Mikityanskiy 
3525307a91STariq Toukan /* API for rx_res_rss_* */
36fc651ff9STariq Toukan 
mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res * res,unsigned int init_nch)37f01cc58cSTariq Toukan static int mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res *res,
38713ba5e5STariq Toukan 				     unsigned int init_nch)
39fc651ff9STariq Toukan {
40fc651ff9STariq Toukan 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
41713ba5e5STariq Toukan 	struct mlx5e_rss *rss;
42fc651ff9STariq Toukan 	int err;
43fc651ff9STariq Toukan 
44f01cc58cSTariq Toukan 	if (WARN_ON(res->rss[0]))
45f01cc58cSTariq Toukan 		return -EINVAL;
46f01cc58cSTariq Toukan 
4725307a91STariq Toukan 	rss = mlx5e_rss_alloc();
48713ba5e5STariq Toukan 	if (!rss)
49713ba5e5STariq Toukan 		return -ENOMEM;
50713ba5e5STariq Toukan 
51f01cc58cSTariq Toukan 	err = mlx5e_rss_init(rss, res->mdev, inner_ft_support, res->drop_rqn,
521f08917aSTariq Toukan 			     &res->pkt_merge_param);
53fc651ff9STariq Toukan 	if (err)
5425307a91STariq Toukan 		goto err_rss_free;
55fc651ff9STariq Toukan 
5625307a91STariq Toukan 	mlx5e_rss_set_indir_uniform(rss, init_nch);
57fc651ff9STariq Toukan 
58f01cc58cSTariq Toukan 	res->rss[0] = rss;
59f01cc58cSTariq Toukan 
60fc651ff9STariq Toukan 	return 0;
61fc651ff9STariq Toukan 
6225307a91STariq Toukan err_rss_free:
6325307a91STariq Toukan 	mlx5e_rss_free(rss);
6443ec0f41SMaxim Mikityanskiy 	return err;
6543ec0f41SMaxim Mikityanskiy }
6643ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_rss_init(struct mlx5e_rx_res * res,u32 * rss_idx,unsigned int init_nch)67f01cc58cSTariq Toukan int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch)
6825307a91STariq Toukan {
69f01cc58cSTariq Toukan 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
70f01cc58cSTariq Toukan 	struct mlx5e_rss *rss;
71f01cc58cSTariq Toukan 	int err, i;
7225307a91STariq Toukan 
73f01cc58cSTariq Toukan 	for (i = 1; i < MLX5E_MAX_NUM_RSS; i++)
74f01cc58cSTariq Toukan 		if (!res->rss[i])
75f01cc58cSTariq Toukan 			break;
76f01cc58cSTariq Toukan 
77f01cc58cSTariq Toukan 	if (i == MLX5E_MAX_NUM_RSS)
78f01cc58cSTariq Toukan 		return -ENOSPC;
79f01cc58cSTariq Toukan 
80f01cc58cSTariq Toukan 	rss = mlx5e_rss_alloc();
81f01cc58cSTariq Toukan 	if (!rss)
82f01cc58cSTariq Toukan 		return -ENOMEM;
83f01cc58cSTariq Toukan 
84f01cc58cSTariq Toukan 	err = mlx5e_rss_init_no_tirs(rss, res->mdev, inner_ft_support, res->drop_rqn);
85f01cc58cSTariq Toukan 	if (err)
86f01cc58cSTariq Toukan 		goto err_rss_free;
87f01cc58cSTariq Toukan 
88f01cc58cSTariq Toukan 	mlx5e_rss_set_indir_uniform(rss, init_nch);
89f01cc58cSTariq Toukan 	if (res->rss_active)
90f01cc58cSTariq Toukan 		mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch);
91f01cc58cSTariq Toukan 
92f01cc58cSTariq Toukan 	res->rss[i] = rss;
93f01cc58cSTariq Toukan 	*rss_idx = i;
94f01cc58cSTariq Toukan 
95f01cc58cSTariq Toukan 	return 0;
96f01cc58cSTariq Toukan 
97f01cc58cSTariq Toukan err_rss_free:
9825307a91STariq Toukan 	mlx5e_rss_free(rss);
99f01cc58cSTariq Toukan 	return err;
100f01cc58cSTariq Toukan }
101f01cc58cSTariq Toukan 
__mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res * res,u32 rss_idx)102f01cc58cSTariq Toukan static int __mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx)
103f01cc58cSTariq Toukan {
104f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[rss_idx];
105f01cc58cSTariq Toukan 	int err;
106f01cc58cSTariq Toukan 
107f01cc58cSTariq Toukan 	err = mlx5e_rss_cleanup(rss);
108f01cc58cSTariq Toukan 	if (err)
109f01cc58cSTariq Toukan 		return err;
110f01cc58cSTariq Toukan 
111f01cc58cSTariq Toukan 	mlx5e_rss_free(rss);
112f01cc58cSTariq Toukan 	res->rss[rss_idx] = NULL;
113f01cc58cSTariq Toukan 
114f01cc58cSTariq Toukan 	return 0;
115f01cc58cSTariq Toukan }
116f01cc58cSTariq Toukan 
mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res * res,u32 rss_idx)117f01cc58cSTariq Toukan int mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx)
118f01cc58cSTariq Toukan {
119f01cc58cSTariq Toukan 	struct mlx5e_rss *rss;
120f01cc58cSTariq Toukan 
121f01cc58cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
122f01cc58cSTariq Toukan 		return -EINVAL;
123f01cc58cSTariq Toukan 
124f01cc58cSTariq Toukan 	rss = res->rss[rss_idx];
125f01cc58cSTariq Toukan 	if (!rss)
126f01cc58cSTariq Toukan 		return -EINVAL;
127f01cc58cSTariq Toukan 
128f01cc58cSTariq Toukan 	return __mlx5e_rx_res_rss_destroy(res, rss_idx);
129f01cc58cSTariq Toukan }
130f01cc58cSTariq Toukan 
mlx5e_rx_res_rss_destroy_all(struct mlx5e_rx_res * res)131f01cc58cSTariq Toukan static void mlx5e_rx_res_rss_destroy_all(struct mlx5e_rx_res *res)
132f01cc58cSTariq Toukan {
133f01cc58cSTariq Toukan 	int i;
134f01cc58cSTariq Toukan 
135f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
136f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[i];
137f01cc58cSTariq Toukan 		int err;
138f01cc58cSTariq Toukan 
139f01cc58cSTariq Toukan 		if (!rss)
140f01cc58cSTariq Toukan 			continue;
141f01cc58cSTariq Toukan 
142f01cc58cSTariq Toukan 		err = __mlx5e_rx_res_rss_destroy(res, i);
143f01cc58cSTariq Toukan 		if (err) {
144f01cc58cSTariq Toukan 			unsigned int refcount;
145f01cc58cSTariq Toukan 
146f01cc58cSTariq Toukan 			refcount = mlx5e_rss_refcnt_read(rss);
147f01cc58cSTariq Toukan 			mlx5_core_warn(res->mdev,
148f01cc58cSTariq Toukan 				       "Failed to destroy RSS context %d, refcount = %u, err = %d\n",
149f01cc58cSTariq Toukan 				       i, refcount, err);
150f01cc58cSTariq Toukan 		}
151f01cc58cSTariq Toukan 	}
15225307a91STariq Toukan }
15325307a91STariq Toukan 
mlx5e_rx_res_rss_enable(struct mlx5e_rx_res * res)15425307a91STariq Toukan static void mlx5e_rx_res_rss_enable(struct mlx5e_rx_res *res)
15525307a91STariq Toukan {
156f01cc58cSTariq Toukan 	int i;
15725307a91STariq Toukan 
15825307a91STariq Toukan 	res->rss_active = true;
15925307a91STariq Toukan 
160f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
161f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[i];
162f01cc58cSTariq Toukan 
163f01cc58cSTariq Toukan 		if (!rss)
164f01cc58cSTariq Toukan 			continue;
16525307a91STariq Toukan 		mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch);
16625307a91STariq Toukan 	}
167f01cc58cSTariq Toukan }
16825307a91STariq Toukan 
mlx5e_rx_res_rss_disable(struct mlx5e_rx_res * res)16925307a91STariq Toukan static void mlx5e_rx_res_rss_disable(struct mlx5e_rx_res *res)
17025307a91STariq Toukan {
171f01cc58cSTariq Toukan 	int i;
17225307a91STariq Toukan 
17325307a91STariq Toukan 	res->rss_active = false;
17425307a91STariq Toukan 
175f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
176f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[i];
177f01cc58cSTariq Toukan 
178f01cc58cSTariq Toukan 		if (!rss)
179f01cc58cSTariq Toukan 			continue;
18025307a91STariq Toukan 		mlx5e_rss_disable(rss);
18125307a91STariq Toukan 	}
182f01cc58cSTariq Toukan }
18325307a91STariq Toukan 
18425307a91STariq Toukan /* Updates the indirection table SW shadow, does not update the HW resources yet */
mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res * res,unsigned int nch)18525307a91STariq Toukan void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch)
18625307a91STariq Toukan {
18725307a91STariq Toukan 	WARN_ON_ONCE(res->rss_active);
188f01cc58cSTariq Toukan 	mlx5e_rss_set_indir_uniform(res->rss[0], nch);
18925307a91STariq Toukan }
19025307a91STariq Toukan 
mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res * res,u32 rss_idx,u32 * indir,u8 * key,u8 * hfunc)191f01cc58cSTariq Toukan int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
192f01cc58cSTariq Toukan 			      u32 *indir, u8 *key, u8 *hfunc)
19325307a91STariq Toukan {
194f01cc58cSTariq Toukan 	struct mlx5e_rss *rss;
195f01cc58cSTariq Toukan 
196f01cc58cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
197f01cc58cSTariq Toukan 		return -EINVAL;
198f01cc58cSTariq Toukan 
199f01cc58cSTariq Toukan 	rss = res->rss[rss_idx];
200f01cc58cSTariq Toukan 	if (!rss)
201f01cc58cSTariq Toukan 		return -ENOENT;
20225307a91STariq Toukan 
20325307a91STariq Toukan 	return mlx5e_rss_get_rxfh(rss, indir, key, hfunc);
20425307a91STariq Toukan }
20525307a91STariq Toukan 
mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res * res,u32 rss_idx,const u32 * indir,const u8 * key,const u8 * hfunc)206f01cc58cSTariq Toukan int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
207f01cc58cSTariq Toukan 			      const u32 *indir, const u8 *key, const u8 *hfunc)
20825307a91STariq Toukan {
209f01cc58cSTariq Toukan 	struct mlx5e_rss *rss;
210f01cc58cSTariq Toukan 
211f01cc58cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
212f01cc58cSTariq Toukan 		return -EINVAL;
213f01cc58cSTariq Toukan 
214f01cc58cSTariq Toukan 	rss = res->rss[rss_idx];
215f01cc58cSTariq Toukan 	if (!rss)
216f01cc58cSTariq Toukan 		return -ENOENT;
21725307a91STariq Toukan 
21825307a91STariq Toukan 	return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch);
21925307a91STariq Toukan }
22025307a91STariq Toukan 
mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res * res,u32 rss_idx,enum mlx5_traffic_types tt)221*0212e5d9SJoe Damato int mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
222*0212e5d9SJoe Damato 				     enum mlx5_traffic_types tt)
22325307a91STariq Toukan {
224*0212e5d9SJoe Damato 	struct mlx5e_rss *rss;
225*0212e5d9SJoe Damato 
226*0212e5d9SJoe Damato 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
227*0212e5d9SJoe Damato 		return -EINVAL;
228*0212e5d9SJoe Damato 
229*0212e5d9SJoe Damato 	rss = res->rss[rss_idx];
230*0212e5d9SJoe Damato 	if (!rss)
231*0212e5d9SJoe Damato 		return -ENOENT;
23225307a91STariq Toukan 
23325307a91STariq Toukan 	return mlx5e_rss_get_hash_fields(rss, tt);
23425307a91STariq Toukan }
23525307a91STariq Toukan 
mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res * res,u32 rss_idx,enum mlx5_traffic_types tt,u8 rx_hash_fields)236*0212e5d9SJoe Damato int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, u32 rss_idx,
237*0212e5d9SJoe Damato 				     enum mlx5_traffic_types tt, u8 rx_hash_fields)
23825307a91STariq Toukan {
239*0212e5d9SJoe Damato 	struct mlx5e_rss *rss;
240*0212e5d9SJoe Damato 
241*0212e5d9SJoe Damato 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
242*0212e5d9SJoe Damato 		return -EINVAL;
243*0212e5d9SJoe Damato 
244*0212e5d9SJoe Damato 	rss = res->rss[rss_idx];
245*0212e5d9SJoe Damato 	if (!rss)
246*0212e5d9SJoe Damato 		return -ENOENT;
24725307a91STariq Toukan 
24825307a91STariq Toukan 	return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
24925307a91STariq Toukan }
25025307a91STariq Toukan 
mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res * res)251f01cc58cSTariq Toukan int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res)
252f01cc58cSTariq Toukan {
253f01cc58cSTariq Toukan 	int i, cnt;
254f01cc58cSTariq Toukan 
255f01cc58cSTariq Toukan 	cnt = 0;
256f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
257f01cc58cSTariq Toukan 		if (res->rss[i])
258f01cc58cSTariq Toukan 			cnt++;
259f01cc58cSTariq Toukan 
260f01cc58cSTariq Toukan 	return cnt;
261f01cc58cSTariq Toukan }
262f01cc58cSTariq Toukan 
mlx5e_rx_res_rss_index(struct mlx5e_rx_res * res,struct mlx5e_rss * rss)263248d3b4cSTariq Toukan int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss)
264248d3b4cSTariq Toukan {
265248d3b4cSTariq Toukan 	int i;
266248d3b4cSTariq Toukan 
267248d3b4cSTariq Toukan 	if (!rss)
268248d3b4cSTariq Toukan 		return -EINVAL;
269248d3b4cSTariq Toukan 
270248d3b4cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
271248d3b4cSTariq Toukan 		if (rss == res->rss[i])
272248d3b4cSTariq Toukan 			return i;
273248d3b4cSTariq Toukan 
274248d3b4cSTariq Toukan 	return -ENOENT;
275248d3b4cSTariq Toukan }
276248d3b4cSTariq Toukan 
mlx5e_rx_res_rss_get(struct mlx5e_rx_res * res,u32 rss_idx)277248d3b4cSTariq Toukan struct mlx5e_rss *mlx5e_rx_res_rss_get(struct mlx5e_rx_res *res, u32 rss_idx)
278248d3b4cSTariq Toukan {
279248d3b4cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
280248d3b4cSTariq Toukan 		return NULL;
281248d3b4cSTariq Toukan 
282248d3b4cSTariq Toukan 	return res->rss[rss_idx];
283248d3b4cSTariq Toukan }
284248d3b4cSTariq Toukan 
28525307a91STariq Toukan /* End of API rx_res_rss_* */
28625307a91STariq Toukan 
mlx5e_rx_res_alloc(void)28725307a91STariq Toukan struct mlx5e_rx_res *mlx5e_rx_res_alloc(void)
28825307a91STariq Toukan {
28925307a91STariq Toukan 	return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL);
29025307a91STariq Toukan }
29125307a91STariq Toukan 
mlx5e_rx_res_channels_init(struct mlx5e_rx_res * res)2921f08917aSTariq Toukan static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res)
29343ec0f41SMaxim Mikityanskiy {
29443ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
29543ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
29643ec0f41SMaxim Mikityanskiy 	int err = 0;
29743ec0f41SMaxim Mikityanskiy 	int ix;
29843ec0f41SMaxim Mikityanskiy 
29943ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
30043ec0f41SMaxim Mikityanskiy 	if (!builder)
30143ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
30243ec0f41SMaxim Mikityanskiy 
3033ac90decSMaxim Mikityanskiy 	res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL);
3043ac90decSMaxim Mikityanskiy 	if (!res->channels) {
3053ac90decSMaxim Mikityanskiy 		err = -ENOMEM;
3063ac90decSMaxim Mikityanskiy 		goto out;
3073ac90decSMaxim Mikityanskiy 	}
3083ac90decSMaxim Mikityanskiy 
30943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
31043ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt,
31143ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
31243ec0f41SMaxim Mikityanskiy 		if (err) {
31343ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n",
31443ec0f41SMaxim Mikityanskiy 				       err, ix);
31543ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_rqts;
31643ec0f41SMaxim Mikityanskiy 		}
31743ec0f41SMaxim Mikityanskiy 	}
31843ec0f41SMaxim Mikityanskiy 
31943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
32043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
32143ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
32243ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
3231f08917aSTariq Toukan 		mlx5e_tir_builder_build_packet_merge(builder, &res->pkt_merge_param);
32443ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
32543ec0f41SMaxim Mikityanskiy 
32643ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true);
32743ec0f41SMaxim Mikityanskiy 		if (err) {
32843ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n",
32943ec0f41SMaxim Mikityanskiy 				       err, ix);
33043ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_tirs;
33143ec0f41SMaxim Mikityanskiy 		}
33243ec0f41SMaxim Mikityanskiy 
33343ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
33443ec0f41SMaxim Mikityanskiy 	}
33543ec0f41SMaxim Mikityanskiy 
33643ec0f41SMaxim Mikityanskiy 	goto out;
33743ec0f41SMaxim Mikityanskiy 
33843ec0f41SMaxim Mikityanskiy err_destroy_direct_tirs:
33943ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
34043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
34143ec0f41SMaxim Mikityanskiy 
34243ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
34343ec0f41SMaxim Mikityanskiy err_destroy_direct_rqts:
34443ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
34543ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
34643ec0f41SMaxim Mikityanskiy 
3473ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
3483ac90decSMaxim Mikityanskiy 
34943ec0f41SMaxim Mikityanskiy out:
35043ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
35143ec0f41SMaxim Mikityanskiy 
35243ec0f41SMaxim Mikityanskiy 	return err;
35343ec0f41SMaxim Mikityanskiy }
35443ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_ptp_init(struct mlx5e_rx_res * res)35543ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res)
35643ec0f41SMaxim Mikityanskiy {
35743ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
35843ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
35943ec0f41SMaxim Mikityanskiy 	int err;
36043ec0f41SMaxim Mikityanskiy 
36143ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
36243ec0f41SMaxim Mikityanskiy 	if (!builder)
36343ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
36443ec0f41SMaxim Mikityanskiy 
36543ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn);
36643ec0f41SMaxim Mikityanskiy 	if (err)
36743ec0f41SMaxim Mikityanskiy 		goto out;
36843ec0f41SMaxim Mikityanskiy 
3694cce2ccfSTariq Toukan 	/* Separated from the channels RQs, does not share pkt_merge state with them */
37043ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
37143ec0f41SMaxim Mikityanskiy 				    mlx5e_rqt_get_rqtn(&res->ptp.rqt),
37243ec0f41SMaxim Mikityanskiy 				    inner_ft_support);
37343ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_direct(builder);
37443ec0f41SMaxim Mikityanskiy 
37543ec0f41SMaxim Mikityanskiy 	err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true);
37643ec0f41SMaxim Mikityanskiy 	if (err)
37743ec0f41SMaxim Mikityanskiy 		goto err_destroy_ptp_rqt;
37843ec0f41SMaxim Mikityanskiy 
37943ec0f41SMaxim Mikityanskiy 	goto out;
38043ec0f41SMaxim Mikityanskiy 
38143ec0f41SMaxim Mikityanskiy err_destroy_ptp_rqt:
38243ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
38343ec0f41SMaxim Mikityanskiy 
38443ec0f41SMaxim Mikityanskiy out:
38543ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
38643ec0f41SMaxim Mikityanskiy 	return err;
38743ec0f41SMaxim Mikityanskiy }
38843ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res * res)38943ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res)
39043ec0f41SMaxim Mikityanskiy {
39143ec0f41SMaxim Mikityanskiy 	unsigned int ix;
39243ec0f41SMaxim Mikityanskiy 
39343ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
39443ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
39543ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
39643ec0f41SMaxim Mikityanskiy 	}
3973ac90decSMaxim Mikityanskiy 
3983ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
39943ec0f41SMaxim Mikityanskiy }
40043ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res * res)40143ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res)
40243ec0f41SMaxim Mikityanskiy {
40343ec0f41SMaxim Mikityanskiy 	mlx5e_tir_destroy(&res->ptp.tir);
40443ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
40543ec0f41SMaxim Mikityanskiy }
40643ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_init(struct mlx5e_rx_res * res,struct mlx5_core_dev * mdev,enum mlx5e_rx_res_features features,unsigned int max_nch,u32 drop_rqn,const struct mlx5e_packet_merge_param * init_pkt_merge_param,unsigned int init_nch)40743ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev,
40843ec0f41SMaxim Mikityanskiy 		      enum mlx5e_rx_res_features features, unsigned int max_nch,
409eaee12f0SKhalid Manaa 		      u32 drop_rqn, const struct mlx5e_packet_merge_param *init_pkt_merge_param,
41043ec0f41SMaxim Mikityanskiy 		      unsigned int init_nch)
41143ec0f41SMaxim Mikityanskiy {
41243ec0f41SMaxim Mikityanskiy 	int err;
41343ec0f41SMaxim Mikityanskiy 
41443ec0f41SMaxim Mikityanskiy 	res->mdev = mdev;
41543ec0f41SMaxim Mikityanskiy 	res->features = features;
41643ec0f41SMaxim Mikityanskiy 	res->max_nch = max_nch;
41743ec0f41SMaxim Mikityanskiy 	res->drop_rqn = drop_rqn;
41843ec0f41SMaxim Mikityanskiy 
4194cce2ccfSTariq Toukan 	res->pkt_merge_param = *init_pkt_merge_param;
4204cce2ccfSTariq Toukan 	init_rwsem(&res->pkt_merge_param_sem);
4214cce2ccfSTariq Toukan 
4221f08917aSTariq Toukan 	err = mlx5e_rx_res_rss_init_def(res, init_nch);
42343ec0f41SMaxim Mikityanskiy 	if (err)
42425307a91STariq Toukan 		goto err_out;
42543ec0f41SMaxim Mikityanskiy 
4261f08917aSTariq Toukan 	err = mlx5e_rx_res_channels_init(res);
42743ec0f41SMaxim Mikityanskiy 	if (err)
42843ec0f41SMaxim Mikityanskiy 		goto err_rss_destroy;
42943ec0f41SMaxim Mikityanskiy 
43043ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_ptp_init(res);
43143ec0f41SMaxim Mikityanskiy 	if (err)
43243ec0f41SMaxim Mikityanskiy 		goto err_channels_destroy;
43343ec0f41SMaxim Mikityanskiy 
43443ec0f41SMaxim Mikityanskiy 	return 0;
43543ec0f41SMaxim Mikityanskiy 
43643ec0f41SMaxim Mikityanskiy err_channels_destroy:
43743ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
43843ec0f41SMaxim Mikityanskiy err_rss_destroy:
439f01cc58cSTariq Toukan 	__mlx5e_rx_res_rss_destroy(res, 0);
44025307a91STariq Toukan err_out:
44143ec0f41SMaxim Mikityanskiy 	return err;
44243ec0f41SMaxim Mikityanskiy }
44343ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_destroy(struct mlx5e_rx_res * res)44443ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res)
44543ec0f41SMaxim Mikityanskiy {
44643ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_ptp_destroy(res);
44743ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
448f01cc58cSTariq Toukan 	mlx5e_rx_res_rss_destroy_all(res);
44943ec0f41SMaxim Mikityanskiy }
45043ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_free(struct mlx5e_rx_res * res)45143ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_free(struct mlx5e_rx_res *res)
45243ec0f41SMaxim Mikityanskiy {
45343ec0f41SMaxim Mikityanskiy 	kvfree(res);
45443ec0f41SMaxim Mikityanskiy }
45543ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res * res,unsigned int ix)45643ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix)
45743ec0f41SMaxim Mikityanskiy {
45843ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir);
45943ec0f41SMaxim Mikityanskiy }
46043ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res * res,enum mlx5_traffic_types tt)461d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
46243ec0f41SMaxim Mikityanskiy {
463f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
464713ba5e5STariq Toukan 
46525307a91STariq Toukan 	return mlx5e_rss_get_tirn(rss, tt, false);
46643ec0f41SMaxim Mikityanskiy }
46743ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res * res,enum mlx5_traffic_types tt)468d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
46943ec0f41SMaxim Mikityanskiy {
470f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
471713ba5e5STariq Toukan 
47225307a91STariq Toukan 	return mlx5e_rss_get_tirn(rss, tt, true);
47343ec0f41SMaxim Mikityanskiy }
47443ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res * res)47543ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res)
47643ec0f41SMaxim Mikityanskiy {
47743ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP));
47843ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->ptp.tir);
47943ec0f41SMaxim Mikityanskiy }
48043ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res * res,unsigned int ix)4814cce2ccfSTariq Toukan static u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix)
48243ec0f41SMaxim Mikityanskiy {
48343ec0f41SMaxim Mikityanskiy 	return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt);
48443ec0f41SMaxim Mikityanskiy }
48543ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_channel_activate_direct(struct mlx5e_rx_res * res,struct mlx5e_channels * chs,unsigned int ix)486d32c2253SMaxim Mikityanskiy static void mlx5e_rx_res_channel_activate_direct(struct mlx5e_rx_res *res,
487d32c2253SMaxim Mikityanskiy 						 struct mlx5e_channels *chs,
488d32c2253SMaxim Mikityanskiy 						 unsigned int ix)
489d32c2253SMaxim Mikityanskiy {
4903db4c85cSMaxim Mikityanskiy 	u32 rqn = res->rss_rqns[ix];
491d32c2253SMaxim Mikityanskiy 	int err;
492d32c2253SMaxim Mikityanskiy 
493d32c2253SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn);
494d32c2253SMaxim Mikityanskiy 	if (err)
495d32c2253SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n",
496d32c2253SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
497d32c2253SMaxim Mikityanskiy 			       rqn, ix, err);
498d32c2253SMaxim Mikityanskiy }
499d32c2253SMaxim Mikityanskiy 
mlx5e_rx_res_channel_deactivate_direct(struct mlx5e_rx_res * res,unsigned int ix)500d32c2253SMaxim Mikityanskiy static void mlx5e_rx_res_channel_deactivate_direct(struct mlx5e_rx_res *res,
501d32c2253SMaxim Mikityanskiy 						   unsigned int ix)
502d32c2253SMaxim Mikityanskiy {
503d32c2253SMaxim Mikityanskiy 	int err;
504d32c2253SMaxim Mikityanskiy 
505d32c2253SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
506d32c2253SMaxim Mikityanskiy 	if (err)
507d32c2253SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
508d32c2253SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
509d32c2253SMaxim Mikityanskiy 			       res->drop_rqn, ix, err);
510d32c2253SMaxim Mikityanskiy }
511d32c2253SMaxim Mikityanskiy 
mlx5e_rx_res_channels_activate(struct mlx5e_rx_res * res,struct mlx5e_channels * chs)51243ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs)
51343ec0f41SMaxim Mikityanskiy {
51443ec0f41SMaxim Mikityanskiy 	unsigned int nch, ix;
51543ec0f41SMaxim Mikityanskiy 	int err;
51643ec0f41SMaxim Mikityanskiy 
51743ec0f41SMaxim Mikityanskiy 	nch = mlx5e_channels_get_num(chs);
51843ec0f41SMaxim Mikityanskiy 
5193db4c85cSMaxim Mikityanskiy 	for (ix = 0; ix < chs->num; ix++) {
5203db4c85cSMaxim Mikityanskiy 		if (mlx5e_channels_is_xsk(chs, ix))
5213db4c85cSMaxim Mikityanskiy 			mlx5e_channels_get_xsk_rqn(chs, ix, &res->rss_rqns[ix]);
5223db4c85cSMaxim Mikityanskiy 		else
52343ec0f41SMaxim Mikityanskiy 			mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]);
5243db4c85cSMaxim Mikityanskiy 	}
52543ec0f41SMaxim Mikityanskiy 	res->rss_nch = chs->num;
52643ec0f41SMaxim Mikityanskiy 
52743ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_enable(res);
52843ec0f41SMaxim Mikityanskiy 
529d32c2253SMaxim Mikityanskiy 	for (ix = 0; ix < nch; ix++)
530d32c2253SMaxim Mikityanskiy 		mlx5e_rx_res_channel_activate_direct(res, chs, ix);
531d32c2253SMaxim Mikityanskiy 	for (ix = nch; ix < res->max_nch; ix++)
532d32c2253SMaxim Mikityanskiy 		mlx5e_rx_res_channel_deactivate_direct(res, ix);
53343ec0f41SMaxim Mikityanskiy 
53443ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
53543ec0f41SMaxim Mikityanskiy 		u32 rqn;
53643ec0f41SMaxim Mikityanskiy 
5378db6a54fSAya Levin 		if (!mlx5e_channels_get_ptp_rqn(chs, &rqn))
53843ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
53943ec0f41SMaxim Mikityanskiy 
54043ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn);
54143ec0f41SMaxim Mikityanskiy 		if (err)
54243ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n",
54343ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
54443ec0f41SMaxim Mikityanskiy 				       rqn, err);
54543ec0f41SMaxim Mikityanskiy 	}
54643ec0f41SMaxim Mikityanskiy }
54743ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res * res)54843ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res)
54943ec0f41SMaxim Mikityanskiy {
55043ec0f41SMaxim Mikityanskiy 	unsigned int ix;
55143ec0f41SMaxim Mikityanskiy 	int err;
55243ec0f41SMaxim Mikityanskiy 
55343ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_disable(res);
55443ec0f41SMaxim Mikityanskiy 
555d32c2253SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++)
556d32c2253SMaxim Mikityanskiy 		mlx5e_rx_res_channel_deactivate_direct(res, ix);
55743ec0f41SMaxim Mikityanskiy 
55843ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
55943ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, res->drop_rqn);
56043ec0f41SMaxim Mikityanskiy 		if (err)
56143ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (PTP): err = %d\n",
56243ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
56343ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, err);
56443ec0f41SMaxim Mikityanskiy 	}
56543ec0f41SMaxim Mikityanskiy }
56643ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_xsk_update(struct mlx5e_rx_res * res,struct mlx5e_channels * chs,unsigned int ix,bool xsk)5673db4c85cSMaxim Mikityanskiy void mlx5e_rx_res_xsk_update(struct mlx5e_rx_res *res, struct mlx5e_channels *chs,
5683db4c85cSMaxim Mikityanskiy 			     unsigned int ix, bool xsk)
56943ec0f41SMaxim Mikityanskiy {
5703db4c85cSMaxim Mikityanskiy 	if (xsk)
5713db4c85cSMaxim Mikityanskiy 		mlx5e_channels_get_xsk_rqn(chs, ix, &res->rss_rqns[ix]);
5723db4c85cSMaxim Mikityanskiy 	else
5733db4c85cSMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]);
57443ec0f41SMaxim Mikityanskiy 
5753db4c85cSMaxim Mikityanskiy 	mlx5e_rx_res_rss_enable(res);
57643ec0f41SMaxim Mikityanskiy 
5773db4c85cSMaxim Mikityanskiy 	mlx5e_rx_res_channel_activate_direct(res, chs, ix);
57843ec0f41SMaxim Mikityanskiy }
57943ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res * res,struct mlx5e_packet_merge_param * pkt_merge_param)580eaee12f0SKhalid Manaa int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res,
581eaee12f0SKhalid Manaa 					struct mlx5e_packet_merge_param *pkt_merge_param)
58243ec0f41SMaxim Mikityanskiy {
58343ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
58443ec0f41SMaxim Mikityanskiy 	int err, final_err;
58543ec0f41SMaxim Mikityanskiy 	unsigned int ix;
58643ec0f41SMaxim Mikityanskiy 
58743ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(true);
58843ec0f41SMaxim Mikityanskiy 	if (!builder)
58943ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
59043ec0f41SMaxim Mikityanskiy 
5914cce2ccfSTariq Toukan 	down_write(&res->pkt_merge_param_sem);
5924cce2ccfSTariq Toukan 	res->pkt_merge_param = *pkt_merge_param;
5934cce2ccfSTariq Toukan 
594eaee12f0SKhalid Manaa 	mlx5e_tir_builder_build_packet_merge(builder, pkt_merge_param);
59543ec0f41SMaxim Mikityanskiy 
59643ec0f41SMaxim Mikityanskiy 	final_err = 0;
59743ec0f41SMaxim Mikityanskiy 
598f01cc58cSTariq Toukan 	for (ix = 0; ix < MLX5E_MAX_NUM_RSS; ix++) {
599f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[ix];
600f01cc58cSTariq Toukan 
601f01cc58cSTariq Toukan 		if (!rss)
602f01cc58cSTariq Toukan 			continue;
603f01cc58cSTariq Toukan 
604eaee12f0SKhalid Manaa 		err = mlx5e_rss_packet_merge_set_param(rss, pkt_merge_param);
60525307a91STariq Toukan 		if (err)
60625307a91STariq Toukan 			final_err = final_err ? : err;
607f01cc58cSTariq Toukan 	}
60843ec0f41SMaxim Mikityanskiy 
60943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
61043ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder);
61143ec0f41SMaxim Mikityanskiy 		if (err) {
612eaee12f0SKhalid Manaa 			mlx5_core_warn(res->mdev, "Failed to update packet merge state of direct TIR %#x for channel %u: err = %d\n",
61343ec0f41SMaxim Mikityanskiy 				       mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err);
61443ec0f41SMaxim Mikityanskiy 			if (!final_err)
61543ec0f41SMaxim Mikityanskiy 				final_err = err;
61643ec0f41SMaxim Mikityanskiy 		}
61743ec0f41SMaxim Mikityanskiy 	}
61843ec0f41SMaxim Mikityanskiy 
6194cce2ccfSTariq Toukan 	up_write(&res->pkt_merge_param_sem);
62043ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
62143ec0f41SMaxim Mikityanskiy 	return final_err;
62243ec0f41SMaxim Mikityanskiy }
62343ec0f41SMaxim Mikityanskiy 
mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res * res)62443ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res)
62543ec0f41SMaxim Mikityanskiy {
626f01cc58cSTariq Toukan 	return mlx5e_rss_get_hash(res->rss[0]);
62743ec0f41SMaxim Mikityanskiy }
6284cce2ccfSTariq Toukan 
mlx5e_rx_res_tls_tir_create(struct mlx5e_rx_res * res,unsigned int rxq,struct mlx5e_tir * tir)6294cce2ccfSTariq Toukan int mlx5e_rx_res_tls_tir_create(struct mlx5e_rx_res *res, unsigned int rxq,
6304cce2ccfSTariq Toukan 				struct mlx5e_tir *tir)
6314cce2ccfSTariq Toukan {
6324cce2ccfSTariq Toukan 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
6334cce2ccfSTariq Toukan 	struct mlx5e_tir_builder *builder;
6344cce2ccfSTariq Toukan 	u32 rqtn;
6354cce2ccfSTariq Toukan 	int err;
6364cce2ccfSTariq Toukan 
6374cce2ccfSTariq Toukan 	builder = mlx5e_tir_builder_alloc(false);
6384cce2ccfSTariq Toukan 	if (!builder)
6394cce2ccfSTariq Toukan 		return -ENOMEM;
6404cce2ccfSTariq Toukan 
6414cce2ccfSTariq Toukan 	rqtn = mlx5e_rx_res_get_rqtn_direct(res, rxq);
6424cce2ccfSTariq Toukan 
6434cce2ccfSTariq Toukan 	mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, rqtn,
6444cce2ccfSTariq Toukan 				    inner_ft_support);
6454cce2ccfSTariq Toukan 	mlx5e_tir_builder_build_direct(builder);
6464cce2ccfSTariq Toukan 	mlx5e_tir_builder_build_tls(builder);
6474cce2ccfSTariq Toukan 	down_read(&res->pkt_merge_param_sem);
6484cce2ccfSTariq Toukan 	mlx5e_tir_builder_build_packet_merge(builder, &res->pkt_merge_param);
6494cce2ccfSTariq Toukan 	err = mlx5e_tir_init(tir, builder, res->mdev, false);
6504cce2ccfSTariq Toukan 	up_read(&res->pkt_merge_param_sem);
6514cce2ccfSTariq Toukan 
6524cce2ccfSTariq Toukan 	mlx5e_tir_builder_free(builder);
6534cce2ccfSTariq Toukan 
6544cce2ccfSTariq Toukan 	return err;
6554cce2ccfSTariq Toukan }
656