1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2018-2019 Solarflare Communications Inc. 5 */ 6 7 #include "efx.h" 8 #include "efx_impl.h" 9 10 11 #if EFSYS_OPT_RIVERHEAD 12 13 /* 14 * Maximum number of Rx prefixes supported by Rx prefix choice to be 15 * returned from firmware. 16 */ 17 #define RHEAD_RX_PREFIX_IDS_MAX 16 18 19 /* 20 * Default Rx prefix layout on Riverhead if FW does not support Rx 21 * prefix choice using MC_CMD_GET_RX_PREFIX_ID and query its layout 22 * using MC_CMD_QUERY_RX_PREFIX_ID. 23 * 24 * See SF-119689-TC Riverhead Host Interface section 6.4. 25 */ 26 static const efx_rx_prefix_layout_t rhead_default_rx_prefix_layout = { 27 .erpl_id = 0, 28 .erpl_length = ESE_GZ_RX_PKT_PREFIX_LEN, 29 .erpl_fields = { 30 #define RHEAD_RX_PREFIX_FIELD(_name, _big_endian) \ 31 EFX_RX_PREFIX_FIELD(_name, ESF_GZ_RX_PREFIX_ ## _name, _big_endian) 32 33 RHEAD_RX_PREFIX_FIELD(LENGTH, B_FALSE), 34 RHEAD_RX_PREFIX_FIELD(RSS_HASH_VALID, B_FALSE), 35 RHEAD_RX_PREFIX_FIELD(USER_FLAG, B_FALSE), 36 RHEAD_RX_PREFIX_FIELD(CLASS, B_FALSE), 37 RHEAD_RX_PREFIX_FIELD(PARTIAL_TSTAMP, B_FALSE), 38 RHEAD_RX_PREFIX_FIELD(RSS_HASH, B_FALSE), 39 RHEAD_RX_PREFIX_FIELD(USER_MARK, B_FALSE), 40 RHEAD_RX_PREFIX_FIELD(INGRESS_MPORT, B_FALSE), 41 RHEAD_RX_PREFIX_FIELD(CSUM_FRAME, B_TRUE), 42 RHEAD_RX_PREFIX_FIELD(VLAN_STRIP_TCI, B_TRUE), 43 44 #undef RHEAD_RX_PREFIX_FIELD 45 } 46 }; 47 48 __checkReturn efx_rc_t 49 rhead_rx_init( 50 __in efx_nic_t *enp) 51 { 52 efx_rc_t rc; 53 54 rc = ef10_rx_init(enp); 55 if (rc != 0) 56 goto fail1; 57 58 return (0); 59 60 fail1: 61 EFSYS_PROBE1(fail1, efx_rc_t, rc); 62 return (rc); 63 } 64 65 void 66 rhead_rx_fini( 67 __in efx_nic_t *enp) 68 { 69 ef10_rx_fini(enp); 70 } 71 72 #if EFSYS_OPT_RX_SCATTER 73 __checkReturn efx_rc_t 74 rhead_rx_scatter_enable( 75 __in efx_nic_t *enp, 76 __in unsigned int buf_size) 77 { 78 _NOTE(ARGUNUSED(enp, buf_size)) 79 /* Nothing to do here */ 80 return (0); 81 } 82 #endif /* EFSYS_OPT_RX_SCATTER */ 83 84 #if EFSYS_OPT_RX_SCALE 85 86 __checkReturn efx_rc_t 87 rhead_rx_scale_context_alloc( 88 __in efx_nic_t *enp, 89 __in efx_rx_scale_context_type_t type, 90 __in uint32_t num_queues, 91 __in uint32_t table_nentries, 92 __out uint32_t *rss_contextp) 93 { 94 efx_rc_t rc; 95 96 rc = ef10_rx_scale_context_alloc(enp, type, num_queues, table_nentries, 97 rss_contextp); 98 if (rc != 0) 99 goto fail1; 100 101 return (0); 102 103 fail1: 104 EFSYS_PROBE1(fail1, efx_rc_t, rc); 105 return (rc); 106 } 107 108 __checkReturn efx_rc_t 109 rhead_rx_scale_context_free( 110 __in efx_nic_t *enp, 111 __in uint32_t rss_context) 112 { 113 efx_rc_t rc; 114 115 rc = ef10_rx_scale_context_free(enp, rss_context); 116 if (rc != 0) 117 goto fail1; 118 119 return (0); 120 121 fail1: 122 EFSYS_PROBE1(fail1, efx_rc_t, rc); 123 return (rc); 124 } 125 126 __checkReturn efx_rc_t 127 rhead_rx_scale_mode_set( 128 __in efx_nic_t *enp, 129 __in uint32_t rss_context, 130 __in efx_rx_hash_alg_t alg, 131 __in efx_rx_hash_type_t type, 132 __in boolean_t insert) 133 { 134 efx_rc_t rc; 135 136 rc = ef10_rx_scale_mode_set(enp, rss_context, alg, type, insert); 137 if (rc != 0) 138 goto fail1; 139 140 return (0); 141 142 fail1: 143 EFSYS_PROBE1(fail1, efx_rc_t, rc); 144 return (rc); 145 } 146 147 __checkReturn efx_rc_t 148 rhead_rx_scale_key_set( 149 __in efx_nic_t *enp, 150 __in uint32_t rss_context, 151 __in_ecount(n) uint8_t *key, 152 __in size_t n) 153 { 154 efx_rc_t rc; 155 156 rc = ef10_rx_scale_key_set(enp, rss_context, key, n); 157 if (rc != 0) 158 goto fail1; 159 160 return (0); 161 162 fail1: 163 EFSYS_PROBE1(fail1, efx_rc_t, rc); 164 return (rc); 165 } 166 167 __checkReturn efx_rc_t 168 rhead_rx_scale_tbl_set( 169 __in efx_nic_t *enp, 170 __in uint32_t rss_context, 171 __in_ecount(nentries) unsigned int *table, 172 __in size_t nentries) 173 { 174 efx_rc_t rc; 175 176 rc = ef10_rx_scale_tbl_set(enp, rss_context, table, nentries); 177 if (rc != 0) 178 goto fail1; 179 180 return (0); 181 182 fail1: 183 EFSYS_PROBE1(fail1, efx_rc_t, rc); 184 return (rc); 185 } 186 187 __checkReturn uint32_t 188 rhead_rx_prefix_hash( 189 __in efx_nic_t *enp, 190 __in efx_rx_hash_alg_t func, 191 __in uint8_t *buffer) 192 { 193 _NOTE(ARGUNUSED(enp, func, buffer)) 194 195 /* FIXME implement the method for Riverhead */ 196 197 return (ENOTSUP); 198 } 199 200 #endif /* EFSYS_OPT_RX_SCALE */ 201 202 __checkReturn efx_rc_t 203 rhead_rx_prefix_pktlen( 204 __in efx_nic_t *enp, 205 __in uint8_t *buffer, 206 __out uint16_t *lengthp) 207 { 208 _NOTE(ARGUNUSED(enp, buffer, lengthp)) 209 210 /* FIXME implement the method for Riverhead */ 211 212 return (ENOTSUP); 213 } 214 215 void 216 rhead_rx_qpost( 217 __in efx_rxq_t *erp, 218 __in_ecount(ndescs) efsys_dma_addr_t *addrp, 219 __in size_t size, 220 __in unsigned int ndescs, 221 __in unsigned int completed, 222 __in unsigned int added) 223 { 224 _NOTE(ARGUNUSED(erp, addrp, size, ndescs, completed, added)) 225 226 /* FIXME implement the method for Riverhead */ 227 228 EFSYS_ASSERT(B_FALSE); 229 } 230 231 void 232 rhead_rx_qpush( 233 __in efx_rxq_t *erp, 234 __in unsigned int added, 235 __inout unsigned int *pushedp) 236 { 237 _NOTE(ARGUNUSED(erp, added, pushedp)) 238 239 /* FIXME implement the method for Riverhead */ 240 241 EFSYS_ASSERT(B_FALSE); 242 } 243 244 __checkReturn efx_rc_t 245 rhead_rx_qflush( 246 __in efx_rxq_t *erp) 247 { 248 efx_nic_t *enp = erp->er_enp; 249 efx_rc_t rc; 250 251 if ((rc = efx_mcdi_fini_rxq(enp, erp->er_index)) != 0) 252 goto fail1; 253 254 return (0); 255 256 fail1: 257 /* 258 * EALREADY is not an error, but indicates that the MC has rebooted and 259 * that the RXQ has already been destroyed. Callers need to know that 260 * the RXQ flush has completed to avoid waiting until timeout for a 261 * flush done event that will not be delivered. 262 */ 263 if (rc != EALREADY) 264 EFSYS_PROBE1(fail1, efx_rc_t, rc); 265 266 return (rc); 267 } 268 269 void 270 rhead_rx_qenable( 271 __in efx_rxq_t *erp) 272 { 273 _NOTE(ARGUNUSED(erp)) 274 } 275 276 static __checkReturn efx_rc_t 277 efx_mcdi_get_rx_prefix_ids( 278 __in efx_nic_t *enp, 279 __in uint32_t mcdi_fields_mask, 280 __in unsigned int max_ids, 281 __out unsigned int *nids, 282 __out_ecount_part(max_ids, *nids) uint32_t *idsp) 283 { 284 efx_mcdi_req_t req; 285 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RX_PREFIX_ID_IN_LEN, 286 MC_CMD_GET_RX_PREFIX_ID_OUT_LENMAX); 287 efx_rc_t rc; 288 uint32_t num; 289 290 req.emr_cmd = MC_CMD_GET_RX_PREFIX_ID; 291 req.emr_in_buf = payload; 292 req.emr_in_length = MC_CMD_GET_RX_PREFIX_ID_IN_LEN; 293 req.emr_out_buf = payload; 294 req.emr_out_length = MC_CMD_GET_RX_PREFIX_ID_OUT_LENMAX; 295 296 MCDI_IN_SET_DWORD(req, GET_RX_PREFIX_ID_IN_FIELDS, mcdi_fields_mask); 297 298 efx_mcdi_execute(enp, &req); 299 300 if (req.emr_rc != 0) { 301 rc = req.emr_rc; 302 goto fail1; 303 } 304 305 if (req.emr_out_length_used < MC_CMD_GET_RX_PREFIX_ID_OUT_LENMIN) { 306 rc = EMSGSIZE; 307 goto fail2; 308 } 309 310 num = MCDI_OUT_DWORD(req, GET_RX_PREFIX_ID_OUT_NUM_RX_PREFIX_IDS); 311 312 if (req.emr_out_length_used != MC_CMD_GET_RX_PREFIX_ID_OUT_LEN(num)) { 313 rc = EMSGSIZE; 314 goto fail3; 315 } 316 317 *nids = MIN(num, max_ids); 318 319 EFX_STATIC_ASSERT(sizeof (idsp[0]) == 320 MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_LEN); 321 memcpy(idsp, 322 MCDI_OUT2(req, uint32_t, GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID), 323 *nids * sizeof (idsp[0])); 324 325 return (0); 326 327 fail3: 328 EFSYS_PROBE(fail3); 329 fail2: 330 EFSYS_PROBE(fail2); 331 fail1: 332 EFSYS_PROBE1(fail1, efx_rc_t, rc); 333 334 return (rc); 335 } 336 337 static __checkReturn efx_rx_prefix_field_t 338 efx_mcdi_rx_prefix_field_map(unsigned int mcdi_idx) 339 { 340 static const efx_rx_prefix_field_t efx_mcdi_to_rx_prefix_field[] = { 341 #define EFX_MCDI_TO_RX_PREFIX_FIELD(_field) \ 342 [RX_PREFIX_FIELD_INFO_ ## _field] = EFX_RX_PREFIX_FIELD_ ## _field 343 344 EFX_MCDI_TO_RX_PREFIX_FIELD(LENGTH), 345 EFX_MCDI_TO_RX_PREFIX_FIELD(RSS_HASH_VALID), 346 EFX_MCDI_TO_RX_PREFIX_FIELD(USER_FLAG), 347 EFX_MCDI_TO_RX_PREFIX_FIELD(CLASS), 348 EFX_MCDI_TO_RX_PREFIX_FIELD(PARTIAL_TSTAMP), 349 EFX_MCDI_TO_RX_PREFIX_FIELD(RSS_HASH), 350 EFX_MCDI_TO_RX_PREFIX_FIELD(USER_MARK), 351 EFX_MCDI_TO_RX_PREFIX_FIELD(INGRESS_VPORT), 352 EFX_MCDI_TO_RX_PREFIX_FIELD(CSUM_FRAME), 353 EFX_MCDI_TO_RX_PREFIX_FIELD(VLAN_STRIP_TCI), 354 355 #undef EFX_MCDI_TO_RX_PREFIX_FIELD 356 }; 357 358 if (mcdi_idx >= EFX_ARRAY_SIZE(efx_mcdi_to_rx_prefix_field)) 359 return (EFX_RX_PREFIX_NFIELDS); 360 361 return (efx_mcdi_to_rx_prefix_field[mcdi_idx]); 362 } 363 364 static __checkReturn int 365 efx_rx_prefix_field_map_to_mcdi( 366 __in efx_rx_prefix_field_t field) 367 { 368 static const int efx_rx_prefix_field_to_mcdi[] = { 369 [EFX_RX_PREFIX_FIELD_LENGTH] = 370 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_LENGTH), 371 [EFX_RX_PREFIX_FIELD_ORIG_LENGTH] = -1, 372 [EFX_RX_PREFIX_FIELD_CLASS] = 373 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_CLASS), 374 [EFX_RX_PREFIX_FIELD_RSS_HASH] = 375 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH), 376 [EFX_RX_PREFIX_FIELD_RSS_HASH_VALID] = 377 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_VALID), 378 [EFX_RX_PREFIX_FIELD_PARTIAL_TSTAMP] = 379 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_PARTIAL_TSTAMP), 380 [EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI] = 381 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI), 382 [EFX_RX_PREFIX_FIELD_INNER_VLAN_STRIP_TCI] = -1, 383 [EFX_RX_PREFIX_FIELD_USER_FLAG] = 384 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_USER_FLAG), 385 [EFX_RX_PREFIX_FIELD_USER_MARK] = 386 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK), 387 [EFX_RX_PREFIX_FIELD_USER_MARK_VALID] = -1, 388 [EFX_RX_PREFIX_FIELD_CSUM_FRAME] = 389 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_CSUM_FRAME), 390 [EFX_RX_PREFIX_FIELD_INGRESS_VPORT] = 391 EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT), 392 }; 393 394 if (field >= EFX_ARRAY_SIZE(efx_rx_prefix_field_to_mcdi)) 395 return (-1); 396 397 return (efx_rx_prefix_field_to_mcdi[field]); 398 } 399 400 static __checkReturn efx_rc_t 401 efx_rx_prefix_fields_mask_to_mcdi( 402 __in uint32_t fields_mask, 403 __out uint32_t *mcdi_fields_maskp) 404 { 405 uint32_t mcdi_fields_mask = 0; 406 unsigned int i; 407 408 for (i = 0; i < EFX_RX_PREFIX_NFIELDS; ++i) { 409 if (fields_mask & (1U << i)) { 410 int mcdi_field = efx_rx_prefix_field_map_to_mcdi(i); 411 412 if (mcdi_field < 0) 413 return (EINVAL); 414 415 mcdi_fields_mask |= (1U << mcdi_field); 416 } 417 } 418 419 *mcdi_fields_maskp = mcdi_fields_mask; 420 return (0); 421 } 422 423 static __checkReturn efx_rc_t 424 efx_mcdi_query_rx_prefix_id( 425 __in efx_nic_t *enp, 426 __in uint32_t prefix_id, 427 __out efx_rx_prefix_layout_t *erplp) 428 { 429 efx_mcdi_req_t req; 430 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_QUERY_RX_PREFIX_ID_IN_LEN, 431 MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMAX); 432 efx_rc_t rc; 433 size_t response_len; 434 const efx_dword_t *resp; 435 const efx_dword_t *finfo; 436 unsigned int num_fields; 437 unsigned int mcdi_field; 438 efx_rx_prefix_field_t field; 439 unsigned int i; 440 441 req.emr_cmd = MC_CMD_QUERY_RX_PREFIX_ID; 442 req.emr_in_buf = payload; 443 req.emr_in_length = MC_CMD_QUERY_RX_PREFIX_ID_IN_LEN; 444 req.emr_out_buf = payload; 445 req.emr_out_length = MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMAX; 446 447 MCDI_IN_SET_DWORD(req, QUERY_RX_PREFIX_ID_IN_RX_PREFIX_ID, prefix_id); 448 449 efx_mcdi_execute(enp, &req); 450 451 if (req.emr_rc != 0) { 452 rc = req.emr_rc; 453 goto fail1; 454 } 455 456 if (req.emr_out_length_used < MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMIN) { 457 rc = EMSGSIZE; 458 goto fail2; 459 } 460 461 if (MCDI_OUT_BYTE(req, QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE) != 462 MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE_FIXED) { 463 rc = ENOTSUP; 464 goto fail3; 465 } 466 467 EFX_STATIC_ASSERT(MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMIN >= 468 MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_OFST); 469 response_len = req.emr_out_length_used - 470 MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_OFST; 471 472 if (response_len < RX_PREFIX_FIXED_RESPONSE_LENMIN) { 473 rc = EMSGSIZE; 474 goto fail4; 475 } 476 477 resp = MCDI_OUT2(req, efx_dword_t, QUERY_RX_PREFIX_ID_OUT_RESPONSE); 478 479 memset(erplp, 0, sizeof (*erplp)); 480 erplp->erpl_id = prefix_id; 481 erplp->erpl_length = 482 EFX_DWORD_FIELD(*resp, RX_PREFIX_FIXED_RESPONSE_PREFIX_LENGTH_BYTES); 483 num_fields = 484 EFX_DWORD_FIELD(*resp, RX_PREFIX_FIXED_RESPONSE_FIELD_COUNT); 485 486 if (response_len < RX_PREFIX_FIXED_RESPONSE_LEN(num_fields)) { 487 rc = EMSGSIZE; 488 goto fail5; 489 } 490 491 finfo = (const efx_dword_t *)((const uint8_t *)resp + 492 RX_PREFIX_FIXED_RESPONSE_FIELDS_OFST); 493 494 for (i = 0; i < num_fields; ++i, ++finfo) { 495 mcdi_field = EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_TYPE); 496 497 field = efx_mcdi_rx_prefix_field_map(mcdi_field); 498 if (field >= EFX_RX_PREFIX_NFIELDS) 499 continue; 500 501 erplp->erpl_fields[field].erpfi_offset_bits = 502 EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_OFFSET_BITS); 503 erplp->erpl_fields[field].erpfi_width_bits = 504 EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_WIDTH_BITS); 505 } 506 507 return (0); 508 509 fail5: 510 EFSYS_PROBE(fail5); 511 fail4: 512 EFSYS_PROBE(fail4); 513 fail3: 514 EFSYS_PROBE(fail3); 515 fail2: 516 EFSYS_PROBE(fail2); 517 fail1: 518 EFSYS_PROBE1(fail1, efx_rc_t, rc); 519 520 return (rc); 521 } 522 523 static __checkReturn efx_rc_t 524 rhead_rx_choose_prefix_id( 525 __in efx_nic_t *enp, 526 __in uint32_t fields_mask, 527 __out efx_rx_prefix_layout_t *erplp) 528 { 529 efx_rx_prefix_layout_t erpl; 530 uint32_t prefix_ids[RHEAD_RX_PREFIX_IDS_MAX]; 531 uint32_t mcdi_fields_mask; 532 unsigned int num = 0; 533 unsigned int i; 534 efx_rc_t rc; 535 536 rc = efx_rx_prefix_fields_mask_to_mcdi(fields_mask, &mcdi_fields_mask); 537 if (rc != 0) 538 goto fail1; 539 540 memset(erplp, 0, sizeof (*erplp)); 541 542 rc = efx_mcdi_get_rx_prefix_ids(enp, mcdi_fields_mask, 543 EFX_ARRAY_SIZE(prefix_ids), &num, prefix_ids); 544 if (rc == ENOTSUP) { 545 /* Not supported MCDI, use default prefix ID */ 546 *erplp = rhead_default_rx_prefix_layout; 547 goto done; 548 } 549 if (rc != 0) 550 goto fail2; 551 552 if (num == 0) { 553 rc = ENOTSUP; 554 goto fail3; 555 } 556 557 for (i = 0; i < num; ++i) { 558 rc = efx_mcdi_query_rx_prefix_id(enp, prefix_ids[i], &erpl); 559 if (rc != 0) 560 goto fail4; 561 562 /* Choose the smallest prefix which meets our requirements */ 563 if (i == 0 || erpl.erpl_length < erplp->erpl_length) 564 *erplp = erpl; 565 } 566 567 done: 568 return (0); 569 570 fail4: 571 EFSYS_PROBE(fail4); 572 fail3: 573 EFSYS_PROBE(fail3); 574 fail2: 575 EFSYS_PROBE(fail2); 576 fail1: 577 EFSYS_PROBE1(fail1, efx_rc_t, rc); 578 579 return (rc); 580 } 581 582 __checkReturn efx_rc_t 583 rhead_rx_qcreate( 584 __in efx_nic_t *enp, 585 __in unsigned int index, 586 __in unsigned int label, 587 __in efx_rxq_type_t type, 588 __in const efx_rxq_type_data_t *type_data, 589 __in efsys_mem_t *esmp, 590 __in size_t ndescs, 591 __in uint32_t id, 592 __in unsigned int flags, 593 __in efx_evq_t *eep, 594 __in efx_rxq_t *erp) 595 { 596 const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp); 597 efx_mcdi_init_rxq_params_t params; 598 efx_rx_prefix_layout_t erpl; 599 uint32_t fields_mask = 0; 600 efx_rc_t rc; 601 602 _NOTE(ARGUNUSED(id)) 603 604 EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS <= 605 (1 << ESF_GZ_EV_RXPKTS_Q_LABEL_WIDTH)); 606 EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS); 607 608 memset(¶ms, 0, sizeof (params)); 609 610 switch (type) { 611 case EFX_RXQ_TYPE_DEFAULT: 612 if (type_data == NULL) { 613 rc = EINVAL; 614 goto fail1; 615 } 616 params.buf_size = type_data->ertd_default.ed_buf_size; 617 break; 618 default: 619 rc = ENOTSUP; 620 goto fail2; 621 } 622 623 /* Scatter can only be disabled if the firmware supports doing so */ 624 if (flags & EFX_RXQ_FLAG_SCATTER) 625 params.disable_scatter = B_FALSE; 626 else 627 params.disable_scatter = encp->enc_rx_disable_scatter_supported; 628 629 if (flags & EFX_RXQ_FLAG_RSS_HASH) { 630 fields_mask |= 1U << EFX_RX_PREFIX_FIELD_RSS_HASH; 631 fields_mask |= 1U << EFX_RX_PREFIX_FIELD_RSS_HASH_VALID; 632 } 633 634 if (flags & EFX_RXQ_FLAG_INGRESS_MPORT) 635 fields_mask |= 1U << EFX_RX_PREFIX_FIELD_INGRESS_MPORT; 636 637 if (flags & EFX_RXQ_FLAG_USER_MARK) 638 fields_mask |= 1U << EFX_RX_PREFIX_FIELD_USER_MARK; 639 640 if (flags & EFX_RXQ_FLAG_USER_FLAG) 641 fields_mask |= 1U << EFX_RX_PREFIX_FIELD_USER_FLAG; 642 643 if (flags & EFX_RXQ_FLAG_VLAN_STRIPPED_TCI) 644 fields_mask |= 1U << EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI; 645 646 /* 647 * LENGTH is required in EF100 host interface, as receive events 648 * do not include the packet length. 649 */ 650 fields_mask |= 1U << EFX_RX_PREFIX_FIELD_LENGTH; 651 if ((rc = rhead_rx_choose_prefix_id(enp, fields_mask, &erpl)) != 0) 652 goto fail3; 653 654 params.prefix_id = erpl.erpl_id; 655 656 /* 657 * Ignore EFX_RXQ_FLAG_INNER_CLASSES since in accordance with 658 * EF100 host interface both inner and outer classes are provided 659 * by HW if applicable. 660 */ 661 662 if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep, label, index, 663 esmp, ¶ms)) != 0) 664 goto fail4; 665 666 erp->er_eep = eep; 667 erp->er_label = label; 668 erp->er_buf_size = params.buf_size; 669 erp->er_prefix_layout = erpl; 670 671 return (0); 672 673 fail4: 674 EFSYS_PROBE(fail4); 675 fail3: 676 EFSYS_PROBE(fail3); 677 fail2: 678 EFSYS_PROBE(fail2); 679 fail1: 680 EFSYS_PROBE1(fail1, efx_rc_t, rc); 681 682 return (rc); 683 } 684 685 void 686 rhead_rx_qdestroy( 687 __in efx_rxq_t *erp) 688 { 689 _NOTE(ARGUNUSED(erp)) 690 /* Nothing to do here */ 691 } 692 693 #endif /* EFSYS_OPT_RIVERHEAD */ 694