xref: /dpdk/drivers/common/sfc_efx/base/rhead_nic.c (revision 950fe1ed0818e4e3582f62f02030c834decf09c0)
13c1c5cc4SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
23c1c5cc4SAndrew Rybchenko  *
3672386c1SAndrew Rybchenko  * Copyright(c) 2019-2021 Xilinx, Inc.
43c1c5cc4SAndrew Rybchenko  * Copyright(c) 2018-2019 Solarflare Communications Inc.
53c1c5cc4SAndrew Rybchenko  */
63c1c5cc4SAndrew Rybchenko 
73c1c5cc4SAndrew Rybchenko #include "efx.h"
83c1c5cc4SAndrew Rybchenko #include "efx_impl.h"
93c1c5cc4SAndrew Rybchenko 
103c1c5cc4SAndrew Rybchenko 
113c1c5cc4SAndrew Rybchenko #if EFSYS_OPT_RIVERHEAD
123c1c5cc4SAndrew Rybchenko 
133c1c5cc4SAndrew Rybchenko 	__checkReturn	efx_rc_t
rhead_board_cfg(__in efx_nic_t * enp)143c1c5cc4SAndrew Rybchenko rhead_board_cfg(
153c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
163c1c5cc4SAndrew Rybchenko {
173c1c5cc4SAndrew Rybchenko 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
183c1c5cc4SAndrew Rybchenko 	uint32_t end_padding;
193c1c5cc4SAndrew Rybchenko 	uint32_t bandwidth;
203c1c5cc4SAndrew Rybchenko 	efx_rc_t rc;
213c1c5cc4SAndrew Rybchenko 
223c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_nic_board_cfg(enp)) != 0)
233c1c5cc4SAndrew Rybchenko 		goto fail1;
243c1c5cc4SAndrew Rybchenko 
25d874d2a1SIgor Romanov 	/*
26d874d2a1SIgor Romanov 	 * The tunnel encapsulation initialization happens unconditionally
27d874d2a1SIgor Romanov 	 * for now.
28d874d2a1SIgor Romanov 	 */
29d874d2a1SIgor Romanov 	encp->enc_tunnel_encapsulations_supported =
30d874d2a1SIgor Romanov 	    (1u << EFX_TUNNEL_PROTOCOL_VXLAN) |
31d874d2a1SIgor Romanov 	    (1u << EFX_TUNNEL_PROTOCOL_NVGRE);
32d874d2a1SIgor Romanov 
33d874d2a1SIgor Romanov 	/*
34d874d2a1SIgor Romanov 	 * Software limitation inherited from EF10. This limit is not
35d874d2a1SIgor Romanov 	 * increased since the hardware does not report this limit, it is
36d874d2a1SIgor Romanov 	 * handled internally resulting in a tunnel add error when there is no
37d874d2a1SIgor Romanov 	 * space for more UDP tunnels.
38d874d2a1SIgor Romanov 	 */
39d874d2a1SIgor Romanov 	encp->enc_tunnel_config_udp_entries_max = EFX_TUNNEL_MAXNENTRIES;
40d874d2a1SIgor Romanov 
413c1c5cc4SAndrew Rybchenko 	encp->enc_clk_mult = 1; /* not used for Riverhead */
423c1c5cc4SAndrew Rybchenko 
4361b3e9e7SIvan Malov 	EFX_STATIC_ASSERT(MC_CMD_INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES_LEN == 4);
4461b3e9e7SIvan Malov 	/* Agrees with MC_CMD_INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES_LEN */
4561b3e9e7SIvan Malov 	encp->enc_rx_dma_desc_size_max = UINT32_MAX;
4661b3e9e7SIvan Malov 
473c1c5cc4SAndrew Rybchenko 	/*
483c1c5cc4SAndrew Rybchenko 	 * FIXME There are TxSend and TxSeg descriptors on Riverhead.
493c1c5cc4SAndrew Rybchenko 	 * TxSeg is bigger than TxSend.
503c1c5cc4SAndrew Rybchenko 	 */
513c1c5cc4SAndrew Rybchenko 	encp->enc_tx_dma_desc_size_max = EFX_MASK32(ESF_GZ_TX_SEND_LEN);
523c1c5cc4SAndrew Rybchenko 	/* No boundary crossing limits */
533c1c5cc4SAndrew Rybchenko 	encp->enc_tx_dma_desc_boundary = 0;
543c1c5cc4SAndrew Rybchenko 
553c1c5cc4SAndrew Rybchenko 	/*
567ed3ac82SIvan Malov 	 * Initialise design parameters to either a runtime value read from
577ed3ac82SIvan Malov 	 * the design parameters area or the well known default value
587ed3ac82SIvan Malov 	 * (see SF-119689-TC section 4.4 for details).
597ed3ac82SIvan Malov 	 * FIXME: Read design parameters area values.
603c1c5cc4SAndrew Rybchenko 	 */
617ed3ac82SIvan Malov 	encp->enc_tx_tso_max_header_ndescs =
627ed3ac82SIvan Malov 	    ESE_EF100_DP_GZ_TSO_MAX_HDR_NUM_SEGS_DEFAULT;
637ed3ac82SIvan Malov 	encp->enc_tx_tso_max_header_length =
647ed3ac82SIvan Malov 	    ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT;
657ed3ac82SIvan Malov 	encp->enc_tx_tso_max_payload_ndescs =
667ed3ac82SIvan Malov 	    ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_NUM_SEGS_DEFAULT;
677ed3ac82SIvan Malov 	encp->enc_tx_tso_max_payload_length =
687ed3ac82SIvan Malov 	    ESE_EF100_DP_GZ_TSO_MAX_PAYLOAD_LEN_DEFAULT;
697ed3ac82SIvan Malov 	encp->enc_tx_tso_max_nframes =
707ed3ac82SIvan Malov 	    ESE_EF100_DP_GZ_TSO_MAX_NUM_FRAMES_DEFAULT;
717ed3ac82SIvan Malov 
727ed3ac82SIvan Malov 	/*
737ed3ac82SIvan Malov 	 * Riverhead does not put any restrictions on TCP header offset limit.
747ed3ac82SIvan Malov 	 */
757ed3ac82SIvan Malov 	encp->enc_tx_tso_tcp_header_offset_limit = UINT32_MAX;
763c1c5cc4SAndrew Rybchenko 
773c1c5cc4SAndrew Rybchenko 	/*
783c1c5cc4SAndrew Rybchenko 	 * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
793c1c5cc4SAndrew Rybchenko 	 * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
803c1c5cc4SAndrew Rybchenko 	 * resources (allocated to this PCIe function), which is zero until
813c1c5cc4SAndrew Rybchenko 	 * after we have allocated VIs.
823c1c5cc4SAndrew Rybchenko 	 */
833c1c5cc4SAndrew Rybchenko 	encp->enc_evq_limit = 1024;
843c1c5cc4SAndrew Rybchenko 	encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
853c1c5cc4SAndrew Rybchenko 	encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
863c1c5cc4SAndrew Rybchenko 
873c1c5cc4SAndrew Rybchenko 	encp->enc_buftbl_limit = UINT32_MAX;
883c1c5cc4SAndrew Rybchenko 
893c1c5cc4SAndrew Rybchenko 	/*
9092fedcd3SIvan Malov 	 * Riverhead event queue creation completes
9192fedcd3SIvan Malov 	 * immediately (no initial event).
9292fedcd3SIvan Malov 	 */
9392fedcd3SIvan Malov 	encp->enc_evq_init_done_ev_supported = B_FALSE;
9492fedcd3SIvan Malov 
9592fedcd3SIvan Malov 	/*
963c1c5cc4SAndrew Rybchenko 	 * Enable firmware workarounds for hardware errata.
973c1c5cc4SAndrew Rybchenko 	 * Expected responses are:
983c1c5cc4SAndrew Rybchenko 	 *  - 0 (zero):
993c1c5cc4SAndrew Rybchenko 	 *	Success: workaround enabled or disabled as requested.
1003c1c5cc4SAndrew Rybchenko 	 *  - MC_CMD_ERR_ENOSYS (reported as ENOTSUP):
1013c1c5cc4SAndrew Rybchenko 	 *	Firmware does not support the MC_CMD_WORKAROUND request.
1023c1c5cc4SAndrew Rybchenko 	 *	(assume that the workaround is not supported).
1033c1c5cc4SAndrew Rybchenko 	 *  - MC_CMD_ERR_ENOENT (reported as ENOENT):
1043c1c5cc4SAndrew Rybchenko 	 *	Firmware does not support the requested workaround.
1053c1c5cc4SAndrew Rybchenko 	 *  - MC_CMD_ERR_EPERM  (reported as EACCES):
1063c1c5cc4SAndrew Rybchenko 	 *	Unprivileged function cannot enable/disable workarounds.
1073c1c5cc4SAndrew Rybchenko 	 *
1083c1c5cc4SAndrew Rybchenko 	 * See efx_mcdi_request_errcode() for MCDI error translations.
1093c1c5cc4SAndrew Rybchenko 	 */
1103c1c5cc4SAndrew Rybchenko 
1113c1c5cc4SAndrew Rybchenko 	/*
1123c1c5cc4SAndrew Rybchenko 	 * Replay engine on Riverhead should suppress duplicate packets
1133c1c5cc4SAndrew Rybchenko 	 * (e.g. because of exact multicast and all-multicast filters
1143c1c5cc4SAndrew Rybchenko 	 * match) to the same RxQ.
1153c1c5cc4SAndrew Rybchenko 	 */
1163c1c5cc4SAndrew Rybchenko 	encp->enc_bug26807_workaround = B_FALSE;
1173c1c5cc4SAndrew Rybchenko 
1183c1c5cc4SAndrew Rybchenko 	/*
1193c1c5cc4SAndrew Rybchenko 	 * Checksums for TSO sends should always be correct on Riverhead.
1203c1c5cc4SAndrew Rybchenko 	 * FIXME: revisit when TSO support is implemented.
1213c1c5cc4SAndrew Rybchenko 	 */
1223c1c5cc4SAndrew Rybchenko 	encp->enc_bug61297_workaround = B_FALSE;
1233c1c5cc4SAndrew Rybchenko 
1243c1c5cc4SAndrew Rybchenko 	encp->enc_evq_max_nevs = RHEAD_EVQ_MAXNEVS;
1253c1c5cc4SAndrew Rybchenko 	encp->enc_evq_min_nevs = RHEAD_EVQ_MINNEVS;
1263c1c5cc4SAndrew Rybchenko 	encp->enc_rxq_max_ndescs = RHEAD_RXQ_MAXNDESCS;
1273c1c5cc4SAndrew Rybchenko 	encp->enc_rxq_min_ndescs = RHEAD_RXQ_MINNDESCS;
1283c1c5cc4SAndrew Rybchenko 	encp->enc_txq_max_ndescs = RHEAD_TXQ_MAXNDESCS;
1293c1c5cc4SAndrew Rybchenko 	encp->enc_txq_min_ndescs = RHEAD_TXQ_MINNDESCS;
1303c1c5cc4SAndrew Rybchenko 
1313c1c5cc4SAndrew Rybchenko 	/* Riverhead FW does not support event queue timers yet. */
1323c1c5cc4SAndrew Rybchenko 	encp->enc_evq_timer_quantum_ns = 0;
1333c1c5cc4SAndrew Rybchenko 	encp->enc_evq_timer_max_us = 0;
1343c1c5cc4SAndrew Rybchenko 
135f8a60f76SAndy Moreton #if EFSYS_OPT_EV_EXTENDED_WIDTH
136f8a60f76SAndy Moreton 	encp->enc_ev_ew_desc_size = RHEAD_EVQ_EW_DESC_SIZE;
137f8a60f76SAndy Moreton #else
138f8a60f76SAndy Moreton 	encp->enc_ev_ew_desc_size = 0;
139f8a60f76SAndy Moreton #endif
140f8a60f76SAndy Moreton 
1413c1c5cc4SAndrew Rybchenko 	encp->enc_ev_desc_size = RHEAD_EVQ_DESC_SIZE;
1423c1c5cc4SAndrew Rybchenko 	encp->enc_rx_desc_size = RHEAD_RXQ_DESC_SIZE;
1433c1c5cc4SAndrew Rybchenko 	encp->enc_tx_desc_size = RHEAD_TXQ_DESC_SIZE;
1443c1c5cc4SAndrew Rybchenko 
1453c1c5cc4SAndrew Rybchenko 	/* No required alignment for WPTR updates */
1463c1c5cc4SAndrew Rybchenko 	encp->enc_rx_push_align = 1;
1473c1c5cc4SAndrew Rybchenko 
1483c1c5cc4SAndrew Rybchenko 	/* Riverhead supports a single Rx prefix size. */
1493c1c5cc4SAndrew Rybchenko 	encp->enc_rx_prefix_size = ESE_GZ_RX_PKT_PREFIX_LEN;
1503c1c5cc4SAndrew Rybchenko 
1513c1c5cc4SAndrew Rybchenko 	/* Alignment for receive packet DMA buffers. */
1523c1c5cc4SAndrew Rybchenko 	encp->enc_rx_buf_align_start = 1;
1533c1c5cc4SAndrew Rybchenko 
1543c1c5cc4SAndrew Rybchenko 	/* Get the RX DMA end padding alignment configuration. */
1553c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_get_rxdp_config(enp, &end_padding)) != 0) {
1563c1c5cc4SAndrew Rybchenko 		if (rc != EACCES)
1573c1c5cc4SAndrew Rybchenko 			goto fail2;
1583c1c5cc4SAndrew Rybchenko 
1593c1c5cc4SAndrew Rybchenko 		/* Assume largest tail padding size supported by hardware. */
1603c1c5cc4SAndrew Rybchenko 		end_padding = 128;
1613c1c5cc4SAndrew Rybchenko 	}
1623c1c5cc4SAndrew Rybchenko 	encp->enc_rx_buf_align_end = end_padding;
1633c1c5cc4SAndrew Rybchenko 
164abd9dc47SAndrew Rybchenko 	/* FIXME: It should be extracted from design parameters (Bug 86844) */
165abd9dc47SAndrew Rybchenko 	encp->enc_rx_scatter_max = 7;
166abd9dc47SAndrew Rybchenko 
1673c1c5cc4SAndrew Rybchenko 	/*
1683c1c5cc4SAndrew Rybchenko 	 * Riverhead stores a single global copy of VPD, not per-PF as on
1693c1c5cc4SAndrew Rybchenko 	 * Huntington.
1703c1c5cc4SAndrew Rybchenko 	 */
1713c1c5cc4SAndrew Rybchenko 	encp->enc_vpd_is_global = B_TRUE;
1723c1c5cc4SAndrew Rybchenko 
1733c1c5cc4SAndrew Rybchenko 	rc = ef10_nic_get_port_mode_bandwidth(enp, &bandwidth);
1743c1c5cc4SAndrew Rybchenko 	if (rc != 0)
1753c1c5cc4SAndrew Rybchenko 		goto fail3;
1763c1c5cc4SAndrew Rybchenko 	encp->enc_required_pcie_bandwidth_mbps = bandwidth;
1773c1c5cc4SAndrew Rybchenko 	encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN3;
1783c1c5cc4SAndrew Rybchenko 
179*950fe1edSDenis Pryazhennikov 	/*
180*950fe1edSDenis Pryazhennikov 	 * FIXME: MCDI table API support depends on an EF100 firmware build
181*950fe1edSDenis Pryazhennikov 	 * and an EF100 platform. It should be discovered by using a capability
182*950fe1edSDenis Pryazhennikov 	 * flag from MCDI that is not implemented yet.
183*950fe1edSDenis Pryazhennikov 	 * Right now we can safely rely on the return code from the libefx
184*950fe1edSDenis Pryazhennikov 	 * MCDI Table API.
185*950fe1edSDenis Pryazhennikov 	 */
186*950fe1edSDenis Pryazhennikov 	encp->enc_table_api_supported = B_TRUE;
187*950fe1edSDenis Pryazhennikov 
1883c1c5cc4SAndrew Rybchenko 	return (0);
1893c1c5cc4SAndrew Rybchenko 
1903c1c5cc4SAndrew Rybchenko fail3:
1913c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail3);
1923c1c5cc4SAndrew Rybchenko fail2:
1933c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail2);
1943c1c5cc4SAndrew Rybchenko fail1:
1953c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
1963c1c5cc4SAndrew Rybchenko 
1973c1c5cc4SAndrew Rybchenko 	return (rc);
1983c1c5cc4SAndrew Rybchenko }
1993c1c5cc4SAndrew Rybchenko 
2003c1c5cc4SAndrew Rybchenko 	__checkReturn	efx_rc_t
rhead_nic_probe(__in efx_nic_t * enp)2013c1c5cc4SAndrew Rybchenko rhead_nic_probe(
2023c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
2033c1c5cc4SAndrew Rybchenko {
2043c1c5cc4SAndrew Rybchenko 	const efx_nic_ops_t *enop = enp->en_enop;
2053c1c5cc4SAndrew Rybchenko 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
2063c1c5cc4SAndrew Rybchenko 	efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
2073c1c5cc4SAndrew Rybchenko 	efx_rc_t rc;
2083c1c5cc4SAndrew Rybchenko 
2093c1c5cc4SAndrew Rybchenko 	EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
2103c1c5cc4SAndrew Rybchenko 
2113c1c5cc4SAndrew Rybchenko 	/* Read and clear any assertion state */
2123c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
2133c1c5cc4SAndrew Rybchenko 		goto fail1;
2143c1c5cc4SAndrew Rybchenko 
2153c1c5cc4SAndrew Rybchenko 	/* Exit the assertion handler */
2163c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
2173c1c5cc4SAndrew Rybchenko 		if (rc != EACCES)
2183c1c5cc4SAndrew Rybchenko 			goto fail2;
2193c1c5cc4SAndrew Rybchenko 
2203c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
2213c1c5cc4SAndrew Rybchenko 		goto fail3;
2223c1c5cc4SAndrew Rybchenko 
2233c1c5cc4SAndrew Rybchenko 	/* Get remaining controller-specific board config */
2243c1c5cc4SAndrew Rybchenko 	if ((rc = enop->eno_board_cfg(enp)) != 0)
2253c1c5cc4SAndrew Rybchenko 		goto fail4;
2263c1c5cc4SAndrew Rybchenko 
2273c1c5cc4SAndrew Rybchenko 	/*
2283c1c5cc4SAndrew Rybchenko 	 * Set default driver config limits (based on board config).
2293c1c5cc4SAndrew Rybchenko 	 *
2303c1c5cc4SAndrew Rybchenko 	 * FIXME: For now allocate a fixed number of VIs which is likely to be
2313c1c5cc4SAndrew Rybchenko 	 * sufficient and small enough to allow multiple functions on the same
2323c1c5cc4SAndrew Rybchenko 	 * port.
2333c1c5cc4SAndrew Rybchenko 	 */
2343c1c5cc4SAndrew Rybchenko 	edcp->edc_min_vi_count = edcp->edc_max_vi_count =
2353c1c5cc4SAndrew Rybchenko 	    MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
2363c1c5cc4SAndrew Rybchenko 
2373c1c5cc4SAndrew Rybchenko 	/*
2383c1c5cc4SAndrew Rybchenko 	 * The client driver must configure and enable PIO buffer support,
2393c1c5cc4SAndrew Rybchenko 	 * but there is no PIO support on Riverhead anyway.
2403c1c5cc4SAndrew Rybchenko 	 */
2413c1c5cc4SAndrew Rybchenko 	edcp->edc_max_piobuf_count = 0;
2423c1c5cc4SAndrew Rybchenko 	edcp->edc_pio_alloc_size = 0;
2433c1c5cc4SAndrew Rybchenko 
2443c1c5cc4SAndrew Rybchenko #if EFSYS_OPT_MAC_STATS
2453c1c5cc4SAndrew Rybchenko 	/* Wipe the MAC statistics */
2463c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
2473c1c5cc4SAndrew Rybchenko 		goto fail5;
2483c1c5cc4SAndrew Rybchenko #endif
2493c1c5cc4SAndrew Rybchenko 
2503c1c5cc4SAndrew Rybchenko #if EFSYS_OPT_LOOPBACK
2513c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
2523c1c5cc4SAndrew Rybchenko 		goto fail6;
2533c1c5cc4SAndrew Rybchenko #endif
2543c1c5cc4SAndrew Rybchenko 
2553c1c5cc4SAndrew Rybchenko 	return (0);
2563c1c5cc4SAndrew Rybchenko 
2573c1c5cc4SAndrew Rybchenko #if EFSYS_OPT_LOOPBACK
2583c1c5cc4SAndrew Rybchenko fail6:
2593c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail6);
2603c1c5cc4SAndrew Rybchenko #endif
2613c1c5cc4SAndrew Rybchenko #if EFSYS_OPT_MAC_STATS
2623c1c5cc4SAndrew Rybchenko fail5:
2633c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail5);
2643c1c5cc4SAndrew Rybchenko #endif
2653c1c5cc4SAndrew Rybchenko fail4:
2663c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail4);
2673c1c5cc4SAndrew Rybchenko fail3:
2683c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail3);
2693c1c5cc4SAndrew Rybchenko fail2:
2703c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail2);
2713c1c5cc4SAndrew Rybchenko fail1:
2723c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
2733c1c5cc4SAndrew Rybchenko 
2743c1c5cc4SAndrew Rybchenko 	return (rc);
2753c1c5cc4SAndrew Rybchenko }
2763c1c5cc4SAndrew Rybchenko 
2773c1c5cc4SAndrew Rybchenko 	__checkReturn	efx_rc_t
rhead_nic_set_drv_limits(__inout efx_nic_t * enp,__in efx_drv_limits_t * edlp)2783c1c5cc4SAndrew Rybchenko rhead_nic_set_drv_limits(
2793c1c5cc4SAndrew Rybchenko 	__inout		efx_nic_t *enp,
2803c1c5cc4SAndrew Rybchenko 	__in		efx_drv_limits_t *edlp)
2813c1c5cc4SAndrew Rybchenko {
2823c1c5cc4SAndrew Rybchenko 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
2833c1c5cc4SAndrew Rybchenko 	efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
2843c1c5cc4SAndrew Rybchenko 	uint32_t min_evq_count, max_evq_count;
2853c1c5cc4SAndrew Rybchenko 	uint32_t min_rxq_count, max_rxq_count;
2863c1c5cc4SAndrew Rybchenko 	uint32_t min_txq_count, max_txq_count;
2873c1c5cc4SAndrew Rybchenko 	efx_rc_t rc;
2883c1c5cc4SAndrew Rybchenko 
2893c1c5cc4SAndrew Rybchenko 	if (edlp == NULL) {
2903c1c5cc4SAndrew Rybchenko 		rc = EINVAL;
2913c1c5cc4SAndrew Rybchenko 		goto fail1;
2923c1c5cc4SAndrew Rybchenko 	}
2933c1c5cc4SAndrew Rybchenko 
2943c1c5cc4SAndrew Rybchenko 	/* Get minimum required and maximum usable VI limits */
2953c1c5cc4SAndrew Rybchenko 	min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
2963c1c5cc4SAndrew Rybchenko 	min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
2973c1c5cc4SAndrew Rybchenko 	min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
2983c1c5cc4SAndrew Rybchenko 
2993c1c5cc4SAndrew Rybchenko 	edcp->edc_min_vi_count =
3003c1c5cc4SAndrew Rybchenko 	    MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
3013c1c5cc4SAndrew Rybchenko 
3023c1c5cc4SAndrew Rybchenko 	max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
3033c1c5cc4SAndrew Rybchenko 	max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
3043c1c5cc4SAndrew Rybchenko 	max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
3053c1c5cc4SAndrew Rybchenko 
3063c1c5cc4SAndrew Rybchenko 	edcp->edc_max_vi_count =
3073c1c5cc4SAndrew Rybchenko 	    MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
3083c1c5cc4SAndrew Rybchenko 
3093c1c5cc4SAndrew Rybchenko 	/* There is no PIO support on Riverhead */
3103c1c5cc4SAndrew Rybchenko 	edcp->edc_max_piobuf_count = 0;
3113c1c5cc4SAndrew Rybchenko 	edcp->edc_pio_alloc_size = 0;
3123c1c5cc4SAndrew Rybchenko 
3133c1c5cc4SAndrew Rybchenko 	return (0);
3143c1c5cc4SAndrew Rybchenko 
3153c1c5cc4SAndrew Rybchenko fail1:
3163c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
3173c1c5cc4SAndrew Rybchenko 
3183c1c5cc4SAndrew Rybchenko 	return (rc);
3193c1c5cc4SAndrew Rybchenko }
3203c1c5cc4SAndrew Rybchenko 
3213c1c5cc4SAndrew Rybchenko 	__checkReturn	efx_rc_t
rhead_nic_reset(__in efx_nic_t * enp)3223c1c5cc4SAndrew Rybchenko rhead_nic_reset(
3233c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
3243c1c5cc4SAndrew Rybchenko {
3253c1c5cc4SAndrew Rybchenko 	efx_rc_t rc;
3263c1c5cc4SAndrew Rybchenko 
3273c1c5cc4SAndrew Rybchenko 	/* ef10_nic_reset() is called to recover from BADASSERT failures. */
3283c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
3293c1c5cc4SAndrew Rybchenko 		goto fail1;
3303c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
3313c1c5cc4SAndrew Rybchenko 		goto fail2;
3323c1c5cc4SAndrew Rybchenko 
3333c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_entity_reset(enp)) != 0)
3343c1c5cc4SAndrew Rybchenko 		goto fail3;
3353c1c5cc4SAndrew Rybchenko 
3363c1c5cc4SAndrew Rybchenko 	/* Clear RX/TX DMA queue errors */
3373c1c5cc4SAndrew Rybchenko 	enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
3383c1c5cc4SAndrew Rybchenko 
3393c1c5cc4SAndrew Rybchenko 	return (0);
3403c1c5cc4SAndrew Rybchenko 
3413c1c5cc4SAndrew Rybchenko fail3:
3423c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail3);
3433c1c5cc4SAndrew Rybchenko fail2:
3443c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail2);
3453c1c5cc4SAndrew Rybchenko fail1:
3463c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
3473c1c5cc4SAndrew Rybchenko 
3483c1c5cc4SAndrew Rybchenko 	return (rc);
3493c1c5cc4SAndrew Rybchenko }
3503c1c5cc4SAndrew Rybchenko 
3513c1c5cc4SAndrew Rybchenko 	__checkReturn	efx_rc_t
rhead_nic_init(__in efx_nic_t * enp)3523c1c5cc4SAndrew Rybchenko rhead_nic_init(
3533c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
3543c1c5cc4SAndrew Rybchenko {
3553c1c5cc4SAndrew Rybchenko 	const efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
3563c1c5cc4SAndrew Rybchenko 	uint32_t min_vi_count, max_vi_count;
3573c1c5cc4SAndrew Rybchenko 	uint32_t vi_count, vi_base, vi_shift;
3583c1c5cc4SAndrew Rybchenko 	uint32_t vi_window_size;
3593c1c5cc4SAndrew Rybchenko 	efx_rc_t rc;
36079867285SAndrew Rybchenko 	boolean_t alloc_vadaptor = B_TRUE;
3613c1c5cc4SAndrew Rybchenko 
3623c1c5cc4SAndrew Rybchenko 	EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
3633c1c5cc4SAndrew Rybchenko 	EFSYS_ASSERT3U(edcp->edc_max_piobuf_count, ==, 0);
3643c1c5cc4SAndrew Rybchenko 
3653c1c5cc4SAndrew Rybchenko 	/* Enable reporting of some events (e.g. link change) */
3663c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
3673c1c5cc4SAndrew Rybchenko 		goto fail1;
3683c1c5cc4SAndrew Rybchenko 
3693c1c5cc4SAndrew Rybchenko 	min_vi_count = edcp->edc_min_vi_count;
3703c1c5cc4SAndrew Rybchenko 	max_vi_count = edcp->edc_max_vi_count;
3713c1c5cc4SAndrew Rybchenko 
3723c1c5cc4SAndrew Rybchenko 	/* Ensure that the previously attached driver's VIs are freed */
3733c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_free_vis(enp)) != 0)
3743c1c5cc4SAndrew Rybchenko 		goto fail2;
3753c1c5cc4SAndrew Rybchenko 
3763c1c5cc4SAndrew Rybchenko 	/*
3773c1c5cc4SAndrew Rybchenko 	 * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
3783c1c5cc4SAndrew Rybchenko 	 * fails then retrying the request for fewer VI resources may succeed.
3793c1c5cc4SAndrew Rybchenko 	 */
3803c1c5cc4SAndrew Rybchenko 	vi_count = 0;
3813c1c5cc4SAndrew Rybchenko 	if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
3823c1c5cc4SAndrew Rybchenko 		    &vi_base, &vi_count, &vi_shift)) != 0)
3833c1c5cc4SAndrew Rybchenko 		goto fail3;
3843c1c5cc4SAndrew Rybchenko 
3853c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
3863c1c5cc4SAndrew Rybchenko 
3873c1c5cc4SAndrew Rybchenko 	if (vi_count < min_vi_count) {
3883c1c5cc4SAndrew Rybchenko 		rc = ENOMEM;
3893c1c5cc4SAndrew Rybchenko 		goto fail4;
3903c1c5cc4SAndrew Rybchenko 	}
3913c1c5cc4SAndrew Rybchenko 
3923c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_vi_base = vi_base;
3933c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_vi_count = vi_count;
3943c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_vi_shift = vi_shift;
3953c1c5cc4SAndrew Rybchenko 
3963c1c5cc4SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, !=,
3973c1c5cc4SAndrew Rybchenko 	    EFX_VI_WINDOW_SHIFT_INVALID);
3983c1c5cc4SAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_nic_cfg.enc_vi_window_shift, <=,
3993c1c5cc4SAndrew Rybchenko 	    EFX_VI_WINDOW_SHIFT_64K);
4003c1c5cc4SAndrew Rybchenko 	vi_window_size = 1U << enp->en_nic_cfg.enc_vi_window_shift;
4013c1c5cc4SAndrew Rybchenko 
4023c1c5cc4SAndrew Rybchenko 	/* Save UC memory mapping details */
4033c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_uc_mem_map_offset = 0;
4043c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_uc_mem_map_size =
4053c1c5cc4SAndrew Rybchenko 	    vi_window_size * enp->en_arch.ef10.ena_vi_count;
4063c1c5cc4SAndrew Rybchenko 
4073c1c5cc4SAndrew Rybchenko 	/* No WC memory mapping since PIO is not supported */
4083c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_pio_write_vi_base = 0;
4093c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_wc_mem_map_offset = 0;
4103c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_wc_mem_map_size = 0;
4113c1c5cc4SAndrew Rybchenko 
4123c1c5cc4SAndrew Rybchenko 	enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V2;
4133c1c5cc4SAndrew Rybchenko 
41479867285SAndrew Rybchenko 	/*
41579867285SAndrew Rybchenko 	 * For SR-IOV use case, vAdaptor is allocated for PF and associated VFs
41679867285SAndrew Rybchenko 	 * during NIC initialization when vSwitch is created and vPorts are
41779867285SAndrew Rybchenko 	 * allocated. Hence, skip vAdaptor allocation for EVB and update vPort
41879867285SAndrew Rybchenko 	 * ID in NIC structure with the one allocated for PF.
41979867285SAndrew Rybchenko 	 */
42079867285SAndrew Rybchenko 
42179867285SAndrew Rybchenko 	enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
42279867285SAndrew Rybchenko #if EFSYS_OPT_EVB
42379867285SAndrew Rybchenko 	if ((enp->en_vswitchp != NULL) && (enp->en_vswitchp->ev_evcp != NULL)) {
42479867285SAndrew Rybchenko 		/* For EVB use vPort allocated on vSwitch */
42579867285SAndrew Rybchenko 		enp->en_vport_id = enp->en_vswitchp->ev_evcp->evc_vport_id;
42679867285SAndrew Rybchenko 		alloc_vadaptor = B_FALSE;
42779867285SAndrew Rybchenko 	}
42879867285SAndrew Rybchenko #endif
42979867285SAndrew Rybchenko 	if (alloc_vadaptor != B_FALSE) {
43079867285SAndrew Rybchenko 		/* Allocate a vAdaptor attached to our upstream vPort/pPort */
43179867285SAndrew Rybchenko 		if ((rc = ef10_upstream_port_vadaptor_alloc(enp)) != 0)
43279867285SAndrew Rybchenko 			goto fail5;
43379867285SAndrew Rybchenko 	}
43479867285SAndrew Rybchenko 
4353c1c5cc4SAndrew Rybchenko 	return (0);
4363c1c5cc4SAndrew Rybchenko 
43779867285SAndrew Rybchenko fail5:
43879867285SAndrew Rybchenko 	EFSYS_PROBE(fail5);
43979867285SAndrew Rybchenko 
4403c1c5cc4SAndrew Rybchenko fail4:
4413c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail4);
4423c1c5cc4SAndrew Rybchenko 
4433c1c5cc4SAndrew Rybchenko 	(void) efx_mcdi_free_vis(enp);
4443c1c5cc4SAndrew Rybchenko 
4453c1c5cc4SAndrew Rybchenko fail3:
4463c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail3);
4473c1c5cc4SAndrew Rybchenko fail2:
4483c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(fail2);
4493c1c5cc4SAndrew Rybchenko fail1:
4503c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
4513c1c5cc4SAndrew Rybchenko 
4523c1c5cc4SAndrew Rybchenko 	return (rc);
4533c1c5cc4SAndrew Rybchenko }
4543c1c5cc4SAndrew Rybchenko 
4553c1c5cc4SAndrew Rybchenko 	__checkReturn	efx_rc_t
rhead_nic_get_vi_pool(__in efx_nic_t * enp,__out uint32_t * vi_countp)4563c1c5cc4SAndrew Rybchenko rhead_nic_get_vi_pool(
4573c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp,
4583c1c5cc4SAndrew Rybchenko 	__out		uint32_t *vi_countp)
4593c1c5cc4SAndrew Rybchenko {
4603c1c5cc4SAndrew Rybchenko 	/*
4613c1c5cc4SAndrew Rybchenko 	 * Report VIs that the client driver can use.
4623c1c5cc4SAndrew Rybchenko 	 * Do not include VIs used for PIO buffer writes.
4633c1c5cc4SAndrew Rybchenko 	 */
4643c1c5cc4SAndrew Rybchenko 	*vi_countp = enp->en_arch.ef10.ena_vi_count;
4653c1c5cc4SAndrew Rybchenko 
4663c1c5cc4SAndrew Rybchenko 	return (0);
4673c1c5cc4SAndrew Rybchenko }
4683c1c5cc4SAndrew Rybchenko 
4693c1c5cc4SAndrew Rybchenko 	__checkReturn	efx_rc_t
rhead_nic_get_bar_region(__in efx_nic_t * enp,__in efx_nic_region_t region,__out uint32_t * offsetp,__out size_t * sizep)4703c1c5cc4SAndrew Rybchenko rhead_nic_get_bar_region(
4713c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp,
4723c1c5cc4SAndrew Rybchenko 	__in		efx_nic_region_t region,
4733c1c5cc4SAndrew Rybchenko 	__out		uint32_t *offsetp,
4743c1c5cc4SAndrew Rybchenko 	__out		size_t *sizep)
4753c1c5cc4SAndrew Rybchenko {
4763c1c5cc4SAndrew Rybchenko 	efx_rc_t rc;
4773c1c5cc4SAndrew Rybchenko 
4783c1c5cc4SAndrew Rybchenko 	EFSYS_ASSERT(EFX_FAMILY_IS_EF100(enp));
4793c1c5cc4SAndrew Rybchenko 
4803c1c5cc4SAndrew Rybchenko 	/*
4813c1c5cc4SAndrew Rybchenko 	 * TODO: Specify host memory mapping alignment and granularity
4823c1c5cc4SAndrew Rybchenko 	 * in efx_drv_limits_t so that they can be taken into account
4833c1c5cc4SAndrew Rybchenko 	 * when allocating extra VIs for PIO writes.
4843c1c5cc4SAndrew Rybchenko 	 */
4853c1c5cc4SAndrew Rybchenko 	switch (region) {
4863c1c5cc4SAndrew Rybchenko 	case EFX_REGION_VI:
4873c1c5cc4SAndrew Rybchenko 		/* UC mapped memory BAR region for VI registers */
4883c1c5cc4SAndrew Rybchenko 		*offsetp = enp->en_arch.ef10.ena_uc_mem_map_offset;
4893c1c5cc4SAndrew Rybchenko 		*sizep = enp->en_arch.ef10.ena_uc_mem_map_size;
4903c1c5cc4SAndrew Rybchenko 		break;
4913c1c5cc4SAndrew Rybchenko 
4923c1c5cc4SAndrew Rybchenko 	case EFX_REGION_PIO_WRITE_VI:
4933c1c5cc4SAndrew Rybchenko 		/* WC mapped memory BAR region for piobuf writes */
4943c1c5cc4SAndrew Rybchenko 		*offsetp = enp->en_arch.ef10.ena_wc_mem_map_offset;
4953c1c5cc4SAndrew Rybchenko 		*sizep = enp->en_arch.ef10.ena_wc_mem_map_size;
4963c1c5cc4SAndrew Rybchenko 		break;
4973c1c5cc4SAndrew Rybchenko 
4983c1c5cc4SAndrew Rybchenko 	default:
4993c1c5cc4SAndrew Rybchenko 		rc = EINVAL;
5003c1c5cc4SAndrew Rybchenko 		goto fail1;
5013c1c5cc4SAndrew Rybchenko 	}
5023c1c5cc4SAndrew Rybchenko 
5033c1c5cc4SAndrew Rybchenko 	return (0);
5043c1c5cc4SAndrew Rybchenko 
5053c1c5cc4SAndrew Rybchenko fail1:
5063c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
5073c1c5cc4SAndrew Rybchenko 
5083c1c5cc4SAndrew Rybchenko 	return (rc);
5093c1c5cc4SAndrew Rybchenko }
5103c1c5cc4SAndrew Rybchenko 
5113c1c5cc4SAndrew Rybchenko 	__checkReturn	boolean_t
rhead_nic_hw_unavailable(__in efx_nic_t * enp)5123c1c5cc4SAndrew Rybchenko rhead_nic_hw_unavailable(
5133c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
5143c1c5cc4SAndrew Rybchenko {
5153c1c5cc4SAndrew Rybchenko 	efx_dword_t dword;
5163c1c5cc4SAndrew Rybchenko 
5173c1c5cc4SAndrew Rybchenko 	if (enp->en_reset_flags & EFX_RESET_HW_UNAVAIL)
5183c1c5cc4SAndrew Rybchenko 		return (B_TRUE);
5193c1c5cc4SAndrew Rybchenko 
520341bd4e0SIgor Romanov 	EFX_BAR_FCW_READD(enp, ER_GZ_MC_SFT_STATUS, &dword);
5213c1c5cc4SAndrew Rybchenko 	if (EFX_DWORD_FIELD(dword, EFX_DWORD_0) == 0xffffffff)
5223c1c5cc4SAndrew Rybchenko 		goto unavail;
5233c1c5cc4SAndrew Rybchenko 
5243c1c5cc4SAndrew Rybchenko 	return (B_FALSE);
5253c1c5cc4SAndrew Rybchenko 
5263c1c5cc4SAndrew Rybchenko unavail:
5273c1c5cc4SAndrew Rybchenko 	rhead_nic_set_hw_unavailable(enp);
5283c1c5cc4SAndrew Rybchenko 
5293c1c5cc4SAndrew Rybchenko 	return (B_TRUE);
5303c1c5cc4SAndrew Rybchenko }
5313c1c5cc4SAndrew Rybchenko 
5323c1c5cc4SAndrew Rybchenko 			void
rhead_nic_set_hw_unavailable(__in efx_nic_t * enp)5333c1c5cc4SAndrew Rybchenko rhead_nic_set_hw_unavailable(
5343c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
5353c1c5cc4SAndrew Rybchenko {
5363c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE(hw_unavail);
5373c1c5cc4SAndrew Rybchenko 	enp->en_reset_flags |= EFX_RESET_HW_UNAVAIL;
5383c1c5cc4SAndrew Rybchenko }
5393c1c5cc4SAndrew Rybchenko 
5403c1c5cc4SAndrew Rybchenko 			void
rhead_nic_fini(__in efx_nic_t * enp)5413c1c5cc4SAndrew Rybchenko rhead_nic_fini(
5423c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
5433c1c5cc4SAndrew Rybchenko {
54479867285SAndrew Rybchenko 	boolean_t do_vadaptor_free = B_TRUE;
54579867285SAndrew Rybchenko 
54679867285SAndrew Rybchenko #if EFSYS_OPT_EVB
54779867285SAndrew Rybchenko 	if (enp->en_vswitchp != NULL) {
54879867285SAndrew Rybchenko 		/*
54979867285SAndrew Rybchenko 		 * For SR-IOV the vAdaptor is freed with the vSwitch,
55079867285SAndrew Rybchenko 		 * so do not free it here.
55179867285SAndrew Rybchenko 		 */
55279867285SAndrew Rybchenko 		do_vadaptor_free = B_FALSE;
55379867285SAndrew Rybchenko 	}
55479867285SAndrew Rybchenko #endif
55579867285SAndrew Rybchenko 	if (do_vadaptor_free != B_FALSE) {
55679867285SAndrew Rybchenko 		(void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
55779867285SAndrew Rybchenko 		enp->en_vport_id = EVB_PORT_ID_NULL;
55879867285SAndrew Rybchenko 	}
55979867285SAndrew Rybchenko 
5603c1c5cc4SAndrew Rybchenko 	(void) efx_mcdi_free_vis(enp);
5613c1c5cc4SAndrew Rybchenko 	enp->en_arch.ef10.ena_vi_count = 0;
5623c1c5cc4SAndrew Rybchenko }
5633c1c5cc4SAndrew Rybchenko 
5643c1c5cc4SAndrew Rybchenko 			void
rhead_nic_unprobe(__in efx_nic_t * enp)5653c1c5cc4SAndrew Rybchenko rhead_nic_unprobe(
5663c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
5673c1c5cc4SAndrew Rybchenko {
5683c1c5cc4SAndrew Rybchenko 	(void) efx_mcdi_drv_attach(enp, B_FALSE);
5693c1c5cc4SAndrew Rybchenko }
5703c1c5cc4SAndrew Rybchenko 
5713c1c5cc4SAndrew Rybchenko #if EFSYS_OPT_DIAG
5723c1c5cc4SAndrew Rybchenko 
5733c1c5cc4SAndrew Rybchenko 	__checkReturn	efx_rc_t
rhead_nic_register_test(__in efx_nic_t * enp)5743c1c5cc4SAndrew Rybchenko rhead_nic_register_test(
5753c1c5cc4SAndrew Rybchenko 	__in		efx_nic_t *enp)
5763c1c5cc4SAndrew Rybchenko {
5773c1c5cc4SAndrew Rybchenko 	efx_rc_t rc;
5783c1c5cc4SAndrew Rybchenko 
5793c1c5cc4SAndrew Rybchenko 	/* FIXME */
5803c1c5cc4SAndrew Rybchenko 	_NOTE(ARGUNUSED(enp))
5813c1c5cc4SAndrew Rybchenko 	_NOTE(CONSTANTCONDITION)
5823c1c5cc4SAndrew Rybchenko 	if (B_FALSE) {
5833c1c5cc4SAndrew Rybchenko 		rc = ENOTSUP;
5843c1c5cc4SAndrew Rybchenko 		goto fail1;
5853c1c5cc4SAndrew Rybchenko 	}
5863c1c5cc4SAndrew Rybchenko 	/* FIXME */
5873c1c5cc4SAndrew Rybchenko 
5883c1c5cc4SAndrew Rybchenko 	return (0);
5893c1c5cc4SAndrew Rybchenko 
5903c1c5cc4SAndrew Rybchenko fail1:
5913c1c5cc4SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
5923c1c5cc4SAndrew Rybchenko 
5933c1c5cc4SAndrew Rybchenko 	return (rc);
5943c1c5cc4SAndrew Rybchenko }
5953c1c5cc4SAndrew Rybchenko 
5963c1c5cc4SAndrew Rybchenko #endif	/* EFSYS_OPT_DIAG */
5973c1c5cc4SAndrew Rybchenko 
598ba9568b8SIgor Romanov 	__checkReturn			efx_rc_t
rhead_nic_xilinx_cap_tbl_read_ef100_locator(__in efsys_bar_t * esbp,__in efsys_dma_addr_t offset,__out efx_bar_region_t * ebrp)599ba9568b8SIgor Romanov rhead_nic_xilinx_cap_tbl_read_ef100_locator(
600ba9568b8SIgor Romanov 	__in				efsys_bar_t *esbp,
601ba9568b8SIgor Romanov 	__in				efsys_dma_addr_t offset,
602ba9568b8SIgor Romanov 	__out				efx_bar_region_t *ebrp)
603ba9568b8SIgor Romanov {
604ba9568b8SIgor Romanov 	efx_oword_t entry;
605ba9568b8SIgor Romanov 	uint32_t rev;
606ba9568b8SIgor Romanov 	uint32_t len;
607ba9568b8SIgor Romanov 	efx_rc_t rc;
608ba9568b8SIgor Romanov 
609ba9568b8SIgor Romanov 	/*
610ba9568b8SIgor Romanov 	 * Xilinx Capabilities Table requires 32bit aligned reads.
611ba9568b8SIgor Romanov 	 * See SF-119689-TC section 4.2.2 "Discovery Steps".
612ba9568b8SIgor Romanov 	 */
613ba9568b8SIgor Romanov 	EFSYS_BAR_READD(esbp, offset +
614ba9568b8SIgor Romanov 			(EFX_LOW_BIT(ESF_GZ_CFGBAR_ENTRY_FORMAT) / 8),
615ba9568b8SIgor Romanov 			&entry.eo_dword[0], B_FALSE);
616ba9568b8SIgor Romanov 	EFSYS_BAR_READD(esbp, offset +
617ba9568b8SIgor Romanov 			(EFX_LOW_BIT(ESF_GZ_CFGBAR_ENTRY_SIZE) / 8),
618ba9568b8SIgor Romanov 			&entry.eo_dword[1], B_FALSE);
619ba9568b8SIgor Romanov 
620ba9568b8SIgor Romanov 	rev = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_ENTRY_REV);
621ba9568b8SIgor Romanov 	len = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_ENTRY_SIZE);
622ba9568b8SIgor Romanov 
623ba9568b8SIgor Romanov 	if (rev != ESE_GZ_CFGBAR_ENTRY_REV_EF100 ||
624ba9568b8SIgor Romanov 	    len < ESE_GZ_CFGBAR_ENTRY_SIZE_EF100) {
625ba9568b8SIgor Romanov 		rc = EINVAL;
626ba9568b8SIgor Romanov 		goto fail1;
627ba9568b8SIgor Romanov 	}
628ba9568b8SIgor Romanov 
629ba9568b8SIgor Romanov 	EFSYS_BAR_READD(esbp, offset +
630ba9568b8SIgor Romanov 			(EFX_LOW_BIT(ESF_GZ_CFGBAR_EF100_BAR) / 8),
631ba9568b8SIgor Romanov 			&entry.eo_dword[2], B_FALSE);
632ba9568b8SIgor Romanov 
633ba9568b8SIgor Romanov 	ebrp->ebr_index = EFX_OWORD_FIELD32(entry, ESF_GZ_CFGBAR_EF100_BAR);
634ba9568b8SIgor Romanov 	ebrp->ebr_offset = EFX_OWORD_FIELD32(entry,
635ba9568b8SIgor Romanov 			ESF_GZ_CFGBAR_EF100_FUNC_CTL_WIN_OFF) <<
636ba9568b8SIgor Romanov 			ESE_GZ_EF100_FUNC_CTL_WIN_OFF_SHIFT;
637ba9568b8SIgor Romanov 	ebrp->ebr_type = EFX_BAR_TYPE_MEM;
638ba9568b8SIgor Romanov 	ebrp->ebr_length = 0;
639ba9568b8SIgor Romanov 
640ba9568b8SIgor Romanov 	return (0);
641ba9568b8SIgor Romanov 
642ba9568b8SIgor Romanov fail1:
643ba9568b8SIgor Romanov 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
644ba9568b8SIgor Romanov 
645ba9568b8SIgor Romanov 	return (rc);
646ba9568b8SIgor Romanov }
647ba9568b8SIgor Romanov 
6483c1c5cc4SAndrew Rybchenko #endif	/* EFSYS_OPT_RIVERHEAD */
649