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