FILE
rss.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c
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 11static 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 64struct mlx5e_rss_params_traffic_type 65mlx5e_rss_get_default_tt_config(enum mlx5_traffic_types tt) 66{ 67 return rss_default_config[tt]; 68} 69 70struct 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; /* primary */ 78 struct mlx5e_rss_params params; 79 bool enabled; 80 refcount_t refcnt; 81}; 82 83bool mlx5e_rss_get_inner_ft_support(struct mlx5e_rss *rss) 84{ 85 return rss->params.inner_ft_support; 86} 87 88void mlx5e_rss_params_indir_modify_actual_size(struct mlx5e_rss *rss, u32 num_channels) 89{ 90 rss->indir.actual_table_size = mlx5e_rqt_size(rss->mdev, num_channels); 91} 92 93int mlx5e_rss_params_indir_init(struct mlx5e_rss_params_indir *indir, 94 u32 actual_table_size, u32 max_table_size) 95{ 96 indir->table = kvmalloc_array(max_table_size, sizeof(*indir->table), GFP_KERNEL); 97 if (!indir->table) 98 return -ENOMEM; 99 100 indir->max_table_size = max_table_size; 101 indir->actual_table_size = actual_table_size; 102 103 return 0; 104} 105 106void mlx5e_rss_params_indir_cleanup(struct mlx5e_rss_params_indir *indir) 107{ 108 kvfree(indir->table); 109} 110 111static int mlx5e_rss_copy(struct mlx5e_rss *to, const struct mlx5e_rss *from) 112{ 113 u32 *dst_indir_table; 114 115 if (to->indir.actual_table_size != from->indir.actual_table_size || 116 to->indir.max_table_size != from->indir.max_table_size) { 117 mlx5e_rss_warn(to->mdev, 118 "Failed to copy RSS due to size mismatch, src (actual %u, max %u) != dst (actual %u, max %u)\n", 119 from->indir.actual_table_size, from->indir.max_table_size, 120 to->indir.actual_table_size, to->indir.max_table_size); 121 return -EINVAL; 122 } 123 124 dst_indir_table = to->indir.table; 125 *to = *from; 126 to->indir.table = dst_indir_table; 127 memcpy(to->indir.table, from->indir.table, 128 from->indir.actual_table_size * sizeof(*from->indir.table)); 129 return 0; 130} 131 132static struct mlx5e_rss *mlx5e_rss_init_copy(const struct mlx5e_rss *from) 133{ 134 struct mlx5e_rss *rss; 135 int err; 136 137 rss = kvzalloc(sizeof(*rss), GFP_KERNEL); 138 if (!rss) 139 return ERR_PTR(-ENOMEM); 140 141 err = mlx5e_rss_params_indir_init(&rss->indir, 142 from->indir.actual_table_size, 143 from->indir.max_table_size); 144 if (err) 145 goto err_free_rss; 146 147 err = mlx5e_rss_copy(rss, from); 148 if (err) 149 goto err_free_indir; 150 151 return rss; 152 153err_free_indir: 154 mlx5e_rss_params_indir_cleanup(&rss->indir); 155err_free_rss: 156 kvfree(rss); 157 return ERR_PTR(err); 158} 159 160static void mlx5e_rss_params_init(struct mlx5e_rss *rss) 161{ 162 enum mlx5_traffic_types tt; 163 164 rss->hash.symmetric = true; 165 rss->hash.hfunc = ETH_RSS_HASH_TOP; 166 netdev_rss_key_fill(rss->hash.toeplitz_hash_key, 167 sizeof(rss->hash.toeplitz_hash_key)); 168 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) 169 rss->rx_hash_fields[tt] = 170 mlx5e_rss_get_default_tt_config(tt).rx_hash_fields; 171} 172 173static struct mlx5e_tir **rss_get_tirp(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, 174 bool inner) 175{ 176 return inner ? &rss->inner_tir[tt] : &rss->tir[tt]; 177} 178 179static struct mlx5e_tir *rss_get_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, 180 bool inner) 181{ 182 return *rss_get_tirp(rss, tt, inner); 183} 184 185static struct mlx5e_rss_params_traffic_type 186mlx5e_rss_get_tt_config(struct mlx5e_rss *rss, enum mlx5_traffic_types tt) 187{ 188 struct mlx5e_rss_params_traffic_type rss_tt; 189 190 rss_tt = mlx5e_rss_get_default_tt_config(tt); 191 rss_tt.rx_hash_fields = rss->rx_hash_fields[tt]; 192 return rss_tt; 193} 194 195static int 196mlx5e_rss_create_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, 197 const struct mlx5e_packet_merge_param *pkt_merge_param, 198 bool inner) 199{ 200 bool rss_inner = rss->params.inner_ft_support; 201 struct mlx5e_rss_params_traffic_type rss_tt; 202 struct mlx5e_tir_builder *builder; 203 struct mlx5e_tir **tir_p; 204 struct mlx5e_tir *tir; 205 u32 rqtn; 206 int err; 207 208 if (inner && !rss_inner) { 209 mlx5e_rss_warn(rss->mdev, 210 "Cannot create inner indirect TIR[%d], RSS inner FT is not supported.\n", 211 tt); 212 return -EINVAL; 213 } 214 215 tir_p = rss_get_tirp(rss, tt, inner); 216 if (*tir_p) 217 return -EINVAL; 218 219 tir = kvzalloc(sizeof(*tir), GFP_KERNEL); 220 if (!tir) 221 return -ENOMEM; 222 223 builder = mlx5e_tir_builder_alloc(false); 224 if (!builder) { 225 err = -ENOMEM; 226 goto free_tir; 227 } 228 229 rqtn = mlx5e_rqt_get_rqtn(&rss->rqt); 230 mlx5e_tir_builder_build_rqt(builder, rss->mdev->mlx5e_res.hw_objs.td.tdn, 231 rqtn, rss_inner); 232 mlx5e_tir_builder_build_packet_merge(builder, pkt_merge_param); 233 rss_tt = mlx5e_rss_get_tt_config(rss, tt); 234 mlx5e_tir_builder_build_self_lb_block(builder, rss->params.self_lb_blk, 235 rss->params.self_lb_blk); 236 mlx5e_tir_builder_build_rss(builder, &rss->hash, &rss_tt, inner); 237 238 err = mlx5e_tir_init(tir, builder, rss->mdev, true); 239 mlx5e_tir_builder_free(builder); 240 if (err) { 241 mlx5e_rss_warn(rss->mdev, "Failed to create %sindirect TIR: err = %d, tt = %d\n", 242 inner ? "inner " : "", err, tt); 243 goto free_tir; 244 } 245 246 *tir_p = tir; 247 return 0; 248 249free_tir: 250 kvfree(tir); 251 return err; 252} 253 254static void mlx5e_rss_destroy_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, 255 bool inner) 256{ 257 struct mlx5e_tir **tir_p; 258 struct mlx5e_tir *tir; 259 260 tir_p = rss_get_tirp(rss, tt, inner); 261 if (!*tir_p) 262 return; 263 264 tir = *tir_p; 265 mlx5e_tir_destroy(tir); 266 kvfree(tir); 267 *tir_p = NULL; 268} 269 270static int 271mlx5e_rss_create_tirs(struct mlx5e_rss *rss, 272 const struct mlx5e_packet_merge_param *pkt_merge_param, 273 bool inner) 274{ 275 enum mlx5_traffic_types tt, max_tt; 276 int err; 277 278 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 279 err = mlx5e_rss_create_tir(rss, tt, pkt_merge_param, inner); 280 if (err) 281 goto err_destroy_tirs; 282 } 283 284 return 0; 285 286err_destroy_tirs: 287 max_tt = tt; 288 for (tt = 0; tt < max_tt; tt++) 289 mlx5e_rss_destroy_tir(rss, tt, inner); 290 return err; 291} 292 293static void mlx5e_rss_destroy_tirs(struct mlx5e_rss *rss, bool inner) 294{ 295 enum mlx5_traffic_types tt; 296 297 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) 298 mlx5e_rss_destroy_tir(rss, tt, inner); 299} 300 301static int mlx5e_rss_update_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, 302 bool inner) 303{ 304 struct mlx5e_rss_params_traffic_type rss_tt; 305 struct mlx5e_tir_builder *builder; 306 struct mlx5e_tir *tir; 307 int err; 308 309 tir = rss_get_tir(rss, tt, inner); 310 if (!tir) 311 return 0; 312 313 builder = mlx5e_tir_builder_alloc(true); 314 if (!builder) 315 return -ENOMEM; 316 317 rss_tt = mlx5e_rss_get_tt_config(rss, tt); 318 319 mlx5e_tir_builder_build_rss(builder, &rss->hash, &rss_tt, inner); 320 err = mlx5e_tir_modify(tir, builder); 321 322 mlx5e_tir_builder_free(builder); 323 return err; 324} 325 326static int mlx5e_rss_update_tirs(struct mlx5e_rss *rss) 327{ 328 enum mlx5_traffic_types tt; 329 int err, retval; 330 331 retval = 0; 332 333 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 334 err = mlx5e_rss_update_tir(rss, tt, false); 335 if (err) { 336 retval = retval ? : err; 337 mlx5e_rss_warn(rss->mdev, 338 "Failed to update RSS hash of indirect TIR for traffic type %d: err = %d\n", 339 tt, err); 340 } 341 342 if (!rss->params.inner_ft_support) 343 continue; 344 345 err = mlx5e_rss_update_tir(rss, tt, true); 346 if (err) { 347 retval = retval ? : err; 348 mlx5e_rss_warn(rss->mdev, 349 "Failed to update RSS hash of inner indirect TIR for traffic type %d: err = %d\n", 350 tt, err); 351 } 352 } 353 return retval; 354} 355 356static int mlx5e_rss_init_no_tirs(struct mlx5e_rss *rss) 357{ 358 mlx5e_rss_params_init(rss); 359 refcount_set(&rss->refcnt, 1); 360 361 return mlx5e_rqt_init_direct(&rss->rqt, rss->mdev, true, 362 rss->params.drop_rqn, 363 rss->indir.max_table_size); 364} 365 366struct mlx5e_rss * 367mlx5e_rss_init(struct mlx5_core_dev *mdev, 368 const struct mlx5e_rss_params *params, 369 const struct mlx5e_rss_init_params *init_params) 370{ 371 u32 rqt_max_size, rqt_size; 372 struct mlx5e_rss *rss; 373 int err; 374 375 rss = kvzalloc(sizeof(*rss), GFP_KERNEL); 376 if (!rss) 377 return ERR_PTR(-ENOMEM); 378 379 rqt_size = mlx5e_rqt_size(mdev, init_params->nch); 380 rqt_max_size = mlx5e_rqt_size(mdev, init_params->max_nch); 381 err = mlx5e_rss_params_indir_init(&rss->indir, rqt_size, rqt_max_size); 382 if (err) 383 goto err_free_rss; 384 385 rss->mdev = mdev; 386 rss->params = *params; 387 388 err = mlx5e_rss_init_no_tirs(rss); 389 if (err) 390 goto err_free_indir; 391 392 if (init_params->type == MLX5E_RSS_INIT_NO_TIRS) 393 goto out; 394 395 err = mlx5e_rss_create_tirs(rss, init_params->pkt_merge_param, 396 false); 397 if (err) 398 goto err_destroy_rqt; 399 400 if (params->inner_ft_support) { 401 err = mlx5e_rss_create_tirs(rss, 402 init_params->pkt_merge_param, 403 true); 404 if (err) 405 goto err_destroy_tirs; 406 } 407 408out: 409 return rss; 410 411err_destroy_tirs: 412 mlx5e_rss_destroy_tirs(rss, false); 413err_destroy_rqt: 414 mlx5e_rqt_destroy(&rss->rqt); 415err_free_indir: 416 mlx5e_rss_params_indir_cleanup(&rss->indir); 417err_free_rss: 418 kvfree(rss); 419 return ERR_PTR(err); 420} 421 422int mlx5e_rss_cleanup(struct mlx5e_rss *rss) 423{ 424 if (!refcount_dec_if_one(&rss->refcnt)) 425 return -EBUSY; 426 427 mlx5e_rss_destroy_tirs(rss, false); 428 429 if (rss->params.inner_ft_support) 430 mlx5e_rss_destroy_tirs(rss, true); 431 432 mlx5e_rqt_destroy(&rss->rqt); 433 mlx5e_rss_params_indir_cleanup(&rss->indir); 434 kvfree(rss); 435 436 return 0; 437} 438 439void mlx5e_rss_refcnt_inc(struct mlx5e_rss *rss) 440{ 441 refcount_inc(&rss->refcnt); 442} 443 444void mlx5e_rss_refcnt_dec(struct mlx5e_rss *rss) 445{ 446 refcount_dec(&rss->refcnt); 447} 448 449unsigned int mlx5e_rss_refcnt_read(struct mlx5e_rss *rss) 450{ 451 return refcount_read(&rss->refcnt); 452} 453 454u32 mlx5e_rss_get_tirn(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, 455 bool inner) 456{ 457 struct mlx5e_tir *tir; 458 459 WARN_ON(inner && !rss->params.inner_ft_support); 460 tir = rss_get_tir(rss, tt, inner); 461 WARN_ON(!tir); 462 463 return mlx5e_tir_get_tirn(tir); 464} 465 466u32 mlx5e_rss_get_rqtn(struct mlx5e_rss *rss) 467{ 468 return mlx5e_rqt_get_rqtn(&rss->rqt); 469} 470 471bool mlx5e_rss_valid_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, bool inner) 472{ 473 return !!rss_get_tir(rss, tt, inner); 474} 475 476/* Fill the "tirn" output parameter. 477 * Create the requested TIR if it's its first usage. 478 */ 479int 480mlx5e_rss_obtain_tirn(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, 481 const struct mlx5e_packet_merge_param *pkt_merge_param, 482 bool inner, u32 *tirn) 483{ 484 struct mlx5e_tir *tir; 485 486 tir = rss_get_tir(rss, tt, inner); 487 if (!tir) { /* TIR doesn't exist, create one */ 488 int err; 489 490 err = mlx5e_rss_create_tir(rss, tt, pkt_merge_param, inner); 491 if (err) 492 return err; 493 tir = rss_get_tir(rss, tt, inner); 494 } 495 496 *tirn = mlx5e_tir_get_tirn(tir); 497 return 0; 498} 499 500static int mlx5e_rss_apply(struct mlx5e_rss *rss, u32 *rqns, u32 *vhca_ids, unsigned int num_rqns) 501{ 502 int err; 503 504 err = mlx5e_rqt_redirect_indir(&rss->rqt, rqns, vhca_ids, num_rqns, rss->hash.hfunc, 505 &rss->indir); 506 if (err) 507 mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to channels: err = %d\n", 508 mlx5e_rqt_get_rqtn(&rss->rqt), err); 509 return err; 510} 511 512void mlx5e_rss_enable(struct mlx5e_rss *rss, u32 *rqns, u32 *vhca_ids, unsigned int num_rqns) 513{ 514 rss->enabled = true; 515 mlx5e_rss_apply(rss, rqns, vhca_ids, num_rqns); 516} 517 518void mlx5e_rss_disable(struct mlx5e_rss *rss) 519{ 520 int err; 521 522 rss->enabled = false; 523 err = mlx5e_rqt_redirect_direct(&rss->rqt, rss->params.drop_rqn, NULL); 524 if (err) 525 mlx5e_rss_warn(rss->mdev, "Failed to redirect RQT %#x to drop RQ %#x: err = %d\n", 526 mlx5e_rqt_get_rqtn(&rss->rqt), 527 rss->params.drop_rqn, err); 528} 529 530int mlx5e_rss_packet_merge_set_param(struct mlx5e_rss *rss, 531 struct mlx5e_packet_merge_param *pkt_merge_param) 532{ 533 struct mlx5e_tir_builder *builder; 534 enum mlx5_traffic_types tt; 535 int err, final_err; 536 537 builder = mlx5e_tir_builder_alloc(true); 538 if (!builder) 539 return -ENOMEM; 540 541 mlx5e_tir_builder_build_packet_merge(builder, pkt_merge_param); 542 543 final_err = 0; 544 545 for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) { 546 struct mlx5e_tir *tir; 547 548 tir = rss_get_tir(rss, tt, false); 549 if (!tir) 550 goto inner_tir; 551 err = mlx5e_tir_modify(tir, builder); 552 if (err) { 553 mlx5e_rss_warn(rss->mdev, "Failed to update packet merge state of indirect TIR %#x for traffic type %d: err = %d\n", 554 mlx5e_tir_get_tirn(tir), tt, err); 555 if (!final_err) 556 final_err = err; 557 } 558 559inner_tir: 560 if (!rss->params.inner_ft_support) 561 continue; 562 563 tir = rss_get_tir(rss, tt, true); 564 if (!tir) 565 continue; 566 err = mlx5e_tir_modify(tir, builder); 567 if (err) { 568 mlx5e_rss_warn(rss->mdev, "Failed to update packet merge state of inner indirect TIR %#x for traffic type %d: err = %d\n", 569 mlx5e_tir_get_tirn(tir), tt, err); 570 if (!final_err) 571 final_err = err; 572 } 573 } 574 575 mlx5e_tir_builder_free(builder); 576 return final_err; 577} 578 579void mlx5e_rss_get_rxfh(struct mlx5e_rss *rss, u32 *indir, u8 *key, u8 *hfunc, 580 bool *symmetric) 581{ 582 if (indir) 583 memcpy(indir, rss->indir.table, 584 rss->indir.actual_table_size * sizeof(*rss->indir.table)); 585 586 if (key) 587 memcpy(key, rss->hash.toeplitz_hash_key, 588 sizeof(rss->hash.toeplitz_hash_key)); 589 590 if (hfunc) 591 *hfunc = rss->hash.hfunc; 592 593 if (symmetric) 594 *symmetric = rss->hash.symmetric; 595} 596 597int mlx5e_rss_set_rxfh(struct mlx5e_rss *rss, const u32 *indir, 598 const u8 *key, const u8 *hfunc, const bool *symmetric, 599 u32 *rqns, u32 *vhca_ids, unsigned int num_rqns) 600{ 601 bool changed_indir = false; 602 bool changed_hash = false; 603 struct mlx5e_rss *old_rss; 604 int err = 0; 605 606 old_rss = mlx5e_rss_init_copy(rss); 607 if (IS_ERR(old_rss)) 608 return PTR_ERR(old_rss); 609 610 if (hfunc && *hfunc != rss->hash.hfunc) { 611 switch (*hfunc) { 612 case ETH_RSS_HASH_XOR: 613 case ETH_RSS_HASH_TOP: 614 break; 615 default: 616 err = -EINVAL; 617 goto out; 618 } 619 changed_hash = true; 620 changed_indir = true; 621 rss->hash.hfunc = *hfunc; 622 } 623 624 if (key) { 625 if (rss->hash.hfunc == ETH_RSS_HASH_TOP) 626 changed_hash = true; 627 memcpy(rss->hash.toeplitz_hash_key, key, 628 sizeof(rss->hash.toeplitz_hash_key)); 629 } 630 631 if (indir) { 632 changed_indir = true; 633 634 memcpy(rss->indir.table, indir, 635 rss->indir.actual_table_size * sizeof(*rss->indir.table)); 636 } 637 638 if (symmetric) { 639 rss->hash.symmetric = *symmetric; 640 changed_hash = true; 641 } 642 643 if (changed_indir && rss->enabled) { 644 err = mlx5e_rss_apply(rss, rqns, vhca_ids, num_rqns); 645 if (err) { 646 mlx5e_rss_copy(rss, old_rss); 647 goto out; 648 } 649 } 650 651 if (changed_hash) 652 mlx5e_rss_update_tirs(rss); 653 654out: 655 mlx5e_rss_params_indir_cleanup(&old_rss->indir); 656 kvfree(old_rss); 657 658 return err; 659} 660 661struct mlx5e_rss_params_hash mlx5e_rss_get_hash(struct mlx5e_rss *rss) 662{ 663 return rss->hash; 664} 665 666u8 mlx5e_rss_get_hash_fields(struct mlx5e_rss *rss, enum mlx5_traffic_types tt) 667{ 668 return rss->rx_hash_fields[tt]; 669} 670 671int mlx5e_rss_set_hash_fields(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, 672 u8 rx_hash_fields) 673{ 674 u8 old_rx_hash_fields; 675 int err; 676 677 old_rx_hash_fields = rss->rx_hash_fields[tt]; 678 679 if (old_rx_hash_fields == rx_hash_fields) 680 return 0; 681 682 rss->rx_hash_fields[tt] = rx_hash_fields; 683 684 err = mlx5e_rss_update_tir(rss, tt, false); 685 if (err) { 686 rss->rx_hash_fields[tt] = old_rx_hash_fields; 687 mlx5e_rss_warn(rss->mdev, 688 "Failed to update RSS hash fields of indirect TIR for traffic type %d: err = %d\n", 689 tt, err); 690 return err; 691 } 692 693 if (!(rss->params.inner_ft_support)) 694 return 0; 695 696 err = mlx5e_rss_update_tir(rss, tt, true); 697 if (err) { 698 /* Partial update happened. Try to revert - it may fail too, but 699 * there is nothing more we can do. 700 */ 701 rss->rx_hash_fields[tt] = old_rx_hash_fields; 702 mlx5e_rss_warn(rss->mdev, 703 "Failed to update RSS hash fields of inner indirect TIR for traffic type %d: err = %d\n", 704 tt, err); 705 if (mlx5e_rss_update_tir(rss, tt, false)) 706 mlx5e_rss_warn(rss->mdev, 707 "Partial update of RSS hash fields happened: failed to revert indirect TIR for traffic type %d to the old values\n", 708 tt); 709 } 710 711 return err; 712} 713 714void mlx5e_rss_set_indir_uniform(struct mlx5e_rss *rss, unsigned int nch) 715{ 716 mlx5e_rss_params_indir_init_uniform(&rss->indir, nch); 717}
~/
Read-only file preview.