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