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 
843ec0f41SMaxim Mikityanskiy struct mlx5e_rx_res {
943ec0f41SMaxim Mikityanskiy 	struct mlx5_core_dev *mdev;
1043ec0f41SMaxim Mikityanskiy 	enum mlx5e_rx_res_features features;
1143ec0f41SMaxim Mikityanskiy 	unsigned int max_nch;
1243ec0f41SMaxim Mikityanskiy 	u32 drop_rqn;
1343ec0f41SMaxim Mikityanskiy 
14713ba5e5STariq Toukan 	struct mlx5e_rss *rss;
1543ec0f41SMaxim Mikityanskiy 	bool rss_active;
1643ec0f41SMaxim Mikityanskiy 	u32 rss_rqns[MLX5E_INDIR_RQT_SIZE];
1743ec0f41SMaxim Mikityanskiy 	unsigned int rss_nch;
1843ec0f41SMaxim Mikityanskiy 
1943ec0f41SMaxim Mikityanskiy 	struct {
2043ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt direct_rqt;
2143ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir direct_tir;
2243ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt xsk_rqt;
2343ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir xsk_tir;
243ac90decSMaxim Mikityanskiy 	} *channels;
2543ec0f41SMaxim Mikityanskiy 
2643ec0f41SMaxim Mikityanskiy 	struct {
2743ec0f41SMaxim Mikityanskiy 		struct mlx5e_rqt rqt;
2843ec0f41SMaxim Mikityanskiy 		struct mlx5e_tir tir;
2943ec0f41SMaxim Mikityanskiy 	} ptp;
3043ec0f41SMaxim Mikityanskiy };
3143ec0f41SMaxim Mikityanskiy 
32*25307a91STariq Toukan /* API for rx_res_rss_* */
33fc651ff9STariq Toukan 
34fc651ff9STariq Toukan static int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res,
35713ba5e5STariq Toukan 				 const struct mlx5e_lro_param *init_lro_param,
36713ba5e5STariq Toukan 				 unsigned int init_nch)
37fc651ff9STariq Toukan {
38fc651ff9STariq Toukan 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
39713ba5e5STariq Toukan 	struct mlx5e_rss *rss;
40fc651ff9STariq Toukan 	int err;
41fc651ff9STariq Toukan 
42*25307a91STariq Toukan 	rss = mlx5e_rss_alloc();
43713ba5e5STariq Toukan 	if (!rss)
44713ba5e5STariq Toukan 		return -ENOMEM;
45713ba5e5STariq Toukan 
46713ba5e5STariq Toukan 	res->rss = rss;
47713ba5e5STariq Toukan 
48*25307a91STariq Toukan 	err = mlx5e_rss_init(rss, res->mdev, inner_ft_support, res->drop_rqn, init_lro_param);
49fc651ff9STariq Toukan 	if (err)
50*25307a91STariq Toukan 		goto err_rss_free;
51fc651ff9STariq Toukan 
52*25307a91STariq Toukan 	mlx5e_rss_set_indir_uniform(rss, init_nch);
53fc651ff9STariq Toukan 
54fc651ff9STariq Toukan 	return 0;
55fc651ff9STariq Toukan 
56*25307a91STariq Toukan err_rss_free:
57*25307a91STariq Toukan 	mlx5e_rss_free(rss);
58713ba5e5STariq Toukan 	res->rss = NULL;
5943ec0f41SMaxim Mikityanskiy 	return err;
6043ec0f41SMaxim Mikityanskiy }
6143ec0f41SMaxim Mikityanskiy 
62*25307a91STariq Toukan static void mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res)
63*25307a91STariq Toukan {
64*25307a91STariq Toukan 	struct mlx5e_rss *rss = res->rss;
65*25307a91STariq Toukan 
66*25307a91STariq Toukan 	mlx5e_rss_cleanup(rss);
67*25307a91STariq Toukan 	mlx5e_rss_free(rss);
68*25307a91STariq Toukan 	res->rss = NULL;
69*25307a91STariq Toukan }
70*25307a91STariq Toukan 
71*25307a91STariq Toukan static void mlx5e_rx_res_rss_enable(struct mlx5e_rx_res *res)
72*25307a91STariq Toukan {
73*25307a91STariq Toukan 	struct mlx5e_rss *rss = res->rss;
74*25307a91STariq Toukan 
75*25307a91STariq Toukan 	res->rss_active = true;
76*25307a91STariq Toukan 
77*25307a91STariq Toukan 	mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch);
78*25307a91STariq Toukan }
79*25307a91STariq Toukan 
80*25307a91STariq Toukan static void mlx5e_rx_res_rss_disable(struct mlx5e_rx_res *res)
81*25307a91STariq Toukan {
82*25307a91STariq Toukan 	struct mlx5e_rss *rss = res->rss;
83*25307a91STariq Toukan 
84*25307a91STariq Toukan 	res->rss_active = false;
85*25307a91STariq Toukan 
86*25307a91STariq Toukan 	mlx5e_rss_disable(rss);
87*25307a91STariq Toukan }
88*25307a91STariq Toukan 
89*25307a91STariq Toukan /* Updates the indirection table SW shadow, does not update the HW resources yet */
90*25307a91STariq Toukan void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch)
91*25307a91STariq Toukan {
92*25307a91STariq Toukan 	WARN_ON_ONCE(res->rss_active);
93*25307a91STariq Toukan 	mlx5e_rss_set_indir_uniform(res->rss, nch);
94*25307a91STariq Toukan }
95*25307a91STariq Toukan 
96*25307a91STariq Toukan int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 *indir, u8 *key, u8 *hfunc)
97*25307a91STariq Toukan {
98*25307a91STariq Toukan 	struct mlx5e_rss *rss = res->rss;
99*25307a91STariq Toukan 
100*25307a91STariq Toukan 	return mlx5e_rss_get_rxfh(rss, indir, key, hfunc);
101*25307a91STariq Toukan }
102*25307a91STariq Toukan 
103*25307a91STariq Toukan int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, const u32 *indir,
104*25307a91STariq Toukan 			      const u8 *key, const u8 *hfunc)
105*25307a91STariq Toukan {
106*25307a91STariq Toukan 	struct mlx5e_rss *rss = res->rss;
107*25307a91STariq Toukan 
108*25307a91STariq Toukan 	return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch);
109*25307a91STariq Toukan }
110*25307a91STariq Toukan 
111*25307a91STariq Toukan u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
112*25307a91STariq Toukan {
113*25307a91STariq Toukan 	struct mlx5e_rss *rss = res->rss;
114*25307a91STariq Toukan 
115*25307a91STariq Toukan 	return mlx5e_rss_get_hash_fields(rss, tt);
116*25307a91STariq Toukan }
117*25307a91STariq Toukan 
118*25307a91STariq Toukan int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
119*25307a91STariq Toukan 				     u8 rx_hash_fields)
120*25307a91STariq Toukan {
121*25307a91STariq Toukan 	struct mlx5e_rss *rss = res->rss;
122*25307a91STariq Toukan 
123*25307a91STariq Toukan 	return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
124*25307a91STariq Toukan }
125*25307a91STariq Toukan 
126*25307a91STariq Toukan /* End of API rx_res_rss_* */
127*25307a91STariq Toukan 
128*25307a91STariq Toukan struct mlx5e_rx_res *mlx5e_rx_res_alloc(void)
129*25307a91STariq Toukan {
130*25307a91STariq Toukan 	return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL);
131*25307a91STariq Toukan }
132*25307a91STariq Toukan 
13343ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res,
13443ec0f41SMaxim Mikityanskiy 				      const struct mlx5e_lro_param *init_lro_param)
13543ec0f41SMaxim Mikityanskiy {
13643ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
13743ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
13843ec0f41SMaxim Mikityanskiy 	int err = 0;
13943ec0f41SMaxim Mikityanskiy 	int ix;
14043ec0f41SMaxim Mikityanskiy 
14143ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
14243ec0f41SMaxim Mikityanskiy 	if (!builder)
14343ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
14443ec0f41SMaxim Mikityanskiy 
1453ac90decSMaxim Mikityanskiy 	res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL);
1463ac90decSMaxim Mikityanskiy 	if (!res->channels) {
1473ac90decSMaxim Mikityanskiy 		err = -ENOMEM;
1483ac90decSMaxim Mikityanskiy 		goto out;
1493ac90decSMaxim Mikityanskiy 	}
1503ac90decSMaxim Mikityanskiy 
15143ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
15243ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt,
15343ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
15443ec0f41SMaxim Mikityanskiy 		if (err) {
15543ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n",
15643ec0f41SMaxim Mikityanskiy 				       err, ix);
15743ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_rqts;
15843ec0f41SMaxim Mikityanskiy 		}
15943ec0f41SMaxim Mikityanskiy 	}
16043ec0f41SMaxim Mikityanskiy 
16143ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
16243ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
16343ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
16443ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
16543ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_lro(builder, init_lro_param);
16643ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
16743ec0f41SMaxim Mikityanskiy 
16843ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true);
16943ec0f41SMaxim Mikityanskiy 		if (err) {
17043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n",
17143ec0f41SMaxim Mikityanskiy 				       err, ix);
17243ec0f41SMaxim Mikityanskiy 			goto err_destroy_direct_tirs;
17343ec0f41SMaxim Mikityanskiy 		}
17443ec0f41SMaxim Mikityanskiy 
17543ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
17643ec0f41SMaxim Mikityanskiy 	}
17743ec0f41SMaxim Mikityanskiy 
17843ec0f41SMaxim Mikityanskiy 	if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
17943ec0f41SMaxim Mikityanskiy 		goto out;
18043ec0f41SMaxim Mikityanskiy 
18143ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
18243ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_init_direct(&res->channels[ix].xsk_rqt,
18343ec0f41SMaxim Mikityanskiy 					    res->mdev, false, res->drop_rqn);
18443ec0f41SMaxim Mikityanskiy 		if (err) {
18543ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create an XSK RQT: err = %d, ix = %u\n",
18643ec0f41SMaxim Mikityanskiy 				       err, ix);
18743ec0f41SMaxim Mikityanskiy 			goto err_destroy_xsk_rqts;
18843ec0f41SMaxim Mikityanskiy 		}
18943ec0f41SMaxim Mikityanskiy 	}
19043ec0f41SMaxim Mikityanskiy 
19143ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
19243ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
19343ec0f41SMaxim Mikityanskiy 					    mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
19443ec0f41SMaxim Mikityanskiy 					    inner_ft_support);
19543ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_lro(builder, init_lro_param);
19643ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_build_direct(builder);
19743ec0f41SMaxim Mikityanskiy 
19843ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_init(&res->channels[ix].xsk_tir, builder, res->mdev, true);
19943ec0f41SMaxim Mikityanskiy 		if (err) {
20043ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to create an XSK TIR: err = %d, ix = %u\n",
20143ec0f41SMaxim Mikityanskiy 				       err, ix);
20243ec0f41SMaxim Mikityanskiy 			goto err_destroy_xsk_tirs;
20343ec0f41SMaxim Mikityanskiy 		}
20443ec0f41SMaxim Mikityanskiy 
20543ec0f41SMaxim Mikityanskiy 		mlx5e_tir_builder_clear(builder);
20643ec0f41SMaxim Mikityanskiy 	}
20743ec0f41SMaxim Mikityanskiy 
20843ec0f41SMaxim Mikityanskiy 	goto out;
20943ec0f41SMaxim Mikityanskiy 
21043ec0f41SMaxim Mikityanskiy err_destroy_xsk_tirs:
21143ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
21243ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
21343ec0f41SMaxim Mikityanskiy 
21443ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
21543ec0f41SMaxim Mikityanskiy err_destroy_xsk_rqts:
21643ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
21743ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
21843ec0f41SMaxim Mikityanskiy 
21943ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
22043ec0f41SMaxim Mikityanskiy err_destroy_direct_tirs:
22143ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
22243ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
22343ec0f41SMaxim Mikityanskiy 
22443ec0f41SMaxim Mikityanskiy 	ix = res->max_nch;
22543ec0f41SMaxim Mikityanskiy err_destroy_direct_rqts:
22643ec0f41SMaxim Mikityanskiy 	while (--ix >= 0)
22743ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
22843ec0f41SMaxim Mikityanskiy 
2293ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
2303ac90decSMaxim Mikityanskiy 
23143ec0f41SMaxim Mikityanskiy out:
23243ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
23343ec0f41SMaxim Mikityanskiy 
23443ec0f41SMaxim Mikityanskiy 	return err;
23543ec0f41SMaxim Mikityanskiy }
23643ec0f41SMaxim Mikityanskiy 
23743ec0f41SMaxim Mikityanskiy static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res)
23843ec0f41SMaxim Mikityanskiy {
23943ec0f41SMaxim Mikityanskiy 	bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
24043ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
24143ec0f41SMaxim Mikityanskiy 	int err;
24243ec0f41SMaxim Mikityanskiy 
24343ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(false);
24443ec0f41SMaxim Mikityanskiy 	if (!builder)
24543ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
24643ec0f41SMaxim Mikityanskiy 
24743ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn);
24843ec0f41SMaxim Mikityanskiy 	if (err)
24943ec0f41SMaxim Mikityanskiy 		goto out;
25043ec0f41SMaxim Mikityanskiy 
25143ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
25243ec0f41SMaxim Mikityanskiy 				    mlx5e_rqt_get_rqtn(&res->ptp.rqt),
25343ec0f41SMaxim Mikityanskiy 				    inner_ft_support);
25443ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_direct(builder);
25543ec0f41SMaxim Mikityanskiy 
25643ec0f41SMaxim Mikityanskiy 	err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true);
25743ec0f41SMaxim Mikityanskiy 	if (err)
25843ec0f41SMaxim Mikityanskiy 		goto err_destroy_ptp_rqt;
25943ec0f41SMaxim Mikityanskiy 
26043ec0f41SMaxim Mikityanskiy 	goto out;
26143ec0f41SMaxim Mikityanskiy 
26243ec0f41SMaxim Mikityanskiy err_destroy_ptp_rqt:
26343ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
26443ec0f41SMaxim Mikityanskiy 
26543ec0f41SMaxim Mikityanskiy out:
26643ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
26743ec0f41SMaxim Mikityanskiy 	return err;
26843ec0f41SMaxim Mikityanskiy }
26943ec0f41SMaxim Mikityanskiy 
27043ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res)
27143ec0f41SMaxim Mikityanskiy {
27243ec0f41SMaxim Mikityanskiy 	unsigned int ix;
27343ec0f41SMaxim Mikityanskiy 
27443ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
27543ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].direct_tir);
27643ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
27743ec0f41SMaxim Mikityanskiy 
27843ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
27943ec0f41SMaxim Mikityanskiy 			continue;
28043ec0f41SMaxim Mikityanskiy 
28143ec0f41SMaxim Mikityanskiy 		mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
28243ec0f41SMaxim Mikityanskiy 		mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
28343ec0f41SMaxim Mikityanskiy 	}
2843ac90decSMaxim Mikityanskiy 
2853ac90decSMaxim Mikityanskiy 	kvfree(res->channels);
28643ec0f41SMaxim Mikityanskiy }
28743ec0f41SMaxim Mikityanskiy 
28843ec0f41SMaxim Mikityanskiy static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res)
28943ec0f41SMaxim Mikityanskiy {
29043ec0f41SMaxim Mikityanskiy 	mlx5e_tir_destroy(&res->ptp.tir);
29143ec0f41SMaxim Mikityanskiy 	mlx5e_rqt_destroy(&res->ptp.rqt);
29243ec0f41SMaxim Mikityanskiy }
29343ec0f41SMaxim Mikityanskiy 
29443ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev,
29543ec0f41SMaxim Mikityanskiy 		      enum mlx5e_rx_res_features features, unsigned int max_nch,
29643ec0f41SMaxim Mikityanskiy 		      u32 drop_rqn, const struct mlx5e_lro_param *init_lro_param,
29743ec0f41SMaxim Mikityanskiy 		      unsigned int init_nch)
29843ec0f41SMaxim Mikityanskiy {
29943ec0f41SMaxim Mikityanskiy 	int err;
30043ec0f41SMaxim Mikityanskiy 
30143ec0f41SMaxim Mikityanskiy 	res->mdev = mdev;
30243ec0f41SMaxim Mikityanskiy 	res->features = features;
30343ec0f41SMaxim Mikityanskiy 	res->max_nch = max_nch;
30443ec0f41SMaxim Mikityanskiy 	res->drop_rqn = drop_rqn;
30543ec0f41SMaxim Mikityanskiy 
306713ba5e5STariq Toukan 	err = mlx5e_rx_res_rss_init(res, init_lro_param, init_nch);
30743ec0f41SMaxim Mikityanskiy 	if (err)
308*25307a91STariq Toukan 		goto err_out;
30943ec0f41SMaxim Mikityanskiy 
31043ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_channels_init(res, init_lro_param);
31143ec0f41SMaxim Mikityanskiy 	if (err)
31243ec0f41SMaxim Mikityanskiy 		goto err_rss_destroy;
31343ec0f41SMaxim Mikityanskiy 
31443ec0f41SMaxim Mikityanskiy 	err = mlx5e_rx_res_ptp_init(res);
31543ec0f41SMaxim Mikityanskiy 	if (err)
31643ec0f41SMaxim Mikityanskiy 		goto err_channels_destroy;
31743ec0f41SMaxim Mikityanskiy 
31843ec0f41SMaxim Mikityanskiy 	return 0;
31943ec0f41SMaxim Mikityanskiy 
32043ec0f41SMaxim Mikityanskiy err_channels_destroy:
32143ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
32243ec0f41SMaxim Mikityanskiy err_rss_destroy:
32343ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_destroy(res);
324*25307a91STariq Toukan err_out:
32543ec0f41SMaxim Mikityanskiy 	return err;
32643ec0f41SMaxim Mikityanskiy }
32743ec0f41SMaxim Mikityanskiy 
32843ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res)
32943ec0f41SMaxim Mikityanskiy {
33043ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_ptp_destroy(res);
33143ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_channels_destroy(res);
33243ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_destroy(res);
33343ec0f41SMaxim Mikityanskiy }
33443ec0f41SMaxim Mikityanskiy 
33543ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_free(struct mlx5e_rx_res *res)
33643ec0f41SMaxim Mikityanskiy {
33743ec0f41SMaxim Mikityanskiy 	kvfree(res);
33843ec0f41SMaxim Mikityanskiy }
33943ec0f41SMaxim Mikityanskiy 
34043ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix)
34143ec0f41SMaxim Mikityanskiy {
34243ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir);
34343ec0f41SMaxim Mikityanskiy }
34443ec0f41SMaxim Mikityanskiy 
34543ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res *res, unsigned int ix)
34643ec0f41SMaxim Mikityanskiy {
34743ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_XSK));
34843ec0f41SMaxim Mikityanskiy 
34943ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->channels[ix].xsk_tir);
35043ec0f41SMaxim Mikityanskiy }
35143ec0f41SMaxim Mikityanskiy 
352d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
35343ec0f41SMaxim Mikityanskiy {
354713ba5e5STariq Toukan 	struct mlx5e_rss *rss = res->rss;
355713ba5e5STariq Toukan 
356*25307a91STariq Toukan 	return mlx5e_rss_get_tirn(rss, tt, false);
35743ec0f41SMaxim Mikityanskiy }
35843ec0f41SMaxim Mikityanskiy 
359d443c6f6SMaor Gottlieb u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
36043ec0f41SMaxim Mikityanskiy {
361713ba5e5STariq Toukan 	struct mlx5e_rss *rss = res->rss;
362713ba5e5STariq Toukan 
363*25307a91STariq Toukan 	return mlx5e_rss_get_tirn(rss, tt, true);
36443ec0f41SMaxim Mikityanskiy }
36543ec0f41SMaxim Mikityanskiy 
36643ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res)
36743ec0f41SMaxim Mikityanskiy {
36843ec0f41SMaxim Mikityanskiy 	WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP));
36943ec0f41SMaxim Mikityanskiy 	return mlx5e_tir_get_tirn(&res->ptp.tir);
37043ec0f41SMaxim Mikityanskiy }
37143ec0f41SMaxim Mikityanskiy 
37243ec0f41SMaxim Mikityanskiy u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix)
37343ec0f41SMaxim Mikityanskiy {
37443ec0f41SMaxim Mikityanskiy 	return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt);
37543ec0f41SMaxim Mikityanskiy }
37643ec0f41SMaxim Mikityanskiy 
37743ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs)
37843ec0f41SMaxim Mikityanskiy {
37943ec0f41SMaxim Mikityanskiy 	unsigned int nch, ix;
38043ec0f41SMaxim Mikityanskiy 	int err;
38143ec0f41SMaxim Mikityanskiy 
38243ec0f41SMaxim Mikityanskiy 	nch = mlx5e_channels_get_num(chs);
38343ec0f41SMaxim Mikityanskiy 
38443ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < chs->num; ix++)
38543ec0f41SMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]);
38643ec0f41SMaxim Mikityanskiy 	res->rss_nch = chs->num;
38743ec0f41SMaxim Mikityanskiy 
38843ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_enable(res);
38943ec0f41SMaxim Mikityanskiy 
39043ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < nch; ix++) {
39143ec0f41SMaxim Mikityanskiy 		u32 rqn;
39243ec0f41SMaxim Mikityanskiy 
39343ec0f41SMaxim Mikityanskiy 		mlx5e_channels_get_regular_rqn(chs, ix, &rqn);
39443ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn);
39543ec0f41SMaxim Mikityanskiy 		if (err)
39643ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n",
39743ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
39843ec0f41SMaxim Mikityanskiy 				       rqn, ix, err);
39943ec0f41SMaxim Mikityanskiy 
40043ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
40143ec0f41SMaxim Mikityanskiy 			continue;
40243ec0f41SMaxim Mikityanskiy 
40343ec0f41SMaxim Mikityanskiy 		if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
40443ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
40543ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
40643ec0f41SMaxim Mikityanskiy 		if (err)
40743ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to RQ %#x (channel %u): err = %d\n",
40843ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
40943ec0f41SMaxim Mikityanskiy 				       rqn, ix, err);
41043ec0f41SMaxim Mikityanskiy 	}
41143ec0f41SMaxim Mikityanskiy 	for (ix = nch; ix < res->max_nch; ix++) {
41243ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
41343ec0f41SMaxim Mikityanskiy 		if (err)
41443ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
41543ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
41643ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
41743ec0f41SMaxim Mikityanskiy 
41843ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
41943ec0f41SMaxim Mikityanskiy 			continue;
42043ec0f41SMaxim Mikityanskiy 
42143ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
42243ec0f41SMaxim Mikityanskiy 		if (err)
42343ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
42443ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
42543ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
42643ec0f41SMaxim Mikityanskiy 	}
42743ec0f41SMaxim Mikityanskiy 
42843ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
42943ec0f41SMaxim Mikityanskiy 		u32 rqn;
43043ec0f41SMaxim Mikityanskiy 
43143ec0f41SMaxim Mikityanskiy 		if (mlx5e_channels_get_ptp_rqn(chs, &rqn))
43243ec0f41SMaxim Mikityanskiy 			rqn = res->drop_rqn;
43343ec0f41SMaxim Mikityanskiy 
43443ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn);
43543ec0f41SMaxim Mikityanskiy 		if (err)
43643ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n",
43743ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
43843ec0f41SMaxim Mikityanskiy 				       rqn, err);
43943ec0f41SMaxim Mikityanskiy 	}
44043ec0f41SMaxim Mikityanskiy }
44143ec0f41SMaxim Mikityanskiy 
44243ec0f41SMaxim Mikityanskiy void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res)
44343ec0f41SMaxim Mikityanskiy {
44443ec0f41SMaxim Mikityanskiy 	unsigned int ix;
44543ec0f41SMaxim Mikityanskiy 	int err;
44643ec0f41SMaxim Mikityanskiy 
44743ec0f41SMaxim Mikityanskiy 	mlx5e_rx_res_rss_disable(res);
44843ec0f41SMaxim Mikityanskiy 
44943ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
45043ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
45143ec0f41SMaxim Mikityanskiy 		if (err)
45243ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
45343ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
45443ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
45543ec0f41SMaxim Mikityanskiy 
45643ec0f41SMaxim Mikityanskiy 		if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
45743ec0f41SMaxim Mikityanskiy 			continue;
45843ec0f41SMaxim Mikityanskiy 
45943ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
46043ec0f41SMaxim Mikityanskiy 		if (err)
46143ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
46243ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
46343ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, ix, err);
46443ec0f41SMaxim Mikityanskiy 	}
46543ec0f41SMaxim Mikityanskiy 
46643ec0f41SMaxim Mikityanskiy 	if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
46743ec0f41SMaxim Mikityanskiy 		err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, res->drop_rqn);
46843ec0f41SMaxim Mikityanskiy 		if (err)
46943ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (PTP): err = %d\n",
47043ec0f41SMaxim Mikityanskiy 				       mlx5e_rqt_get_rqtn(&res->ptp.rqt),
47143ec0f41SMaxim Mikityanskiy 				       res->drop_rqn, err);
47243ec0f41SMaxim Mikityanskiy 	}
47343ec0f41SMaxim Mikityanskiy }
47443ec0f41SMaxim Mikityanskiy 
47543ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs,
47643ec0f41SMaxim Mikityanskiy 			      unsigned int ix)
47743ec0f41SMaxim Mikityanskiy {
47843ec0f41SMaxim Mikityanskiy 	u32 rqn;
47943ec0f41SMaxim Mikityanskiy 	int err;
48043ec0f41SMaxim Mikityanskiy 
48143ec0f41SMaxim Mikityanskiy 	if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
48243ec0f41SMaxim Mikityanskiy 		return -EINVAL;
48343ec0f41SMaxim Mikityanskiy 
48443ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
48543ec0f41SMaxim Mikityanskiy 	if (err)
48643ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to XSK RQ %#x (channel %u): err = %d\n",
48743ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
48843ec0f41SMaxim Mikityanskiy 			       rqn, ix, err);
48943ec0f41SMaxim Mikityanskiy 	return err;
49043ec0f41SMaxim Mikityanskiy }
49143ec0f41SMaxim Mikityanskiy 
49243ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res *res, unsigned int ix)
49343ec0f41SMaxim Mikityanskiy {
49443ec0f41SMaxim Mikityanskiy 	int err;
49543ec0f41SMaxim Mikityanskiy 
49643ec0f41SMaxim Mikityanskiy 	err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
49743ec0f41SMaxim Mikityanskiy 	if (err)
49843ec0f41SMaxim Mikityanskiy 		mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
49943ec0f41SMaxim Mikityanskiy 			       mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
50043ec0f41SMaxim Mikityanskiy 			       res->drop_rqn, ix, err);
50143ec0f41SMaxim Mikityanskiy 	return err;
50243ec0f41SMaxim Mikityanskiy }
50343ec0f41SMaxim Mikityanskiy 
50443ec0f41SMaxim Mikityanskiy int mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res *res, struct mlx5e_lro_param *lro_param)
50543ec0f41SMaxim Mikityanskiy {
506713ba5e5STariq Toukan 	struct mlx5e_rss *rss = res->rss;
50743ec0f41SMaxim Mikityanskiy 	struct mlx5e_tir_builder *builder;
50843ec0f41SMaxim Mikityanskiy 	int err, final_err;
50943ec0f41SMaxim Mikityanskiy 	unsigned int ix;
51043ec0f41SMaxim Mikityanskiy 
51143ec0f41SMaxim Mikityanskiy 	builder = mlx5e_tir_builder_alloc(true);
51243ec0f41SMaxim Mikityanskiy 	if (!builder)
51343ec0f41SMaxim Mikityanskiy 		return -ENOMEM;
51443ec0f41SMaxim Mikityanskiy 
51543ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_build_lro(builder, lro_param);
51643ec0f41SMaxim Mikityanskiy 
51743ec0f41SMaxim Mikityanskiy 	final_err = 0;
51843ec0f41SMaxim Mikityanskiy 
519*25307a91STariq Toukan 	err = mlx5e_rss_lro_set_param(rss, lro_param);
520*25307a91STariq Toukan 	if (err)
521*25307a91STariq Toukan 		final_err = final_err ? : err;
52243ec0f41SMaxim Mikityanskiy 
52343ec0f41SMaxim Mikityanskiy 	for (ix = 0; ix < res->max_nch; ix++) {
52443ec0f41SMaxim Mikityanskiy 		err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder);
52543ec0f41SMaxim Mikityanskiy 		if (err) {
52643ec0f41SMaxim Mikityanskiy 			mlx5_core_warn(res->mdev, "Failed to update LRO state of direct TIR %#x for channel %u: err = %d\n",
52743ec0f41SMaxim Mikityanskiy 				       mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err);
52843ec0f41SMaxim Mikityanskiy 			if (!final_err)
52943ec0f41SMaxim Mikityanskiy 				final_err = err;
53043ec0f41SMaxim Mikityanskiy 		}
53143ec0f41SMaxim Mikityanskiy 	}
53243ec0f41SMaxim Mikityanskiy 
53343ec0f41SMaxim Mikityanskiy 	mlx5e_tir_builder_free(builder);
53443ec0f41SMaxim Mikityanskiy 	return final_err;
53543ec0f41SMaxim Mikityanskiy }
53643ec0f41SMaxim Mikityanskiy 
53743ec0f41SMaxim Mikityanskiy struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res)
53843ec0f41SMaxim Mikityanskiy {
539*25307a91STariq Toukan 	return mlx5e_rss_get_hash(res->rss);
54043ec0f41SMaxim Mikityanskiy }
541