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