1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2021, Mellanox Technologies inc. All rights reserved. */
3
4 #include "rx_res.h"
5 #include "channels.h"
6 #include "params.h"
7
8 #define MLX5E_MAX_NUM_RSS 16
9
10 struct mlx5e_rx_res {
11 struct mlx5_core_dev *mdev;
12 enum mlx5e_rx_res_features features;
13 unsigned int max_nch;
14 u32 drop_rqn;
15
16 struct mlx5e_rss *rss[MLX5E_MAX_NUM_RSS];
17 bool rss_active;
18 u32 rss_rqns[MLX5E_INDIR_RQT_SIZE];
19 unsigned int rss_nch;
20
21 struct {
22 struct mlx5e_rqt direct_rqt;
23 struct mlx5e_tir direct_tir;
24 struct mlx5e_rqt xsk_rqt;
25 struct mlx5e_tir xsk_tir;
26 } *channels;
27
28 struct {
29 struct mlx5e_rqt rqt;
30 struct mlx5e_tir tir;
31 } ptp;
32 };
33
34 /* API for rx_res_rss_* */
35
mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res * res,const struct mlx5e_lro_param * init_lro_param,unsigned int init_nch)36 static int mlx5e_rx_res_rss_init_def(struct mlx5e_rx_res *res,
37 const struct mlx5e_lro_param *init_lro_param,
38 unsigned int init_nch)
39 {
40 bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
41 struct mlx5e_rss *rss;
42 int err;
43
44 if (WARN_ON(res->rss[0]))
45 return -EINVAL;
46
47 rss = mlx5e_rss_alloc();
48 if (!rss)
49 return -ENOMEM;
50
51 err = mlx5e_rss_init(rss, res->mdev, inner_ft_support, res->drop_rqn,
52 init_lro_param);
53 if (err)
54 goto err_rss_free;
55
56 mlx5e_rss_set_indir_uniform(rss, init_nch);
57
58 res->rss[0] = rss;
59
60 return 0;
61
62 err_rss_free:
63 mlx5e_rss_free(rss);
64 return err;
65 }
66
mlx5e_rx_res_rss_init(struct mlx5e_rx_res * res,u32 * rss_idx,unsigned int init_nch)67 int mlx5e_rx_res_rss_init(struct mlx5e_rx_res *res, u32 *rss_idx, unsigned int init_nch)
68 {
69 bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
70 struct mlx5e_rss *rss;
71 int err, i;
72
73 for (i = 1; i < MLX5E_MAX_NUM_RSS; i++)
74 if (!res->rss[i])
75 break;
76
77 if (i == MLX5E_MAX_NUM_RSS)
78 return -ENOSPC;
79
80 rss = mlx5e_rss_alloc();
81 if (!rss)
82 return -ENOMEM;
83
84 err = mlx5e_rss_init_no_tirs(rss, res->mdev, inner_ft_support, res->drop_rqn);
85 if (err)
86 goto err_rss_free;
87
88 mlx5e_rss_set_indir_uniform(rss, init_nch);
89 if (res->rss_active)
90 mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch);
91
92 res->rss[i] = rss;
93 *rss_idx = i;
94
95 return 0;
96
97 err_rss_free:
98 mlx5e_rss_free(rss);
99 return err;
100 }
101
__mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res * res,u32 rss_idx)102 static int __mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx)
103 {
104 struct mlx5e_rss *rss = res->rss[rss_idx];
105 int err;
106
107 err = mlx5e_rss_cleanup(rss);
108 if (err)
109 return err;
110
111 mlx5e_rss_free(rss);
112 res->rss[rss_idx] = NULL;
113
114 return 0;
115 }
116
mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res * res,u32 rss_idx)117 int mlx5e_rx_res_rss_destroy(struct mlx5e_rx_res *res, u32 rss_idx)
118 {
119 struct mlx5e_rss *rss;
120
121 if (rss_idx >= MLX5E_MAX_NUM_RSS)
122 return -EINVAL;
123
124 rss = res->rss[rss_idx];
125 if (!rss)
126 return -EINVAL;
127
128 return __mlx5e_rx_res_rss_destroy(res, rss_idx);
129 }
130
mlx5e_rx_res_rss_destroy_all(struct mlx5e_rx_res * res)131 static void mlx5e_rx_res_rss_destroy_all(struct mlx5e_rx_res *res)
132 {
133 int i;
134
135 for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
136 struct mlx5e_rss *rss = res->rss[i];
137 int err;
138
139 if (!rss)
140 continue;
141
142 err = __mlx5e_rx_res_rss_destroy(res, i);
143 if (err) {
144 unsigned int refcount;
145
146 refcount = mlx5e_rss_refcnt_read(rss);
147 mlx5_core_warn(res->mdev,
148 "Failed to destroy RSS context %d, refcount = %u, err = %d\n",
149 i, refcount, err);
150 }
151 }
152 }
153
mlx5e_rx_res_rss_enable(struct mlx5e_rx_res * res)154 static void mlx5e_rx_res_rss_enable(struct mlx5e_rx_res *res)
155 {
156 int i;
157
158 res->rss_active = true;
159
160 for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
161 struct mlx5e_rss *rss = res->rss[i];
162
163 if (!rss)
164 continue;
165 mlx5e_rss_enable(rss, res->rss_rqns, res->rss_nch);
166 }
167 }
168
mlx5e_rx_res_rss_disable(struct mlx5e_rx_res * res)169 static void mlx5e_rx_res_rss_disable(struct mlx5e_rx_res *res)
170 {
171 int i;
172
173 res->rss_active = false;
174
175 for (i = 0; i < MLX5E_MAX_NUM_RSS; i++) {
176 struct mlx5e_rss *rss = res->rss[i];
177
178 if (!rss)
179 continue;
180 mlx5e_rss_disable(rss);
181 }
182 }
183
184 /* Updates the indirection table SW shadow, does not update the HW resources yet */
mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res * res,unsigned int nch)185 void mlx5e_rx_res_rss_set_indir_uniform(struct mlx5e_rx_res *res, unsigned int nch)
186 {
187 WARN_ON_ONCE(res->rss_active);
188 mlx5e_rss_set_indir_uniform(res->rss[0], nch);
189 }
190
mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res * res,u32 rss_idx,u32 * indir,u8 * key,u8 * hfunc)191 int mlx5e_rx_res_rss_get_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
192 u32 *indir, u8 *key, u8 *hfunc)
193 {
194 struct mlx5e_rss *rss;
195
196 if (rss_idx >= MLX5E_MAX_NUM_RSS)
197 return -EINVAL;
198
199 rss = res->rss[rss_idx];
200 if (!rss)
201 return -ENOENT;
202
203 return mlx5e_rss_get_rxfh(rss, indir, key, hfunc);
204 }
205
mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res * res,u32 rss_idx,const u32 * indir,const u8 * key,const u8 * hfunc)206 int mlx5e_rx_res_rss_set_rxfh(struct mlx5e_rx_res *res, u32 rss_idx,
207 const u32 *indir, const u8 *key, const u8 *hfunc)
208 {
209 struct mlx5e_rss *rss;
210
211 if (rss_idx >= MLX5E_MAX_NUM_RSS)
212 return -EINVAL;
213
214 rss = res->rss[rss_idx];
215 if (!rss)
216 return -ENOENT;
217
218 return mlx5e_rss_set_rxfh(rss, indir, key, hfunc, res->rss_rqns, res->rss_nch);
219 }
220
mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res * res,enum mlx5_traffic_types tt)221 u8 mlx5e_rx_res_rss_get_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
222 {
223 struct mlx5e_rss *rss = res->rss[0];
224
225 return mlx5e_rss_get_hash_fields(rss, tt);
226 }
227
mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res * res,enum mlx5_traffic_types tt,u8 rx_hash_fields)228 int mlx5e_rx_res_rss_set_hash_fields(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt,
229 u8 rx_hash_fields)
230 {
231 struct mlx5e_rss *rss = res->rss[0];
232
233 return mlx5e_rss_set_hash_fields(rss, tt, rx_hash_fields);
234 }
235
mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res * res)236 int mlx5e_rx_res_rss_cnt(struct mlx5e_rx_res *res)
237 {
238 int i, cnt;
239
240 cnt = 0;
241 for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
242 if (res->rss[i])
243 cnt++;
244
245 return cnt;
246 }
247
mlx5e_rx_res_rss_index(struct mlx5e_rx_res * res,struct mlx5e_rss * rss)248 int mlx5e_rx_res_rss_index(struct mlx5e_rx_res *res, struct mlx5e_rss *rss)
249 {
250 int i;
251
252 if (!rss)
253 return -EINVAL;
254
255 for (i = 0; i < MLX5E_MAX_NUM_RSS; i++)
256 if (rss == res->rss[i])
257 return i;
258
259 return -ENOENT;
260 }
261
mlx5e_rx_res_rss_get(struct mlx5e_rx_res * res,u32 rss_idx)262 struct mlx5e_rss *mlx5e_rx_res_rss_get(struct mlx5e_rx_res *res, u32 rss_idx)
263 {
264 if (rss_idx >= MLX5E_MAX_NUM_RSS)
265 return NULL;
266
267 return res->rss[rss_idx];
268 }
269
270 /* End of API rx_res_rss_* */
271
mlx5e_rx_res_alloc(void)272 struct mlx5e_rx_res *mlx5e_rx_res_alloc(void)
273 {
274 return kvzalloc(sizeof(struct mlx5e_rx_res), GFP_KERNEL);
275 }
276
mlx5e_rx_res_channels_init(struct mlx5e_rx_res * res,const struct mlx5e_lro_param * init_lro_param)277 static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res,
278 const struct mlx5e_lro_param *init_lro_param)
279 {
280 bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
281 struct mlx5e_tir_builder *builder;
282 int err = 0;
283 int ix;
284
285 builder = mlx5e_tir_builder_alloc(false);
286 if (!builder)
287 return -ENOMEM;
288
289 res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL);
290 if (!res->channels) {
291 err = -ENOMEM;
292 goto out;
293 }
294
295 for (ix = 0; ix < res->max_nch; ix++) {
296 err = mlx5e_rqt_init_direct(&res->channels[ix].direct_rqt,
297 res->mdev, false, res->drop_rqn);
298 if (err) {
299 mlx5_core_warn(res->mdev, "Failed to create a direct RQT: err = %d, ix = %u\n",
300 err, ix);
301 goto err_destroy_direct_rqts;
302 }
303 }
304
305 for (ix = 0; ix < res->max_nch; ix++) {
306 mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
307 mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
308 inner_ft_support);
309 mlx5e_tir_builder_build_lro(builder, init_lro_param);
310 mlx5e_tir_builder_build_direct(builder);
311
312 err = mlx5e_tir_init(&res->channels[ix].direct_tir, builder, res->mdev, true);
313 if (err) {
314 mlx5_core_warn(res->mdev, "Failed to create a direct TIR: err = %d, ix = %u\n",
315 err, ix);
316 goto err_destroy_direct_tirs;
317 }
318
319 mlx5e_tir_builder_clear(builder);
320 }
321
322 if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
323 goto out;
324
325 for (ix = 0; ix < res->max_nch; ix++) {
326 err = mlx5e_rqt_init_direct(&res->channels[ix].xsk_rqt,
327 res->mdev, false, res->drop_rqn);
328 if (err) {
329 mlx5_core_warn(res->mdev, "Failed to create an XSK RQT: err = %d, ix = %u\n",
330 err, ix);
331 goto err_destroy_xsk_rqts;
332 }
333 }
334
335 for (ix = 0; ix < res->max_nch; ix++) {
336 mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
337 mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
338 inner_ft_support);
339 mlx5e_tir_builder_build_lro(builder, init_lro_param);
340 mlx5e_tir_builder_build_direct(builder);
341
342 err = mlx5e_tir_init(&res->channels[ix].xsk_tir, builder, res->mdev, true);
343 if (err) {
344 mlx5_core_warn(res->mdev, "Failed to create an XSK TIR: err = %d, ix = %u\n",
345 err, ix);
346 goto err_destroy_xsk_tirs;
347 }
348
349 mlx5e_tir_builder_clear(builder);
350 }
351
352 goto out;
353
354 err_destroy_xsk_tirs:
355 while (--ix >= 0)
356 mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
357
358 ix = res->max_nch;
359 err_destroy_xsk_rqts:
360 while (--ix >= 0)
361 mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
362
363 ix = res->max_nch;
364 err_destroy_direct_tirs:
365 while (--ix >= 0)
366 mlx5e_tir_destroy(&res->channels[ix].direct_tir);
367
368 ix = res->max_nch;
369 err_destroy_direct_rqts:
370 while (--ix >= 0)
371 mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
372
373 kvfree(res->channels);
374
375 out:
376 mlx5e_tir_builder_free(builder);
377
378 return err;
379 }
380
mlx5e_rx_res_ptp_init(struct mlx5e_rx_res * res)381 static int mlx5e_rx_res_ptp_init(struct mlx5e_rx_res *res)
382 {
383 bool inner_ft_support = res->features & MLX5E_RX_RES_FEATURE_INNER_FT;
384 struct mlx5e_tir_builder *builder;
385 int err;
386
387 builder = mlx5e_tir_builder_alloc(false);
388 if (!builder)
389 return -ENOMEM;
390
391 err = mlx5e_rqt_init_direct(&res->ptp.rqt, res->mdev, false, res->drop_rqn);
392 if (err)
393 goto out;
394
395 mlx5e_tir_builder_build_rqt(builder, res->mdev->mlx5e_res.hw_objs.td.tdn,
396 mlx5e_rqt_get_rqtn(&res->ptp.rqt),
397 inner_ft_support);
398 mlx5e_tir_builder_build_direct(builder);
399
400 err = mlx5e_tir_init(&res->ptp.tir, builder, res->mdev, true);
401 if (err)
402 goto err_destroy_ptp_rqt;
403
404 goto out;
405
406 err_destroy_ptp_rqt:
407 mlx5e_rqt_destroy(&res->ptp.rqt);
408
409 out:
410 mlx5e_tir_builder_free(builder);
411 return err;
412 }
413
mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res * res)414 static void mlx5e_rx_res_channels_destroy(struct mlx5e_rx_res *res)
415 {
416 unsigned int ix;
417
418 for (ix = 0; ix < res->max_nch; ix++) {
419 mlx5e_tir_destroy(&res->channels[ix].direct_tir);
420 mlx5e_rqt_destroy(&res->channels[ix].direct_rqt);
421
422 if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
423 continue;
424
425 mlx5e_tir_destroy(&res->channels[ix].xsk_tir);
426 mlx5e_rqt_destroy(&res->channels[ix].xsk_rqt);
427 }
428
429 kvfree(res->channels);
430 }
431
mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res * res)432 static void mlx5e_rx_res_ptp_destroy(struct mlx5e_rx_res *res)
433 {
434 mlx5e_tir_destroy(&res->ptp.tir);
435 mlx5e_rqt_destroy(&res->ptp.rqt);
436 }
437
mlx5e_rx_res_init(struct mlx5e_rx_res * res,struct mlx5_core_dev * mdev,enum mlx5e_rx_res_features features,unsigned int max_nch,u32 drop_rqn,const struct mlx5e_lro_param * init_lro_param,unsigned int init_nch)438 int mlx5e_rx_res_init(struct mlx5e_rx_res *res, struct mlx5_core_dev *mdev,
439 enum mlx5e_rx_res_features features, unsigned int max_nch,
440 u32 drop_rqn, const struct mlx5e_lro_param *init_lro_param,
441 unsigned int init_nch)
442 {
443 int err;
444
445 res->mdev = mdev;
446 res->features = features;
447 res->max_nch = max_nch;
448 res->drop_rqn = drop_rqn;
449
450 err = mlx5e_rx_res_rss_init_def(res, init_lro_param, init_nch);
451 if (err)
452 goto err_out;
453
454 err = mlx5e_rx_res_channels_init(res, init_lro_param);
455 if (err)
456 goto err_rss_destroy;
457
458 err = mlx5e_rx_res_ptp_init(res);
459 if (err)
460 goto err_channels_destroy;
461
462 return 0;
463
464 err_channels_destroy:
465 mlx5e_rx_res_channels_destroy(res);
466 err_rss_destroy:
467 __mlx5e_rx_res_rss_destroy(res, 0);
468 err_out:
469 return err;
470 }
471
mlx5e_rx_res_destroy(struct mlx5e_rx_res * res)472 void mlx5e_rx_res_destroy(struct mlx5e_rx_res *res)
473 {
474 mlx5e_rx_res_ptp_destroy(res);
475 mlx5e_rx_res_channels_destroy(res);
476 mlx5e_rx_res_rss_destroy_all(res);
477 }
478
mlx5e_rx_res_free(struct mlx5e_rx_res * res)479 void mlx5e_rx_res_free(struct mlx5e_rx_res *res)
480 {
481 kvfree(res);
482 }
483
mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res * res,unsigned int ix)484 u32 mlx5e_rx_res_get_tirn_direct(struct mlx5e_rx_res *res, unsigned int ix)
485 {
486 return mlx5e_tir_get_tirn(&res->channels[ix].direct_tir);
487 }
488
mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res * res,unsigned int ix)489 u32 mlx5e_rx_res_get_tirn_xsk(struct mlx5e_rx_res *res, unsigned int ix)
490 {
491 WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_XSK));
492
493 return mlx5e_tir_get_tirn(&res->channels[ix].xsk_tir);
494 }
495
mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res * res,enum mlx5_traffic_types tt)496 u32 mlx5e_rx_res_get_tirn_rss(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
497 {
498 struct mlx5e_rss *rss = res->rss[0];
499
500 return mlx5e_rss_get_tirn(rss, tt, false);
501 }
502
mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res * res,enum mlx5_traffic_types tt)503 u32 mlx5e_rx_res_get_tirn_rss_inner(struct mlx5e_rx_res *res, enum mlx5_traffic_types tt)
504 {
505 struct mlx5e_rss *rss = res->rss[0];
506
507 return mlx5e_rss_get_tirn(rss, tt, true);
508 }
509
mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res * res)510 u32 mlx5e_rx_res_get_tirn_ptp(struct mlx5e_rx_res *res)
511 {
512 WARN_ON(!(res->features & MLX5E_RX_RES_FEATURE_PTP));
513 return mlx5e_tir_get_tirn(&res->ptp.tir);
514 }
515
mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res * res,unsigned int ix)516 u32 mlx5e_rx_res_get_rqtn_direct(struct mlx5e_rx_res *res, unsigned int ix)
517 {
518 return mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt);
519 }
520
mlx5e_rx_res_channels_activate(struct mlx5e_rx_res * res,struct mlx5e_channels * chs)521 void mlx5e_rx_res_channels_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs)
522 {
523 unsigned int nch, ix;
524 int err;
525
526 nch = mlx5e_channels_get_num(chs);
527
528 for (ix = 0; ix < chs->num; ix++)
529 mlx5e_channels_get_regular_rqn(chs, ix, &res->rss_rqns[ix]);
530 res->rss_nch = chs->num;
531
532 mlx5e_rx_res_rss_enable(res);
533
534 for (ix = 0; ix < nch; ix++) {
535 u32 rqn;
536
537 mlx5e_channels_get_regular_rqn(chs, ix, &rqn);
538 err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, rqn);
539 if (err)
540 mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (channel %u): err = %d\n",
541 mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
542 rqn, ix, err);
543
544 if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
545 continue;
546
547 if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
548 rqn = res->drop_rqn;
549 err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
550 if (err)
551 mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to RQ %#x (channel %u): err = %d\n",
552 mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
553 rqn, ix, err);
554 }
555 for (ix = nch; ix < res->max_nch; ix++) {
556 err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
557 if (err)
558 mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
559 mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
560 res->drop_rqn, ix, err);
561
562 if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
563 continue;
564
565 err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
566 if (err)
567 mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
568 mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
569 res->drop_rqn, ix, err);
570 }
571
572 if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
573 u32 rqn;
574
575 if (!mlx5e_channels_get_ptp_rqn(chs, &rqn))
576 rqn = res->drop_rqn;
577
578 err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, rqn);
579 if (err)
580 mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to RQ %#x (PTP): err = %d\n",
581 mlx5e_rqt_get_rqtn(&res->ptp.rqt),
582 rqn, err);
583 }
584 }
585
mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res * res)586 void mlx5e_rx_res_channels_deactivate(struct mlx5e_rx_res *res)
587 {
588 unsigned int ix;
589 int err;
590
591 mlx5e_rx_res_rss_disable(res);
592
593 for (ix = 0; ix < res->max_nch; ix++) {
594 err = mlx5e_rqt_redirect_direct(&res->channels[ix].direct_rqt, res->drop_rqn);
595 if (err)
596 mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (channel %u): err = %d\n",
597 mlx5e_rqt_get_rqtn(&res->channels[ix].direct_rqt),
598 res->drop_rqn, ix, err);
599
600 if (!(res->features & MLX5E_RX_RES_FEATURE_XSK))
601 continue;
602
603 err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
604 if (err)
605 mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
606 mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
607 res->drop_rqn, ix, err);
608 }
609
610 if (res->features & MLX5E_RX_RES_FEATURE_PTP) {
611 err = mlx5e_rqt_redirect_direct(&res->ptp.rqt, res->drop_rqn);
612 if (err)
613 mlx5_core_warn(res->mdev, "Failed to redirect direct RQT %#x to drop RQ %#x (PTP): err = %d\n",
614 mlx5e_rqt_get_rqtn(&res->ptp.rqt),
615 res->drop_rqn, err);
616 }
617 }
618
mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res * res,struct mlx5e_channels * chs,unsigned int ix)619 int mlx5e_rx_res_xsk_activate(struct mlx5e_rx_res *res, struct mlx5e_channels *chs,
620 unsigned int ix)
621 {
622 u32 rqn;
623 int err;
624
625 if (!mlx5e_channels_get_xsk_rqn(chs, ix, &rqn))
626 return -EINVAL;
627
628 err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, rqn);
629 if (err)
630 mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to XSK RQ %#x (channel %u): err = %d\n",
631 mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
632 rqn, ix, err);
633 return err;
634 }
635
mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res * res,unsigned int ix)636 int mlx5e_rx_res_xsk_deactivate(struct mlx5e_rx_res *res, unsigned int ix)
637 {
638 int err;
639
640 err = mlx5e_rqt_redirect_direct(&res->channels[ix].xsk_rqt, res->drop_rqn);
641 if (err)
642 mlx5_core_warn(res->mdev, "Failed to redirect XSK RQT %#x to drop RQ %#x (channel %u): err = %d\n",
643 mlx5e_rqt_get_rqtn(&res->channels[ix].xsk_rqt),
644 res->drop_rqn, ix, err);
645 return err;
646 }
647
mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res * res,struct mlx5e_lro_param * lro_param)648 int mlx5e_rx_res_lro_set_param(struct mlx5e_rx_res *res, struct mlx5e_lro_param *lro_param)
649 {
650 struct mlx5e_tir_builder *builder;
651 int err, final_err;
652 unsigned int ix;
653
654 builder = mlx5e_tir_builder_alloc(true);
655 if (!builder)
656 return -ENOMEM;
657
658 mlx5e_tir_builder_build_lro(builder, lro_param);
659
660 final_err = 0;
661
662 for (ix = 0; ix < MLX5E_MAX_NUM_RSS; ix++) {
663 struct mlx5e_rss *rss = res->rss[ix];
664
665 if (!rss)
666 continue;
667
668 err = mlx5e_rss_lro_set_param(rss, lro_param);
669 if (err)
670 final_err = final_err ? : err;
671 }
672
673 for (ix = 0; ix < res->max_nch; ix++) {
674 err = mlx5e_tir_modify(&res->channels[ix].direct_tir, builder);
675 if (err) {
676 mlx5_core_warn(res->mdev, "Failed to update LRO state of direct TIR %#x for channel %u: err = %d\n",
677 mlx5e_tir_get_tirn(&res->channels[ix].direct_tir), ix, err);
678 if (!final_err)
679 final_err = err;
680 }
681 }
682
683 mlx5e_tir_builder_free(builder);
684 return final_err;
685 }
686
mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res * res)687 struct mlx5e_rss_params_hash mlx5e_rx_res_get_current_hash(struct mlx5e_rx_res *res)
688 {
689 return mlx5e_rss_get_hash(res->rss[0]);
690 }
691