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_packet_merge_param * init_pkt_merge_param,bool inner)128 static int mlx5e_rss_create_tir(struct mlx5e_rss *rss,
129 enum mlx5_traffic_types tt,
130 const struct mlx5e_packet_merge_param *init_pkt_merge_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_packet_merge(builder, init_pkt_merge_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_packet_merge_param * init_pkt_merge_param,bool inner)200 static int mlx5e_rss_create_tirs(struct mlx5e_rss *rss,
201 const struct mlx5e_packet_merge_param *init_pkt_merge_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_pkt_merge_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_packet_merge_param * init_pkt_merge_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_packet_merge_param *init_pkt_merge_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_pkt_merge_param, false);
309 if (err)
310 goto err_destroy_rqt;
311
312 if (inner_ft_support) {
313 err = mlx5e_rss_create_tirs(rss, init_pkt_merge_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_packet_merge_param * init_pkt_merge_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_packet_merge_param *init_pkt_merge_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_pkt_merge_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 int 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 return err;
403 }
404
mlx5e_rss_enable(struct mlx5e_rss * rss,u32 * rqns,unsigned int num_rqns)405 void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, unsigned int num_rqns)
406 {
407 rss->enabled = true;
408 mlx5e_rss_apply(rss, rqns, num_rqns);
409 }
410
mlx5e_rss_disable(struct mlx5e_rss * rss)411 void mlx5e_rss_disable(struct mlx5e_rss *rss)
412 {
413 int err;
414
415 rss->enabled = false;
416 err = mlx5e_rqt_redirect_direct(&rss->rqt, rss->drop_rqn);
417 if (err)
418 mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to drop RQ %#x: err = %d\n",
419 mlx5e_rqt_get_rqtn(&rss->rqt), rss->drop_rqn, err);
420 }
421
mlx5e_rss_packet_merge_set_param(struct mlx5e_rss * rss,struct mlx5e_packet_merge_param * pkt_merge_param)422 int mlx5e_rss_packet_merge_set_param(struct mlx5e_rss *rss,
423 struct mlx5e_packet_merge_param *pkt_merge_param)
424 {
425 struct mlx5e_tir_builder *builder;
426 enum mlx5_traffic_types tt;
427 int err, final_err;
428
429 builder = mlx5e_tir_builder_alloc(true);
430 if (!builder)
431 return -ENOMEM;
432
433 mlx5e_tir_builder_build_packet_merge(builder, pkt_merge_param);
434
435 final_err = 0;
436
437 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
438 struct mlx5e_tir *tir;
439
440 tir = rss_get_tir(rss, tt, false);
441 if (!tir)
442 goto inner_tir;
443 err = mlx5e_tir_modify(tir, builder);
444 if (err) {
445 mlx5e_rss_warn(rss->mdev, "Failed to update packet merge state of indirect TIR %#x for traffic type %d: err = %d\n",
446 mlx5e_tir_get_tirn(tir), tt, err);
447 if (!final_err)
448 final_err = err;
449 }
450
451 inner_tir:
452 if (!rss->inner_ft_support)
453 continue;
454
455 tir = rss_get_tir(rss, tt, true);
456 if (!tir)
457 continue;
458 err = mlx5e_tir_modify(tir, builder);
459 if (err) {
460 mlx5e_rss_warn(rss->mdev, "Failed to update packet merge state of inner indirect TIR %#x for traffic type %d: err = %d\n",
461 mlx5e_tir_get_tirn(tir), tt, err);
462 if (!final_err)
463 final_err = err;
464 }
465 }
466
467 mlx5e_tir_builder_free(builder);
468 return final_err;
469 }
470
mlx5e_rss_get_rxfh(struct mlx5e_rss * rss,u32 * indir,u8 * key,u8 * hfunc)471 int mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc)
472 {
473 unsigned int i;
474
475 if (indir)
476 for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++)
477 indir[i] = rss->indir.table[i];
478
479 if (key)
480 memcpy(key, rss->hash.toeplitz_hash_key,
481 sizeof(rss->hash.toeplitz_hash_key));
482
483 if (hfunc)
484 *hfunc = rss->hash.hfunc;
485
486 return 0;
487 }
488
mlx5e_rss_set_rxfh(struct mlx5e_rss * rss,const u32 * indir,const u8 * key,const u8 * hfunc,u32 * rqns,unsigned int num_rqns)489 int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir,
490 const u8 *key, const u8 *hfunc,
491 u32 *rqns, unsigned int num_rqns)
492 {
493 bool changed_indir = false;
494 bool changed_hash = false;
495 struct mlx5e_rss *old_rss;
496 int err = 0;
497
498 old_rss = mlx5e_rss_alloc();
499 if (!old_rss)
500 return -ENOMEM;
501
502 *old_rss = *rss;
503
504 if (hfunc && *hfunc != rss->hash.hfunc) {
505 switch (*hfunc) {
506 case ETH_RSS_HASH_XOR:
507 case ETH_RSS_HASH_TOP:
508 break;
509 default:
510 err = -EINVAL;
511 goto out;
512 }
513 changed_hash = true;
514 changed_indir = true;
515 rss->hash.hfunc = *hfunc;
516 }
517
518 if (key) {
519 if (rss->hash.hfunc == ETH_RSS_HASH_TOP)
520 changed_hash = true;
521 memcpy(rss->hash.toeplitz_hash_key, key,
522 sizeof(rss->hash.toeplitz_hash_key));
523 }
524
525 if (indir) {
526 unsigned int i;
527
528 changed_indir = true;
529
530 for (i = 0; i < MLX5E_INDIR_RQT_SIZE; i++)
531 rss->indir.table[i] = indir[i];
532 }
533
534 if (changed_indir && rss->enabled) {
535 err = mlx5e_rss_apply(rss, rqns, num_rqns);
536 if (err) {
537 *rss = *old_rss;
538 goto out;
539 }
540 }
541
542 if (changed_hash)
543 mlx5e_rss_update_tirs(rss);
544
545 out:
546 mlx5e_rss_free(old_rss);
547 return err;
548 }
549
mlx5e_rss_get_hash(struct mlx5e_rss * rss)550 struct mlx5e_rss_params_hash mlx5e_rss_get_hash(struct mlx5e_rss *rss)
551 {
552 return rss->hash;
553 }
554
mlx5e_rss_get_hash_fields(struct mlx5e_rss * rss,enum mlx5_traffic_types tt)555 u8 mlx5e_rss_get_hash_fields(struct mlx5e_rss *rss, enum mlx5_traffic_types tt)
556 {
557 return rss->rx_hash_fields[tt];
558 }
559
mlx5e_rss_set_hash_fields(struct mlx5e_rss * rss,enum mlx5_traffic_types tt,u8 rx_hash_fields)560 int mlx5e_rss_set_hash_fields(struct mlx5e_rss *rss, enum mlx5_traffic_types tt,
561 u8 rx_hash_fields)
562 {
563 u8 old_rx_hash_fields;
564 int err;
565
566 old_rx_hash_fields = rss->rx_hash_fields[tt];
567
568 if (old_rx_hash_fields == rx_hash_fields)
569 return 0;
570
571 rss->rx_hash_fields[tt] = rx_hash_fields;
572
573 err = mlx5e_rss_update_tir(rss, tt, false);
574 if (err) {
575 rss->rx_hash_fields[tt] = old_rx_hash_fields;
576 mlx5e_rss_warn(rss->mdev,
577 "Failed to update RSS hash fields of indirect TIR for traffic type %d: err = %d\n",
578 tt, err);
579 return err;
580 }
581
582 if (!(rss->inner_ft_support))
583 return 0;
584
585 err = mlx5e_rss_update_tir(rss, tt, true);
586 if (err) {
587 /* Partial update happened. Try to revert - it may fail too, but
588 * there is nothing more we can do.
589 */
590 rss->rx_hash_fields[tt] = old_rx_hash_fields;
591 mlx5e_rss_warn(rss->mdev,
592 "Failed to update RSS hash fields of inner indirect TIR for traffic type %d: err = %d\n",
593 tt, err);
594 if (mlx5e_rss_update_tir(rss, tt, false))
595 mlx5e_rss_warn(rss->mdev,
596 "Partial update of RSS hash fields happened: failed to revert indirect TIR for traffic type %d to the old values\n",
597 tt);
598 }
599
600 return err;
601 }
602
mlx5e_rss_set_indir_uniform(struct mlx5e_rss * rss,unsigned int nch)603 void mlx5e_rss_set_indir_uniform(struct mlx5e_rss *rss, unsigned int nch)
604 {
605 mlx5e_rss_params_indir_init_uniform(&rss->indir, nch);
606 }
607