dpdk/drivers/common/sfc_efx/base/rhead_nic.c
<<
>>
Prefs
   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        __checkReturn   efx_rc_t
  14rhead_board_cfg(
  15        __in            efx_nic_t *enp)
  16{
  17        efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
  18        uint32_t end_padding;
  19        uint32_t bandwidth;
  20        efx_rc_t rc;
  21
  22        if ((rc = efx_mcdi_nic_board_cfg(enp)) != 0)
  23                goto fail1;
  24
  25        /*
  26         * The tunnel encapsulation initialization happens unconditionally
  27         * for now.
  28         */
  29        encp->enc_tunnel_encapsulations_supported =
  30            (1u << EFX_TUNNEL_PROTOCOL_VXLAN) |
  31            (1u << EFX_TUNNEL_PROTOCOL_NVGRE);
  32
  33        /*
  34         * Software limitation inherited from EF10. This limit is not
  35         * increased since the hardware does not report this limit, it is
  36         * handled internally resulting in a tunnel add error when there is no
  37         * space for more UDP tunnels.
  38         */
  39        encp->enc_tunnel_config_udp_entries_max = EFX_TUNNEL_MAXNENTRIES;
  40
  41        encp->enc_clk_mult = 1; /* not used for Riverhead */
  42
  43        /*
  44         * FIXME There are TxSend and TxSeg descriptors on Riverhead.
  45         * TxSeg is bigger than TxSend.
  46         */
  47        encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_GZ_TX_SEND_LEN);
  48        /* No boundary crossing limits */
  49        encp->enc_tx_dma_desc_boundary = 0;
  50
  51        /*
  52         * Initialise design parameters to either a runtime value read from
  53         * the design parameters area or the well known default value
  54         * (see SF-119689-TC section 4.4 for details).
  55         * FIXME: Read design parameters area values.
  56         */
  57        encp->enc_tx_tso_max_header_ndescs =
  58            ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT;
  59        encp->enc_tx_tso_max_header_length =
  60            ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT;
  61        encp->enc_tx_tso_max_payload_ndescs =
  62            ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT;
  63        encp->enc_tx_tso_max_payload_length =
  64            ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT;
  65        encp->enc_tx_tso_max_nframes =
  66            ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT;
  67
  68        /*
  69         * Riverhead does not put any restrictions on TCP header offset limit.
  70         */
  71        encp->enc_tx_tso_tcp_header_offset_limit = UINT32_MAX;
  72
  73        /*
  74         * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
  75         * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
  76         * resources (allocated to this PCIe function), which is zero until
  77         * after we have allocated VIs.
  78         */
  79        encp->enc_evq_limit = 1024;
  80        encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
  81        encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
  82
  83        encp->enc_buftbl_limit = UINT32_MAX;
  84
  85        /*
  86         * Riverhead event queue creation completes
  87         * immediately (no initial event).
  88         */
  89        encp->enc_evq_init_done_ev_supported = B_FALSE;
  90
  91        /*
  92         * Enable firmware workarounds for hardware errata.
  93         * Expected responses are:
  94         *  - 0 (zero):
  95         *      Success: workaround enabled or disabled as requested.
  96         *  - MC_CMD_ERR_ENOSYS (reported as ENOTSUP):
  97         *      Firmware does not support the MC_CMD_WORKAROUND request.
  98         *      (assume that the workaround is not supported).
  99         *  - MC_CMD_ERR_ENOENT (reported as ENOENT):
 100         *      Firmware does not support the requested workaround.
 101         *  - MC_CMD_ERR_EPERM  (reported as EACCES):
 102         *      Unprivileged function cannot enable/disable workarounds.
 103         *
 104         * See efx_mcdi_request_errcode() for MCDI error translations.
 105         */
 106
 107        /*
 108         * Replay engine on Riverhead should suppress duplicate packets
 109         * (e.g. because of exact multicast and all-multicast filters
 110         * match) to the same RxQ.
 111         */
 112        encp->enc_bug26807_workaround = B_FALSE;
 113
 114        /*
 115         * Checksums for TSO sends should always be correct on Riverhead.
 116         * FIXME: revisit when TSO support is implemented.
 117         */
 118        encp->enc_bug61297_workaround = B_FALSE;
 119
 120        encp->enc_evq_max_nevs = RHEAD_EVQ_MAXNEVS;
 121        encp->enc_evq_min_nevs = RHEAD_EVQ_MINNEVS;
 122        encp->enc_rxq_max_ndescs = RHEAD_RXQ_MAXNDESCS;
 123        encp->enc_rxq_min_ndescs = RHEAD_RXQ_MINNDESCS;
 124        encp->enc_txq_max_ndescs = RHEAD_TXQ_MAXNDESCS;
 125        encp->enc_txq_min_ndescs = RHEAD_TXQ_MINNDESCS;
 126
 127        /* Riverhead FW does not support event queue timers yet. */
 128        encp->enc_evq_timer_quantum_ns = 0;
 129        encp->enc_evq_timer_max_us = 0;
 130
 131#if EFSYS_OPT_EV_EXTENDED_WIDTH
 132        encp->enc_ev_ew_desc_size = RHEAD_EVQ_EW_DESC_SIZE;
 133#else
 134        encp->enc_ev_ew_desc_size = 0;
 135#endif
 136
 137        encp->enc_ev_desc_size = RHEAD_EVQ_DESC_SIZE;
 138        encp->enc_rx_desc_size = RHEAD_RXQ_DESC_SIZE;
 139        encp->enc_tx_desc_size = RHEAD_TXQ_DESC_SIZE;
 140
 141        /* No required alignment for WPTR updates */
 142        encp->enc_rx_push_align = 1;
 143
 144        /* Riverhead supports a single Rx prefix size. */
 145        encp->enc_rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN;
 146
 147        /* Alignment for receive packet DMA buffers. */
 148        encp->enc_rx_buf_align_start = 1;
 149
 150        /* Get the RX DMA end padding alignment configuration. */
 151        if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0) {
 152                if (rc != EACCES)
 153                        goto fail2;
 154
 155                /* Assume largest tail padding size supported by hardware. */
 156                end_padding = 128;
 157        }
 158        encp->enc_rx_buf_align_end = end_padding;
 159
 160        /* FIXME: It should be extracted from design parameters (Bug 86844) */
 161        encp->enc_rx_scatter_max = 7;
 162
 163        /*
 164         * Riverhead stores a single global copy of VPD, not per-PF as on
 165         * Huntington.
 166         */
 167        encp->enc_vpd_is_global = B_TRUE;
 168
 169        rc = ef10_nic_get_port_mode_bandwidth(enp, &bandwidth);
 170        if (rc != 0)
 171                goto fail3;
 172        encp->enc_required_pcie_bandwidth_mbps = bandwidth;
 173        encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN3;
 174
 175        return (0);
 176
 177fail3:
 178        EFSYS_PROBE(fail3);
 179fail2:
 180        EFSYS_PROBE(fail2);
 181fail1:
 182        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 183
 184        return (rc);
 185}
 186
 187        __checkReturn   efx_rc_t
 188rhead_nic_probe(
 189        __in            efx_nic_t *enp)
 190{
 191        const efx_nic_ops_t *enop = enp->en_enop;
 192        efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 193        efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
 194        efx_rc_t rc;
 195
 196        EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
 197
 198        /* Read and clear any assertion state */
 199        if ((rc = efx_mcdi_read_assertion(enp)) != 0)
 200                goto fail1;
 201
 202        /* Exit the assertion handler */
 203        if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
 204                if (rc != EACCES)
 205                        goto fail2;
 206
 207        if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
 208                goto fail3;
 209
 210        /* Get remaining controller-specific board config */
 211        if ((rc = enop->eno_board_cfg(enp)) != 0)
 212                goto fail4;
 213
 214        /*
 215         * Set default driver config limits (based on board config).
 216         *
 217         * FIXME: For now allocate a fixed number of VIs which is likely to be
 218         * sufficient and small enough to allow multiple functions on the same
 219         * port.
 220         */
 221        edcp->edc_min_vi_count = edcp->edc_max_vi_count =
 222            MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
 223
 224        /*
 225         * The client driver must configure and enable PIO buffer support,
 226         * but there is no PIO support on Riverhead anyway.
 227         */
 228        edcp->edc_max_piobuf_count = 0;
 229        edcp->edc_pio_alloc_size = 0;
 230
 231#if EFSYS_OPT_MAC_STATS
 232        /* Wipe the MAC statistics */
 233        if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
 234                goto fail5;
 235#endif
 236
 237#if EFSYS_OPT_LOOPBACK
 238        if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
 239                goto fail6;
 240#endif
 241
 242        return (0);
 243
 244#if EFSYS_OPT_LOOPBACK
 245fail6:
 246        EFSYS_PROBE(fail6);
 247#endif
 248#if EFSYS_OPT_MAC_STATS
 249fail5:
 250        EFSYS_PROBE(fail5);
 251#endif
 252fail4:
 253        EFSYS_PROBE(fail4);
 254fail3:
 255        EFSYS_PROBE(fail3);
 256fail2:
 257        EFSYS_PROBE(fail2);
 258fail1:
 259        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 260
 261        return (rc);
 262}
 263
 264        __checkReturn   efx_rc_t
 265rhead_nic_set_drv_limits(
 266        __inout         efx_nic_t *enp,
 267        __in            efx_drv_limits_t *edlp)
 268{
 269        const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
 270        efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
 271        uint32_t min_evq_count, max_evq_count;
 272        uint32_t min_rxq_count, max_rxq_count;
 273        uint32_t min_txq_count, max_txq_count;
 274        efx_rc_t rc;
 275
 276        if (edlp == NULL) {
 277                rc = EINVAL;
 278                goto fail1;
 279        }
 280
 281        /* Get minimum required and maximum usable VI limits */
 282        min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
 283        min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
 284        min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
 285
 286        edcp->edc_min_vi_count =
 287            MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
 288
 289        max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
 290        max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
 291        max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
 292
 293        edcp->edc_max_vi_count =
 294            MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
 295
 296        /* There is no PIO support on Riverhead */
 297        edcp->edc_max_piobuf_count = 0;
 298        edcp->edc_pio_alloc_size = 0;
 299
 300        return (0);
 301
 302fail1:
 303        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 304
 305        return (rc);
 306}
 307
 308        __checkReturn   efx_rc_t
 309rhead_nic_reset(
 310        __in            efx_nic_t *enp)
 311{
 312        efx_rc_t rc;
 313
 314        /* ef10_nic_reset() is called to recover from BADASSERT failures. */
 315        if ((rc = efx_mcdi_read_assertion(enp)) != 0)
 316                goto fail1;
 317        if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
 318                goto fail2;
 319
 320        if ((rc = efx_mcdi_entity_reset(enp)) != 0)
 321                goto fail3;
 322
 323        /* Clear RX/TX DMA queue errors */
 324        enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
 325
 326        return (0);
 327
 328fail3:
 329        EFSYS_PROBE(fail3);
 330fail2:
 331        EFSYS_PROBE(fail2);
 332fail1:
 333        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 334
 335        return (rc);
 336}
 337
 338        __checkReturn   efx_rc_t
 339rhead_nic_init(
 340        __in            efx_nic_t *enp)
 341{
 342        const efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
 343        uint32_t min_vi_count, max_vi_count;
 344        uint32_t vi_count, vi_base, vi_shift;
 345        uint32_t vi_window_size;
 346        efx_rc_t rc;
 347        boolean_t alloc_vadaptor = B_TRUE;
 348
 349        EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
 350        EFSYS_ASSERT3U(edcp->edc_max_piobuf_count, ==, 0);
 351
 352        /* Enable reporting of some events (e.g. link change) */
 353        if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
 354                goto fail1;
 355
 356        min_vi_count = edcp->edc_min_vi_count;
 357        max_vi_count = edcp->edc_max_vi_count;
 358
 359        /* Ensure that the previously attached driver's VIs are freed */
 360        if ((rc = efx_mcdi_free_vis(enp)) != 0)
 361                goto fail2;
 362
 363        /*
 364         * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
 365         * fails then retrying the request for fewer VI resources may succeed.
 366         */
 367        vi_count = 0;
 368        if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
 369                    &vi_base, &vi_count, &vi_shift)) != 0)
 370                goto fail3;
 371
 372        EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
 373
 374        if (vi_count < min_vi_count) {
 375                rc = ENOMEM;
 376                goto fail4;
 377        }
 378
 379        enp->en_arch.ef10.ena_vi_base = vi_base;
 380        enp->en_arch.ef10.ena_vi_count = vi_count;
 381        enp->en_arch.ef10.ena_vi_shift = vi_shift;
 382
 383        EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=,
 384            EFX_VI_WINDOW_SHIFT_INVALID);
 385        EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=,
 386            EFX_VI_WINDOW_SHIFT_64K);
 387        vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift;
 388
 389        /* Save UC memory mapping details */
 390        enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
 391        enp->en_arch.ef10.ena_uc_mem_map_size =
 392            vi_window_size * enp->en_arch.ef10.ena_vi_count;
 393
 394        /* No WC memory mapping since PIO is not supported */
 395        enp->en_arch.ef10.ena_pio_write_vi_base = 0;
 396        enp->en_arch.ef10.ena_wc_mem_map_offset = 0;
 397        enp->en_arch.ef10.ena_wc_mem_map_size = 0;
 398
 399        enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2;
 400
 401        /*
 402         * For SR-IOV use case, vAdaptor is allocated for PF and associated VFs
 403         * during NIC initialization when vSwitch is created and vPorts are
 404         * allocated. Hence, skip vAdaptor allocation for EVB and update vPort
 405         * ID in NIC structure with the one allocated for PF.
 406         */
 407
 408        enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
 409#if EFSYS_OPT_EVB
 410        if ((enp->en_vswitchp != NULL) && (enp->en_vswitchp->ev_evcp != NULL)) {
 411                /* For EVB use vPort allocated on vSwitch */
 412                enp->en_vport_id = enp->en_vswitchp->ev_evcp->evc_vport_id;
 413                alloc_vadaptor = B_FALSE;
 414        }
 415#endif
 416        if (alloc_vadaptor != B_FALSE) {
 417                /* Allocate a vAdaptor attached to our upstream vPort/pPort */
 418                if ((rc = ef10_upstream_port_vadaptor_alloc(enp)) != 0)
 419                        goto fail5;
 420        }
 421
 422        return (0);
 423
 424fail5:
 425        EFSYS_PROBE(fail5);
 426
 427fail4:
 428        EFSYS_PROBE(fail4);
 429
 430        (void) efx_mcdi_free_vis(enp);
 431
 432fail3:
 433        EFSYS_PROBE(fail3);
 434fail2:
 435        EFSYS_PROBE(fail2);
 436fail1:
 437        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 438
 439        return (rc);
 440}
 441
 442        __checkReturn   efx_rc_t
 443rhead_nic_get_vi_pool(
 444        __in            efx_nic_t *enp,
 445        __out           uint32_t *vi_countp)
 446{
 447        /*
 448         * Report VIs that the client driver can use.
 449         * Do not include VIs used for PIO buffer writes.
 450         */
 451        *vi_countp = enp->en_arch.ef10.ena_vi_count;
 452
 453        return (0);
 454}
 455
 456        __checkReturn   efx_rc_t
 457rhead_nic_get_bar_region(
 458        __in            efx_nic_t *enp,
 459        __in            efx_nic_region_t region,
 460        __out           uint32_t *offsetp,
 461        __out           size_t *sizep)
 462{
 463        efx_rc_t rc;
 464
 465        EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
 466
 467        /*
 468         * TODO: Specify host memory mapping alignment and granularity
 469         * in efx_drv_limits_t so that they can be taken into account
 470         * when allocating extra VIs for PIO writes.
 471         */
 472        switch (region) {
 473        case EFX_REGION_VI:
 474                /* UC mapped memory BAR region for VI registers */
 475                *offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
 476                *sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
 477                break;
 478
 479        case EFX_REGION_PIO_WRITE_VI:
 480                /* WC mapped memory BAR region for piobuf writes */
 481                *offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
 482                *sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
 483                break;
 484
 485        default:
 486                rc = EINVAL;
 487                goto fail1;
 488        }
 489
 490        return (0);
 491
 492fail1:
 493        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 494
 495        return (rc);
 496}
 497
 498        __checkReturn   boolean_t
 499rhead_nic_hw_unavailable(
 500        __in            efx_nic_t *enp)
 501{
 502        efx_dword_t dword;
 503
 504        if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
 505                return (B_TRUE);
 506
 507        EFX_BAR_FCW_READD(enp, ER_GZ_MC_SFT_STATUS, &dword);
 508        if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
 509                goto unavail;
 510
 511        return (B_FALSE);
 512
 513unavail:
 514        rhead_nic_set_hw_unavailable(enp);
 515
 516        return (B_TRUE);
 517}
 518
 519                        void
 520rhead_nic_set_hw_unavailable(
 521        __in            efx_nic_t *enp)
 522{
 523        EFSYS_PROBE(hw_unavail);
 524        enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
 525}
 526
 527                        void
 528rhead_nic_fini(
 529        __in            efx_nic_t *enp)
 530{
 531        boolean_t do_vadaptor_free = B_TRUE;
 532
 533#if EFSYS_OPT_EVB
 534        if (enp->en_vswitchp != NULL) {
 535                /*
 536                 * For SR-IOV the vAdaptor is freed with the vSwitch,
 537                 * so do not free it here.
 538                 */
 539                do_vadaptor_free = B_FALSE;
 540        }
 541#endif
 542        if (do_vadaptor_free != B_FALSE) {
 543                (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
 544                enp->en_vport_id = EVB_PORT_ID_NULL;
 545        }
 546
 547        (void) efx_mcdi_free_vis(enp);
 548        enp->en_arch.ef10.ena_vi_count = 0;
 549}
 550
 551                        void
 552rhead_nic_unprobe(
 553        __in            efx_nic_t *enp)
 554{
 555        (void) efx_mcdi_drv_attach(enp, B_FALSE);
 556}
 557
 558#if EFSYS_OPT_DIAG
 559
 560        __checkReturn   efx_rc_t
 561rhead_nic_register_test(
 562        __in            efx_nic_t *enp)
 563{
 564        efx_rc_t rc;
 565
 566        /* FIXME */
 567        _NOTE(ARGUNUSED(enp))
 568        _NOTE(CONSTANTCONDITION)
 569        if (B_FALSE) {
 570                rc = ENOTSUP;
 571                goto fail1;
 572        }
 573        /* FIXME */
 574
 575        return (0);
 576
 577fail1:
 578        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 579
 580        return (rc);
 581}
 582
 583#endif  /* EFSYS_OPT_DIAG */
 584
 585        __checkReturn                   efx_rc_t
 586rhead_nic_xilinx_cap_tbl_read_ef100_locator(
 587        __in                            efsys_bar_t *esbp,
 588        __in                            efsys_dma_addr_t offset,
 589        __out                           efx_bar_region_t *ebrp)
 590{
 591        efx_oword_t entry;
 592        uint32_t rev;
 593        uint32_t len;
 594        efx_rc_t rc;
 595
 596        /*
 597         * Xilinx Capabilities Table requires 32bit aligned reads.
 598         * See SF-119689-TC section 4.2.2 "Discovery Steps".
 599         */
 600        EFSYS_BAR_READD(esbp, offset +
 601                        (EFX_LOW_BIT(ESF_GZ_CFGBAR_ENTRY_FORMAT) / 8),
 602                        &entry.eo_dword[0], B_FALSE);
 603        EFSYS_BAR_READD(esbp, offset +
 604                        (EFX_LOW_BIT(ESF_GZ_CFGBAR_ENTRY_SIZE) / 8),
 605                        &entry.eo_dword[1], B_FALSE);
 606
 607        rev = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_ENTRY_REV);
 608        len = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_ENTRY_SIZE);
 609
 610        if (rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100 ||
 611            len < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100) {
 612                rc = EINVAL;
 613                goto fail1;
 614        }
 615
 616        EFSYS_BAR_READD(esbp, offset +
 617                        (EFX_LOW_BIT(ESF_GZ_CFGBAR_EF100_BAR) / 8),
 618                        &entry.eo_dword[2], B_FALSE);
 619
 620        ebrp->ebr_index = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_EF100_BAR);
 621        ebrp->ebr_offset = EFX_OWORD_FIELD32(entry,
 622                        ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF) <<
 623                        ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
 624        ebrp->ebr_type = EFX_BAR_TYPE_MEM;
 625        ebrp->ebr_length = 0;
 626
 627        return (0);
 628
 629fail1:
 630        EFSYS_PROBE1(fail1, efx_rc_t, rc);
 631
 632        return (rc);
 633}
 634
 635#endif  /* EFSYS_OPT_RIVERHEAD */
 636