1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2020 Amazon.com, Inc. or its affiliates. 3 * All rights reserved. 4 */ 5 6 #include "ena_ethdev.h" 7 #include "ena_logs.h" 8 9 #include <ena_admin_defs.h> 10 11 #define TEST_BIT(val, bit_shift) ((val) & (1UL << (bit_shift))) 12 13 #define ENA_HF_RSS_ALL_L2 (ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA) 14 #define ENA_HF_RSS_ALL_L3 (ENA_ADMIN_RSS_L3_SA | ENA_ADMIN_RSS_L3_DA) 15 #define ENA_HF_RSS_ALL_L4 (ENA_ADMIN_RSS_L4_SP | ENA_ADMIN_RSS_L4_DP) 16 #define ENA_HF_RSS_ALL_L3_L4 (ENA_HF_RSS_ALL_L3 | ENA_HF_RSS_ALL_L4) 17 #define ENA_HF_RSS_ALL_L2_L3_L4 (ENA_HF_RSS_ALL_L2 | ENA_HF_RSS_ALL_L3_L4) 18 19 enum ena_rss_hash_fields { 20 ENA_HF_RSS_TCP4 = ENA_HF_RSS_ALL_L3_L4, 21 ENA_HF_RSS_UDP4 = ENA_HF_RSS_ALL_L3_L4, 22 ENA_HF_RSS_TCP6 = ENA_HF_RSS_ALL_L3_L4, 23 ENA_HF_RSS_UDP6 = ENA_HF_RSS_ALL_L3_L4, 24 ENA_HF_RSS_IP4 = ENA_HF_RSS_ALL_L3, 25 ENA_HF_RSS_IP6 = ENA_HF_RSS_ALL_L3, 26 ENA_HF_RSS_IP4_FRAG = ENA_HF_RSS_ALL_L3, 27 ENA_HF_RSS_NOT_IP = ENA_HF_RSS_ALL_L2, 28 ENA_HF_RSS_TCP6_EX = ENA_HF_RSS_ALL_L3_L4, 29 ENA_HF_RSS_IP6_EX = ENA_HF_RSS_ALL_L3, 30 }; 31 32 static int ena_fill_indirect_table_default(struct ena_com_dev *ena_dev, 33 size_t tbl_size, 34 size_t queue_num); 35 static uint64_t ena_admin_hf_to_eth_hf(enum ena_admin_flow_hash_proto proto, 36 uint16_t field); 37 static uint16_t ena_eth_hf_to_admin_hf(enum ena_admin_flow_hash_proto proto, 38 uint64_t rss_hf); 39 static int ena_set_hash_fields(struct ena_com_dev *ena_dev, uint64_t rss_hf); 40 static int ena_rss_hash_set(struct ena_com_dev *ena_dev, 41 struct rte_eth_rss_conf *rss_conf, 42 bool default_allowed); 43 static void ena_reorder_rss_hash_key(uint8_t *reordered_key, 44 uint8_t *key, 45 size_t key_size); 46 static int ena_get_rss_hash_key(struct ena_com_dev *ena_dev, uint8_t *rss_key); 47 48 void ena_rss_key_fill(void *key, size_t size) 49 { 50 static bool key_generated; 51 static uint8_t default_key[ENA_HASH_KEY_SIZE]; 52 size_t i; 53 54 RTE_ASSERT(size <= ENA_HASH_KEY_SIZE); 55 56 if (!key_generated) { 57 for (i = 0; i < ENA_HASH_KEY_SIZE; ++i) 58 default_key[i] = rte_rand() & 0xff; 59 key_generated = true; 60 } 61 62 rte_memcpy(key, default_key, size); 63 } 64 65 int ena_rss_reta_update(struct rte_eth_dev *dev, 66 struct rte_eth_rss_reta_entry64 *reta_conf, 67 uint16_t reta_size) 68 { 69 struct ena_adapter *adapter = dev->data->dev_private; 70 struct ena_com_dev *ena_dev = &adapter->ena_dev; 71 int rc, i; 72 u16 entry_value; 73 int conf_idx; 74 int idx; 75 76 if (reta_size == 0 || reta_conf == NULL) 77 return -EINVAL; 78 79 if (!(dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_RSS_HASH)) { 80 PMD_DRV_LOG(ERR, 81 "RSS was not configured for the PMD\n"); 82 return -ENOTSUP; 83 } 84 85 if (reta_size > ENA_RX_RSS_TABLE_SIZE) { 86 PMD_DRV_LOG(WARNING, 87 "Requested indirection table size (%d) is bigger than supported: %d\n", 88 reta_size, ENA_RX_RSS_TABLE_SIZE); 89 return -EINVAL; 90 } 91 92 for (i = 0 ; i < reta_size ; i++) { 93 /* Each reta_conf is for 64 entries. 94 * To support 128 we use 2 conf of 64. 95 */ 96 conf_idx = i / RTE_RETA_GROUP_SIZE; 97 idx = i % RTE_RETA_GROUP_SIZE; 98 if (TEST_BIT(reta_conf[conf_idx].mask, idx)) { 99 entry_value = 100 ENA_IO_RXQ_IDX(reta_conf[conf_idx].reta[idx]); 101 102 rc = ena_com_indirect_table_fill_entry(ena_dev, i, 103 entry_value); 104 if (unlikely(rc != 0)) { 105 PMD_DRV_LOG(ERR, 106 "Cannot fill indirection table\n"); 107 return rc; 108 } 109 } 110 } 111 112 rte_spinlock_lock(&adapter->admin_lock); 113 rc = ena_com_indirect_table_set(ena_dev); 114 rte_spinlock_unlock(&adapter->admin_lock); 115 if (unlikely(rc != 0)) { 116 PMD_DRV_LOG(ERR, "Cannot set the indirection table\n"); 117 return rc; 118 } 119 120 PMD_DRV_LOG(DEBUG, "RSS configured %d entries for port %d\n", 121 reta_size, dev->data->port_id); 122 123 return 0; 124 } 125 126 /* Query redirection table. */ 127 int ena_rss_reta_query(struct rte_eth_dev *dev, 128 struct rte_eth_rss_reta_entry64 *reta_conf, 129 uint16_t reta_size) 130 { 131 uint32_t indirect_table[ENA_RX_RSS_TABLE_SIZE] = { 0 }; 132 struct ena_adapter *adapter = dev->data->dev_private; 133 struct ena_com_dev *ena_dev = &adapter->ena_dev; 134 int rc; 135 int i; 136 int reta_conf_idx; 137 int reta_idx; 138 139 if (reta_size == 0 || reta_conf == NULL || 140 (reta_size > RTE_RETA_GROUP_SIZE && ((reta_conf + 1) == NULL))) 141 return -EINVAL; 142 143 if (!(dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_RSS_HASH)) { 144 PMD_DRV_LOG(ERR, 145 "RSS was not configured for the PMD\n"); 146 return -ENOTSUP; 147 } 148 149 rte_spinlock_lock(&adapter->admin_lock); 150 rc = ena_com_indirect_table_get(ena_dev, indirect_table); 151 rte_spinlock_unlock(&adapter->admin_lock); 152 if (unlikely(rc != 0)) { 153 PMD_DRV_LOG(ERR, "Cannot get indirection table\n"); 154 return rc; 155 } 156 157 for (i = 0 ; i < reta_size ; i++) { 158 reta_conf_idx = i / RTE_RETA_GROUP_SIZE; 159 reta_idx = i % RTE_RETA_GROUP_SIZE; 160 if (TEST_BIT(reta_conf[reta_conf_idx].mask, reta_idx)) 161 reta_conf[reta_conf_idx].reta[reta_idx] = 162 ENA_IO_RXQ_IDX_REV(indirect_table[i]); 163 } 164 165 return 0; 166 } 167 168 static int ena_fill_indirect_table_default(struct ena_com_dev *ena_dev, 169 size_t tbl_size, 170 size_t queue_num) 171 { 172 size_t i; 173 int rc; 174 uint16_t val; 175 176 for (i = 0; i < tbl_size; ++i) { 177 val = i % queue_num; 178 rc = ena_com_indirect_table_fill_entry(ena_dev, i, 179 ENA_IO_RXQ_IDX(val)); 180 if (unlikely(rc != 0)) { 181 PMD_DRV_LOG(DEBUG, 182 "Failed to set %zu indirection table entry with val %" PRIu16 "\n", 183 i, val); 184 return rc; 185 } 186 } 187 188 return 0; 189 } 190 191 static uint64_t ena_admin_hf_to_eth_hf(enum ena_admin_flow_hash_proto proto, 192 uint16_t fields) 193 { 194 uint64_t rss_hf = 0; 195 196 /* If no fields are activated, then RSS is disabled for this proto */ 197 if ((fields & ENA_HF_RSS_ALL_L2_L3_L4) == 0) 198 return 0; 199 200 /* Convert proto to ETH flag */ 201 switch (proto) { 202 case ENA_ADMIN_RSS_TCP4: 203 rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP; 204 break; 205 case ENA_ADMIN_RSS_UDP4: 206 rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP; 207 break; 208 case ENA_ADMIN_RSS_TCP6: 209 rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP; 210 break; 211 case ENA_ADMIN_RSS_UDP6: 212 rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP; 213 break; 214 case ENA_ADMIN_RSS_IP4: 215 rss_hf |= ETH_RSS_IPV4; 216 break; 217 case ENA_ADMIN_RSS_IP6: 218 rss_hf |= ETH_RSS_IPV6; 219 break; 220 case ENA_ADMIN_RSS_IP4_FRAG: 221 rss_hf |= ETH_RSS_FRAG_IPV4; 222 break; 223 case ENA_ADMIN_RSS_NOT_IP: 224 rss_hf |= ETH_RSS_L2_PAYLOAD; 225 break; 226 case ENA_ADMIN_RSS_TCP6_EX: 227 rss_hf |= ETH_RSS_IPV6_TCP_EX; 228 break; 229 case ENA_ADMIN_RSS_IP6_EX: 230 rss_hf |= ETH_RSS_IPV6_EX; 231 break; 232 default: 233 break; 234 }; 235 236 /* Check if only DA or SA is being used for L3. */ 237 switch (fields & ENA_HF_RSS_ALL_L3) { 238 case ENA_ADMIN_RSS_L3_SA: 239 rss_hf |= ETH_RSS_L3_SRC_ONLY; 240 break; 241 case ENA_ADMIN_RSS_L3_DA: 242 rss_hf |= ETH_RSS_L3_DST_ONLY; 243 break; 244 default: 245 break; 246 }; 247 248 /* Check if only DA or SA is being used for L4. */ 249 switch (fields & ENA_HF_RSS_ALL_L4) { 250 case ENA_ADMIN_RSS_L4_SP: 251 rss_hf |= ETH_RSS_L4_SRC_ONLY; 252 break; 253 case ENA_ADMIN_RSS_L4_DP: 254 rss_hf |= ETH_RSS_L4_DST_ONLY; 255 break; 256 default: 257 break; 258 }; 259 260 return rss_hf; 261 } 262 263 static uint16_t ena_eth_hf_to_admin_hf(enum ena_admin_flow_hash_proto proto, 264 uint64_t rss_hf) 265 { 266 uint16_t fields_mask = 0; 267 268 /* L2 always uses source and destination addresses. */ 269 fields_mask = ENA_ADMIN_RSS_L2_DA | ENA_ADMIN_RSS_L2_SA; 270 271 /* Determine which fields of L3 should be used. */ 272 switch (rss_hf & (ETH_RSS_L3_SRC_ONLY | ETH_RSS_L3_DST_ONLY)) { 273 case ETH_RSS_L3_DST_ONLY: 274 fields_mask |= ENA_ADMIN_RSS_L3_DA; 275 break; 276 case ETH_RSS_L3_SRC_ONLY: 277 fields_mask |= ENA_ADMIN_RSS_L3_SA; 278 break; 279 default: 280 /* 281 * If SRC nor DST aren't set, it means both of them should be 282 * used. 283 */ 284 fields_mask |= ENA_HF_RSS_ALL_L3; 285 } 286 287 /* Determine which fields of L4 should be used. */ 288 switch (rss_hf & (ETH_RSS_L4_SRC_ONLY | ETH_RSS_L4_DST_ONLY)) { 289 case ETH_RSS_L4_DST_ONLY: 290 fields_mask |= ENA_ADMIN_RSS_L4_DP; 291 break; 292 case ETH_RSS_L4_SRC_ONLY: 293 fields_mask |= ENA_ADMIN_RSS_L4_SP; 294 break; 295 default: 296 /* 297 * If SRC nor DST aren't set, it means both of them should be 298 * used. 299 */ 300 fields_mask |= ENA_HF_RSS_ALL_L4; 301 } 302 303 /* Return appropriate hash fields. */ 304 switch (proto) { 305 case ENA_ADMIN_RSS_TCP4: 306 return ENA_HF_RSS_TCP4 & fields_mask; 307 case ENA_ADMIN_RSS_UDP4: 308 return ENA_HF_RSS_UDP4 & fields_mask; 309 case ENA_ADMIN_RSS_TCP6: 310 return ENA_HF_RSS_TCP6 & fields_mask; 311 case ENA_ADMIN_RSS_UDP6: 312 return ENA_HF_RSS_UDP6 & fields_mask; 313 case ENA_ADMIN_RSS_IP4: 314 return ENA_HF_RSS_IP4 & fields_mask; 315 case ENA_ADMIN_RSS_IP6: 316 return ENA_HF_RSS_IP6 & fields_mask; 317 case ENA_ADMIN_RSS_IP4_FRAG: 318 return ENA_HF_RSS_IP4_FRAG & fields_mask; 319 case ENA_ADMIN_RSS_NOT_IP: 320 return ENA_HF_RSS_NOT_IP & fields_mask; 321 case ENA_ADMIN_RSS_TCP6_EX: 322 return ENA_HF_RSS_TCP6_EX & fields_mask; 323 case ENA_ADMIN_RSS_IP6_EX: 324 return ENA_HF_RSS_IP6_EX & fields_mask; 325 default: 326 break; 327 } 328 329 return 0; 330 } 331 332 static int ena_set_hash_fields(struct ena_com_dev *ena_dev, uint64_t rss_hf) 333 { 334 struct ena_admin_proto_input selected_fields[ENA_ADMIN_RSS_PROTO_NUM] = {}; 335 int rc, i; 336 337 /* Turn on appropriate fields for each requested packet type */ 338 if ((rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) != 0) 339 selected_fields[ENA_ADMIN_RSS_TCP4].fields = 340 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_TCP4, rss_hf); 341 342 if ((rss_hf & ETH_RSS_NONFRAG_IPV4_UDP) != 0) 343 selected_fields[ENA_ADMIN_RSS_UDP4].fields = 344 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_UDP4, rss_hf); 345 346 if ((rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) != 0) 347 selected_fields[ENA_ADMIN_RSS_TCP6].fields = 348 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_TCP6, rss_hf); 349 350 if ((rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) != 0) 351 selected_fields[ENA_ADMIN_RSS_UDP6].fields = 352 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_UDP6, rss_hf); 353 354 if ((rss_hf & ETH_RSS_IPV4) != 0) 355 selected_fields[ENA_ADMIN_RSS_IP4].fields = 356 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_IP4, rss_hf); 357 358 if ((rss_hf & ETH_RSS_IPV6) != 0) 359 selected_fields[ENA_ADMIN_RSS_IP6].fields = 360 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_IP6, rss_hf); 361 362 if ((rss_hf & ETH_RSS_FRAG_IPV4) != 0) 363 selected_fields[ENA_ADMIN_RSS_IP4_FRAG].fields = 364 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_IP4_FRAG, rss_hf); 365 366 if ((rss_hf & ETH_RSS_L2_PAYLOAD) != 0) 367 selected_fields[ENA_ADMIN_RSS_NOT_IP].fields = 368 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_NOT_IP, rss_hf); 369 370 if ((rss_hf & ETH_RSS_IPV6_TCP_EX) != 0) 371 selected_fields[ENA_ADMIN_RSS_TCP6_EX].fields = 372 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_TCP6_EX, rss_hf); 373 374 if ((rss_hf & ETH_RSS_IPV6_EX) != 0) 375 selected_fields[ENA_ADMIN_RSS_IP6_EX].fields = 376 ena_eth_hf_to_admin_hf(ENA_ADMIN_RSS_IP6_EX, rss_hf); 377 378 /* Try to write them to the device */ 379 for (i = 0; i < ENA_ADMIN_RSS_PROTO_NUM; i++) { 380 rc = ena_com_fill_hash_ctrl(ena_dev, 381 (enum ena_admin_flow_hash_proto)i, 382 selected_fields[i].fields); 383 if (unlikely(rc != 0)) { 384 PMD_DRV_LOG(DEBUG, 385 "Failed to set ENA HF %d with fields %" PRIu16 "\n", 386 i, selected_fields[i].fields); 387 return rc; 388 } 389 } 390 391 return 0; 392 } 393 394 static int ena_rss_hash_set(struct ena_com_dev *ena_dev, 395 struct rte_eth_rss_conf *rss_conf, 396 bool default_allowed) 397 { 398 uint8_t hw_rss_key[ENA_HASH_KEY_SIZE]; 399 uint8_t *rss_key; 400 int rc; 401 402 if (rss_conf->rss_key != NULL) { 403 /* Reorder the RSS key bytes for the hardware requirements. */ 404 ena_reorder_rss_hash_key(hw_rss_key, rss_conf->rss_key, 405 ENA_HASH_KEY_SIZE); 406 rss_key = hw_rss_key; 407 } else { 408 rss_key = NULL; 409 } 410 411 /* If the rss_key is NULL, then the randomized key will be used. */ 412 rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_TOEPLITZ, 413 rss_key, ENA_HASH_KEY_SIZE, 0); 414 if (rc != 0 && !(default_allowed && rc == ENA_COM_UNSUPPORTED)) { 415 PMD_DRV_LOG(ERR, 416 "Failed to set RSS hash function in the device\n"); 417 return rc; 418 } 419 420 rc = ena_set_hash_fields(ena_dev, rss_conf->rss_hf); 421 if (rc == ENA_COM_UNSUPPORTED) { 422 if (rss_conf->rss_key == NULL && !default_allowed) { 423 PMD_DRV_LOG(ERR, 424 "Setting RSS hash fields is not supported\n"); 425 return -ENOTSUP; 426 } 427 PMD_DRV_LOG(WARNING, 428 "Setting RSS hash fields is not supported. Using default values: 0x%" PRIx64 "\n", 429 (uint64_t)(ENA_ALL_RSS_HF)); 430 } else if (rc != 0) { 431 PMD_DRV_LOG(ERR, "Failed to set RSS hash fields\n"); 432 return rc; 433 } 434 435 return 0; 436 } 437 438 /* ENA HW interprets the RSS key in reverse bytes order. Because of that, the 439 * key must be processed upon interaction with ena_com layer. 440 */ 441 static void ena_reorder_rss_hash_key(uint8_t *reordered_key, 442 uint8_t *key, 443 size_t key_size) 444 { 445 size_t i, rev_i; 446 447 for (i = 0, rev_i = key_size - 1; i < key_size; ++i, --rev_i) 448 reordered_key[i] = key[rev_i]; 449 } 450 451 static int ena_get_rss_hash_key(struct ena_com_dev *ena_dev, uint8_t *rss_key) 452 { 453 uint8_t hw_rss_key[ENA_HASH_KEY_SIZE]; 454 int rc; 455 456 /* The default RSS hash key cannot be retrieved from the HW. Unless it's 457 * explicitly set, this operation shouldn't be supported. 458 */ 459 if (ena_dev->rss.hash_key == NULL) { 460 PMD_DRV_LOG(WARNING, 461 "Retrieving default RSS hash key is not supported\n"); 462 return -ENOTSUP; 463 } 464 465 rc = ena_com_get_hash_key(ena_dev, hw_rss_key); 466 if (rc != 0) 467 return rc; 468 469 ena_reorder_rss_hash_key(rss_key, hw_rss_key, ENA_HASH_KEY_SIZE); 470 471 return 0; 472 } 473 474 int ena_rss_configure(struct ena_adapter *adapter) 475 { 476 struct rte_eth_rss_conf *rss_conf; 477 struct ena_com_dev *ena_dev; 478 int rc; 479 480 ena_dev = &adapter->ena_dev; 481 rss_conf = &adapter->edev_data->dev_conf.rx_adv_conf.rss_conf; 482 483 if (adapter->edev_data->nb_rx_queues == 0) 484 return 0; 485 486 /* Restart the indirection table. The number of queues could change 487 * between start/stop calls, so it must be reinitialized with default 488 * values. 489 */ 490 rc = ena_fill_indirect_table_default(ena_dev, ENA_RX_RSS_TABLE_SIZE, 491 adapter->edev_data->nb_rx_queues); 492 if (unlikely(rc != 0)) { 493 PMD_DRV_LOG(ERR, 494 "Failed to fill indirection table with default values\n"); 495 return rc; 496 } 497 498 rc = ena_com_indirect_table_set(ena_dev); 499 if (unlikely(rc != 0 && rc != ENA_COM_UNSUPPORTED)) { 500 PMD_DRV_LOG(ERR, 501 "Failed to set indirection table in the device\n"); 502 return rc; 503 } 504 505 rc = ena_rss_hash_set(ena_dev, rss_conf, true); 506 if (unlikely(rc != 0)) { 507 PMD_DRV_LOG(ERR, "Failed to set RSS hash\n"); 508 return rc; 509 } 510 511 PMD_DRV_LOG(DEBUG, "RSS configured for port %d\n", 512 adapter->edev_data->port_id); 513 514 return 0; 515 } 516 517 int ena_rss_hash_update(struct rte_eth_dev *dev, 518 struct rte_eth_rss_conf *rss_conf) 519 { 520 struct ena_adapter *adapter = dev->data->dev_private; 521 int rc; 522 523 rte_spinlock_lock(&adapter->admin_lock); 524 rc = ena_rss_hash_set(&adapter->ena_dev, rss_conf, false); 525 rte_spinlock_unlock(&adapter->admin_lock); 526 if (unlikely(rc != 0)) { 527 PMD_DRV_LOG(ERR, "Failed to set RSS hash\n"); 528 return rc; 529 } 530 531 return 0; 532 } 533 534 int ena_rss_hash_conf_get(struct rte_eth_dev *dev, 535 struct rte_eth_rss_conf *rss_conf) 536 { 537 struct ena_adapter *adapter = dev->data->dev_private; 538 struct ena_com_dev *ena_dev = &adapter->ena_dev; 539 enum ena_admin_flow_hash_proto proto; 540 uint64_t rss_hf = 0; 541 int rc, i; 542 uint16_t admin_hf; 543 static bool warn_once; 544 545 if (!(dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_RSS_HASH)) { 546 PMD_DRV_LOG(ERR, "RSS was not configured for the PMD\n"); 547 return -ENOTSUP; 548 } 549 550 if (rss_conf->rss_key != NULL) { 551 rc = ena_get_rss_hash_key(ena_dev, rss_conf->rss_key); 552 if (unlikely(rc != 0)) { 553 PMD_DRV_LOG(ERR, 554 "Cannot retrieve RSS hash key, err: %d\n", 555 rc); 556 return rc; 557 } 558 } 559 560 for (i = 0; i < ENA_ADMIN_RSS_PROTO_NUM; ++i) { 561 proto = (enum ena_admin_flow_hash_proto)i; 562 rte_spinlock_lock(&adapter->admin_lock); 563 rc = ena_com_get_hash_ctrl(ena_dev, proto, &admin_hf); 564 rte_spinlock_unlock(&adapter->admin_lock); 565 if (rc == ENA_COM_UNSUPPORTED) { 566 /* As some devices may support only reading rss hash 567 * key and not the hash ctrl, we want to notify the 568 * caller that this feature is only partially supported 569 * and do not return an error - the caller could be 570 * interested only in the key value. 571 */ 572 if (!warn_once) { 573 PMD_DRV_LOG(WARNING, 574 "Reading hash control from the device is not supported. .rss_hf will contain a default value.\n"); 575 warn_once = true; 576 } 577 rss_hf = ENA_ALL_RSS_HF; 578 break; 579 } else if (rc != 0) { 580 PMD_DRV_LOG(ERR, 581 "Failed to retrieve hash ctrl for proto: %d with err: %d\n", 582 i, rc); 583 return rc; 584 } 585 586 rss_hf |= ena_admin_hf_to_eth_hf(proto, admin_hf); 587 } 588 589 rss_conf->rss_hf = rss_hf; 590 return 0; 591 } 592