1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 // Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES.
3
4 #include "rss.h"
5
6 #define mlx5e_rss_warn(__dev, format, ...) \
7 dev_warn((__dev)->device, "%s:%d:(pid %d): " format, \
8 __func__, __LINE__, current->pid, \
9 ##__VA_ARGS__)
10
11 static const struct mlx5e_rss_params_traffic_type rss_default_config[MLX5E_NUM_INDIR_TIRS] = {
12 [MLX5_TT_IPV4_TCP] = {
13 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
14 .l4_prot_type = MLX5_L4_PROT_TYPE_TCP,
15 .rx_hash_fields = MLX5_HASH_IP_L4PORTS,
16 },
17 [MLX5_TT_IPV6_TCP] = {
18 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
19 .l4_prot_type = MLX5_L4_PROT_TYPE_TCP,
20 .rx_hash_fields = MLX5_HASH_IP_L4PORTS,
21 },
22 [MLX5_TT_IPV4_UDP] = {
23 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
24 .l4_prot_type = MLX5_L4_PROT_TYPE_UDP,
25 .rx_hash_fields = MLX5_HASH_IP_L4PORTS,
26 },
27 [MLX5_TT_IPV6_UDP] = {
28 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
29 .l4_prot_type = MLX5_L4_PROT_TYPE_UDP,
30 .rx_hash_fields = MLX5_HASH_IP_L4PORTS,
31 },
32 [MLX5_TT_IPV4_IPSEC_AH] = {
33 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
34 .l4_prot_type = 0,
35 .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
36 },
37 [MLX5_TT_IPV6_IPSEC_AH] = {
38 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
39 .l4_prot_type = 0,
40 .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
41 },
42 [MLX5_TT_IPV4_IPSEC_ESP] = {
43 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
44 .l4_prot_type = 0,
45 .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
46 },
47 [MLX5_TT_IPV6_IPSEC_ESP] = {
48 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
49 .l4_prot_type = 0,
50 .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
51 },
52 [MLX5_TT_IPV4] = {
53 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
54 .l4_prot_type = 0,
55 .rx_hash_fields = MLX5_HASH_IP,
56 },
57 [MLX5_TT_IPV6] = {
58 .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
59 .l4_prot_type = 0,
60 .rx_hash_fields = MLX5_HASH_IP,
61 },
62 };
63
64 struct mlx5e_rss_params_traffic_type
mlx5e_rss_get_default_tt_config(enum mlx5_traffic_types tt)65 mlx5e_rss_get_default_tt_config(enum mlx5_traffic_types tt)
66 {
67 return rss_default_config[tt];
68 }
69
70 struct mlx5e_rss {
71 struct mlx5e_rss_params_hash hash;
72 struct mlx5e_rss_params_indir indir;
73 u32 rx_hash_fields[MLX5E_NUM_INDIR_TIRS];
74 struct mlx5e_tir *tir[MLX5E_NUM_INDIR_TIRS];
75 struct mlx5e_tir *inner_tir[MLX5E_NUM_INDIR_TIRS];
76 struct mlx5e_rqt rqt;
77 struct mlx5_core_dev *mdev;
78 u32 drop_rqn;
79 bool inner_ft_support;
80 bool enabled;
81 refcount_t refcnt;
82 };
83
mlx5e_rss_alloc(void)84 struct mlx5e_rss *mlx5e_rss_alloc(void)
85 {
86 return kvzalloc(sizeof(struct mlx5e_rss), GFP_KERNEL);
87 }
88
mlx5e_rss_free(struct mlx5e_rss * rss)89 void mlx5e_rss_free(struct mlx5e_rss *rss)
90 {
91 kvfree(rss);
92 }
93
mlx5e_rss_params_init(struct mlx5e_rss * rss)94 static void mlx5e_rss_params_init(struct mlx5e_rss *rss)
95 {
96 enum mlx5_traffic_types tt;
97
98 rss->hash.hfunc = ETH_RSS_HASH_TOP;
99 netdev_rss_key_fill(rss->hash.toeplitz_hash_key,
100 sizeof(rss->hash.toeplitz_hash_key));
101 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
102 rss->rx_hash_fields[tt] =
103 mlx5e_rss_get_default_tt_config(tt).rx_hash_fields;
104 }
105
rss_get_tirp(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,bool inner)106 static struct mlx5e_tir **rss_get_tirp(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
107 bool inner)
108 {
109 return inner ? &rss->inner_tir[tt] : &rss->tir[tt];
110 }
111
rss_get_tir(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,bool inner)112 static struct mlx5e_tir *rss_get_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
113 bool inner)
114 {
115 return *rss_get_tirp(rss, tt, inner);
116 }
117
118 static struct mlx5e_rss_params_traffic_type
mlx5e_rss_get_tt_config(struct mlx5e_rss * rss,enum mlx5_traffic_types tt)119 mlx5e_rss_get_tt_config(struct mlx5e_rss *rss, enum mlx5_traffic_types tt)
120 {
121 struct mlx5e_rss_params_traffic_type rss_tt;
122
123 rss_tt = mlx5e_rss_get_default_tt_config(tt);
124 rss_tt.rx_hash_fields = rss->rx_hash_fields[tt];
125 return rss_tt;
126 }
127
mlx5e_rss_create_tir(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,const struct mlx5e_lro_param * init_lro_param,bool inner)128 static int mlx5e_rss_create_tir(struct mlx5e_rss *rss,
129 enum mlx5_traffic_types tt,
130 const struct mlx5e_lro_param *init_lro_param,
131 bool inner)
132 {
133 struct mlx5e_rss_params_traffic_type rss_tt;
134 struct mlx5e_tir_builder *builder;
135 struct mlx5e_tir **tir_p;
136 struct mlx5e_tir *tir;
137 u32 rqtn;
138 int err;
139
140 if (inner && !rss->inner_ft_support) {
141 mlx5e_rss_warn(rss->mdev,
142 "Cannot create inner indirect TIR[%d], RSS inner FT is not supported.\n",
143 tt);
144 return -EINVAL;
145 }
146
147 tir_p = rss_get_tirp(rss, tt, inner);
148 if (*tir_p)
149 return -EINVAL;
150
151 tir = kvzalloc(sizeof(*tir), GFP_KERNEL);
152 if (!tir)
153 return -ENOMEM;
154
155 builder = mlx5e_tir_builder_alloc(false);
156 if (!builder) {
157 err = -ENOMEM;
158 goto free_tir;
159 }
160
161 rqtn = mlx5e_rqt_get_rqtn(&rss->rqt);
162 mlx5e_tir_builder_build_rqt(builder, rss->mdev->mlx5e_res.hw_objs.td.tdn,
163 rqtn, rss->inner_ft_support);
164 mlx5e_tir_builder_build_lro(builder, init_lro_param);
165 rss_tt = mlx5e_rss_get_tt_config(rss, tt);
166 mlx5e_tir_builder_build_rss(builder, &rss->hash, &rss_tt, inner);
167
168 err = mlx5e_tir_init(tir, builder, rss->mdev, true);
169 mlx5e_tir_builder_free(builder);
170 if (err) {
171 mlx5e_rss_warn(rss->mdev, "Failed to create %sindirect TIR: err = %d, tt = %d\n",
172 inner ? "inner " : "", err, tt);
173 goto free_tir;
174 }
175
176 *tir_p = tir;
177 return 0;
178
179 free_tir:
180 kvfree(tir);
181 return err;
182 }
183
mlx5e_rss_destroy_tir(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,bool inner)184 static void mlx5e_rss_destroy_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
185 bool inner)
186 {
187 struct mlx5e_tir **tir_p;
188 struct mlx5e_tir *tir;
189
190 tir_p = rss_get_tirp(rss, tt, inner);
191 if (!*tir_p)
192 return;
193
194 tir = *tir_p;
195 mlx5e_tir_destroy(tir);
196 kvfree(tir);
197 *tir_p = NULL;
198 }
199
mlx5e_rss_create_tirs(struct mlx5e_rss * rss,const struct mlx5e_lro_param * init_lro_param,bool inner)200 static int mlx5e_rss_create_tirs(struct mlx5e_rss *rss,
201 const struct mlx5e_lro_param *init_lro_param,
202 bool inner)
203 {
204 enum mlx5_traffic_types tt, max_tt;
205 int err;
206
207 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
208 err = mlx5e_rss_create_tir(rss, tt, init_lro_param, inner);
209 if (err)
210 goto err_destroy_tirs;
211 }
212
213 return 0;
214
215 err_destroy_tirs:
216 max_tt = tt;
217 for (tt = 0; tt < max_tt; tt++)
218 mlx5e_rss_destroy_tir(rss, tt, inner);
219 return err;
220 }
221
mlx5e_rss_destroy_tirs(struct mlx5e_rss * rss,bool inner)222 static void mlx5e_rss_destroy_tirs(struct mlx5e_rss *rss, bool inner)
223 {
224 enum mlx5_traffic_types tt;
225
226 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
227 mlx5e_rss_destroy_tir(rss, tt, inner);
228 }
229
mlx5e_rss_update_tir(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,bool inner)230 static int mlx5e_rss_update_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
231 bool inner)
232 {
233 struct mlx5e_rss_params_traffic_type rss_tt;
234 struct mlx5e_tir_builder *builder;
235 struct mlx5e_tir *tir;
236 int err;
237
238 tir = rss_get_tir(rss, tt, inner);
239 if (!tir)
240 return 0;
241
242 builder = mlx5e_tir_builder_alloc(true);
243 if (!builder)
244 return -ENOMEM;
245
246 rss_tt = mlx5e_rss_get_tt_config(rss, tt);
247
248 mlx5e_tir_builder_build_rss(builder, &rss->hash, &rss_tt, inner);
249 err = mlx5e_tir_modify(tir, builder);
250
251 mlx5e_tir_builder_free(builder);
252 return err;
253 }
254
mlx5e_rss_update_tirs(struct mlx5e_rss * rss)255 static int mlx5e_rss_update_tirs(struct mlx5e_rss *rss)
256 {
257 enum mlx5_traffic_types tt;
258 int err, retval;
259
260 retval = 0;
261
262 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
263 err = mlx5e_rss_update_tir(rss, tt, false);
264 if (err) {
265 retval = retval ? : err;
266 mlx5e_rss_warn(rss->mdev,
267 "Failed to update RSS hash of indirect TIR for traffic type %d: err = %d\n",
268 tt, err);
269 }
270
271 if (!rss->inner_ft_support)
272 continue;
273
274 err = mlx5e_rss_update_tir(rss, tt, true);
275 if (err) {
276 retval = retval ? : err;
277 mlx5e_rss_warn(rss->mdev,
278 "Failed to update RSS hash of inner indirect TIR for traffic type %d: err = %d\n",
279 tt, err);
280 }
281 }
282 return retval;
283 }
284
mlx5e_rss_init_no_tirs(struct mlx5e_rss * rss,struct mlx5_core_dev * mdev,bool inner_ft_support,u32 drop_rqn)285 int mlx5e_rss_init_no_tirs(struct mlx5e_rss *rss, struct mlx5_core_dev *mdev,
286 bool inner_ft_support, u32 drop_rqn)
287 {
288 rss->mdev = mdev;
289 rss->inner_ft_support = inner_ft_support;
290 rss->drop_rqn = drop_rqn;
291
292 mlx5e_rss_params_init(rss);
293 refcount_set(&rss->refcnt, 1);
294
295 return mlx5e_rqt_init_direct(&rss->rqt, mdev, true, drop_rqn);
296 }
297
mlx5e_rss_init(struct mlx5e_rss * rss,struct mlx5_core_dev * mdev,bool inner_ft_support,u32 drop_rqn,const struct mlx5e_lro_param * init_lro_param)298 int mlx5e_rss_init(struct mlx5e_rss *rss, struct mlx5_core_dev *mdev,
299 bool inner_ft_support, u32 drop_rqn,
300 const struct mlx5e_lro_param *init_lro_param)
301 {
302 int err;
303
304 err = mlx5e_rss_init_no_tirs(rss, mdev, inner_ft_support, drop_rqn);
305 if (err)
306 goto err_out;
307
308 err = mlx5e_rss_create_tirs(rss, init_lro_param, false);
309 if (err)
310 goto err_destroy_rqt;
311
312 if (inner_ft_support) {
313 err = mlx5e_rss_create_tirs(rss, init_lro_param, true);
314 if (err)
315 goto err_destroy_tirs;
316 }
317
318 return 0;
319
320 err_destroy_tirs:
321 mlx5e_rss_destroy_tirs(rss, false);
322 err_destroy_rqt:
323 mlx5e_rqt_destroy(&rss->rqt);
324 err_out:
325 return err;
326 }
327
mlx5e_rss_cleanup(struct mlx5e_rss * rss)328 int mlx5e_rss_cleanup(struct mlx5e_rss *rss)
329 {
330 if (!refcount_dec_if_one(&rss->refcnt))
331 return -EBUSY;
332
333 mlx5e_rss_destroy_tirs(rss, false);
334
335 if (rss->inner_ft_support)
336 mlx5e_rss_destroy_tirs(rss, true);
337
338 mlx5e_rqt_destroy(&rss->rqt);
339
340 return 0;
341 }
342
mlx5e_rss_refcnt_inc(struct mlx5e_rss * rss)343 void mlx5e_rss_refcnt_inc(struct mlx5e_rss *rss)
344 {
345 refcount_inc(&rss->refcnt);
346 }
347
mlx5e_rss_refcnt_dec(struct mlx5e_rss * rss)348 void mlx5e_rss_refcnt_dec(struct mlx5e_rss *rss)
349 {
350 refcount_dec(&rss->refcnt);
351 }
352
mlx5e_rss_refcnt_read(struct mlx5e_rss * rss)353 unsigned int mlx5e_rss_refcnt_read(struct mlx5e_rss *rss)
354 {
355 return refcount_read(&rss->refcnt);
356 }
357
mlx5e_rss_get_tirn(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,bool inner)358 u32 mlx5e_rss_get_tirn(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
359 bool inner)
360 {
361 struct mlx5e_tir *tir;
362
363 WARN_ON(inner && !rss->inner_ft_support);
364 tir = rss_get_tir(rss, tt, inner);
365 WARN_ON(!tir);
366
367 return mlx5e_tir_get_tirn(tir);
368 }
369
370 /* Fill the "tirn" output parameter.
371 * Create the requested TIR if it's its first usage.
372 */
mlx5e_rss_obtain_tirn(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,const struct mlx5e_lro_param * init_lro_param,bool inner,u32 * tirn)373 int mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss,
374 enum mlx5_traffic_types tt,
375 const struct mlx5e_lro_param *init_lro_param,
376 bool inner, u32 *tirn)
377 {
378 struct mlx5e_tir *tir;
379
380 tir = rss_get_tir(rss, tt, inner);
381 if (!tir) { /* TIR doesn't exist, create one */
382 int err;
383
384 err = mlx5e_rss_create_tir(rss, tt, init_lro_param, inner);
385 if (err)
386 return err;
387 tir = rss_get_tir(rss, tt, inner);
388 }
389
390 *tirn = mlx5e_tir_get_tirn(tir);
391 return 0;
392 }
393
mlx5e_rss_apply(struct mlx5e_rss * rss,u32 * rqns,unsigned int num_rqns)394 static void mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
395 {
396 int err;
397
398 err = mlx5e_rqt_redirect_indir(&rss->rqt, rqns, num_rqns, rss->hash.hfunc, &rss->indir);
399 if (err)
400 mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to channels: err = %d\n",
401 mlx5e_rqt_get_rqtn(&rss->rqt), err);
402 }
403
mlx5e_rss_enable(struct mlx5e_rss * rss,u32 * rqns,unsigned int num_rqns)404 void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
405 {
406 rss->enabled = true;
407 mlx5e_rss_apply(rss, rqns, num_rqns);
408 }
409
mlx5e_rss_disable(struct mlx5e_rss * rss)410 void mlx5e_rss_disable(struct mlx5e_rss *rss)
411 {
412 int err;
413
414 rss->enabled = false;
415 err = mlx5e_rqt_redirect_direct(&rss->rqt, rss->drop_rqn);
416 if (err)
417 mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to drop RQ %#x: err = %d\n",
418 mlx5e_rqt_get_rqtn(&rss->rqt), rss->drop_rqn, err);
419 }
420
mlx5e_rss_lro_set_param(struct mlx5e_rss * rss,struct mlx5e_lro_param * lro_param)421 int mlx5e_rss_lro_set_param(struct mlx5e_rss *rss, struct mlx5e_lro_param *lro_param)
422 {
423 struct mlx5e_tir_builder *builder;
424 enum mlx5_traffic_types tt;
425 int err, final_err;
426
427 builder = mlx5e_tir_builder_alloc(true);
428 if (!builder)
429 return -ENOMEM;
430
431 mlx5e_tir_builder_build_lro(builder, lro_param);
432
433 final_err = 0;
434
435 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
436 struct mlx5e_tir *tir;
437
438 tir = rss_get_tir(rss, tt, false);
439 if (!tir)
440 goto inner_tir;
441 err = mlx5e_tir_modify(tir, builder);
442 if (err) {
443 mlx5e_rss_warn(rss->mdev, "Failed to update LRO state of indirect TIR %#x for traffic type %d: err = %d\n",
444 mlx5e_tir_get_tirn(tir), tt, err);
445 if (!final_err)
446 final_err = err;
447 }
448
449 inner_tir:
450 if (!rss->inner_ft_support)
451 continue;
452
453 tir = rss_get_tir(rss, tt, true);
454 if (!tir)
455 continue;
456 err = mlx5e_tir_modify(tir, builder);
457 if (err) {
458 mlx5e_rss_warn(rss->mdev, "Failed to update LRO state of inner indirect TIR %#x for traffic type %d: err = %d\n",
459 mlx5e_tir_get_tirn(tir), tt, err);
460 if (!final_err)
461 final_err = err;
462 }
463 }
464
465 mlx5e_tir_builder_free(builder);
466 return final_err;
467 }
468
mlx5e_rss_get_rxfh(struct mlx5e_rss * rss,u32 * indir,u8 * key,u8 * hfunc)469 int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc)
470 {
471 unsigned int i;
472
473 if (indir)
474 for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++)
475 indir[i] = rss->indir.table[i];
476
477 if (key)
478 memcpy(key, rss->hash.toeplitz_hash_key,
479 sizeof(rss->hash.toeplitz_hash_key));
480
481 if (hfunc)
482 *hfunc = rss->hash.hfunc;
483
484 return 0;
485 }
486
mlx5e_rss_set_rxfh(struct mlx5e_rss * rss,const u32 * indir,const u8 * key,const u8 * hfunc,u32 * rqns,unsigned int num_rqns)487 int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
488 const u8 *key, const u8 *hfunc,
489 u32 *rqns, unsigned int num_rqns)
490 {
491 bool changed_indir = false;
492 bool changed_hash = false;
493
494 if (hfunc && *hfunc != rss->hash.hfunc) {
495 switch (*hfunc) {
496 case ETH_RSS_HASH_XOR:
497 case ETH_RSS_HASH_TOP:
498 break;
499 default:
500 return -EINVAL;
501 }
502 changed_hash = true;
503 changed_indir = true;
504 rss->hash.hfunc = *hfunc;
505 }
506
507 if (key) {
508 if (rss->hash.hfunc == ETH_RSS_HASH_TOP)
509 changed_hash = true;
510 memcpy(rss->hash.toeplitz_hash_key, key,
511 sizeof(rss->hash.toeplitz_hash_key));
512 }
513
514 if (indir) {
515 unsigned int i;
516
517 changed_indir = true;
518
519 for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++)
520 rss->indir.table[i] = indir[i];
521 }
522
523 if (changed_indir && rss->enabled)
524 mlx5e_rss_apply(rss, rqns, num_rqns);
525
526 if (changed_hash)
527 mlx5e_rss_update_tirs(rss);
528
529 return 0;
530 }
531
mlx5e_rss_get_hash(struct mlx5e_rss * rss)532 struct mlx5e_rss_params_hash mlx5e_rss_get_hash(struct mlx5e_rss *rss)
533 {
534 return rss->hash;
535 }
536
mlx5e_rss_get_hash_fields(struct mlx5e_rss * rss,enum mlx5_traffic_types tt)537 u8 mlx5e_rss_get_hash_fields(struct mlx5e_rss *rss, enum mlx5_traffic_types tt)
538 {
539 return rss->rx_hash_fields[tt];
540 }
541
mlx5e_rss_set_hash_fields(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,u8 rx_hash_fields)542 int mlx5e_rss_set_hash_fields(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
543 u8 rx_hash_fields)
544 {
545 u8 old_rx_hash_fields;
546 int err;
547
548 old_rx_hash_fields = rss->rx_hash_fields[tt];
549
550 if (old_rx_hash_fields == rx_hash_fields)
551 return 0;
552
553 rss->rx_hash_fields[tt] = rx_hash_fields;
554
555 err = mlx5e_rss_update_tir(rss, tt, false);
556 if (err) {
557 rss->rx_hash_fields[tt] = old_rx_hash_fields;
558 mlx5e_rss_warn(rss->mdev,
559 "Failed to update RSS hash fields of indirect TIR for traffic type %d: err = %d\n",
560 tt, err);
561 return err;
562 }
563
564 if (!(rss->inner_ft_support))
565 return 0;
566
567 err = mlx5e_rss_update_tir(rss, tt, true);
568 if (err) {
569 /* Partial update happened. Try to revert - it may fail too, but
570 * there is nothing more we can do.
571 */
572 rss->rx_hash_fields[tt] = old_rx_hash_fields;
573 mlx5e_rss_warn(rss->mdev,
574 "Failed to update RSS hash fields of inner indirect TIR for traffic type %d: err = %d\n",
575 tt, err);
576 if (mlx5e_rss_update_tir(rss, tt, false))
577 mlx5e_rss_warn(rss->mdev,
578 "Partial update of RSS hash fields happened: failed to revert indirect TIR for traffic type %d to the old values\n",
579 tt);
580 }
581
582 return err;
583 }
584
mlx5e_rss_set_indir_uniform(struct mlx5e_rss * rss,unsigned int nch)585 void mlx5e_rss_set_indir_uniform(struct mlx5e_rss *rss, unsigned int nch)
586 {
587 mlx5e_rss_params_indir_init_uniform(&rss->indir, nch);
588 }
589