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;
2743ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt xsk_rqt;
2843ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir xsk_tir;
293ac90decSMaxim Mikityanskiy 	} *channels;
3043ec0f41SMaxim Mikityanskiy 
3143ec0f41SMaxim Mikityanskiy 	struct {
3243ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt rqt;
3343ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir tir;
3443ec0f41SMaxim Mikityanskiy 	} ptp;
3543ec0f41SMaxim Mikityanskiy };
3643ec0f41SMaxim Mikityanskiy 
3725307a91STariq Toukan /* API for rx_res_rss_* */
38fc651ff9STariq Toukan 
39f01cc58cSTariq Toukan static int mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res *res,
40713ba5e5STariq Toukan 				     unsigned int init_nch)
41fc651ff9STariq Toukan {
42fc651ff9STariq Toukan 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
43713ba5e5STariq Toukan 	struct mlx5e_rss *rss;
44fc651ff9STariq Toukan 	int err;
45fc651ff9STariq Toukan 
46f01cc58cSTariq Toukan 	if (WARN_ON(res->rss[0]))
47f01cc58cSTariq Toukan 		return -EINVAL;
48f01cc58cSTariq Toukan 
4925307a91STariq Toukan 	rss = mlx5e_rss_alloc();
50713ba5e5STariq Toukan 	if (!rss)
51713ba5e5STariq Toukan 		return -ENOMEM;
52713ba5e5STariq Toukan 
53f01cc58cSTariq Toukan 	err = mlx5e_rss_init(rss, res->mdev, inner_ft_support, res->drop_rqn,
54*1f08917aSTariq Toukan 			     &res->pkt_merge_param);
55fc651ff9STariq Toukan 	if (err)
5625307a91STariq Toukan 		goto err_rss_free;
57fc651ff9STariq Toukan 
5825307a91STariq Toukan 	mlx5e_rss_set_indir_uniform(rss, init_nch);
59fc651ff9STariq Toukan 
60f01cc58cSTariq Toukan 	res->rss[0] = rss;
61f01cc58cSTariq Toukan 
62fc651ff9STariq Toukan 	return 0;
63fc651ff9STariq Toukan 
6425307a91STariq Toukan err_rss_free:
6525307a91STariq Toukan 	mlx5e_rss_free(rss);
6643ec0f41SMaxim Mikityanskiy 	return err;
6743ec0f41SMaxim Mikityanskiy }
6843ec0f41SMaxim Mikityanskiy 
69f01cc58cSTariq Toukan int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch)
7025307a91STariq Toukan {
71f01cc58cSTariq Toukan 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
72f01cc58cSTariq Toukan 	struct mlx5e_rss *rss;
73f01cc58cSTariq Toukan 	int err, i;
7425307a91STariq Toukan 
75f01cc58cSTariq Toukan 	for (i = 1; i < MLX5E_MAX_NUM_RSS; i++)
76f01cc58cSTariq Toukan 		if (!res->rss[i])
77f01cc58cSTariq Toukan 			break;
78f01cc58cSTariq Toukan 
79f01cc58cSTariq Toukan 	if (i == MLX5E_MAX_NUM_RSS)
80f01cc58cSTariq Toukan 		return -ENOSPC;
81f01cc58cSTariq Toukan 
82f01cc58cSTariq Toukan 	rss = mlx5e_rss_alloc();
83f01cc58cSTariq Toukan 	if (!rss)
84f01cc58cSTariq Toukan 		return -ENOMEM;
85f01cc58cSTariq Toukan 
86f01cc58cSTariq Toukan 	err = mlx5e_rss_init_no_tirs(rss, res->mdev, inner_ft_support, res->drop_rqn);
87f01cc58cSTariq Toukan 	if (err)
88f01cc58cSTariq Toukan 		goto err_rss_free;
89f01cc58cSTariq Toukan 
90f01cc58cSTariq Toukan 	mlx5e_rss_set_indir_uniform(rss, init_nch);
91f01cc58cSTariq Toukan 	if (res->rss_active)
92f01cc58cSTariq Toukan 		mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch);
93f01cc58cSTariq Toukan 
94f01cc58cSTariq Toukan 	res->rss[i] = rss;
95f01cc58cSTariq Toukan 	*rss_idx = i;
96f01cc58cSTariq Toukan 
97f01cc58cSTariq Toukan 	return 0;
98f01cc58cSTariq Toukan 
99f01cc58cSTariq Toukan err_rss_free:
10025307a91STariq Toukan 	mlx5e_rss_free(rss);
101f01cc58cSTariq Toukan 	return err;
102f01cc58cSTariq Toukan }
103f01cc58cSTariq Toukan 
104f01cc58cSTariq Toukan static int __mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx)
105f01cc58cSTariq Toukan {
106f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[rss_idx];
107f01cc58cSTariq Toukan 	int err;
108f01cc58cSTariq Toukan 
109f01cc58cSTariq Toukan 	err = mlx5e_rss_cleanup(rss);
110f01cc58cSTariq Toukan 	if (err)
111f01cc58cSTariq Toukan 		return err;
112f01cc58cSTariq Toukan 
113f01cc58cSTariq Toukan 	mlx5e_rss_free(rss);
114f01cc58cSTariq Toukan 	res->rss[rss_idx] = NULL;
115f01cc58cSTariq Toukan 
116f01cc58cSTariq Toukan 	return 0;
117f01cc58cSTariq Toukan }
118f01cc58cSTariq Toukan 
119f01cc58cSTariq Toukan int mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx)
120f01cc58cSTariq Toukan {
121f01cc58cSTariq Toukan 	struct mlx5e_rss *rss;
122f01cc58cSTariq Toukan 
123f01cc58cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
124f01cc58cSTariq Toukan 		return -EINVAL;
125f01cc58cSTariq Toukan 
126f01cc58cSTariq Toukan 	rss = res->rss[rss_idx];
127f01cc58cSTariq Toukan 	if (!rss)
128f01cc58cSTariq Toukan 		return -EINVAL;
129f01cc58cSTariq Toukan 
130f01cc58cSTariq Toukan 	return __mlx5e_rx_res_rss_destroy(res, rss_idx);
131f01cc58cSTariq Toukan }
132f01cc58cSTariq Toukan 
133f01cc58cSTariq Toukan static void mlx5e_rx_res_rss_destroy_all(struct mlx5e_rx_res *res)
134f01cc58cSTariq Toukan {
135f01cc58cSTariq Toukan 	int i;
136f01cc58cSTariq Toukan 
137f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
138f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[i];
139f01cc58cSTariq Toukan 		int err;
140f01cc58cSTariq Toukan 
141f01cc58cSTariq Toukan 		if (!rss)
142f01cc58cSTariq Toukan 			continue;
143f01cc58cSTariq Toukan 
144f01cc58cSTariq Toukan 		err = __mlx5e_rx_res_rss_destroy(res, i);
145f01cc58cSTariq Toukan 		if (err) {
146f01cc58cSTariq Toukan 			unsigned int refcount;
147f01cc58cSTariq Toukan 
148f01cc58cSTariq Toukan 			refcount = mlx5e_rss_refcnt_read(rss);
149f01cc58cSTariq Toukan 			mlx5_core_warn(res->mdev,
150f01cc58cSTariq Toukan 				       "Failed to destroy RSS context %d, refcount = %u, err = %d\n",
151f01cc58cSTariq Toukan 				       i, refcount, err);
152f01cc58cSTariq Toukan 		}
153f01cc58cSTariq Toukan 	}
15425307a91STariq Toukan }
15525307a91STariq Toukan 
15625307a91STariq Toukan static void mlx5e_rx_res_rss_enable(struct mlx5e_rx_res *res)
15725307a91STariq Toukan {
158f01cc58cSTariq Toukan 	int i;
15925307a91STariq Toukan 
16025307a91STariq Toukan 	res->rss_active = true;
16125307a91STariq Toukan 
162f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
163f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[i];
164f01cc58cSTariq Toukan 
165f01cc58cSTariq Toukan 		if (!rss)
166f01cc58cSTariq Toukan 			continue;
16725307a91STariq Toukan 		mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch);
16825307a91STariq Toukan 	}
169f01cc58cSTariq Toukan }
17025307a91STariq Toukan 
17125307a91STariq Toukan static void mlx5e_rx_res_rss_disable(struct mlx5e_rx_res *res)
17225307a91STariq Toukan {
173f01cc58cSTariq Toukan 	int i;
17425307a91STariq Toukan 
17525307a91STariq Toukan 	res->rss_active = false;
17625307a91STariq Toukan 
177f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
178f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[i];
179f01cc58cSTariq Toukan 
180f01cc58cSTariq Toukan 		if (!rss)
181f01cc58cSTariq Toukan 			continue;
18225307a91STariq Toukan 		mlx5e_rss_disable(rss);
18325307a91STariq Toukan 	}
184f01cc58cSTariq Toukan }
18525307a91STariq Toukan 
18625307a91STariq Toukan /* Updates the indirection table SW shadow, does not update the HW resources yet */
18725307a91STariq Toukan void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch)
18825307a91STariq Toukan {
18925307a91STariq Toukan 	WARN_ON_ONCE(res->rss_active);
190f01cc58cSTariq Toukan 	mlx5e_rss_set_indir_uniform(res->rss[0], nch);
19125307a91STariq Toukan }
19225307a91STariq Toukan 
193f01cc58cSTariq Toukan int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
194f01cc58cSTariq Toukan 			      u32 *indir, u8 *key, u8 *hfunc)
19525307a91STariq Toukan {
196f01cc58cSTariq Toukan 	struct mlx5e_rss *rss;
197f01cc58cSTariq Toukan 
198f01cc58cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
199f01cc58cSTariq Toukan 		return -EINVAL;
200f01cc58cSTariq Toukan 
201f01cc58cSTariq Toukan 	rss = res->rss[rss_idx];
202f01cc58cSTariq Toukan 	if (!rss)
203f01cc58cSTariq Toukan 		return -ENOENT;
20425307a91STariq Toukan 
20525307a91STariq Toukan 	return mlx5e_rss_get_rxfh(rss, indir, key, hfunc);
20625307a91STariq Toukan }
20725307a91STariq Toukan 
208f01cc58cSTariq Toukan int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
209f01cc58cSTariq Toukan 			      const u32 *indir, const u8 *key, const u8 *hfunc)
21025307a91STariq Toukan {
211f01cc58cSTariq Toukan 	struct mlx5e_rss *rss;
212f01cc58cSTariq Toukan 
213f01cc58cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
214f01cc58cSTariq Toukan 		return -EINVAL;
215f01cc58cSTariq Toukan 
216f01cc58cSTariq Toukan 	rss = res->rss[rss_idx];
217f01cc58cSTariq Toukan 	if (!rss)
218f01cc58cSTariq Toukan 		return -ENOENT;
21925307a91STariq Toukan 
22025307a91STariq Toukan 	return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch);
22125307a91STariq Toukan }
22225307a91STariq Toukan 
22325307a91STariq Toukan u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
22425307a91STariq Toukan {
225f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
22625307a91STariq Toukan 
22725307a91STariq Toukan 	return mlx5e_rss_get_hash_fields(rss, tt);
22825307a91STariq Toukan }
22925307a91STariq Toukan 
23025307a91STariq Toukan int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
23125307a91STariq Toukan 				     u8 rx_hash_fields)
23225307a91STariq Toukan {
233f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
23425307a91STariq Toukan 
23525307a91STariq Toukan 	return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
23625307a91STariq Toukan }
23725307a91STariq Toukan 
238f01cc58cSTariq Toukan int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res)
239f01cc58cSTariq Toukan {
240f01cc58cSTariq Toukan 	int i, cnt;
241f01cc58cSTariq Toukan 
242f01cc58cSTariq Toukan 	cnt = 0;
243f01cc58cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
244f01cc58cSTariq Toukan 		if (res->rss[i])
245f01cc58cSTariq Toukan 			cnt++;
246f01cc58cSTariq Toukan 
247f01cc58cSTariq Toukan 	return cnt;
248f01cc58cSTariq Toukan }
249f01cc58cSTariq Toukan 
250248d3b4cSTariq Toukan int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss)
251248d3b4cSTariq Toukan {
252248d3b4cSTariq Toukan 	int i;
253248d3b4cSTariq Toukan 
254248d3b4cSTariq Toukan 	if (!rss)
255248d3b4cSTariq Toukan 		return -EINVAL;
256248d3b4cSTariq Toukan 
257248d3b4cSTariq Toukan 	for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
258248d3b4cSTariq Toukan 		if (rss == res->rss[i])
259248d3b4cSTariq Toukan 			return i;
260248d3b4cSTariq Toukan 
261248d3b4cSTariq Toukan 	return -ENOENT;
262248d3b4cSTariq Toukan }
263248d3b4cSTariq Toukan 
264248d3b4cSTariq Toukan struct mlx5e_rss *mlx5e_rx_res_rss_get(struct mlx5e_rx_res *res, u32 rss_idx)
265248d3b4cSTariq Toukan {
266248d3b4cSTariq Toukan 	if (rss_idx >= MLX5E_MAX_NUM_RSS)
267248d3b4cSTariq Toukan 		return NULL;
268248d3b4cSTariq Toukan 
269248d3b4cSTariq Toukan 	return res->rss[rss_idx];
270248d3b4cSTariq Toukan }
271248d3b4cSTariq Toukan 
27225307a91STariq Toukan /* End of API rx_res_rss_* */
27325307a91STariq Toukan 
27425307a91STariq Toukan struct mlx5e_rx_res *mlx5e_rx_res_alloc(void)
27525307a91STariq Toukan {
27625307a91STariq Toukan 	return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL);
27725307a91STariq Toukan }
27825307a91STariq Toukan 
279*1f08917aSTariq Toukan static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res)
28043ec0f41SMaxim Mikityanskiy {
28143ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
28243ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
28343ec0f41SMaxim Mikityanskiy 	int err = 0;
28443ec0f41SMaxim Mikityanskiy 	int ix;
28543ec0f41SMaxim Mikityanskiy 
28643ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
28743ec0f41SMaxim Mikityanskiy 	if (!builder)
28843ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
28943ec0f41SMaxim Mikityanskiy 
2903ac90decSMaxim Mikityanskiy 	res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL);
2913ac90decSMaxim Mikityanskiy 	if (!res->channels) {
2923ac90decSMaxim Mikityanskiy 		err = -ENOMEM;
2933ac90decSMaxim Mikityanskiy 		goto out;
2943ac90decSMaxim Mikityanskiy 	}
2953ac90decSMaxim Mikityanskiy 
29643ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
29743ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt,
29843ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
29943ec0f41SMaxim Mikityanskiy 		if (err) {
30043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n",
30143ec0f41SMaxim Mikityanskiy 				       err, ix);
30243ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_rqts;
30343ec0f41SMaxim Mikityanskiy 		}
30443ec0f41SMaxim Mikityanskiy 	}
30543ec0f41SMaxim Mikityanskiy 
30643ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
30743ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
30843ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
30943ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
310*1f08917aSTariq Toukan 		mlx5e_tir_builder_build_packet_merge(builder, &res->pkt_merge_param);
31143ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
31243ec0f41SMaxim Mikityanskiy 
31343ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true);
31443ec0f41SMaxim Mikityanskiy 		if (err) {
31543ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n",
31643ec0f41SMaxim Mikityanskiy 				       err, ix);
31743ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_tirs;
31843ec0f41SMaxim Mikityanskiy 		}
31943ec0f41SMaxim Mikityanskiy 
32043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
32143ec0f41SMaxim Mikityanskiy 	}
32243ec0f41SMaxim Mikityanskiy 
32343ec0f41SMaxim Mikityanskiy 	if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
32443ec0f41SMaxim Mikityanskiy 		goto out;
32543ec0f41SMaxim Mikityanskiy 
32643ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
32743ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].xsk_rqt,
32843ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
32943ec0f41SMaxim Mikityanskiy 		if (err) {
33043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create an XSK RQT: err = %d, ix = %u\n",
33143ec0f41SMaxim Mikityanskiy 				       err, ix);
33243ec0f41SMaxim Mikityanskiy 			goto err_destroy_xsk_rqts;
33343ec0f41SMaxim Mikityanskiy 		}
33443ec0f41SMaxim Mikityanskiy 	}
33543ec0f41SMaxim Mikityanskiy 
33643ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
33743ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
33843ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
33943ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
340*1f08917aSTariq Toukan 		mlx5e_tir_builder_build_packet_merge(builder, &res->pkt_merge_param);
34143ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
34243ec0f41SMaxim Mikityanskiy 
34343ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].xsk_tir, builder, res->mdev, true);
34443ec0f41SMaxim Mikityanskiy 		if (err) {
34543ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create an XSK TIR: err = %d, ix = %u\n",
34643ec0f41SMaxim Mikityanskiy 				       err, ix);
34743ec0f41SMaxim Mikityanskiy 			goto err_destroy_xsk_tirs;
34843ec0f41SMaxim Mikityanskiy 		}
34943ec0f41SMaxim Mikityanskiy 
35043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
35143ec0f41SMaxim Mikityanskiy 	}
35243ec0f41SMaxim Mikityanskiy 
35343ec0f41SMaxim Mikityanskiy 	goto out;
35443ec0f41SMaxim Mikityanskiy 
35543ec0f41SMaxim Mikityanskiy err_destroy_xsk_tirs:
35643ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
35743ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
35843ec0f41SMaxim Mikityanskiy 
35943ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
36043ec0f41SMaxim Mikityanskiy err_destroy_xsk_rqts:
36143ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
36243ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
36343ec0f41SMaxim Mikityanskiy 
36443ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
36543ec0f41SMaxim Mikityanskiy err_destroy_direct_tirs:
36643ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
36743ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
36843ec0f41SMaxim Mikityanskiy 
36943ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
37043ec0f41SMaxim Mikityanskiy err_destroy_direct_rqts:
37143ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
37243ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
37343ec0f41SMaxim Mikityanskiy 
3743ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
3753ac90decSMaxim Mikityanskiy 
37643ec0f41SMaxim Mikityanskiy out:
37743ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
37843ec0f41SMaxim Mikityanskiy 
37943ec0f41SMaxim Mikityanskiy 	return err;
38043ec0f41SMaxim Mikityanskiy }
38143ec0f41SMaxim Mikityanskiy 
38243ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res)
38343ec0f41SMaxim Mikityanskiy {
38443ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
38543ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
38643ec0f41SMaxim Mikityanskiy 	int err;
38743ec0f41SMaxim Mikityanskiy 
38843ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
38943ec0f41SMaxim Mikityanskiy 	if (!builder)
39043ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
39143ec0f41SMaxim Mikityanskiy 
39243ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn);
39343ec0f41SMaxim Mikityanskiy 	if (err)
39443ec0f41SMaxim Mikityanskiy 		goto out;
39543ec0f41SMaxim Mikityanskiy 
3964cce2ccfSTariq Toukan 	/* Separated from the channels RQs, does not share pkt_merge state with them */
39743ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
39843ec0f41SMaxim Mikityanskiy 				    mlx5e_rqt_get_rqtn(&res->ptp.rqt),
39943ec0f41SMaxim Mikityanskiy 				    inner_ft_support);
40043ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_direct(builder);
40143ec0f41SMaxim Mikityanskiy 
40243ec0f41SMaxim Mikityanskiy 	err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true);
40343ec0f41SMaxim Mikityanskiy 	if (err)
40443ec0f41SMaxim Mikityanskiy 		goto err_destroy_ptp_rqt;
40543ec0f41SMaxim Mikityanskiy 
40643ec0f41SMaxim Mikityanskiy 	goto out;
40743ec0f41SMaxim Mikityanskiy 
40843ec0f41SMaxim Mikityanskiy err_destroy_ptp_rqt:
40943ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
41043ec0f41SMaxim Mikityanskiy 
41143ec0f41SMaxim Mikityanskiy out:
41243ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
41343ec0f41SMaxim Mikityanskiy 	return err;
41443ec0f41SMaxim Mikityanskiy }
41543ec0f41SMaxim Mikityanskiy 
41643ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res)
41743ec0f41SMaxim Mikityanskiy {
41843ec0f41SMaxim Mikityanskiy 	unsigned int ix;
41943ec0f41SMaxim Mikityanskiy 
42043ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
42143ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
42243ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
42343ec0f41SMaxim Mikityanskiy 
42443ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
42543ec0f41SMaxim Mikityanskiy 			continue;
42643ec0f41SMaxim Mikityanskiy 
42743ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
42843ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
42943ec0f41SMaxim Mikityanskiy 	}
4303ac90decSMaxim Mikityanskiy 
4313ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
43243ec0f41SMaxim Mikityanskiy }
43343ec0f41SMaxim Mikityanskiy 
43443ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res)
43543ec0f41SMaxim Mikityanskiy {
43643ec0f41SMaxim Mikityanskiy 	mlx5e_tir_destroy(&res->ptp.tir);
43743ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
43843ec0f41SMaxim Mikityanskiy }
43943ec0f41SMaxim Mikityanskiy 
44043ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev,
44143ec0f41SMaxim Mikityanskiy 		      enum mlx5e_rx_res_features features, unsigned int max_nch,
442eaee12f0SKhalid Manaa 		      u32 drop_rqn, const struct mlx5e_packet_merge_param *init_pkt_merge_param,
44343ec0f41SMaxim Mikityanskiy 		      unsigned int init_nch)
44443ec0f41SMaxim Mikityanskiy {
44543ec0f41SMaxim Mikityanskiy 	int err;
44643ec0f41SMaxim Mikityanskiy 
44743ec0f41SMaxim Mikityanskiy 	res->mdev = mdev;
44843ec0f41SMaxim Mikityanskiy 	res->features = features;
44943ec0f41SMaxim Mikityanskiy 	res->max_nch = max_nch;
45043ec0f41SMaxim Mikityanskiy 	res->drop_rqn = drop_rqn;
45143ec0f41SMaxim Mikityanskiy 
4524cce2ccfSTariq Toukan 	res->pkt_merge_param = *init_pkt_merge_param;
4534cce2ccfSTariq Toukan 	init_rwsem(&res->pkt_merge_param_sem);
4544cce2ccfSTariq Toukan 
455*1f08917aSTariq Toukan 	err = mlx5e_rx_res_rss_init_def(res, init_nch);
45643ec0f41SMaxim Mikityanskiy 	if (err)
45725307a91STariq Toukan 		goto err_out;
45843ec0f41SMaxim Mikityanskiy 
459*1f08917aSTariq Toukan 	err = mlx5e_rx_res_channels_init(res);
46043ec0f41SMaxim Mikityanskiy 	if (err)
46143ec0f41SMaxim Mikityanskiy 		goto err_rss_destroy;
46243ec0f41SMaxim Mikityanskiy 
46343ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_ptp_init(res);
46443ec0f41SMaxim Mikityanskiy 	if (err)
46543ec0f41SMaxim Mikityanskiy 		goto err_channels_destroy;
46643ec0f41SMaxim Mikityanskiy 
46743ec0f41SMaxim Mikityanskiy 	return 0;
46843ec0f41SMaxim Mikityanskiy 
46943ec0f41SMaxim Mikityanskiy err_channels_destroy:
47043ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
47143ec0f41SMaxim Mikityanskiy err_rss_destroy:
472f01cc58cSTariq Toukan 	__mlx5e_rx_res_rss_destroy(res, 0);
47325307a91STariq Toukan err_out:
47443ec0f41SMaxim Mikityanskiy 	return err;
47543ec0f41SMaxim Mikityanskiy }
47643ec0f41SMaxim Mikityanskiy 
47743ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res)
47843ec0f41SMaxim Mikityanskiy {
47943ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_ptp_destroy(res);
48043ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
481f01cc58cSTariq Toukan 	mlx5e_rx_res_rss_destroy_all(res);
48243ec0f41SMaxim Mikityanskiy }
48343ec0f41SMaxim Mikityanskiy 
48443ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_free(struct mlx5e_rx_res *res)
48543ec0f41SMaxim Mikityanskiy {
48643ec0f41SMaxim Mikityanskiy 	kvfree(res);
48743ec0f41SMaxim Mikityanskiy }
48843ec0f41SMaxim Mikityanskiy 
48943ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix)
49043ec0f41SMaxim Mikityanskiy {
49143ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir);
49243ec0f41SMaxim Mikityanskiy }
49343ec0f41SMaxim Mikityanskiy 
49443ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res *res, unsigned int ix)
49543ec0f41SMaxim Mikityanskiy {
49643ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_XSK));
49743ec0f41SMaxim Mikityanskiy 
49843ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].xsk_tir);
49943ec0f41SMaxim Mikityanskiy }
50043ec0f41SMaxim Mikityanskiy 
501d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
50243ec0f41SMaxim Mikityanskiy {
503f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
504713ba5e5STariq Toukan 
50525307a91STariq Toukan 	return mlx5e_rss_get_tirn(rss, tt, false);
50643ec0f41SMaxim Mikityanskiy }
50743ec0f41SMaxim Mikityanskiy 
508d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
50943ec0f41SMaxim Mikityanskiy {
510f01cc58cSTariq Toukan 	struct mlx5e_rss *rss = res->rss[0];
511713ba5e5STariq Toukan 
51225307a91STariq Toukan 	return mlx5e_rss_get_tirn(rss, tt, true);
51343ec0f41SMaxim Mikityanskiy }
51443ec0f41SMaxim Mikityanskiy 
51543ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res)
51643ec0f41SMaxim Mikityanskiy {
51743ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP));
51843ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->ptp.tir);
51943ec0f41SMaxim Mikityanskiy }
52043ec0f41SMaxim Mikityanskiy 
5214cce2ccfSTariq Toukan static u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix)
52243ec0f41SMaxim Mikityanskiy {
52343ec0f41SMaxim Mikityanskiy 	return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt);
52443ec0f41SMaxim Mikityanskiy }
52543ec0f41SMaxim Mikityanskiy 
52643ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs)
52743ec0f41SMaxim Mikityanskiy {
52843ec0f41SMaxim Mikityanskiy 	unsigned int nch, ix;
52943ec0f41SMaxim Mikityanskiy 	int err;
53043ec0f41SMaxim Mikityanskiy 
53143ec0f41SMaxim Mikityanskiy 	nch = mlx5e_channels_get_num(chs);
53243ec0f41SMaxim Mikityanskiy 
53343ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < chs->num; ix++)
53443ec0f41SMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]);
53543ec0f41SMaxim Mikityanskiy 	res->rss_nch = chs->num;
53643ec0f41SMaxim Mikityanskiy 
53743ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_enable(res);
53843ec0f41SMaxim Mikityanskiy 
53943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < nch; ix++) {
54043ec0f41SMaxim Mikityanskiy 		u32 rqn;
54143ec0f41SMaxim Mikityanskiy 
54243ec0f41SMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &rqn);
54343ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn);
54443ec0f41SMaxim Mikityanskiy 		if (err)
54543ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n",
54643ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
54743ec0f41SMaxim Mikityanskiy 				       rqn, ix, err);
54843ec0f41SMaxim Mikityanskiy 
54943ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
55043ec0f41SMaxim Mikityanskiy 			continue;
55143ec0f41SMaxim Mikityanskiy 
55243ec0f41SMaxim Mikityanskiy 		if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
55343ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
55443ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
55543ec0f41SMaxim Mikityanskiy 		if (err)
55643ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to RQ %#x (channel %u): err = %d\n",
55743ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
55843ec0f41SMaxim Mikityanskiy 				       rqn, ix, err);
55943ec0f41SMaxim Mikityanskiy 	}
56043ec0f41SMaxim Mikityanskiy 	for (ix = nch; ix < res->max_nch; ix++) {
56143ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
56243ec0f41SMaxim Mikityanskiy 		if (err)
56343ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
56443ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
56543ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
56643ec0f41SMaxim Mikityanskiy 
56743ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
56843ec0f41SMaxim Mikityanskiy 			continue;
56943ec0f41SMaxim Mikityanskiy 
57043ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
57143ec0f41SMaxim Mikityanskiy 		if (err)
57243ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
57343ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
57443ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
57543ec0f41SMaxim Mikityanskiy 	}
57643ec0f41SMaxim Mikityanskiy 
57743ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
57843ec0f41SMaxim Mikityanskiy 		u32 rqn;
57943ec0f41SMaxim Mikityanskiy 
5808db6a54fSAya Levin 		if (!mlx5e_channels_get_ptp_rqn(chs, &rqn))
58143ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
58243ec0f41SMaxim Mikityanskiy 
58343ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn);
58443ec0f41SMaxim Mikityanskiy 		if (err)
58543ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n",
58643ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
58743ec0f41SMaxim Mikityanskiy 				       rqn, err);
58843ec0f41SMaxim Mikityanskiy 	}
58943ec0f41SMaxim Mikityanskiy }
59043ec0f41SMaxim Mikityanskiy 
59143ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res)
59243ec0f41SMaxim Mikityanskiy {
59343ec0f41SMaxim Mikityanskiy 	unsigned int ix;
59443ec0f41SMaxim Mikityanskiy 	int err;
59543ec0f41SMaxim Mikityanskiy 
59643ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_disable(res);
59743ec0f41SMaxim Mikityanskiy 
59843ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
59943ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
60043ec0f41SMaxim Mikityanskiy 		if (err)
60143ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
60243ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
60343ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
60443ec0f41SMaxim Mikityanskiy 
60543ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
60643ec0f41SMaxim Mikityanskiy 			continue;
60743ec0f41SMaxim Mikityanskiy 
60843ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
60943ec0f41SMaxim Mikityanskiy 		if (err)
61043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
61143ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
61243ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
61343ec0f41SMaxim Mikityanskiy 	}
61443ec0f41SMaxim Mikityanskiy 
61543ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
61643ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, res->drop_rqn);
61743ec0f41SMaxim Mikityanskiy 		if (err)
61843ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (PTP): err = %d\n",
61943ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
62043ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, err);
62143ec0f41SMaxim Mikityanskiy 	}
62243ec0f41SMaxim Mikityanskiy }
62343ec0f41SMaxim Mikityanskiy 
62443ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs,
62543ec0f41SMaxim Mikityanskiy 			      unsigned int ix)
62643ec0f41SMaxim Mikityanskiy {
62743ec0f41SMaxim Mikityanskiy 	u32 rqn;
62843ec0f41SMaxim Mikityanskiy 	int err;
62943ec0f41SMaxim Mikityanskiy 
63043ec0f41SMaxim Mikityanskiy 	if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
63143ec0f41SMaxim Mikityanskiy 		return -EINVAL;
63243ec0f41SMaxim Mikityanskiy 
63343ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
63443ec0f41SMaxim Mikityanskiy 	if (err)
63543ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to XSK RQ %#x (channel %u): err = %d\n",
63643ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
63743ec0f41SMaxim Mikityanskiy 			       rqn, ix, err);
63843ec0f41SMaxim Mikityanskiy 	return err;
63943ec0f41SMaxim Mikityanskiy }
64043ec0f41SMaxim Mikityanskiy 
64143ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res *res, unsigned int ix)
64243ec0f41SMaxim Mikityanskiy {
64343ec0f41SMaxim Mikityanskiy 	int err;
64443ec0f41SMaxim Mikityanskiy 
64543ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
64643ec0f41SMaxim Mikityanskiy 	if (err)
64743ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
64843ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
64943ec0f41SMaxim Mikityanskiy 			       res->drop_rqn, ix, err);
65043ec0f41SMaxim Mikityanskiy 	return err;
65143ec0f41SMaxim Mikityanskiy }
65243ec0f41SMaxim Mikityanskiy 
653eaee12f0SKhalid Manaa int mlx5e_rx_res_packet_merge_set_param(struct mlx5e_rx_res *res,
654eaee12f0SKhalid Manaa 					struct mlx5e_packet_merge_param *pkt_merge_param)
65543ec0f41SMaxim Mikityanskiy {
65643ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
65743ec0f41SMaxim Mikityanskiy 	int err, final_err;
65843ec0f41SMaxim Mikityanskiy 	unsigned int ix;
65943ec0f41SMaxim Mikityanskiy 
66043ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(true);
66143ec0f41SMaxim Mikityanskiy 	if (!builder)
66243ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
66343ec0f41SMaxim Mikityanskiy 
6644cce2ccfSTariq Toukan 	down_write(&res->pkt_merge_param_sem);
6654cce2ccfSTariq Toukan 	res->pkt_merge_param = *pkt_merge_param;
6664cce2ccfSTariq Toukan 
667eaee12f0SKhalid Manaa 	mlx5e_tir_builder_build_packet_merge(builder, pkt_merge_param);
66843ec0f41SMaxim Mikityanskiy 
66943ec0f41SMaxim Mikityanskiy 	final_err = 0;
67043ec0f41SMaxim Mikityanskiy 
671f01cc58cSTariq Toukan 	for (ix = 0; ix < MLX5E_MAX_NUM_RSS; ix++) {
672f01cc58cSTariq Toukan 		struct mlx5e_rss *rss = res->rss[ix];
673f01cc58cSTariq Toukan 
674f01cc58cSTariq Toukan 		if (!rss)
675f01cc58cSTariq Toukan 			continue;
676f01cc58cSTariq Toukan 
677eaee12f0SKhalid Manaa 		err = mlx5e_rss_packet_merge_set_param(rss, pkt_merge_param);
67825307a91STariq Toukan 		if (err)
67925307a91STariq Toukan 			final_err = final_err ? : err;
680f01cc58cSTariq Toukan 	}
68143ec0f41SMaxim Mikityanskiy 
68243ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
68343ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder);
68443ec0f41SMaxim Mikityanskiy 		if (err) {
685eaee12f0SKhalid Manaa 			mlx5_core_warn(res->mdev, "Failed to update packet merge state of direct TIR %#x for channel %u: err = %d\n",
68643ec0f41SMaxim Mikityanskiy 				       mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err);
68743ec0f41SMaxim Mikityanskiy 			if (!final_err)
68843ec0f41SMaxim Mikityanskiy 				final_err = err;
68943ec0f41SMaxim Mikityanskiy 		}
69043ec0f41SMaxim Mikityanskiy 	}
69143ec0f41SMaxim Mikityanskiy 
6924cce2ccfSTariq Toukan 	up_write(&res->pkt_merge_param_sem);
69343ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
69443ec0f41SMaxim Mikityanskiy 	return final_err;
69543ec0f41SMaxim Mikityanskiy }
69643ec0f41SMaxim Mikityanskiy 
69743ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res)
69843ec0f41SMaxim Mikityanskiy {
699f01cc58cSTariq Toukan 	return mlx5e_rss_get_hash(res->rss[0]);
70043ec0f41SMaxim Mikityanskiy }
7014cce2ccfSTariq Toukan 
7024cce2ccfSTariq Toukan int mlx5e_rx_res_tls_tir_create(struct mlx5e_rx_res *res, unsigned int rxq,
7034cce2ccfSTariq Toukan 				struct mlx5e_tir *tir)
7044cce2ccfSTariq Toukan {
7054cce2ccfSTariq Toukan 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
7064cce2ccfSTariq Toukan 	struct mlx5e_tir_builder *builder;
7074cce2ccfSTariq Toukan 	u32 rqtn;
7084cce2ccfSTariq Toukan 	int err;
7094cce2ccfSTariq Toukan 
7104cce2ccfSTariq Toukan 	builder = mlx5e_tir_builder_alloc(false);
7114cce2ccfSTariq Toukan 	if (!builder)
7124cce2ccfSTariq Toukan 		return -ENOMEM;
7134cce2ccfSTariq Toukan 
7144cce2ccfSTariq Toukan 	rqtn = mlx5e_rx_res_get_rqtn_direct(res, rxq);
7154cce2ccfSTariq Toukan 
7164cce2ccfSTariq Toukan 	mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn, rqtn,
7174cce2ccfSTariq Toukan 				    inner_ft_support);
7184cce2ccfSTariq Toukan 	mlx5e_tir_builder_build_direct(builder);
7194cce2ccfSTariq Toukan 	mlx5e_tir_builder_build_tls(builder);
7204cce2ccfSTariq Toukan 	down_read(&res->pkt_merge_param_sem);
7214cce2ccfSTariq Toukan 	mlx5e_tir_builder_build_packet_merge(builder, &res->pkt_merge_param);
7224cce2ccfSTariq Toukan 	err = mlx5e_tir_init(tir, builder, res->mdev, false);
7234cce2ccfSTariq Toukan 	up_read(&res->pkt_merge_param_sem);
7244cce2ccfSTariq Toukan 
7254cce2ccfSTariq Toukan 	mlx5e_tir_builder_free(builder);
7264cce2ccfSTariq Toukan 
7274cce2ccfSTariq Toukan 	return err;
7284cce2ccfSTariq Toukan }
729