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