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 
865d6b6e5SMaxim Mikityanskiy static const struct mlx5e_rss_params_traffic_type rss_default_config[MLX5E_NUM_INDIR_TIRS] = {
9d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV4_TCP] = {
1065d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
1165d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = MLX5_L4_PROT_TYPE_TCP,
1265d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP_L4PORTS,
1365d6b6e5SMaxim Mikityanskiy 	},
14d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV6_TCP] = {
1565d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
1665d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = MLX5_L4_PROT_TYPE_TCP,
1765d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP_L4PORTS,
1865d6b6e5SMaxim Mikityanskiy 	},
19d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV4_UDP] = {
2065d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
2165d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = MLX5_L4_PROT_TYPE_UDP,
2265d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP_L4PORTS,
2365d6b6e5SMaxim Mikityanskiy 	},
24d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV6_UDP] = {
2565d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
2665d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = MLX5_L4_PROT_TYPE_UDP,
2765d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP_L4PORTS,
2865d6b6e5SMaxim Mikityanskiy 	},
29d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV4_IPSEC_AH] = {
3065d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
3165d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = 0,
3265d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
3365d6b6e5SMaxim Mikityanskiy 	},
34d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV6_IPSEC_AH] = {
3565d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
3665d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = 0,
3765d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
3865d6b6e5SMaxim Mikityanskiy 	},
39d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV4_IPSEC_ESP] = {
4065d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
4165d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = 0,
4265d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
4365d6b6e5SMaxim Mikityanskiy 	},
44d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV6_IPSEC_ESP] = {
4565d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
4665d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = 0,
4765d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
4865d6b6e5SMaxim Mikityanskiy 	},
49d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV4] = {
5065d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
5165d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = 0,
5265d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP,
5365d6b6e5SMaxim Mikityanskiy 	},
54d443c6f6SMaor Gottlieb 	[MLX5_TT_IPV6] = {
5565d6b6e5SMaxim Mikityanskiy 		.l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
5665d6b6e5SMaxim Mikityanskiy 		.l4_prot_type = 0,
5765d6b6e5SMaxim Mikityanskiy 		.rx_hash_fields = MLX5_HASH_IP,
5865d6b6e5SMaxim Mikityanskiy 	},
5965d6b6e5SMaxim Mikityanskiy };
6065d6b6e5SMaxim Mikityanskiy 
6165d6b6e5SMaxim Mikityanskiy struct mlx5e_rss_params_traffic_type
62d443c6f6SMaor Gottlieb mlx5e_rss_get_default_tt_config(enum mlx5_traffic_types tt)
6365d6b6e5SMaxim Mikityanskiy {
6465d6b6e5SMaxim Mikityanskiy 	return rss_default_config[tt];
6565d6b6e5SMaxim Mikityanskiy }
6665d6b6e5SMaxim Mikityanskiy 
6743ec0f41SMaxim Mikityanskiy struct mlx5e_rx_res {
6843ec0f41SMaxim Mikityanskiy 	struct mlx5_core_dev *mdev;
6943ec0f41SMaxim Mikityanskiy 	enum mlx5e_rx_res_features features;
7043ec0f41SMaxim Mikityanskiy 	unsigned int max_nch;
7143ec0f41SMaxim Mikityanskiy 	u32 drop_rqn;
7243ec0f41SMaxim Mikityanskiy 
7343ec0f41SMaxim Mikityanskiy 	struct {
7443ec0f41SMaxim Mikityanskiy 		struct mlx5e_rss_params_hash hash;
7543ec0f41SMaxim Mikityanskiy 		struct mlx5e_rss_params_indir indir;
7643ec0f41SMaxim Mikityanskiy 		u32 rx_hash_fields[MLX5E_NUM_INDIR_TIRS];
7743ec0f41SMaxim Mikityanskiy 	} rss_params;
7843ec0f41SMaxim Mikityanskiy 
7943ec0f41SMaxim Mikityanskiy 	struct mlx5e_rqt indir_rqt;
8043ec0f41SMaxim Mikityanskiy 	struct {
8143ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir indir_tir;
8243ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir inner_indir_tir;
8343ec0f41SMaxim Mikityanskiy 	} rss[MLX5E_NUM_INDIR_TIRS];
8443ec0f41SMaxim Mikityanskiy 
8543ec0f41SMaxim Mikityanskiy 	bool rss_active;
8643ec0f41SMaxim Mikityanskiy 	u32 rss_rqns[MLX5E_INDIR_RQT_SIZE];
8743ec0f41SMaxim Mikityanskiy 	unsigned int rss_nch;
8843ec0f41SMaxim Mikityanskiy 
8943ec0f41SMaxim Mikityanskiy 	struct {
9043ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt direct_rqt;
9143ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir direct_tir;
9243ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt xsk_rqt;
9343ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir xsk_tir;
943ac90decSMaxim Mikityanskiy 	} *channels;
9543ec0f41SMaxim Mikityanskiy 
9643ec0f41SMaxim Mikityanskiy 	struct {
9743ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt rqt;
9843ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir tir;
9943ec0f41SMaxim Mikityanskiy 	} ptp;
10043ec0f41SMaxim Mikityanskiy };
10143ec0f41SMaxim Mikityanskiy 
10243ec0f41SMaxim Mikityanskiy struct mlx5e_rx_res *mlx5e_rx_res_alloc(void)
10343ec0f41SMaxim Mikityanskiy {
10443ec0f41SMaxim Mikityanskiy 	return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL);
10543ec0f41SMaxim Mikityanskiy }
10643ec0f41SMaxim Mikityanskiy 
10743ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_rss_params_init(struct mlx5e_rx_res *res, unsigned int init_nch)
10843ec0f41SMaxim Mikityanskiy {
109d443c6f6SMaor Gottlieb 	enum mlx5_traffic_types tt;
11043ec0f41SMaxim Mikityanskiy 
11143ec0f41SMaxim Mikityanskiy 	res->rss_params.hash.hfunc = ETH_RSS_HASH_TOP;
11243ec0f41SMaxim Mikityanskiy 	netdev_rss_key_fill(res->rss_params.hash.toeplitz_hash_key,
11343ec0f41SMaxim Mikityanskiy 			    sizeof(res->rss_params.hash.toeplitz_hash_key));
11443ec0f41SMaxim Mikityanskiy 	mlx5e_rss_params_indir_init_uniform(&res->rss_params.indir, init_nch);
11543ec0f41SMaxim Mikityanskiy 	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
11643ec0f41SMaxim Mikityanskiy 		res->rss_params.rx_hash_fields[tt] =
11743ec0f41SMaxim Mikityanskiy 			mlx5e_rss_get_default_tt_config(tt).rx_hash_fields;
11843ec0f41SMaxim Mikityanskiy }
11943ec0f41SMaxim Mikityanskiy 
120*fc651ff9STariq Toukan static void mlx5e_rx_res_rss_destroy_tir(struct mlx5e_rx_res *res,
121*fc651ff9STariq Toukan 					 enum mlx5_traffic_types tt,
122*fc651ff9STariq Toukan 					 bool inner)
123*fc651ff9STariq Toukan {
124*fc651ff9STariq Toukan 	struct mlx5e_tir *tir;
125*fc651ff9STariq Toukan 
126*fc651ff9STariq Toukan 	tir = inner ? &res->rss[tt].inner_indir_tir : &res->rss[tt].indir_tir;
127*fc651ff9STariq Toukan 	mlx5e_tir_destroy(tir);
128*fc651ff9STariq Toukan }
129*fc651ff9STariq Toukan 
130*fc651ff9STariq Toukan static int mlx5e_rx_res_rss_create_tir(struct mlx5e_rx_res *res,
131*fc651ff9STariq Toukan 				       struct mlx5e_tir_builder *builder,
132*fc651ff9STariq Toukan 				       enum mlx5_traffic_types tt,
133*fc651ff9STariq Toukan 				       const struct mlx5e_lro_param *init_lro_param,
134*fc651ff9STariq Toukan 				       bool inner)
13543ec0f41SMaxim Mikityanskiy {
13643ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
137*fc651ff9STariq Toukan 	struct mlx5e_rss_params_traffic_type rss_tt;
138*fc651ff9STariq Toukan 	struct mlx5e_tir *tir;
139*fc651ff9STariq Toukan 	u32 rqtn;
140*fc651ff9STariq Toukan 	int err;
141*fc651ff9STariq Toukan 
142*fc651ff9STariq Toukan 	tir = inner ? &res->rss[tt].inner_indir_tir : &res->rss[tt].indir_tir;
143*fc651ff9STariq Toukan 
144*fc651ff9STariq Toukan 	rqtn = mlx5e_rqt_get_rqtn(&res->indir_rqt);
145*fc651ff9STariq Toukan 	mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
146*fc651ff9STariq Toukan 				    rqtn, inner_ft_support);
147*fc651ff9STariq Toukan 	mlx5e_tir_builder_build_lro(builder, init_lro_param);
148*fc651ff9STariq Toukan 	rss_tt = mlx5e_rx_res_rss_get_current_tt_config(res, tt);
149*fc651ff9STariq Toukan 	mlx5e_tir_builder_build_rss(builder, &res->rss_params.hash, &rss_tt, inner);
150*fc651ff9STariq Toukan 
151*fc651ff9STariq Toukan 	err = mlx5e_tir_init(tir, builder, res->mdev, true);
152*fc651ff9STariq Toukan 	if (err) {
153*fc651ff9STariq Toukan 		mlx5_core_warn(res->mdev, "Failed to create %sindirect TIR: err = %d, tt = %d\n",
154*fc651ff9STariq Toukan 			       inner ? "inner " : "", err, tt);
155*fc651ff9STariq Toukan 		return err;
156*fc651ff9STariq Toukan 	}
157*fc651ff9STariq Toukan 
158*fc651ff9STariq Toukan 	return 0;
159*fc651ff9STariq Toukan }
160*fc651ff9STariq Toukan 
161*fc651ff9STariq Toukan static int mlx5e_rx_res_rss_create_tirs(struct mlx5e_rx_res *res,
162*fc651ff9STariq Toukan 					const struct mlx5e_lro_param *init_lro_param,
163*fc651ff9STariq Toukan 					bool inner)
164*fc651ff9STariq Toukan {
165d443c6f6SMaor Gottlieb 	enum mlx5_traffic_types tt, max_tt;
16643ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
16743ec0f41SMaxim Mikityanskiy 	int err;
16843ec0f41SMaxim Mikityanskiy 
16943ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
17043ec0f41SMaxim Mikityanskiy 	if (!builder)
17143ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
17243ec0f41SMaxim Mikityanskiy 
173*fc651ff9STariq Toukan 	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
174*fc651ff9STariq Toukan 		err = mlx5e_rx_res_rss_create_tir(res, builder, tt, init_lro_param, inner);
17543ec0f41SMaxim Mikityanskiy 		if (err)
17643ec0f41SMaxim Mikityanskiy 			goto err_destroy_tirs;
17743ec0f41SMaxim Mikityanskiy 
17843ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
17943ec0f41SMaxim Mikityanskiy 	}
18043ec0f41SMaxim Mikityanskiy 
18143ec0f41SMaxim Mikityanskiy out:
18243ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
183*fc651ff9STariq Toukan 	return err;
184*fc651ff9STariq Toukan 
185*fc651ff9STariq Toukan err_destroy_tirs:
186*fc651ff9STariq Toukan 	max_tt = tt;
187*fc651ff9STariq Toukan 	for (tt = 0; tt < max_tt; tt++)
188*fc651ff9STariq Toukan 		mlx5e_rx_res_rss_destroy_tir(res, tt, inner);
189*fc651ff9STariq Toukan 	goto out;
190*fc651ff9STariq Toukan }
191*fc651ff9STariq Toukan 
192*fc651ff9STariq Toukan static void mlx5e_rx_res_rss_destroy_tirs(struct mlx5e_rx_res *res, bool inner)
193*fc651ff9STariq Toukan {
194*fc651ff9STariq Toukan 	enum mlx5_traffic_types tt;
195*fc651ff9STariq Toukan 
196*fc651ff9STariq Toukan 	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
197*fc651ff9STariq Toukan 		mlx5e_rx_res_rss_destroy_tir(res, tt, inner);
198*fc651ff9STariq Toukan }
199*fc651ff9STariq Toukan 
200*fc651ff9STariq Toukan static int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res,
201*fc651ff9STariq Toukan 				 const struct mlx5e_lro_param *init_lro_param)
202*fc651ff9STariq Toukan {
203*fc651ff9STariq Toukan 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
204*fc651ff9STariq Toukan 	int err;
205*fc651ff9STariq Toukan 
206*fc651ff9STariq Toukan 	err = mlx5e_rqt_init_direct(&res->indir_rqt, res->mdev, true, res->drop_rqn);
207*fc651ff9STariq Toukan 	if (err)
208*fc651ff9STariq Toukan 		return err;
209*fc651ff9STariq Toukan 
210*fc651ff9STariq Toukan 	err = mlx5e_rx_res_rss_create_tirs(res, init_lro_param, false);
211*fc651ff9STariq Toukan 	if (err)
212*fc651ff9STariq Toukan 		goto err_destroy_rqt;
213*fc651ff9STariq Toukan 
214*fc651ff9STariq Toukan 	if (inner_ft_support) {
215*fc651ff9STariq Toukan 		err = mlx5e_rx_res_rss_create_tirs(res, init_lro_param, true);
216*fc651ff9STariq Toukan 		if (err)
217*fc651ff9STariq Toukan 			goto err_destroy_tirs;
218*fc651ff9STariq Toukan 	}
219*fc651ff9STariq Toukan 
220*fc651ff9STariq Toukan 	return 0;
221*fc651ff9STariq Toukan 
222*fc651ff9STariq Toukan err_destroy_tirs:
223*fc651ff9STariq Toukan 	mlx5e_rx_res_rss_destroy_tirs(res, false);
224*fc651ff9STariq Toukan 
225*fc651ff9STariq Toukan err_destroy_rqt:
226*fc651ff9STariq Toukan 	mlx5e_rqt_destroy(&res->indir_rqt);
22743ec0f41SMaxim Mikityanskiy 
22843ec0f41SMaxim Mikityanskiy 	return err;
22943ec0f41SMaxim Mikityanskiy }
23043ec0f41SMaxim Mikityanskiy 
23143ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res,
23243ec0f41SMaxim Mikityanskiy 				      const struct mlx5e_lro_param *init_lro_param)
23343ec0f41SMaxim Mikityanskiy {
23443ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
23543ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
23643ec0f41SMaxim Mikityanskiy 	int err = 0;
23743ec0f41SMaxim Mikityanskiy 	int ix;
23843ec0f41SMaxim Mikityanskiy 
23943ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
24043ec0f41SMaxim Mikityanskiy 	if (!builder)
24143ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
24243ec0f41SMaxim Mikityanskiy 
2433ac90decSMaxim Mikityanskiy 	res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL);
2443ac90decSMaxim Mikityanskiy 	if (!res->channels) {
2453ac90decSMaxim Mikityanskiy 		err = -ENOMEM;
2463ac90decSMaxim Mikityanskiy 		goto out;
2473ac90decSMaxim Mikityanskiy 	}
2483ac90decSMaxim Mikityanskiy 
24943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
25043ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt,
25143ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
25243ec0f41SMaxim Mikityanskiy 		if (err) {
25343ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n",
25443ec0f41SMaxim Mikityanskiy 				       err, ix);
25543ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_rqts;
25643ec0f41SMaxim Mikityanskiy 		}
25743ec0f41SMaxim Mikityanskiy 	}
25843ec0f41SMaxim Mikityanskiy 
25943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
26043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
26143ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
26243ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
26343ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_lro(builder, init_lro_param);
26443ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
26543ec0f41SMaxim Mikityanskiy 
26643ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true);
26743ec0f41SMaxim Mikityanskiy 		if (err) {
26843ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n",
26943ec0f41SMaxim Mikityanskiy 				       err, ix);
27043ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_tirs;
27143ec0f41SMaxim Mikityanskiy 		}
27243ec0f41SMaxim Mikityanskiy 
27343ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
27443ec0f41SMaxim Mikityanskiy 	}
27543ec0f41SMaxim Mikityanskiy 
27643ec0f41SMaxim Mikityanskiy 	if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
27743ec0f41SMaxim Mikityanskiy 		goto out;
27843ec0f41SMaxim Mikityanskiy 
27943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
28043ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].xsk_rqt,
28143ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
28243ec0f41SMaxim Mikityanskiy 		if (err) {
28343ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create an XSK RQT: err = %d, ix = %u\n",
28443ec0f41SMaxim Mikityanskiy 				       err, ix);
28543ec0f41SMaxim Mikityanskiy 			goto err_destroy_xsk_rqts;
28643ec0f41SMaxim Mikityanskiy 		}
28743ec0f41SMaxim Mikityanskiy 	}
28843ec0f41SMaxim Mikityanskiy 
28943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
29043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
29143ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
29243ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
29343ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_lro(builder, init_lro_param);
29443ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
29543ec0f41SMaxim Mikityanskiy 
29643ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].xsk_tir, builder, res->mdev, true);
29743ec0f41SMaxim Mikityanskiy 		if (err) {
29843ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create an XSK TIR: err = %d, ix = %u\n",
29943ec0f41SMaxim Mikityanskiy 				       err, ix);
30043ec0f41SMaxim Mikityanskiy 			goto err_destroy_xsk_tirs;
30143ec0f41SMaxim Mikityanskiy 		}
30243ec0f41SMaxim Mikityanskiy 
30343ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
30443ec0f41SMaxim Mikityanskiy 	}
30543ec0f41SMaxim Mikityanskiy 
30643ec0f41SMaxim Mikityanskiy 	goto out;
30743ec0f41SMaxim Mikityanskiy 
30843ec0f41SMaxim Mikityanskiy err_destroy_xsk_tirs:
30943ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
31043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
31143ec0f41SMaxim Mikityanskiy 
31243ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
31343ec0f41SMaxim Mikityanskiy err_destroy_xsk_rqts:
31443ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
31543ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
31643ec0f41SMaxim Mikityanskiy 
31743ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
31843ec0f41SMaxim Mikityanskiy err_destroy_direct_tirs:
31943ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
32043ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
32143ec0f41SMaxim Mikityanskiy 
32243ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
32343ec0f41SMaxim Mikityanskiy err_destroy_direct_rqts:
32443ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
32543ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
32643ec0f41SMaxim Mikityanskiy 
3273ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
3283ac90decSMaxim Mikityanskiy 
32943ec0f41SMaxim Mikityanskiy out:
33043ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
33143ec0f41SMaxim Mikityanskiy 
33243ec0f41SMaxim Mikityanskiy 	return err;
33343ec0f41SMaxim Mikityanskiy }
33443ec0f41SMaxim Mikityanskiy 
33543ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res)
33643ec0f41SMaxim Mikityanskiy {
33743ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
33843ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
33943ec0f41SMaxim Mikityanskiy 	int err;
34043ec0f41SMaxim Mikityanskiy 
34143ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
34243ec0f41SMaxim Mikityanskiy 	if (!builder)
34343ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
34443ec0f41SMaxim Mikityanskiy 
34543ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn);
34643ec0f41SMaxim Mikityanskiy 	if (err)
34743ec0f41SMaxim Mikityanskiy 		goto out;
34843ec0f41SMaxim Mikityanskiy 
34943ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
35043ec0f41SMaxim Mikityanskiy 				    mlx5e_rqt_get_rqtn(&res->ptp.rqt),
35143ec0f41SMaxim Mikityanskiy 				    inner_ft_support);
35243ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_direct(builder);
35343ec0f41SMaxim Mikityanskiy 
35443ec0f41SMaxim Mikityanskiy 	err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true);
35543ec0f41SMaxim Mikityanskiy 	if (err)
35643ec0f41SMaxim Mikityanskiy 		goto err_destroy_ptp_rqt;
35743ec0f41SMaxim Mikityanskiy 
35843ec0f41SMaxim Mikityanskiy 	goto out;
35943ec0f41SMaxim Mikityanskiy 
36043ec0f41SMaxim Mikityanskiy err_destroy_ptp_rqt:
36143ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
36243ec0f41SMaxim Mikityanskiy 
36343ec0f41SMaxim Mikityanskiy out:
36443ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
36543ec0f41SMaxim Mikityanskiy 	return err;
36643ec0f41SMaxim Mikityanskiy }
36743ec0f41SMaxim Mikityanskiy 
36843ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res)
36943ec0f41SMaxim Mikityanskiy {
370*fc651ff9STariq Toukan 	mlx5e_rx_res_rss_destroy_tirs(res, false);
37143ec0f41SMaxim Mikityanskiy 
37243ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_INNER_FT)
373*fc651ff9STariq Toukan 		mlx5e_rx_res_rss_destroy_tirs(res, true);
37443ec0f41SMaxim Mikityanskiy 
37543ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->indir_rqt);
37643ec0f41SMaxim Mikityanskiy }
37743ec0f41SMaxim Mikityanskiy 
37843ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res)
37943ec0f41SMaxim Mikityanskiy {
38043ec0f41SMaxim Mikityanskiy 	unsigned int ix;
38143ec0f41SMaxim Mikityanskiy 
38243ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
38343ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
38443ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
38543ec0f41SMaxim Mikityanskiy 
38643ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
38743ec0f41SMaxim Mikityanskiy 			continue;
38843ec0f41SMaxim Mikityanskiy 
38943ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
39043ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
39143ec0f41SMaxim Mikityanskiy 	}
3923ac90decSMaxim Mikityanskiy 
3933ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
39443ec0f41SMaxim Mikityanskiy }
39543ec0f41SMaxim Mikityanskiy 
39643ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res)
39743ec0f41SMaxim Mikityanskiy {
39843ec0f41SMaxim Mikityanskiy 	mlx5e_tir_destroy(&res->ptp.tir);
39943ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
40043ec0f41SMaxim Mikityanskiy }
40143ec0f41SMaxim Mikityanskiy 
40243ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev,
40343ec0f41SMaxim Mikityanskiy 		      enum mlx5e_rx_res_features features, unsigned int max_nch,
40443ec0f41SMaxim Mikityanskiy 		      u32 drop_rqn, const struct mlx5e_lro_param *init_lro_param,
40543ec0f41SMaxim Mikityanskiy 		      unsigned int init_nch)
40643ec0f41SMaxim Mikityanskiy {
40743ec0f41SMaxim Mikityanskiy 	int err;
40843ec0f41SMaxim Mikityanskiy 
40943ec0f41SMaxim Mikityanskiy 	res->mdev = mdev;
41043ec0f41SMaxim Mikityanskiy 	res->features = features;
41143ec0f41SMaxim Mikityanskiy 	res->max_nch = max_nch;
41243ec0f41SMaxim Mikityanskiy 	res->drop_rqn = drop_rqn;
41343ec0f41SMaxim Mikityanskiy 
41443ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_params_init(res, init_nch);
41543ec0f41SMaxim Mikityanskiy 
41643ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_rss_init(res, init_lro_param);
41743ec0f41SMaxim Mikityanskiy 	if (err)
41843ec0f41SMaxim Mikityanskiy 		return err;
41943ec0f41SMaxim Mikityanskiy 
42043ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_channels_init(res, init_lro_param);
42143ec0f41SMaxim Mikityanskiy 	if (err)
42243ec0f41SMaxim Mikityanskiy 		goto err_rss_destroy;
42343ec0f41SMaxim Mikityanskiy 
42443ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_ptp_init(res);
42543ec0f41SMaxim Mikityanskiy 	if (err)
42643ec0f41SMaxim Mikityanskiy 		goto err_channels_destroy;
42743ec0f41SMaxim Mikityanskiy 
42843ec0f41SMaxim Mikityanskiy 	return 0;
42943ec0f41SMaxim Mikityanskiy 
43043ec0f41SMaxim Mikityanskiy err_channels_destroy:
43143ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
43243ec0f41SMaxim Mikityanskiy err_rss_destroy:
43343ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_destroy(res);
43443ec0f41SMaxim Mikityanskiy 	return err;
43543ec0f41SMaxim Mikityanskiy }
43643ec0f41SMaxim Mikityanskiy 
43743ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res)
43843ec0f41SMaxim Mikityanskiy {
43943ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_ptp_destroy(res);
44043ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
44143ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_destroy(res);
44243ec0f41SMaxim Mikityanskiy }
44343ec0f41SMaxim Mikityanskiy 
44443ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_free(struct mlx5e_rx_res *res)
44543ec0f41SMaxim Mikityanskiy {
44643ec0f41SMaxim Mikityanskiy 	kvfree(res);
44743ec0f41SMaxim Mikityanskiy }
44843ec0f41SMaxim Mikityanskiy 
44943ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix)
45043ec0f41SMaxim Mikityanskiy {
45143ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir);
45243ec0f41SMaxim Mikityanskiy }
45343ec0f41SMaxim Mikityanskiy 
45443ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res *res, unsigned int ix)
45543ec0f41SMaxim Mikityanskiy {
45643ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_XSK));
45743ec0f41SMaxim Mikityanskiy 
45843ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].xsk_tir);
45943ec0f41SMaxim Mikityanskiy }
46043ec0f41SMaxim Mikityanskiy 
461d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
46243ec0f41SMaxim Mikityanskiy {
46343ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->rss[tt].indir_tir);
46443ec0f41SMaxim Mikityanskiy }
46543ec0f41SMaxim Mikityanskiy 
466d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
46743ec0f41SMaxim Mikityanskiy {
46843ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_INNER_FT));
46943ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->rss[tt].inner_indir_tir);
47043ec0f41SMaxim Mikityanskiy }
47143ec0f41SMaxim Mikityanskiy 
47243ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res)
47343ec0f41SMaxim Mikityanskiy {
47443ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP));
47543ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->ptp.tir);
47643ec0f41SMaxim Mikityanskiy }
47743ec0f41SMaxim Mikityanskiy 
47843ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix)
47943ec0f41SMaxim Mikityanskiy {
48043ec0f41SMaxim Mikityanskiy 	return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt);
48143ec0f41SMaxim Mikityanskiy }
48243ec0f41SMaxim Mikityanskiy 
48343ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_rss_enable(struct mlx5e_rx_res *res)
48443ec0f41SMaxim Mikityanskiy {
48543ec0f41SMaxim Mikityanskiy 	int err;
48643ec0f41SMaxim Mikityanskiy 
48743ec0f41SMaxim Mikityanskiy 	res->rss_active = true;
48843ec0f41SMaxim Mikityanskiy 
48943ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_indir(&res->indir_rqt, res->rss_rqns, res->rss_nch,
49043ec0f41SMaxim Mikityanskiy 				       res->rss_params.hash.hfunc,
49143ec0f41SMaxim Mikityanskiy 				       &res->rss_params.indir);
49243ec0f41SMaxim Mikityanskiy 	if (err)
49343ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect indirect RQT %#x to channels: err = %d\n",
49443ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->indir_rqt), err);
49543ec0f41SMaxim Mikityanskiy }
49643ec0f41SMaxim Mikityanskiy 
49743ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_rss_disable(struct mlx5e_rx_res *res)
49843ec0f41SMaxim Mikityanskiy {
49943ec0f41SMaxim Mikityanskiy 	int err;
50043ec0f41SMaxim Mikityanskiy 
50143ec0f41SMaxim Mikityanskiy 	res->rss_active = false;
50243ec0f41SMaxim Mikityanskiy 
50343ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->indir_rqt, res->drop_rqn);
50443ec0f41SMaxim Mikityanskiy 	if (err)
50543ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect indirect RQT %#x to drop RQ %#x: err = %d\n",
50643ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->indir_rqt), res->drop_rqn, err);
50743ec0f41SMaxim Mikityanskiy }
50843ec0f41SMaxim Mikityanskiy 
50943ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs)
51043ec0f41SMaxim Mikityanskiy {
51143ec0f41SMaxim Mikityanskiy 	unsigned int nch, ix;
51243ec0f41SMaxim Mikityanskiy 	int err;
51343ec0f41SMaxim Mikityanskiy 
51443ec0f41SMaxim Mikityanskiy 	nch = mlx5e_channels_get_num(chs);
51543ec0f41SMaxim Mikityanskiy 
51643ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < chs->num; ix++)
51743ec0f41SMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]);
51843ec0f41SMaxim Mikityanskiy 	res->rss_nch = chs->num;
51943ec0f41SMaxim Mikityanskiy 
52043ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_enable(res);
52143ec0f41SMaxim Mikityanskiy 
52243ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < nch; ix++) {
52343ec0f41SMaxim Mikityanskiy 		u32 rqn;
52443ec0f41SMaxim Mikityanskiy 
52543ec0f41SMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &rqn);
52643ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn);
52743ec0f41SMaxim Mikityanskiy 		if (err)
52843ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n",
52943ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
53043ec0f41SMaxim Mikityanskiy 				       rqn, ix, err);
53143ec0f41SMaxim Mikityanskiy 
53243ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
53343ec0f41SMaxim Mikityanskiy 			continue;
53443ec0f41SMaxim Mikityanskiy 
53543ec0f41SMaxim Mikityanskiy 		if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
53643ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
53743ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
53843ec0f41SMaxim Mikityanskiy 		if (err)
53943ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to RQ %#x (channel %u): err = %d\n",
54043ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
54143ec0f41SMaxim Mikityanskiy 				       rqn, ix, err);
54243ec0f41SMaxim Mikityanskiy 	}
54343ec0f41SMaxim Mikityanskiy 	for (ix = nch; ix < res->max_nch; ix++) {
54443ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
54543ec0f41SMaxim Mikityanskiy 		if (err)
54643ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
54743ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
54843ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
54943ec0f41SMaxim Mikityanskiy 
55043ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
55143ec0f41SMaxim Mikityanskiy 			continue;
55243ec0f41SMaxim Mikityanskiy 
55343ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
55443ec0f41SMaxim Mikityanskiy 		if (err)
55543ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
55643ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
55743ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
55843ec0f41SMaxim Mikityanskiy 	}
55943ec0f41SMaxim Mikityanskiy 
56043ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
56143ec0f41SMaxim Mikityanskiy 		u32 rqn;
56243ec0f41SMaxim Mikityanskiy 
56343ec0f41SMaxim Mikityanskiy 		if (mlx5e_channels_get_ptp_rqn(chs, &rqn))
56443ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
56543ec0f41SMaxim Mikityanskiy 
56643ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn);
56743ec0f41SMaxim Mikityanskiy 		if (err)
56843ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n",
56943ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
57043ec0f41SMaxim Mikityanskiy 				       rqn, err);
57143ec0f41SMaxim Mikityanskiy 	}
57243ec0f41SMaxim Mikityanskiy }
57343ec0f41SMaxim Mikityanskiy 
57443ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res)
57543ec0f41SMaxim Mikityanskiy {
57643ec0f41SMaxim Mikityanskiy 	unsigned int ix;
57743ec0f41SMaxim Mikityanskiy 	int err;
57843ec0f41SMaxim Mikityanskiy 
57943ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_disable(res);
58043ec0f41SMaxim Mikityanskiy 
58143ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
58243ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
58343ec0f41SMaxim Mikityanskiy 		if (err)
58443ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
58543ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
58643ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
58743ec0f41SMaxim Mikityanskiy 
58843ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
58943ec0f41SMaxim Mikityanskiy 			continue;
59043ec0f41SMaxim Mikityanskiy 
59143ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
59243ec0f41SMaxim Mikityanskiy 		if (err)
59343ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
59443ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
59543ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
59643ec0f41SMaxim Mikityanskiy 	}
59743ec0f41SMaxim Mikityanskiy 
59843ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
59943ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.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 (PTP): err = %d\n",
60243ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
60343ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, err);
60443ec0f41SMaxim Mikityanskiy 	}
60543ec0f41SMaxim Mikityanskiy }
60643ec0f41SMaxim Mikityanskiy 
60743ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs,
60843ec0f41SMaxim Mikityanskiy 			      unsigned int ix)
60943ec0f41SMaxim Mikityanskiy {
61043ec0f41SMaxim Mikityanskiy 	u32 rqn;
61143ec0f41SMaxim Mikityanskiy 	int err;
61243ec0f41SMaxim Mikityanskiy 
61343ec0f41SMaxim Mikityanskiy 	if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
61443ec0f41SMaxim Mikityanskiy 		return -EINVAL;
61543ec0f41SMaxim Mikityanskiy 
61643ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
61743ec0f41SMaxim Mikityanskiy 	if (err)
61843ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to XSK RQ %#x (channel %u): err = %d\n",
61943ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
62043ec0f41SMaxim Mikityanskiy 			       rqn, ix, err);
62143ec0f41SMaxim Mikityanskiy 	return err;
62243ec0f41SMaxim Mikityanskiy }
62343ec0f41SMaxim Mikityanskiy 
62443ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res *res, unsigned int ix)
62543ec0f41SMaxim Mikityanskiy {
62643ec0f41SMaxim Mikityanskiy 	int err;
62743ec0f41SMaxim Mikityanskiy 
62843ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
62943ec0f41SMaxim Mikityanskiy 	if (err)
63043ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
63143ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
63243ec0f41SMaxim Mikityanskiy 			       res->drop_rqn, ix, err);
63343ec0f41SMaxim Mikityanskiy 	return err;
63443ec0f41SMaxim Mikityanskiy }
63543ec0f41SMaxim Mikityanskiy 
63665d6b6e5SMaxim Mikityanskiy struct mlx5e_rss_params_traffic_type
637d443c6f6SMaor Gottlieb mlx5e_rx_res_rss_get_current_tt_config(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
63865d6b6e5SMaxim Mikityanskiy {
63965d6b6e5SMaxim Mikityanskiy 	struct mlx5e_rss_params_traffic_type rss_tt;
64065d6b6e5SMaxim Mikityanskiy 
64165d6b6e5SMaxim Mikityanskiy 	rss_tt = mlx5e_rss_get_default_tt_config(tt);
64265d6b6e5SMaxim Mikityanskiy 	rss_tt.rx_hash_fields = res->rss_params.rx_hash_fields[tt];
64365d6b6e5SMaxim Mikityanskiy 	return rss_tt;
64465d6b6e5SMaxim Mikityanskiy }
64543ec0f41SMaxim Mikityanskiy 
6466e5fea51STariq Toukan /* Updates the indirection table SW shadow, does not update the HW resources yet */
64743ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch)
64843ec0f41SMaxim Mikityanskiy {
6496e5fea51STariq Toukan 	WARN_ON_ONCE(res->rss_active);
65043ec0f41SMaxim Mikityanskiy 	mlx5e_rss_params_indir_init_uniform(&res->rss_params.indir, nch);
65143ec0f41SMaxim Mikityanskiy }
65243ec0f41SMaxim Mikityanskiy 
65343ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 *indir, u8 *key, u8 *hfunc)
65443ec0f41SMaxim Mikityanskiy {
65543ec0f41SMaxim Mikityanskiy 	unsigned int i;
65643ec0f41SMaxim Mikityanskiy 
65743ec0f41SMaxim Mikityanskiy 	if (indir)
65843ec0f41SMaxim Mikityanskiy 		for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++)
65943ec0f41SMaxim Mikityanskiy 			indir[i] = res->rss_params.indir.table[i];
66043ec0f41SMaxim Mikityanskiy 
66143ec0f41SMaxim Mikityanskiy 	if (key)
66243ec0f41SMaxim Mikityanskiy 		memcpy(key, res->rss_params.hash.toeplitz_hash_key,
66343ec0f41SMaxim Mikityanskiy 		       sizeof(res->rss_params.hash.toeplitz_hash_key));
66443ec0f41SMaxim Mikityanskiy 
66543ec0f41SMaxim Mikityanskiy 	if (hfunc)
66643ec0f41SMaxim Mikityanskiy 		*hfunc = res->rss_params.hash.hfunc;
66743ec0f41SMaxim Mikityanskiy }
66843ec0f41SMaxim Mikityanskiy 
669d443c6f6SMaor Gottlieb static int mlx5e_rx_res_rss_update_tir(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
67043ec0f41SMaxim Mikityanskiy 				       bool inner)
67143ec0f41SMaxim Mikityanskiy {
67243ec0f41SMaxim Mikityanskiy 	struct mlx5e_rss_params_traffic_type rss_tt;
67343ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
67443ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir *tir;
67543ec0f41SMaxim Mikityanskiy 	int err;
67643ec0f41SMaxim Mikityanskiy 
67743ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(true);
67843ec0f41SMaxim Mikityanskiy 	if (!builder)
67943ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
68043ec0f41SMaxim Mikityanskiy 
68143ec0f41SMaxim Mikityanskiy 	rss_tt = mlx5e_rx_res_rss_get_current_tt_config(res, tt);
68243ec0f41SMaxim Mikityanskiy 
68343ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_rss(builder, &res->rss_params.hash, &rss_tt, inner);
68443ec0f41SMaxim Mikityanskiy 	tir = inner ? &res->rss[tt].inner_indir_tir : &res->rss[tt].indir_tir;
68543ec0f41SMaxim Mikityanskiy 	err = mlx5e_tir_modify(tir, builder);
68643ec0f41SMaxim Mikityanskiy 
68743ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
68843ec0f41SMaxim Mikityanskiy 	return err;
68943ec0f41SMaxim Mikityanskiy }
69043ec0f41SMaxim Mikityanskiy 
69143ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, const u32 *indir,
69243ec0f41SMaxim Mikityanskiy 			      const u8 *key, const u8 *hfunc)
69343ec0f41SMaxim Mikityanskiy {
694d443c6f6SMaor Gottlieb 	enum mlx5_traffic_types tt;
69543ec0f41SMaxim Mikityanskiy 	bool changed_indir = false;
69643ec0f41SMaxim Mikityanskiy 	bool changed_hash = false;
69743ec0f41SMaxim Mikityanskiy 	int err;
69843ec0f41SMaxim Mikityanskiy 
69943ec0f41SMaxim Mikityanskiy 	if (hfunc && *hfunc != res->rss_params.hash.hfunc) {
70043ec0f41SMaxim Mikityanskiy 		switch (*hfunc) {
70143ec0f41SMaxim Mikityanskiy 		case ETH_RSS_HASH_XOR:
70243ec0f41SMaxim Mikityanskiy 		case ETH_RSS_HASH_TOP:
70343ec0f41SMaxim Mikityanskiy 			break;
70443ec0f41SMaxim Mikityanskiy 		default:
70543ec0f41SMaxim Mikityanskiy 			return -EINVAL;
70643ec0f41SMaxim Mikityanskiy 		}
70743ec0f41SMaxim Mikityanskiy 		changed_hash = true;
70843ec0f41SMaxim Mikityanskiy 		changed_indir = true;
70943ec0f41SMaxim Mikityanskiy 		res->rss_params.hash.hfunc = *hfunc;
71043ec0f41SMaxim Mikityanskiy 	}
71143ec0f41SMaxim Mikityanskiy 
71243ec0f41SMaxim Mikityanskiy 	if (key) {
71343ec0f41SMaxim Mikityanskiy 		if (res->rss_params.hash.hfunc == ETH_RSS_HASH_TOP)
71443ec0f41SMaxim Mikityanskiy 			changed_hash = true;
71543ec0f41SMaxim Mikityanskiy 		memcpy(res->rss_params.hash.toeplitz_hash_key, key,
71643ec0f41SMaxim Mikityanskiy 		       sizeof(res->rss_params.hash.toeplitz_hash_key));
71743ec0f41SMaxim Mikityanskiy 	}
71843ec0f41SMaxim Mikityanskiy 
71943ec0f41SMaxim Mikityanskiy 	if (indir) {
72043ec0f41SMaxim Mikityanskiy 		unsigned int i;
72143ec0f41SMaxim Mikityanskiy 
72243ec0f41SMaxim Mikityanskiy 		changed_indir = true;
72343ec0f41SMaxim Mikityanskiy 
72443ec0f41SMaxim Mikityanskiy 		for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++)
72543ec0f41SMaxim Mikityanskiy 			res->rss_params.indir.table[i] = indir[i];
72643ec0f41SMaxim Mikityanskiy 	}
72743ec0f41SMaxim Mikityanskiy 
72843ec0f41SMaxim Mikityanskiy 	if (changed_indir && res->rss_active) {
72943ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_indir(&res->indir_rqt, res->rss_rqns, res->rss_nch,
73043ec0f41SMaxim Mikityanskiy 					       res->rss_params.hash.hfunc,
73143ec0f41SMaxim Mikityanskiy 					       &res->rss_params.indir);
73243ec0f41SMaxim Mikityanskiy 		if (err)
73343ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect indirect RQT %#x to channels: err = %d\n",
73443ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->indir_rqt), err);
73543ec0f41SMaxim Mikityanskiy 	}
73643ec0f41SMaxim Mikityanskiy 
73743ec0f41SMaxim Mikityanskiy 	if (changed_hash)
73843ec0f41SMaxim Mikityanskiy 		for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
73943ec0f41SMaxim Mikityanskiy 			err = mlx5e_rx_res_rss_update_tir(res, tt, false);
74043ec0f41SMaxim Mikityanskiy 			if (err)
74143ec0f41SMaxim Mikityanskiy 				mlx5_core_warn(res->mdev, "Failed to update RSS hash of indirect TIR for traffic type %d: err = %d\n",
74243ec0f41SMaxim Mikityanskiy 					       tt, err);
74343ec0f41SMaxim Mikityanskiy 
74443ec0f41SMaxim Mikityanskiy 			if (!(res->features & MLX5E_RX_RES_FEATURE_INNER_FT))
74543ec0f41SMaxim Mikityanskiy 				continue;
74643ec0f41SMaxim Mikityanskiy 
74743ec0f41SMaxim Mikityanskiy 			err = mlx5e_rx_res_rss_update_tir(res, tt, true);
74843ec0f41SMaxim Mikityanskiy 			if (err)
74943ec0f41SMaxim Mikityanskiy 				mlx5_core_warn(res->mdev, "Failed to update RSS hash of inner indirect TIR for traffic type %d: err = %d\n",
75043ec0f41SMaxim Mikityanskiy 					       tt, err);
75143ec0f41SMaxim Mikityanskiy 		}
75243ec0f41SMaxim Mikityanskiy 
75343ec0f41SMaxim Mikityanskiy 	return 0;
75443ec0f41SMaxim Mikityanskiy }
75543ec0f41SMaxim Mikityanskiy 
756d443c6f6SMaor Gottlieb u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
75743ec0f41SMaxim Mikityanskiy {
75843ec0f41SMaxim Mikityanskiy 	return res->rss_params.rx_hash_fields[tt];
75943ec0f41SMaxim Mikityanskiy }
76043ec0f41SMaxim Mikityanskiy 
761d443c6f6SMaor Gottlieb int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
76243ec0f41SMaxim Mikityanskiy 				     u8 rx_hash_fields)
76343ec0f41SMaxim Mikityanskiy {
76443ec0f41SMaxim Mikityanskiy 	u8 old_rx_hash_fields;
76543ec0f41SMaxim Mikityanskiy 	int err;
76643ec0f41SMaxim Mikityanskiy 
76743ec0f41SMaxim Mikityanskiy 	old_rx_hash_fields = res->rss_params.rx_hash_fields[tt];
76843ec0f41SMaxim Mikityanskiy 
76943ec0f41SMaxim Mikityanskiy 	if (old_rx_hash_fields == rx_hash_fields)
77043ec0f41SMaxim Mikityanskiy 		return 0;
77143ec0f41SMaxim Mikityanskiy 
77243ec0f41SMaxim Mikityanskiy 	res->rss_params.rx_hash_fields[tt] = rx_hash_fields;
77343ec0f41SMaxim Mikityanskiy 
77443ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_rss_update_tir(res, tt, false);
77543ec0f41SMaxim Mikityanskiy 	if (err) {
77643ec0f41SMaxim Mikityanskiy 		res->rss_params.rx_hash_fields[tt] = old_rx_hash_fields;
77743ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to update RSS hash fields of indirect TIR for traffic type %d: err = %d\n",
77843ec0f41SMaxim Mikityanskiy 			       tt, err);
77943ec0f41SMaxim Mikityanskiy 		return err;
78043ec0f41SMaxim Mikityanskiy 	}
78143ec0f41SMaxim Mikityanskiy 
78243ec0f41SMaxim Mikityanskiy 	if (!(res->features & MLX5E_RX_RES_FEATURE_INNER_FT))
78343ec0f41SMaxim Mikityanskiy 		return 0;
78443ec0f41SMaxim Mikityanskiy 
78543ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_rss_update_tir(res, tt, true);
78643ec0f41SMaxim Mikityanskiy 	if (err) {
78743ec0f41SMaxim Mikityanskiy 		/* Partial update happened. Try to revert - it may fail too, but
78843ec0f41SMaxim Mikityanskiy 		 * there is nothing more we can do.
78943ec0f41SMaxim Mikityanskiy 		 */
79043ec0f41SMaxim Mikityanskiy 		res->rss_params.rx_hash_fields[tt] = old_rx_hash_fields;
79143ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to update RSS hash fields of inner indirect TIR for traffic type %d: err = %d\n",
79243ec0f41SMaxim Mikityanskiy 			       tt, err);
79343ec0f41SMaxim Mikityanskiy 		if (mlx5e_rx_res_rss_update_tir(res, tt, false))
79443ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Partial update of RSS hash fields happened: failed to revert indirect TIR for traffic type %d to the old values\n",
79543ec0f41SMaxim Mikityanskiy 				       tt);
79643ec0f41SMaxim Mikityanskiy 	}
79743ec0f41SMaxim Mikityanskiy 
79843ec0f41SMaxim Mikityanskiy 	return err;
79943ec0f41SMaxim Mikityanskiy }
80043ec0f41SMaxim Mikityanskiy 
80143ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res *res, struct mlx5e_lro_param *lro_param)
80243ec0f41SMaxim Mikityanskiy {
80343ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
804d443c6f6SMaor Gottlieb 	enum mlx5_traffic_types tt;
80543ec0f41SMaxim Mikityanskiy 	int err, final_err;
80643ec0f41SMaxim Mikityanskiy 	unsigned int ix;
80743ec0f41SMaxim Mikityanskiy 
80843ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(true);
80943ec0f41SMaxim Mikityanskiy 	if (!builder)
81043ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
81143ec0f41SMaxim Mikityanskiy 
81243ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_lro(builder, lro_param);
81343ec0f41SMaxim Mikityanskiy 
81443ec0f41SMaxim Mikityanskiy 	final_err = 0;
81543ec0f41SMaxim Mikityanskiy 
81643ec0f41SMaxim Mikityanskiy 	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
81743ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_modify(&res->rss[tt].indir_tir, builder);
81843ec0f41SMaxim Mikityanskiy 		if (err) {
81943ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to update LRO state of indirect TIR %#x for traffic type %d: err = %d\n",
82043ec0f41SMaxim Mikityanskiy 				       mlx5e_tir_get_tirn(&res->rss[tt].indir_tir), tt, err);
82143ec0f41SMaxim Mikityanskiy 			if (!final_err)
82243ec0f41SMaxim Mikityanskiy 				final_err = err;
82343ec0f41SMaxim Mikityanskiy 		}
82443ec0f41SMaxim Mikityanskiy 
82543ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_INNER_FT))
82643ec0f41SMaxim Mikityanskiy 			continue;
82743ec0f41SMaxim Mikityanskiy 
82843ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_modify(&res->rss[tt].inner_indir_tir, builder);
82943ec0f41SMaxim Mikityanskiy 		if (err) {
83043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to update LRO state of inner indirect TIR %#x for traffic type %d: err = %d\n",
83143ec0f41SMaxim Mikityanskiy 				       mlx5e_tir_get_tirn(&res->rss[tt].inner_indir_tir), tt, err);
83243ec0f41SMaxim Mikityanskiy 			if (!final_err)
83343ec0f41SMaxim Mikityanskiy 				final_err = err;
83443ec0f41SMaxim Mikityanskiy 		}
83543ec0f41SMaxim Mikityanskiy 	}
83643ec0f41SMaxim Mikityanskiy 
83743ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
83843ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder);
83943ec0f41SMaxim Mikityanskiy 		if (err) {
84043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to update LRO state of direct TIR %#x for channel %u: err = %d\n",
84143ec0f41SMaxim Mikityanskiy 				       mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err);
84243ec0f41SMaxim Mikityanskiy 			if (!final_err)
84343ec0f41SMaxim Mikityanskiy 				final_err = err;
84443ec0f41SMaxim Mikityanskiy 		}
84543ec0f41SMaxim Mikityanskiy 	}
84643ec0f41SMaxim Mikityanskiy 
84743ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
84843ec0f41SMaxim Mikityanskiy 	return final_err;
84943ec0f41SMaxim Mikityanskiy }
85043ec0f41SMaxim Mikityanskiy 
85143ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res)
85243ec0f41SMaxim Mikityanskiy {
85343ec0f41SMaxim Mikityanskiy 	return res->rss_params.hash;
85443ec0f41SMaxim Mikityanskiy }
855