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 
16f01cc58cSTariq Toukan 	struct mlx5e_rss *rss[MLX5E_MAX_NUM_RSS];
1743ec0f41SMaxim Mikityanskiy 	bool rss_active;
1843ec0f41SMaxim Mikityanskiy 	u32 rss_rqns[MLX5E_INDIR_RQT_SIZE];
1943ec0f41SMaxim Mikityanskiy 	unsigned int rss_nch;
2043ec0f41SMaxim Mikityanskiy 
2143ec0f41SMaxim Mikityanskiy 	struct {
2243ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt direct_rqt;
2343ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir direct_tir;
2443ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt xsk_rqt;
2543ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir xsk_tir;
263ac90decSMaxim Mikityanskiy 	} *channels;
2743ec0f41SMaxim Mikityanskiy 
2843ec0f41SMaxim Mikityanskiy 	struct {
2943ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt rqt;
3043ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir tir;
3143ec0f41SMaxim Mikityanskiy 	} ptp;
3243ec0f41SMaxim Mikityanskiy };
3343ec0f41SMaxim Mikityanskiy 
3425307a91STariq Toukan /* API for rx_res_rss_* */
35fc651ff9STariq Toukan 
36f01cc58cSTariq Toukan static int mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res *res,
37713ba5e5STariq Toukan 				     const struct mlx5e_lro_param *init_lro_param,
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,
52f01cc58cSTariq Toukan 			     init_lro_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 
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 
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 
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 
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 
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 
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 */
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 
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 
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 
22125307a91STariq Toukan u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
22225307a91STariq Toukan {
223f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
22425307a91STariq Toukan 
22525307a91STariq Toukan 	return mlx5e_rss_get_hash_fields(rss, tt);
22625307a91STariq Toukan }
22725307a91STariq Toukan 
22825307a91STariq Toukan int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
22925307a91STariq Toukan 				     u8 rx_hash_fields)
23025307a91STariq Toukan {
231f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
23225307a91STariq Toukan 
23325307a91STariq Toukan 	return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
23425307a91STariq Toukan }
23525307a91STariq Toukan 
236f01cc58cSTariq Toukan int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res)
237f01cc58cSTariq Toukan {
238f01cc58cSTariq Toukan 	int i, cnt;
239f01cc58cSTariq Toukan 
240f01cc58cSTariq Toukan 	cnt = 0;
241f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
242f01cc58cSTariq Toukan 		if (res->rss[i])
243f01cc58cSTariq Toukan 			cnt++;
244f01cc58cSTariq Toukan 
245f01cc58cSTariq Toukan 	return cnt;
246f01cc58cSTariq Toukan }
247f01cc58cSTariq Toukan 
248248d3b4cSTariq Toukan int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss)
249248d3b4cSTariq Toukan {
250248d3b4cSTariq Toukan 	int i;
251248d3b4cSTariq Toukan 
252248d3b4cSTariq Toukan 	if (!rss)
253248d3b4cSTariq Toukan 		return -EINVAL;
254248d3b4cSTariq Toukan 
255248d3b4cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
256248d3b4cSTariq Toukan 		if (rss == res->rss[i])
257248d3b4cSTariq Toukan 			return i;
258248d3b4cSTariq Toukan 
259248d3b4cSTariq Toukan 	return -ENOENT;
260248d3b4cSTariq Toukan }
261248d3b4cSTariq Toukan 
262248d3b4cSTariq Toukan struct mlx5e_rss *mlx5e_rx_res_rss_get(struct mlx5e_rx_res *res, u32 rss_idx)
263248d3b4cSTariq Toukan {
264248d3b4cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
265248d3b4cSTariq Toukan 		return NULL;
266248d3b4cSTariq Toukan 
267248d3b4cSTariq Toukan 	return res->rss[rss_idx];
268248d3b4cSTariq Toukan }
269248d3b4cSTariq Toukan 
27025307a91STariq Toukan /* End of API rx_res_rss_* */
27125307a91STariq Toukan 
27225307a91STariq Toukan struct mlx5e_rx_res *mlx5e_rx_res_alloc(void)
27325307a91STariq Toukan {
27425307a91STariq Toukan 	return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL);
27525307a91STariq Toukan }
27625307a91STariq Toukan 
27743ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res,
27843ec0f41SMaxim Mikityanskiy 				      const struct mlx5e_lro_param *init_lro_param)
27943ec0f41SMaxim Mikityanskiy {
28043ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
28143ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
28243ec0f41SMaxim Mikityanskiy 	int err = 0;
28343ec0f41SMaxim Mikityanskiy 	int ix;
28443ec0f41SMaxim Mikityanskiy 
28543ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
28643ec0f41SMaxim Mikityanskiy 	if (!builder)
28743ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
28843ec0f41SMaxim Mikityanskiy 
2893ac90decSMaxim Mikityanskiy 	res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL);
2903ac90decSMaxim Mikityanskiy 	if (!res->channels) {
2913ac90decSMaxim Mikityanskiy 		err = -ENOMEM;
2923ac90decSMaxim Mikityanskiy 		goto out;
2933ac90decSMaxim Mikityanskiy 	}
2943ac90decSMaxim Mikityanskiy 
29543ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
29643ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt,
29743ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
29843ec0f41SMaxim Mikityanskiy 		if (err) {
29943ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n",
30043ec0f41SMaxim Mikityanskiy 				       err, ix);
30143ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_rqts;
30243ec0f41SMaxim Mikityanskiy 		}
30343ec0f41SMaxim Mikityanskiy 	}
30443ec0f41SMaxim Mikityanskiy 
30543ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
30643ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
30743ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
30843ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
30943ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_lro(builder, init_lro_param);
31043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
31143ec0f41SMaxim Mikityanskiy 
31243ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true);
31343ec0f41SMaxim Mikityanskiy 		if (err) {
31443ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n",
31543ec0f41SMaxim Mikityanskiy 				       err, ix);
31643ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_tirs;
31743ec0f41SMaxim Mikityanskiy 		}
31843ec0f41SMaxim Mikityanskiy 
31943ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
32043ec0f41SMaxim Mikityanskiy 	}
32143ec0f41SMaxim Mikityanskiy 
32243ec0f41SMaxim Mikityanskiy 	if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
32343ec0f41SMaxim Mikityanskiy 		goto out;
32443ec0f41SMaxim Mikityanskiy 
32543ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
32643ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].xsk_rqt,
32743ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
32843ec0f41SMaxim Mikityanskiy 		if (err) {
32943ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create an XSK RQT: err = %d, ix = %u\n",
33043ec0f41SMaxim Mikityanskiy 				       err, ix);
33143ec0f41SMaxim Mikityanskiy 			goto err_destroy_xsk_rqts;
33243ec0f41SMaxim Mikityanskiy 		}
33343ec0f41SMaxim Mikityanskiy 	}
33443ec0f41SMaxim Mikityanskiy 
33543ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
33643ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
33743ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
33843ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
33943ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_lro(builder, init_lro_param);
34043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
34143ec0f41SMaxim Mikityanskiy 
34243ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].xsk_tir, builder, res->mdev, true);
34343ec0f41SMaxim Mikityanskiy 		if (err) {
34443ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create an XSK TIR: err = %d, ix = %u\n",
34543ec0f41SMaxim Mikityanskiy 				       err, ix);
34643ec0f41SMaxim Mikityanskiy 			goto err_destroy_xsk_tirs;
34743ec0f41SMaxim Mikityanskiy 		}
34843ec0f41SMaxim Mikityanskiy 
34943ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
35043ec0f41SMaxim Mikityanskiy 	}
35143ec0f41SMaxim Mikityanskiy 
35243ec0f41SMaxim Mikityanskiy 	goto out;
35343ec0f41SMaxim Mikityanskiy 
35443ec0f41SMaxim Mikityanskiy err_destroy_xsk_tirs:
35543ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
35643ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
35743ec0f41SMaxim Mikityanskiy 
35843ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
35943ec0f41SMaxim Mikityanskiy err_destroy_xsk_rqts:
36043ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
36143ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
36243ec0f41SMaxim Mikityanskiy 
36343ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
36443ec0f41SMaxim Mikityanskiy err_destroy_direct_tirs:
36543ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
36643ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
36743ec0f41SMaxim Mikityanskiy 
36843ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
36943ec0f41SMaxim Mikityanskiy err_destroy_direct_rqts:
37043ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
37143ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
37243ec0f41SMaxim Mikityanskiy 
3733ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
3743ac90decSMaxim Mikityanskiy 
37543ec0f41SMaxim Mikityanskiy out:
37643ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
37743ec0f41SMaxim Mikityanskiy 
37843ec0f41SMaxim Mikityanskiy 	return err;
37943ec0f41SMaxim Mikityanskiy }
38043ec0f41SMaxim Mikityanskiy 
38143ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res)
38243ec0f41SMaxim Mikityanskiy {
38343ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
38443ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
38543ec0f41SMaxim Mikityanskiy 	int err;
38643ec0f41SMaxim Mikityanskiy 
38743ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
38843ec0f41SMaxim Mikityanskiy 	if (!builder)
38943ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
39043ec0f41SMaxim Mikityanskiy 
39143ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn);
39243ec0f41SMaxim Mikityanskiy 	if (err)
39343ec0f41SMaxim Mikityanskiy 		goto out;
39443ec0f41SMaxim Mikityanskiy 
39543ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
39643ec0f41SMaxim Mikityanskiy 				    mlx5e_rqt_get_rqtn(&res->ptp.rqt),
39743ec0f41SMaxim Mikityanskiy 				    inner_ft_support);
39843ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_direct(builder);
39943ec0f41SMaxim Mikityanskiy 
40043ec0f41SMaxim Mikityanskiy 	err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true);
40143ec0f41SMaxim Mikityanskiy 	if (err)
40243ec0f41SMaxim Mikityanskiy 		goto err_destroy_ptp_rqt;
40343ec0f41SMaxim Mikityanskiy 
40443ec0f41SMaxim Mikityanskiy 	goto out;
40543ec0f41SMaxim Mikityanskiy 
40643ec0f41SMaxim Mikityanskiy err_destroy_ptp_rqt:
40743ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
40843ec0f41SMaxim Mikityanskiy 
40943ec0f41SMaxim Mikityanskiy out:
41043ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
41143ec0f41SMaxim Mikityanskiy 	return err;
41243ec0f41SMaxim Mikityanskiy }
41343ec0f41SMaxim Mikityanskiy 
41443ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res)
41543ec0f41SMaxim Mikityanskiy {
41643ec0f41SMaxim Mikityanskiy 	unsigned int ix;
41743ec0f41SMaxim Mikityanskiy 
41843ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
41943ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
42043ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
42143ec0f41SMaxim Mikityanskiy 
42243ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
42343ec0f41SMaxim Mikityanskiy 			continue;
42443ec0f41SMaxim Mikityanskiy 
42543ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
42643ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
42743ec0f41SMaxim Mikityanskiy 	}
4283ac90decSMaxim Mikityanskiy 
4293ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
43043ec0f41SMaxim Mikityanskiy }
43143ec0f41SMaxim Mikityanskiy 
43243ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res)
43343ec0f41SMaxim Mikityanskiy {
43443ec0f41SMaxim Mikityanskiy 	mlx5e_tir_destroy(&res->ptp.tir);
43543ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
43643ec0f41SMaxim Mikityanskiy }
43743ec0f41SMaxim Mikityanskiy 
43843ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev,
43943ec0f41SMaxim Mikityanskiy 		      enum mlx5e_rx_res_features features, unsigned int max_nch,
44043ec0f41SMaxim Mikityanskiy 		      u32 drop_rqn, const struct mlx5e_lro_param *init_lro_param,
44143ec0f41SMaxim Mikityanskiy 		      unsigned int init_nch)
44243ec0f41SMaxim Mikityanskiy {
44343ec0f41SMaxim Mikityanskiy 	int err;
44443ec0f41SMaxim Mikityanskiy 
44543ec0f41SMaxim Mikityanskiy 	res->mdev = mdev;
44643ec0f41SMaxim Mikityanskiy 	res->features = features;
44743ec0f41SMaxim Mikityanskiy 	res->max_nch = max_nch;
44843ec0f41SMaxim Mikityanskiy 	res->drop_rqn = drop_rqn;
44943ec0f41SMaxim Mikityanskiy 
450f01cc58cSTariq Toukan 	err = mlx5e_rx_res_rss_init_def(res, init_lro_param, init_nch);
45143ec0f41SMaxim Mikityanskiy 	if (err)
45225307a91STariq Toukan 		goto err_out;
45343ec0f41SMaxim Mikityanskiy 
45443ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_channels_init(res, init_lro_param);
45543ec0f41SMaxim Mikityanskiy 	if (err)
45643ec0f41SMaxim Mikityanskiy 		goto err_rss_destroy;
45743ec0f41SMaxim Mikityanskiy 
45843ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_ptp_init(res);
45943ec0f41SMaxim Mikityanskiy 	if (err)
46043ec0f41SMaxim Mikityanskiy 		goto err_channels_destroy;
46143ec0f41SMaxim Mikityanskiy 
46243ec0f41SMaxim Mikityanskiy 	return 0;
46343ec0f41SMaxim Mikityanskiy 
46443ec0f41SMaxim Mikityanskiy err_channels_destroy:
46543ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
46643ec0f41SMaxim Mikityanskiy err_rss_destroy:
467f01cc58cSTariq Toukan 	__mlx5e_rx_res_rss_destroy(res, 0);
46825307a91STariq Toukan err_out:
46943ec0f41SMaxim Mikityanskiy 	return err;
47043ec0f41SMaxim Mikityanskiy }
47143ec0f41SMaxim Mikityanskiy 
47243ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res)
47343ec0f41SMaxim Mikityanskiy {
47443ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_ptp_destroy(res);
47543ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
476f01cc58cSTariq Toukan 	mlx5e_rx_res_rss_destroy_all(res);
47743ec0f41SMaxim Mikityanskiy }
47843ec0f41SMaxim Mikityanskiy 
47943ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_free(struct mlx5e_rx_res *res)
48043ec0f41SMaxim Mikityanskiy {
48143ec0f41SMaxim Mikityanskiy 	kvfree(res);
48243ec0f41SMaxim Mikityanskiy }
48343ec0f41SMaxim Mikityanskiy 
48443ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix)
48543ec0f41SMaxim Mikityanskiy {
48643ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir);
48743ec0f41SMaxim Mikityanskiy }
48843ec0f41SMaxim Mikityanskiy 
48943ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res *res, unsigned int ix)
49043ec0f41SMaxim Mikityanskiy {
49143ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_XSK));
49243ec0f41SMaxim Mikityanskiy 
49343ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].xsk_tir);
49443ec0f41SMaxim Mikityanskiy }
49543ec0f41SMaxim Mikityanskiy 
496d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
49743ec0f41SMaxim Mikityanskiy {
498f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
499713ba5e5STariq Toukan 
50025307a91STariq Toukan 	return mlx5e_rss_get_tirn(rss, tt, false);
50143ec0f41SMaxim Mikityanskiy }
50243ec0f41SMaxim Mikityanskiy 
503d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
50443ec0f41SMaxim Mikityanskiy {
505f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
506713ba5e5STariq Toukan 
50725307a91STariq Toukan 	return mlx5e_rss_get_tirn(rss, tt, true);
50843ec0f41SMaxim Mikityanskiy }
50943ec0f41SMaxim Mikityanskiy 
51043ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res)
51143ec0f41SMaxim Mikityanskiy {
51243ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP));
51343ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->ptp.tir);
51443ec0f41SMaxim Mikityanskiy }
51543ec0f41SMaxim Mikityanskiy 
51643ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix)
51743ec0f41SMaxim Mikityanskiy {
51843ec0f41SMaxim Mikityanskiy 	return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt);
51943ec0f41SMaxim Mikityanskiy }
52043ec0f41SMaxim Mikityanskiy 
52143ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs)
52243ec0f41SMaxim Mikityanskiy {
52343ec0f41SMaxim Mikityanskiy 	unsigned int nch, ix;
52443ec0f41SMaxim Mikityanskiy 	int err;
52543ec0f41SMaxim Mikityanskiy 
52643ec0f41SMaxim Mikityanskiy 	nch = mlx5e_channels_get_num(chs);
52743ec0f41SMaxim Mikityanskiy 
52843ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < chs->num; ix++)
52943ec0f41SMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]);
53043ec0f41SMaxim Mikityanskiy 	res->rss_nch = chs->num;
53143ec0f41SMaxim Mikityanskiy 
53243ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_enable(res);
53343ec0f41SMaxim Mikityanskiy 
53443ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < nch; ix++) {
53543ec0f41SMaxim Mikityanskiy 		u32 rqn;
53643ec0f41SMaxim Mikityanskiy 
53743ec0f41SMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &rqn);
53843ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn);
53943ec0f41SMaxim Mikityanskiy 		if (err)
54043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n",
54143ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
54243ec0f41SMaxim Mikityanskiy 				       rqn, ix, err);
54343ec0f41SMaxim Mikityanskiy 
54443ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
54543ec0f41SMaxim Mikityanskiy 			continue;
54643ec0f41SMaxim Mikityanskiy 
54743ec0f41SMaxim Mikityanskiy 		if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
54843ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
54943ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
55043ec0f41SMaxim Mikityanskiy 		if (err)
55143ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to RQ %#x (channel %u): err = %d\n",
55243ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
55343ec0f41SMaxim Mikityanskiy 				       rqn, ix, err);
55443ec0f41SMaxim Mikityanskiy 	}
55543ec0f41SMaxim Mikityanskiy 	for (ix = nch; ix < res->max_nch; ix++) {
55643ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
55743ec0f41SMaxim Mikityanskiy 		if (err)
55843ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
55943ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
56043ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
56143ec0f41SMaxim Mikityanskiy 
56243ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
56343ec0f41SMaxim Mikityanskiy 			continue;
56443ec0f41SMaxim Mikityanskiy 
56543ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
56643ec0f41SMaxim Mikityanskiy 		if (err)
56743ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
56843ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
56943ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
57043ec0f41SMaxim Mikityanskiy 	}
57143ec0f41SMaxim Mikityanskiy 
57243ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
57343ec0f41SMaxim Mikityanskiy 		u32 rqn;
57443ec0f41SMaxim Mikityanskiy 
575*8db6a54fSAya Levin 		if (!mlx5e_channels_get_ptp_rqn(chs, &rqn))
57643ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
57743ec0f41SMaxim Mikityanskiy 
57843ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn);
57943ec0f41SMaxim Mikityanskiy 		if (err)
58043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n",
58143ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
58243ec0f41SMaxim Mikityanskiy 				       rqn, err);
58343ec0f41SMaxim Mikityanskiy 	}
58443ec0f41SMaxim Mikityanskiy }
58543ec0f41SMaxim Mikityanskiy 
58643ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res)
58743ec0f41SMaxim Mikityanskiy {
58843ec0f41SMaxim Mikityanskiy 	unsigned int ix;
58943ec0f41SMaxim Mikityanskiy 	int err;
59043ec0f41SMaxim Mikityanskiy 
59143ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_disable(res);
59243ec0f41SMaxim Mikityanskiy 
59343ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
59443ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
59543ec0f41SMaxim Mikityanskiy 		if (err)
59643ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
59743ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
59843ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
59943ec0f41SMaxim Mikityanskiy 
60043ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
60143ec0f41SMaxim Mikityanskiy 			continue;
60243ec0f41SMaxim Mikityanskiy 
60343ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
60443ec0f41SMaxim Mikityanskiy 		if (err)
60543ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
60643ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
60743ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
60843ec0f41SMaxim Mikityanskiy 	}
60943ec0f41SMaxim Mikityanskiy 
61043ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
61143ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, res->drop_rqn);
61243ec0f41SMaxim Mikityanskiy 		if (err)
61343ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (PTP): err = %d\n",
61443ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
61543ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, err);
61643ec0f41SMaxim Mikityanskiy 	}
61743ec0f41SMaxim Mikityanskiy }
61843ec0f41SMaxim Mikityanskiy 
61943ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs,
62043ec0f41SMaxim Mikityanskiy 			      unsigned int ix)
62143ec0f41SMaxim Mikityanskiy {
62243ec0f41SMaxim Mikityanskiy 	u32 rqn;
62343ec0f41SMaxim Mikityanskiy 	int err;
62443ec0f41SMaxim Mikityanskiy 
62543ec0f41SMaxim Mikityanskiy 	if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
62643ec0f41SMaxim Mikityanskiy 		return -EINVAL;
62743ec0f41SMaxim Mikityanskiy 
62843ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
62943ec0f41SMaxim Mikityanskiy 	if (err)
63043ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to XSK RQ %#x (channel %u): err = %d\n",
63143ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
63243ec0f41SMaxim Mikityanskiy 			       rqn, ix, err);
63343ec0f41SMaxim Mikityanskiy 	return err;
63443ec0f41SMaxim Mikityanskiy }
63543ec0f41SMaxim Mikityanskiy 
63643ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res *res, unsigned int ix)
63743ec0f41SMaxim Mikityanskiy {
63843ec0f41SMaxim Mikityanskiy 	int err;
63943ec0f41SMaxim Mikityanskiy 
64043ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
64143ec0f41SMaxim Mikityanskiy 	if (err)
64243ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
64343ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
64443ec0f41SMaxim Mikityanskiy 			       res->drop_rqn, ix, err);
64543ec0f41SMaxim Mikityanskiy 	return err;
64643ec0f41SMaxim Mikityanskiy }
64743ec0f41SMaxim Mikityanskiy 
64843ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res *res, struct mlx5e_lro_param *lro_param)
64943ec0f41SMaxim Mikityanskiy {
65043ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
65143ec0f41SMaxim Mikityanskiy 	int err, final_err;
65243ec0f41SMaxim Mikityanskiy 	unsigned int ix;
65343ec0f41SMaxim Mikityanskiy 
65443ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(true);
65543ec0f41SMaxim Mikityanskiy 	if (!builder)
65643ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
65743ec0f41SMaxim Mikityanskiy 
65843ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_lro(builder, lro_param);
65943ec0f41SMaxim Mikityanskiy 
66043ec0f41SMaxim Mikityanskiy 	final_err = 0;
66143ec0f41SMaxim Mikityanskiy 
662f01cc58cSTariq Toukan 	for (ix = 0; ix < MLX5E_MAX_NUM_RSS; ix++) {
663f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[ix];
664f01cc58cSTariq Toukan 
665f01cc58cSTariq Toukan 		if (!rss)
666f01cc58cSTariq Toukan 			continue;
667f01cc58cSTariq Toukan 
66825307a91STariq Toukan 		err = mlx5e_rss_lro_set_param(rss, lro_param);
66925307a91STariq Toukan 		if (err)
67025307a91STariq Toukan 			final_err = final_err ? : err;
671f01cc58cSTariq Toukan 	}
67243ec0f41SMaxim Mikityanskiy 
67343ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
67443ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder);
67543ec0f41SMaxim Mikityanskiy 		if (err) {
67643ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to update LRO state of direct TIR %#x for channel %u: err = %d\n",
67743ec0f41SMaxim Mikityanskiy 				       mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err);
67843ec0f41SMaxim Mikityanskiy 			if (!final_err)
67943ec0f41SMaxim Mikityanskiy 				final_err = err;
68043ec0f41SMaxim Mikityanskiy 		}
68143ec0f41SMaxim Mikityanskiy 	}
68243ec0f41SMaxim Mikityanskiy 
68343ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
68443ec0f41SMaxim Mikityanskiy 	return final_err;
68543ec0f41SMaxim Mikityanskiy }
68643ec0f41SMaxim Mikityanskiy 
68743ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res)
68843ec0f41SMaxim Mikityanskiy {
689f01cc58cSTariq Toukan 	return mlx5e_rss_get_hash(res->rss[0]);
69043ec0f41SMaxim Mikityanskiy }
691