siena_nic.c revision 311481
1227569Sphilip/*-
2300607Sarybchik * Copyright (c) 2009-2016 Solarflare Communications Inc.
3283514Sarybchik * All rights reserved.
4227569Sphilip *
5227569Sphilip * Redistribution and use in source and binary forms, with or without
6283514Sarybchik * modification, are permitted provided that the following conditions are met:
7227569Sphilip *
8283514Sarybchik * 1. Redistributions of source code must retain the above copyright notice,
9283514Sarybchik *    this list of conditions and the following disclaimer.
10283514Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice,
11283514Sarybchik *    this list of conditions and the following disclaimer in the documentation
12283514Sarybchik *    and/or other materials provided with the distribution.
13283514Sarybchik *
14283514Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15283514Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16283514Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17283514Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18283514Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19283514Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20283514Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21283514Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22283514Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23283514Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24283514Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25283514Sarybchik *
26283514Sarybchik * The views and conclusions contained in the software and documentation are
27283514Sarybchik * those of the authors and should not be interpreted as representing official
28283514Sarybchik * policies, either expressed or implied, of the FreeBSD Project.
29227569Sphilip */
30228078Sphilip
31228078Sphilip#include <sys/cdefs.h>
32228078Sphilip__FBSDID("$FreeBSD: stable/11/sys/dev/sfxge/common/siena_nic.c 311481 2017-01-06 07:05:02Z arybchik $");
33228078Sphilip
34227569Sphilip#include "efx.h"
35227569Sphilip#include "efx_impl.h"
36283514Sarybchik#include "mcdi_mon.h"
37227569Sphilip
38227569Sphilip#if EFSYS_OPT_SIENA
39227569Sphilip
40310933Sarybchik#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
41310933Sarybchik
42291436Sarybchikstatic	__checkReturn		efx_rc_t
43227569Sphilipsiena_nic_get_partn_mask(
44227569Sphilip	__in			efx_nic_t *enp,
45227569Sphilip	__out			unsigned int *maskp)
46227569Sphilip{
47227569Sphilip	efx_mcdi_req_t req;
48283514Sarybchik	uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
49283514Sarybchik			    MC_CMD_NVRAM_TYPES_OUT_LEN)];
50291436Sarybchik	efx_rc_t rc;
51227569Sphilip
52283514Sarybchik	(void) memset(payload, 0, sizeof (payload));
53227569Sphilip	req.emr_cmd = MC_CMD_NVRAM_TYPES;
54283514Sarybchik	req.emr_in_buf = payload;
55283514Sarybchik	req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
56283514Sarybchik	req.emr_out_buf = payload;
57283514Sarybchik	req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
58227569Sphilip
59227569Sphilip	efx_mcdi_execute(enp, &req);
60227569Sphilip
61227569Sphilip	if (req.emr_rc != 0) {
62227569Sphilip		rc = req.emr_rc;
63227569Sphilip		goto fail1;
64227569Sphilip	}
65227569Sphilip
66227569Sphilip	if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
67227569Sphilip		rc = EMSGSIZE;
68227569Sphilip		goto fail2;
69227569Sphilip	}
70227569Sphilip
71227569Sphilip	*maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
72227569Sphilip
73227569Sphilip	return (0);
74227569Sphilip
75227569Sphilipfail2:
76227569Sphilip	EFSYS_PROBE(fail2);
77227569Sphilipfail1:
78291436Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
79227569Sphilip
80227569Sphilip	return (rc);
81227569Sphilip}
82227569Sphilip
83310933Sarybchik#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
84310933Sarybchik
85291436Sarybchikstatic	__checkReturn	efx_rc_t
86227569Sphilipsiena_board_cfg(
87227569Sphilip	__in		efx_nic_t *enp)
88227569Sphilip{
89227569Sphilip	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
90283514Sarybchik	uint8_t mac_addr[6];
91283514Sarybchik	efx_dword_t capabilities;
92283514Sarybchik	uint32_t board_type;
93283514Sarybchik	uint32_t nevq, nrxq, ntxq;
94291436Sarybchik	efx_rc_t rc;
95227569Sphilip
96283514Sarybchik	/* External port identifier using one-based port numbering */
97283514Sarybchik	encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
98283514Sarybchik
99227569Sphilip	/* Board configuration */
100283514Sarybchik	if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
101283514Sarybchik		    &capabilities, mac_addr)) != 0)
102227569Sphilip		goto fail1;
103227569Sphilip
104279048Sarybchik	EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
105227569Sphilip
106283514Sarybchik	encp->enc_board_type = board_type;
107227569Sphilip
108311016Sarybchik	/*
109311016Sarybchik	 * There is no possibility to determine the number of PFs on Siena
110311016Sarybchik	 * by issuing MCDI request, and it is not an easy task to find the
111311016Sarybchik	 * value based on the board type, so 'enc_hw_pf_count' is set to 1
112311016Sarybchik	 */
113311016Sarybchik	encp->enc_hw_pf_count = 1;
114311016Sarybchik
115279048Sarybchik	/* Additional capabilities */
116279048Sarybchik	encp->enc_clk_mult = 1;
117283514Sarybchik	if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
118279048Sarybchik		enp->en_features |= EFX_FEATURE_TURBO;
119279048Sarybchik
120283514Sarybchik		if (EFX_DWORD_FIELD(capabilities,
121283514Sarybchik			MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
122279048Sarybchik			encp->enc_clk_mult = 2;
123283514Sarybchik		}
124279048Sarybchik	}
125279048Sarybchik
126279182Sarybchik	encp->enc_evq_timer_quantum_ns =
127279182Sarybchik		EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
128279182Sarybchik	encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
129279182Sarybchik		FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
130279048Sarybchik
131283514Sarybchik	/* When hash header insertion is enabled, Siena inserts 16 bytes */
132283514Sarybchik	encp->enc_rx_prefix_size = 16;
133227569Sphilip
134283514Sarybchik	/* Alignment for receive packet DMA buffers */
135283514Sarybchik	encp->enc_rx_buf_align_start = 1;
136283514Sarybchik	encp->enc_rx_buf_align_end = 1;
137227569Sphilip
138283514Sarybchik	/* Alignment for WPTR updates */
139283514Sarybchik	encp->enc_rx_push_align = 1;
140227569Sphilip
141283514Sarybchik	/* Resource limits */
142283514Sarybchik	rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
143283514Sarybchik	if (rc != 0) {
144283514Sarybchik		if (rc != ENOTSUP)
145283514Sarybchik			goto fail2;
146283514Sarybchik
147283514Sarybchik		nevq = 1024;
148283514Sarybchik		nrxq = EFX_RXQ_LIMIT_TARGET;
149283514Sarybchik		ntxq = EFX_TXQ_LIMIT_TARGET;
150227569Sphilip	}
151283514Sarybchik	encp->enc_evq_limit = nevq;
152283514Sarybchik	encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
153283514Sarybchik	encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
154227569Sphilip
155227569Sphilip	encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
156279098Sarybchik	    (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
157279098Sarybchik	    (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
158227569Sphilip
159283514Sarybchik	encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
160283514Sarybchik	encp->enc_fw_assisted_tso_enabled = B_FALSE;
161293891Sarybchik	encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
162311015Sarybchik	encp->enc_fw_assisted_tso_v2_n_contexts = 0;
163291922Sarybchik	encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
164283514Sarybchik
165299904Sarybchik	/* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
166299904Sarybchik	encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
167299904Sarybchik	encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
168299904Sarybchik
169311481Sarybchik	encp->enc_fw_verified_nvram_update_required = B_FALSE;
170311481Sarybchik
171227569Sphilip	return (0);
172227569Sphilip
173227569Sphilipfail2:
174227569Sphilip	EFSYS_PROBE(fail2);
175227569Sphilipfail1:
176291436Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
177227569Sphilip
178227569Sphilip	return (rc);
179227569Sphilip}
180227569Sphilip
181291436Sarybchikstatic	__checkReturn	efx_rc_t
182227569Sphilipsiena_phy_cfg(
183227569Sphilip	__in		efx_nic_t *enp)
184227569Sphilip{
185227569Sphilip	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
186291436Sarybchik	efx_rc_t rc;
187227569Sphilip
188283514Sarybchik	/* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
189283514Sarybchik	if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
190227569Sphilip		goto fail1;
191227569Sphilip
192227569Sphilip#if EFSYS_OPT_PHY_STATS
193227569Sphilip	/* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
194283514Sarybchik	siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
195227569Sphilip			    NULL, &encp->enc_phy_stat_mask, NULL);
196227569Sphilip#endif	/* EFSYS_OPT_PHY_STATS */
197227569Sphilip
198227569Sphilip	return (0);
199227569Sphilip
200227569Sphilipfail1:
201291436Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
202227569Sphilip
203227569Sphilip	return (rc);
204227569Sphilip}
205227569Sphilip
206291436Sarybchik	__checkReturn	efx_rc_t
207227569Sphilipsiena_nic_probe(
208227569Sphilip	__in		efx_nic_t *enp)
209227569Sphilip{
210227569Sphilip	efx_port_t *epp = &(enp->en_port);
211227569Sphilip	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
212227569Sphilip	siena_link_state_t sls;
213227569Sphilip	unsigned int mask;
214283514Sarybchik	efx_oword_t oword;
215291436Sarybchik	efx_rc_t rc;
216227569Sphilip
217227569Sphilip	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
218227569Sphilip
219283514Sarybchik	/* Test BIU */
220283514Sarybchik	if ((rc = efx_nic_biu_test(enp)) != 0)
221227569Sphilip		goto fail1;
222227569Sphilip
223283514Sarybchik	/* Clear the region register */
224283514Sarybchik	EFX_POPULATE_OWORD_4(oword,
225283514Sarybchik	    FRF_AZ_ADR_REGION0, 0,
226283514Sarybchik	    FRF_AZ_ADR_REGION1, (1 << 16),
227283514Sarybchik	    FRF_AZ_ADR_REGION2, (2 << 16),
228283514Sarybchik	    FRF_AZ_ADR_REGION3, (3 << 16));
229283514Sarybchik	EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
230283514Sarybchik
231283514Sarybchik	/* Read clear any assertion state */
232283514Sarybchik	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
233227569Sphilip		goto fail2;
234227569Sphilip
235283514Sarybchik	/* Exit the assertion handler */
236283514Sarybchik	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
237227569Sphilip		goto fail3;
238227569Sphilip
239283514Sarybchik	/* Wrestle control from the BMC */
240283514Sarybchik	if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
241227569Sphilip		goto fail4;
242227569Sphilip
243283514Sarybchik	if ((rc = siena_board_cfg(enp)) != 0)
244227569Sphilip		goto fail5;
245227569Sphilip
246283514Sarybchik	if ((rc = siena_phy_cfg(enp)) != 0)
247283514Sarybchik		goto fail6;
248283514Sarybchik
249227569Sphilip	/* Obtain the default PHY advertised capabilities */
250227569Sphilip	if ((rc = siena_nic_reset(enp)) != 0)
251283514Sarybchik		goto fail7;
252227569Sphilip	if ((rc = siena_phy_get_link(enp, &sls)) != 0)
253283514Sarybchik		goto fail8;
254227569Sphilip	epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
255227569Sphilip	epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
256227569Sphilip
257227569Sphilip#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
258227569Sphilip	if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
259283514Sarybchik		goto fail9;
260227569Sphilip	enp->en_u.siena.enu_partn_mask = mask;
261227569Sphilip#endif
262227569Sphilip
263227569Sphilip#if EFSYS_OPT_MAC_STATS
264227569Sphilip	/* Wipe the MAC statistics */
265283514Sarybchik	if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
266283514Sarybchik		goto fail10;
267227569Sphilip#endif
268227569Sphilip
269227569Sphilip#if EFSYS_OPT_LOOPBACK
270283514Sarybchik	if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
271283514Sarybchik		goto fail11;
272227569Sphilip#endif
273227569Sphilip
274227569Sphilip#if EFSYS_OPT_MON_STATS
275283514Sarybchik	if ((rc = mcdi_mon_cfg_build(enp)) != 0)
276283514Sarybchik		goto fail12;
277227569Sphilip#endif
278227569Sphilip
279227569Sphilip	encp->enc_features = enp->en_features;
280227569Sphilip
281227569Sphilip	return (0);
282227569Sphilip
283227569Sphilip#if EFSYS_OPT_MON_STATS
284283514Sarybchikfail12:
285283514Sarybchik	EFSYS_PROBE(fail12);
286283514Sarybchik#endif
287283514Sarybchik#if EFSYS_OPT_LOOPBACK
288227569Sphilipfail11:
289227569Sphilip	EFSYS_PROBE(fail11);
290227569Sphilip#endif
291283514Sarybchik#if EFSYS_OPT_MAC_STATS
292227569Sphilipfail10:
293227569Sphilip	EFSYS_PROBE(fail10);
294227569Sphilip#endif
295283514Sarybchik#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
296227569Sphilipfail9:
297227569Sphilip	EFSYS_PROBE(fail9);
298227569Sphilip#endif
299227569Sphilipfail8:
300227569Sphilip	EFSYS_PROBE(fail8);
301227569Sphilipfail7:
302227569Sphilip	EFSYS_PROBE(fail7);
303227569Sphilipfail6:
304227569Sphilip	EFSYS_PROBE(fail6);
305227569Sphilipfail5:
306227569Sphilip	EFSYS_PROBE(fail5);
307227569Sphilipfail4:
308227569Sphilip	EFSYS_PROBE(fail4);
309227569Sphilipfail3:
310227569Sphilip	EFSYS_PROBE(fail3);
311227569Sphilipfail2:
312227569Sphilip	EFSYS_PROBE(fail2);
313227569Sphilipfail1:
314291436Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
315227569Sphilip
316227569Sphilip	return (rc);
317227569Sphilip}
318227569Sphilip
319291436Sarybchik	__checkReturn	efx_rc_t
320227569Sphilipsiena_nic_reset(
321227569Sphilip	__in		efx_nic_t *enp)
322227569Sphilip{
323227569Sphilip	efx_mcdi_req_t req;
324291436Sarybchik	efx_rc_t rc;
325227569Sphilip
326227569Sphilip	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
327227569Sphilip
328227569Sphilip	/* siena_nic_reset() is called to recover from BADASSERT failures. */
329283514Sarybchik	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
330227569Sphilip		goto fail1;
331283514Sarybchik	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
332227569Sphilip		goto fail2;
333227569Sphilip
334283514Sarybchik	/*
335283514Sarybchik	 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
336283514Sarybchik	 * for backwards compatibility with PORT_RESET_IN_LEN.
337283514Sarybchik	 */
338283514Sarybchik	EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
339283514Sarybchik
340283514Sarybchik	req.emr_cmd = MC_CMD_ENTITY_RESET;
341227569Sphilip	req.emr_in_buf = NULL;
342227569Sphilip	req.emr_in_length = 0;
343227569Sphilip	req.emr_out_buf = NULL;
344227569Sphilip	req.emr_out_length = 0;
345227569Sphilip
346227569Sphilip	efx_mcdi_execute(enp, &req);
347227569Sphilip
348227569Sphilip	if (req.emr_rc != 0) {
349227569Sphilip		rc = req.emr_rc;
350227569Sphilip		goto fail3;
351227569Sphilip	}
352227569Sphilip
353227569Sphilip	return (0);
354227569Sphilip
355227569Sphilipfail3:
356227569Sphilip	EFSYS_PROBE(fail3);
357227569Sphilipfail2:
358227569Sphilip	EFSYS_PROBE(fail2);
359227569Sphilipfail1:
360291436Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
361227569Sphilip
362227569Sphilip	return (0);
363227569Sphilip}
364227569Sphilip
365227569Sphilipstatic			void
366227569Sphilipsiena_nic_rx_cfg(
367227569Sphilip	__in		efx_nic_t *enp)
368227569Sphilip{
369227569Sphilip	efx_oword_t oword;
370227569Sphilip
371227569Sphilip	/*
372227569Sphilip	 * RX_INGR_EN is always enabled on Siena, because we rely on
373227569Sphilip	 * the RX parser to be resiliant to missing SOP/EOP.
374227569Sphilip	 */
375227569Sphilip	EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
376227569Sphilip	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
377227569Sphilip	EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
378227569Sphilip
379227569Sphilip	/* Disable parsing of additional 802.1Q in Q packets */
380227569Sphilip	EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
381227569Sphilip	EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
382227569Sphilip	EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
383227569Sphilip}
384227569Sphilip
385227569Sphilipstatic			void
386227569Sphilipsiena_nic_usrev_dis(
387227569Sphilip	__in		efx_nic_t *enp)
388227569Sphilip{
389227569Sphilip	efx_oword_t	oword;
390227569Sphilip
391227569Sphilip	EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
392227569Sphilip	EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
393227569Sphilip}
394227569Sphilip
395291436Sarybchik	__checkReturn	efx_rc_t
396227569Sphilipsiena_nic_init(
397227569Sphilip	__in		efx_nic_t *enp)
398227569Sphilip{
399291436Sarybchik	efx_rc_t rc;
400227569Sphilip
401227569Sphilip	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
402227569Sphilip
403283514Sarybchik	/* Enable reporting of some events (e.g. link change) */
404283514Sarybchik	if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
405227569Sphilip		goto fail1;
406227569Sphilip
407227569Sphilip	siena_sram_init(enp);
408227569Sphilip
409227569Sphilip	/* Configure Siena's RX block */
410227569Sphilip	siena_nic_rx_cfg(enp);
411227569Sphilip
412227569Sphilip	/* Disable USR_EVents for now */
413227569Sphilip	siena_nic_usrev_dis(enp);
414227569Sphilip
415227569Sphilip	/* bug17057: Ensure set_link is called */
416227569Sphilip	if ((rc = siena_phy_reconfigure(enp)) != 0)
417227569Sphilip		goto fail2;
418227569Sphilip
419291923Sarybchik	enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
420291923Sarybchik
421227569Sphilip	return (0);
422227569Sphilip
423227569Sphilipfail2:
424227569Sphilip	EFSYS_PROBE(fail2);
425227569Sphilipfail1:
426291436Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
427227569Sphilip
428227569Sphilip	return (rc);
429227569Sphilip}
430227569Sphilip
431227569Sphilip			void
432227569Sphilipsiena_nic_fini(
433227569Sphilip	__in		efx_nic_t *enp)
434227569Sphilip{
435227569Sphilip	_NOTE(ARGUNUSED(enp))
436227569Sphilip}
437227569Sphilip
438227569Sphilip			void
439227569Sphilipsiena_nic_unprobe(
440227569Sphilip	__in		efx_nic_t *enp)
441227569Sphilip{
442283514Sarybchik#if EFSYS_OPT_MON_STATS
443283514Sarybchik	mcdi_mon_cfg_free(enp);
444283514Sarybchik#endif /* EFSYS_OPT_MON_STATS */
445283514Sarybchik	(void) efx_mcdi_drv_attach(enp, B_FALSE);
446227569Sphilip}
447227569Sphilip
448227569Sphilip#if EFSYS_OPT_DIAG
449227569Sphilip
450283514Sarybchikstatic efx_register_set_t __siena_registers[] = {
451227569Sphilip	{ FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
452227569Sphilip	{ FR_CZ_USR_EV_CFG_OFST, 0, 1 },
453227569Sphilip	{ FR_AZ_RX_CFG_REG_OFST, 0, 1 },
454227569Sphilip	{ FR_AZ_TX_CFG_REG_OFST, 0, 1 },
455227569Sphilip	{ FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
456227569Sphilip	{ FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
457227569Sphilip	{ FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
458227569Sphilip	{ FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
459227569Sphilip	{ FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
460227569Sphilip	{ FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
461227569Sphilip	{ FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
462227569Sphilip	{ FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
463227569Sphilip	{ FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
464227569Sphilip};
465227569Sphilip
466283514Sarybchikstatic const uint32_t __siena_register_masks[] = {
467227569Sphilip	0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
468227569Sphilip	0x000103FF, 0x00000000, 0x00000000, 0x00000000,
469227569Sphilip	0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
470227569Sphilip	0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
471227569Sphilip	0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
472227569Sphilip	0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
473227569Sphilip	0x00000003, 0x00000000, 0x00000000, 0x00000000,
474227569Sphilip	0x000003FF, 0x00000000, 0x00000000, 0x00000000,
475227569Sphilip	0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
476227569Sphilip	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
477227569Sphilip	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
478227569Sphilip	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
479227569Sphilip	0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
480227569Sphilip};
481227569Sphilip
482283514Sarybchikstatic efx_register_set_t __siena_tables[] = {
483227569Sphilip	{ FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
484227569Sphilip	    FR_AZ_RX_FILTER_TBL0_ROWS },
485227569Sphilip	{ FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
486227569Sphilip	    FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
487227569Sphilip	{ FR_AZ_RX_DESC_PTR_TBL_OFST,
488227569Sphilip	    FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
489227569Sphilip	{ FR_AZ_TX_DESC_PTR_TBL_OFST,
490227569Sphilip	    FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
491227569Sphilip	{ FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
492227569Sphilip	{ FR_CZ_TX_FILTER_TBL0_OFST,
493227569Sphilip	    FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
494227569Sphilip	{ FR_CZ_TX_MAC_FILTER_TBL0_OFST,
495227569Sphilip	    FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
496227569Sphilip};
497227569Sphilip
498283514Sarybchikstatic const uint32_t __siena_table_masks[] = {
499227569Sphilip	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
500227569Sphilip	0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
501279095Sarybchik	0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
502227569Sphilip	0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
503227569Sphilip	0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
504227569Sphilip	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
505227569Sphilip	0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
506227569Sphilip};
507227569Sphilip
508291436Sarybchik	__checkReturn	efx_rc_t
509227569Sphilipsiena_nic_register_test(
510227569Sphilip	__in		efx_nic_t *enp)
511227569Sphilip{
512227569Sphilip	efx_register_set_t *rsp;
513227569Sphilip	const uint32_t *dwordp;
514227569Sphilip	unsigned int nitems;
515227569Sphilip	unsigned int count;
516291436Sarybchik	efx_rc_t rc;
517227569Sphilip
518227569Sphilip	/* Fill out the register mask entries */
519227569Sphilip	EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
520227569Sphilip		    == EFX_ARRAY_SIZE(__siena_registers) * 4);
521227569Sphilip
522227569Sphilip	nitems = EFX_ARRAY_SIZE(__siena_registers);
523227569Sphilip	dwordp = __siena_register_masks;
524227569Sphilip	for (count = 0; count < nitems; ++count) {
525227569Sphilip		rsp = __siena_registers + count;
526227569Sphilip		rsp->mask.eo_u32[0] = *dwordp++;
527227569Sphilip		rsp->mask.eo_u32[1] = *dwordp++;
528227569Sphilip		rsp->mask.eo_u32[2] = *dwordp++;
529227569Sphilip		rsp->mask.eo_u32[3] = *dwordp++;
530227569Sphilip	}
531227569Sphilip
532227569Sphilip	/* Fill out the register table entries */
533227569Sphilip	EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
534227569Sphilip		    == EFX_ARRAY_SIZE(__siena_tables) * 4);
535227569Sphilip
536227569Sphilip	nitems = EFX_ARRAY_SIZE(__siena_tables);
537227569Sphilip	dwordp = __siena_table_masks;
538227569Sphilip	for (count = 0; count < nitems; ++count) {
539227569Sphilip		rsp = __siena_tables + count;
540227569Sphilip		rsp->mask.eo_u32[0] = *dwordp++;
541227569Sphilip		rsp->mask.eo_u32[1] = *dwordp++;
542227569Sphilip		rsp->mask.eo_u32[2] = *dwordp++;
543227569Sphilip		rsp->mask.eo_u32[3] = *dwordp++;
544227569Sphilip	}
545227569Sphilip
546227569Sphilip	if ((rc = efx_nic_test_registers(enp, __siena_registers,
547227569Sphilip	    EFX_ARRAY_SIZE(__siena_registers))) != 0)
548227569Sphilip		goto fail1;
549227569Sphilip
550227569Sphilip	if ((rc = efx_nic_test_tables(enp, __siena_tables,
551227569Sphilip	    EFX_PATTERN_BYTE_ALTERNATE,
552227569Sphilip	    EFX_ARRAY_SIZE(__siena_tables))) != 0)
553227569Sphilip		goto fail2;
554227569Sphilip
555227569Sphilip	if ((rc = efx_nic_test_tables(enp, __siena_tables,
556227569Sphilip	    EFX_PATTERN_BYTE_CHANGING,
557227569Sphilip	    EFX_ARRAY_SIZE(__siena_tables))) != 0)
558227569Sphilip		goto fail3;
559227569Sphilip
560227569Sphilip	if ((rc = efx_nic_test_tables(enp, __siena_tables,
561227569Sphilip	    EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
562227569Sphilip		goto fail4;
563227569Sphilip
564227569Sphilip	return (0);
565227569Sphilip
566227569Sphilipfail4:
567227569Sphilip	EFSYS_PROBE(fail4);
568227569Sphilipfail3:
569227569Sphilip	EFSYS_PROBE(fail3);
570227569Sphilipfail2:
571227569Sphilip	EFSYS_PROBE(fail2);
572227569Sphilipfail1:
573291436Sarybchik	EFSYS_PROBE1(fail1, efx_rc_t, rc);
574227569Sphilip
575227569Sphilip	return (rc);
576227569Sphilip}
577227569Sphilip
578227569Sphilip#endif	/* EFSYS_OPT_DIAG */
579227569Sphilip
580227569Sphilip#endif	/* EFSYS_OPT_SIENA */
581