siena_nic.c revision 310933
1/*-
2 * Copyright (c) 2009-2016 Solarflare Communications Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 *    this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 *    this list of conditions and the following disclaimer in the documentation
12 *    and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: stable/11/sys/dev/sfxge/common/siena_nic.c 310933 2016-12-31 11:14:03Z arybchik $");
33
34#include "efx.h"
35#include "efx_impl.h"
36#include "mcdi_mon.h"
37
38#if EFSYS_OPT_SIENA
39
40#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
41
42static	__checkReturn		efx_rc_t
43siena_nic_get_partn_mask(
44	__in			efx_nic_t *enp,
45	__out			unsigned int *maskp)
46{
47	efx_mcdi_req_t req;
48	uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
49			    MC_CMD_NVRAM_TYPES_OUT_LEN)];
50	efx_rc_t rc;
51
52	(void) memset(payload, 0, sizeof (payload));
53	req.emr_cmd = MC_CMD_NVRAM_TYPES;
54	req.emr_in_buf = payload;
55	req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
56	req.emr_out_buf = payload;
57	req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
58
59	efx_mcdi_execute(enp, &req);
60
61	if (req.emr_rc != 0) {
62		rc = req.emr_rc;
63		goto fail1;
64	}
65
66	if (req.emr_out_length_used < MC_CMD_NVRAM_TYPES_OUT_LEN) {
67		rc = EMSGSIZE;
68		goto fail2;
69	}
70
71	*maskp = MCDI_OUT_DWORD(req, NVRAM_TYPES_OUT_TYPES);
72
73	return (0);
74
75fail2:
76	EFSYS_PROBE(fail2);
77fail1:
78	EFSYS_PROBE1(fail1, efx_rc_t, rc);
79
80	return (rc);
81}
82
83#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
84
85static	__checkReturn	efx_rc_t
86siena_board_cfg(
87	__in		efx_nic_t *enp)
88{
89	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
90	uint8_t mac_addr[6];
91	efx_dword_t capabilities;
92	uint32_t board_type;
93	uint32_t nevq, nrxq, ntxq;
94	efx_rc_t rc;
95
96	/* External port identifier using one-based port numbering */
97	encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
98
99	/* Board configuration */
100	if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
101		    &capabilities, mac_addr)) != 0)
102		goto fail1;
103
104	EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
105
106	encp->enc_board_type = board_type;
107
108	/* Additional capabilities */
109	encp->enc_clk_mult = 1;
110	if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
111		enp->en_features |= EFX_FEATURE_TURBO;
112
113		if (EFX_DWORD_FIELD(capabilities,
114			MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
115			encp->enc_clk_mult = 2;
116		}
117	}
118
119	encp->enc_evq_timer_quantum_ns =
120		EFX_EVQ_SIENA_TIMER_QUANTUM_NS / encp->enc_clk_mult;
121	encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
122		FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
123
124	/* When hash header insertion is enabled, Siena inserts 16 bytes */
125	encp->enc_rx_prefix_size = 16;
126
127	/* Alignment for receive packet DMA buffers */
128	encp->enc_rx_buf_align_start = 1;
129	encp->enc_rx_buf_align_end = 1;
130
131	/* Alignment for WPTR updates */
132	encp->enc_rx_push_align = 1;
133
134	/* Resource limits */
135	rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
136	if (rc != 0) {
137		if (rc != ENOTSUP)
138			goto fail2;
139
140		nevq = 1024;
141		nrxq = EFX_RXQ_LIMIT_TARGET;
142		ntxq = EFX_TXQ_LIMIT_TARGET;
143	}
144	encp->enc_evq_limit = nevq;
145	encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
146	encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
147
148	encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
149	    (encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
150	    (encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
151
152	encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
153	encp->enc_fw_assisted_tso_enabled = B_FALSE;
154	encp->enc_fw_assisted_tso_v2_enabled = B_FALSE;
155	encp->enc_allow_set_mac_with_installed_filters = B_TRUE;
156
157	/* Siena supports two 10G ports, and 8 lanes of PCIe Gen2 */
158	encp->enc_required_pcie_bandwidth_mbps = 2 * 10000;
159	encp->enc_max_pcie_link_gen = EFX_PCIE_LINK_SPEED_GEN2;
160
161	return (0);
162
163fail2:
164	EFSYS_PROBE(fail2);
165fail1:
166	EFSYS_PROBE1(fail1, efx_rc_t, rc);
167
168	return (rc);
169}
170
171static	__checkReturn	efx_rc_t
172siena_phy_cfg(
173	__in		efx_nic_t *enp)
174{
175	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
176	efx_rc_t rc;
177
178	/* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
179	if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
180		goto fail1;
181
182#if EFSYS_OPT_PHY_STATS
183	/* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
184	siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
185			    NULL, &encp->enc_phy_stat_mask, NULL);
186#endif	/* EFSYS_OPT_PHY_STATS */
187
188	return (0);
189
190fail1:
191	EFSYS_PROBE1(fail1, efx_rc_t, rc);
192
193	return (rc);
194}
195
196	__checkReturn	efx_rc_t
197siena_nic_probe(
198	__in		efx_nic_t *enp)
199{
200	efx_port_t *epp = &(enp->en_port);
201	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
202	siena_link_state_t sls;
203	unsigned int mask;
204	efx_oword_t oword;
205	efx_rc_t rc;
206
207	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
208
209	/* Test BIU */
210	if ((rc = efx_nic_biu_test(enp)) != 0)
211		goto fail1;
212
213	/* Clear the region register */
214	EFX_POPULATE_OWORD_4(oword,
215	    FRF_AZ_ADR_REGION0, 0,
216	    FRF_AZ_ADR_REGION1, (1 << 16),
217	    FRF_AZ_ADR_REGION2, (2 << 16),
218	    FRF_AZ_ADR_REGION3, (3 << 16));
219	EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
220
221	/* Read clear any assertion state */
222	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
223		goto fail2;
224
225	/* Exit the assertion handler */
226	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
227		goto fail3;
228
229	/* Wrestle control from the BMC */
230	if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
231		goto fail4;
232
233	if ((rc = siena_board_cfg(enp)) != 0)
234		goto fail5;
235
236	if ((rc = siena_phy_cfg(enp)) != 0)
237		goto fail6;
238
239	/* Obtain the default PHY advertised capabilities */
240	if ((rc = siena_nic_reset(enp)) != 0)
241		goto fail7;
242	if ((rc = siena_phy_get_link(enp, &sls)) != 0)
243		goto fail8;
244	epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
245	epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
246
247#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
248	if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
249		goto fail9;
250	enp->en_u.siena.enu_partn_mask = mask;
251#endif
252
253#if EFSYS_OPT_MAC_STATS
254	/* Wipe the MAC statistics */
255	if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
256		goto fail10;
257#endif
258
259#if EFSYS_OPT_LOOPBACK
260	if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
261		goto fail11;
262#endif
263
264#if EFSYS_OPT_MON_STATS
265	if ((rc = mcdi_mon_cfg_build(enp)) != 0)
266		goto fail12;
267#endif
268
269	encp->enc_features = enp->en_features;
270
271	return (0);
272
273#if EFSYS_OPT_MON_STATS
274fail12:
275	EFSYS_PROBE(fail12);
276#endif
277#if EFSYS_OPT_LOOPBACK
278fail11:
279	EFSYS_PROBE(fail11);
280#endif
281#if EFSYS_OPT_MAC_STATS
282fail10:
283	EFSYS_PROBE(fail10);
284#endif
285#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
286fail9:
287	EFSYS_PROBE(fail9);
288#endif
289fail8:
290	EFSYS_PROBE(fail8);
291fail7:
292	EFSYS_PROBE(fail7);
293fail6:
294	EFSYS_PROBE(fail6);
295fail5:
296	EFSYS_PROBE(fail5);
297fail4:
298	EFSYS_PROBE(fail4);
299fail3:
300	EFSYS_PROBE(fail3);
301fail2:
302	EFSYS_PROBE(fail2);
303fail1:
304	EFSYS_PROBE1(fail1, efx_rc_t, rc);
305
306	return (rc);
307}
308
309	__checkReturn	efx_rc_t
310siena_nic_reset(
311	__in		efx_nic_t *enp)
312{
313	efx_mcdi_req_t req;
314	efx_rc_t rc;
315
316	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
317
318	/* siena_nic_reset() is called to recover from BADASSERT failures. */
319	if ((rc = efx_mcdi_read_assertion(enp)) != 0)
320		goto fail1;
321	if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
322		goto fail2;
323
324	/*
325	 * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
326	 * for backwards compatibility with PORT_RESET_IN_LEN.
327	 */
328	EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
329
330	req.emr_cmd = MC_CMD_ENTITY_RESET;
331	req.emr_in_buf = NULL;
332	req.emr_in_length = 0;
333	req.emr_out_buf = NULL;
334	req.emr_out_length = 0;
335
336	efx_mcdi_execute(enp, &req);
337
338	if (req.emr_rc != 0) {
339		rc = req.emr_rc;
340		goto fail3;
341	}
342
343	return (0);
344
345fail3:
346	EFSYS_PROBE(fail3);
347fail2:
348	EFSYS_PROBE(fail2);
349fail1:
350	EFSYS_PROBE1(fail1, efx_rc_t, rc);
351
352	return (0);
353}
354
355static			void
356siena_nic_rx_cfg(
357	__in		efx_nic_t *enp)
358{
359	efx_oword_t oword;
360
361	/*
362	 * RX_INGR_EN is always enabled on Siena, because we rely on
363	 * the RX parser to be resiliant to missing SOP/EOP.
364	 */
365	EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
366	EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_INGR_EN, 1);
367	EFX_BAR_WRITEO(enp, FR_AZ_RX_CFG_REG, &oword);
368
369	/* Disable parsing of additional 802.1Q in Q packets */
370	EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
371	EFX_SET_OWORD_FIELD(oword, FRF_CZ_RX_FILTER_ALL_VLAN_ETHERTYPES, 0);
372	EFX_BAR_WRITEO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
373}
374
375static			void
376siena_nic_usrev_dis(
377	__in		efx_nic_t *enp)
378{
379	efx_oword_t	oword;
380
381	EFX_POPULATE_OWORD_1(oword, FRF_CZ_USREV_DIS, 1);
382	EFX_BAR_WRITEO(enp, FR_CZ_USR_EV_CFG, &oword);
383}
384
385	__checkReturn	efx_rc_t
386siena_nic_init(
387	__in		efx_nic_t *enp)
388{
389	efx_rc_t rc;
390
391	EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
392
393	/* Enable reporting of some events (e.g. link change) */
394	if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
395		goto fail1;
396
397	siena_sram_init(enp);
398
399	/* Configure Siena's RX block */
400	siena_nic_rx_cfg(enp);
401
402	/* Disable USR_EVents for now */
403	siena_nic_usrev_dis(enp);
404
405	/* bug17057: Ensure set_link is called */
406	if ((rc = siena_phy_reconfigure(enp)) != 0)
407		goto fail2;
408
409	enp->en_nic_cfg.enc_mcdi_max_payload_length = MCDI_CTL_SDU_LEN_MAX_V1;
410
411	return (0);
412
413fail2:
414	EFSYS_PROBE(fail2);
415fail1:
416	EFSYS_PROBE1(fail1, efx_rc_t, rc);
417
418	return (rc);
419}
420
421			void
422siena_nic_fini(
423	__in		efx_nic_t *enp)
424{
425	_NOTE(ARGUNUSED(enp))
426}
427
428			void
429siena_nic_unprobe(
430	__in		efx_nic_t *enp)
431{
432#if EFSYS_OPT_MON_STATS
433	mcdi_mon_cfg_free(enp);
434#endif /* EFSYS_OPT_MON_STATS */
435	(void) efx_mcdi_drv_attach(enp, B_FALSE);
436}
437
438#if EFSYS_OPT_DIAG
439
440static efx_register_set_t __siena_registers[] = {
441	{ FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
442	{ FR_CZ_USR_EV_CFG_OFST, 0, 1 },
443	{ FR_AZ_RX_CFG_REG_OFST, 0, 1 },
444	{ FR_AZ_TX_CFG_REG_OFST, 0, 1 },
445	{ FR_AZ_TX_RESERVED_REG_OFST, 0, 1 },
446	{ FR_AZ_SRM_TX_DC_CFG_REG_OFST, 0, 1 },
447	{ FR_AZ_RX_DC_CFG_REG_OFST, 0, 1 },
448	{ FR_AZ_RX_DC_PF_WM_REG_OFST, 0, 1 },
449	{ FR_AZ_DP_CTRL_REG_OFST, 0, 1 },
450	{ FR_BZ_RX_RSS_TKEY_REG_OFST, 0, 1},
451	{ FR_CZ_RX_RSS_IPV6_REG1_OFST, 0, 1},
452	{ FR_CZ_RX_RSS_IPV6_REG2_OFST, 0, 1},
453	{ FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
454};
455
456static const uint32_t __siena_register_masks[] = {
457	0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
458	0x000103FF, 0x00000000, 0x00000000, 0x00000000,
459	0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
460	0x7FFF0037, 0xFFFF8000, 0xFFFFFFFF, 0x03FFFFFF,
461	0xFFFEFE80, 0x1FFFFFFF, 0x020000FE, 0x007FFFFF,
462	0x001FFFFF, 0x00000000, 0x00000000, 0x00000000,
463	0x00000003, 0x00000000, 0x00000000, 0x00000000,
464	0x000003FF, 0x00000000, 0x00000000, 0x00000000,
465	0x00000FFF, 0x00000000, 0x00000000, 0x00000000,
466	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
467	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
468	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
469	0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
470};
471
472static efx_register_set_t __siena_tables[] = {
473	{ FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
474	    FR_AZ_RX_FILTER_TBL0_ROWS },
475	{ FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
476	    FR_CZ_RX_MAC_FILTER_TBL0_ROWS },
477	{ FR_AZ_RX_DESC_PTR_TBL_OFST,
478	    FR_AZ_RX_DESC_PTR_TBL_STEP, FR_CZ_RX_DESC_PTR_TBL_ROWS },
479	{ FR_AZ_TX_DESC_PTR_TBL_OFST,
480	    FR_AZ_TX_DESC_PTR_TBL_STEP, FR_CZ_TX_DESC_PTR_TBL_ROWS },
481	{ FR_AZ_TIMER_TBL_OFST, FR_AZ_TIMER_TBL_STEP, FR_CZ_TIMER_TBL_ROWS },
482	{ FR_CZ_TX_FILTER_TBL0_OFST,
483	    FR_CZ_TX_FILTER_TBL0_STEP, FR_CZ_TX_FILTER_TBL0_ROWS },
484	{ FR_CZ_TX_MAC_FILTER_TBL0_OFST,
485	    FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
486};
487
488static const uint32_t __siena_table_masks[] = {
489	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
490	0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
491	0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
492	0xFFFFFFFE, 0x0FFFFFFF, 0x0C000000, 0x00000000,
493	0x3FFFFFFF, 0x00000000, 0x00000000, 0x00000000,
494	0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000013FF,
495	0xFFFF07FF, 0xFFFFFFFF, 0x0000007F, 0x00000000,
496};
497
498	__checkReturn	efx_rc_t
499siena_nic_register_test(
500	__in		efx_nic_t *enp)
501{
502	efx_register_set_t *rsp;
503	const uint32_t *dwordp;
504	unsigned int nitems;
505	unsigned int count;
506	efx_rc_t rc;
507
508	/* Fill out the register mask entries */
509	EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_register_masks)
510		    == EFX_ARRAY_SIZE(__siena_registers) * 4);
511
512	nitems = EFX_ARRAY_SIZE(__siena_registers);
513	dwordp = __siena_register_masks;
514	for (count = 0; count < nitems; ++count) {
515		rsp = __siena_registers + count;
516		rsp->mask.eo_u32[0] = *dwordp++;
517		rsp->mask.eo_u32[1] = *dwordp++;
518		rsp->mask.eo_u32[2] = *dwordp++;
519		rsp->mask.eo_u32[3] = *dwordp++;
520	}
521
522	/* Fill out the register table entries */
523	EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__siena_table_masks)
524		    == EFX_ARRAY_SIZE(__siena_tables) * 4);
525
526	nitems = EFX_ARRAY_SIZE(__siena_tables);
527	dwordp = __siena_table_masks;
528	for (count = 0; count < nitems; ++count) {
529		rsp = __siena_tables + count;
530		rsp->mask.eo_u32[0] = *dwordp++;
531		rsp->mask.eo_u32[1] = *dwordp++;
532		rsp->mask.eo_u32[2] = *dwordp++;
533		rsp->mask.eo_u32[3] = *dwordp++;
534	}
535
536	if ((rc = efx_nic_test_registers(enp, __siena_registers,
537	    EFX_ARRAY_SIZE(__siena_registers))) != 0)
538		goto fail1;
539
540	if ((rc = efx_nic_test_tables(enp, __siena_tables,
541	    EFX_PATTERN_BYTE_ALTERNATE,
542	    EFX_ARRAY_SIZE(__siena_tables))) != 0)
543		goto fail2;
544
545	if ((rc = efx_nic_test_tables(enp, __siena_tables,
546	    EFX_PATTERN_BYTE_CHANGING,
547	    EFX_ARRAY_SIZE(__siena_tables))) != 0)
548		goto fail3;
549
550	if ((rc = efx_nic_test_tables(enp, __siena_tables,
551	    EFX_PATTERN_BIT_SWEEP, EFX_ARRAY_SIZE(__siena_tables))) != 0)
552		goto fail4;
553
554	return (0);
555
556fail4:
557	EFSYS_PROBE(fail4);
558fail3:
559	EFSYS_PROBE(fail3);
560fail2:
561	EFSYS_PROBE(fail2);
562fail1:
563	EFSYS_PROBE1(fail1, efx_rc_t, rc);
564
565	return (rc);
566}
567
568#endif	/* EFSYS_OPT_DIAG */
569
570#endif	/* EFSYS_OPT_SIENA */
571