xref: /freebsd/sys/dev/sfxge/common/efx_nvram.c (revision 134c4c4a6c93d45751b9818e1bf985196b8330bc)
1e948693eSPhilip Paeps /*-
23c838a9fSAndrew Rybchenko  * Copyright (c) 2009-2015 Solarflare Communications Inc.
33c838a9fSAndrew Rybchenko  * All rights reserved.
4e948693eSPhilip Paeps  *
5e948693eSPhilip Paeps  * Redistribution and use in source and binary forms, with or without
63c838a9fSAndrew Rybchenko  * modification, are permitted provided that the following conditions are met:
7e948693eSPhilip Paeps  *
83c838a9fSAndrew Rybchenko  * 1. Redistributions of source code must retain the above copyright notice,
93c838a9fSAndrew Rybchenko  *    this list of conditions and the following disclaimer.
103c838a9fSAndrew Rybchenko  * 2. Redistributions in binary form must reproduce the above copyright notice,
113c838a9fSAndrew Rybchenko  *    this list of conditions and the following disclaimer in the documentation
123c838a9fSAndrew Rybchenko  *    and/or other materials provided with the distribution.
133c838a9fSAndrew Rybchenko  *
143c838a9fSAndrew Rybchenko  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
153c838a9fSAndrew Rybchenko  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
163c838a9fSAndrew Rybchenko  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
173c838a9fSAndrew Rybchenko  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
183c838a9fSAndrew Rybchenko  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
193c838a9fSAndrew Rybchenko  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
203c838a9fSAndrew Rybchenko  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
213c838a9fSAndrew Rybchenko  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
223c838a9fSAndrew Rybchenko  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
233c838a9fSAndrew Rybchenko  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
243c838a9fSAndrew Rybchenko  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
253c838a9fSAndrew Rybchenko  *
263c838a9fSAndrew Rybchenko  * The views and conclusions contained in the software and documentation are
273c838a9fSAndrew Rybchenko  * those of the authors and should not be interpreted as representing official
283c838a9fSAndrew Rybchenko  * policies, either expressed or implied, of the FreeBSD Project.
29e948693eSPhilip Paeps  */
30e948693eSPhilip Paeps 
315dee87d7SPhilip Paeps #include <sys/cdefs.h>
325dee87d7SPhilip Paeps __FBSDID("$FreeBSD$");
335dee87d7SPhilip Paeps 
34e948693eSPhilip Paeps #include "efx.h"
35e948693eSPhilip Paeps #include "efx_impl.h"
36e948693eSPhilip Paeps 
37e948693eSPhilip Paeps #if EFSYS_OPT_NVRAM
38e948693eSPhilip Paeps 
39e948693eSPhilip Paeps #if EFSYS_OPT_FALCON
40e948693eSPhilip Paeps 
413c838a9fSAndrew Rybchenko static efx_nvram_ops_t	__efx_nvram_falcon_ops = {
42e948693eSPhilip Paeps #if EFSYS_OPT_DIAG
43e948693eSPhilip Paeps 	falcon_nvram_test,		/* envo_test */
44e948693eSPhilip Paeps #endif	/* EFSYS_OPT_DIAG */
45e948693eSPhilip Paeps 	falcon_nvram_get_version,	/* envo_get_version */
46e948693eSPhilip Paeps 	falcon_nvram_rw_finish,		/* envo_rw_finish */
47e948693eSPhilip Paeps 	falcon_nvram_set_version,	/* envo_set_version */
48bce88e31SAndrew Rybchenko 	falcon_nvram_type_to_partn,	/* envo_type_to_partn */
4956bd83b0SAndrew Rybchenko 	falcon_nvram_partn_size,	/* envo_partn_size */
505d846e87SAndrew Rybchenko 	falcon_nvram_partn_rw_start,	/* envo_partn_rw_start */
510afdf29cSAndrew Rybchenko 	falcon_nvram_partn_read,	/* envo_partn_read */
52b60ff840SAndrew Rybchenko 	falcon_nvram_partn_erase,	/* envo_partn_erase */
53*134c4c4aSAndrew Rybchenko 	falcon_nvram_partn_write,	/* envo_partn_write */
54e948693eSPhilip Paeps };
55e948693eSPhilip Paeps 
56e948693eSPhilip Paeps #endif	/* EFSYS_OPT_FALCON */
57e948693eSPhilip Paeps 
58e948693eSPhilip Paeps #if EFSYS_OPT_SIENA
59e948693eSPhilip Paeps 
603c838a9fSAndrew Rybchenko static efx_nvram_ops_t	__efx_nvram_siena_ops = {
61e948693eSPhilip Paeps #if EFSYS_OPT_DIAG
62e948693eSPhilip Paeps 	siena_nvram_test,		/* envo_test */
63e948693eSPhilip Paeps #endif	/* EFSYS_OPT_DIAG */
64e948693eSPhilip Paeps 	siena_nvram_get_version,	/* envo_get_version */
65e948693eSPhilip Paeps 	siena_nvram_rw_finish,		/* envo_rw_finish */
66e948693eSPhilip Paeps 	siena_nvram_set_version,	/* envo_set_version */
67bce88e31SAndrew Rybchenko 	siena_nvram_type_to_partn,	/* envo_type_to_partn */
6856bd83b0SAndrew Rybchenko 	siena_nvram_partn_size,		/* envo_partn_size */
695d846e87SAndrew Rybchenko 	siena_nvram_partn_rw_start,	/* envo_partn_rw_start */
700afdf29cSAndrew Rybchenko 	siena_nvram_partn_read,		/* envo_partn_read */
71b60ff840SAndrew Rybchenko 	siena_nvram_partn_erase,	/* envo_partn_erase */
72*134c4c4aSAndrew Rybchenko 	siena_nvram_partn_write,	/* envo_partn_write */
73e948693eSPhilip Paeps };
74e948693eSPhilip Paeps 
75e948693eSPhilip Paeps #endif	/* EFSYS_OPT_SIENA */
76e948693eSPhilip Paeps 
77de9775adSAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
783c838a9fSAndrew Rybchenko 
79de9775adSAndrew Rybchenko static efx_nvram_ops_t	__efx_nvram_ef10_ops = {
803c838a9fSAndrew Rybchenko #if EFSYS_OPT_DIAG
81de9775adSAndrew Rybchenko 	ef10_nvram_test,		/* envo_test */
823c838a9fSAndrew Rybchenko #endif	/* EFSYS_OPT_DIAG */
83de9775adSAndrew Rybchenko 	ef10_nvram_get_version,		/* envo_get_version */
84de9775adSAndrew Rybchenko 	ef10_nvram_rw_finish,		/* envo_rw_finish */
85de9775adSAndrew Rybchenko 	ef10_nvram_set_version,		/* envo_set_version */
86bce88e31SAndrew Rybchenko 	ef10_nvram_type_to_partn,	/* envo_type_to_partn */
8756bd83b0SAndrew Rybchenko 	ef10_nvram_partn_size,		/* envo_partn_size */
885d846e87SAndrew Rybchenko 	ef10_nvram_partn_rw_start,	/* envo_partn_rw_start */
890afdf29cSAndrew Rybchenko 	ef10_nvram_partn_read,		/* envo_partn_read */
90b60ff840SAndrew Rybchenko 	ef10_nvram_partn_erase,		/* envo_partn_erase */
91*134c4c4aSAndrew Rybchenko 	ef10_nvram_partn_write,		/* envo_partn_write */
923c838a9fSAndrew Rybchenko };
933c838a9fSAndrew Rybchenko 
94de9775adSAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
953c838a9fSAndrew Rybchenko 
96460cb568SAndrew Rybchenko 	__checkReturn	efx_rc_t
97e948693eSPhilip Paeps efx_nvram_init(
98e948693eSPhilip Paeps 	__in		efx_nic_t *enp)
99e948693eSPhilip Paeps {
100e948693eSPhilip Paeps 	efx_nvram_ops_t *envop;
101460cb568SAndrew Rybchenko 	efx_rc_t rc;
102e948693eSPhilip Paeps 
103e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
104e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
105e948693eSPhilip Paeps 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NVRAM));
106e948693eSPhilip Paeps 
107e948693eSPhilip Paeps 	switch (enp->en_family) {
108e948693eSPhilip Paeps #if EFSYS_OPT_FALCON
109e948693eSPhilip Paeps 	case EFX_FAMILY_FALCON:
110e948693eSPhilip Paeps 		envop = (efx_nvram_ops_t *)&__efx_nvram_falcon_ops;
111e948693eSPhilip Paeps 		break;
112e948693eSPhilip Paeps #endif	/* EFSYS_OPT_FALCON */
113e948693eSPhilip Paeps 
114e948693eSPhilip Paeps #if EFSYS_OPT_SIENA
115e948693eSPhilip Paeps 	case EFX_FAMILY_SIENA:
116e948693eSPhilip Paeps 		envop = (efx_nvram_ops_t *)&__efx_nvram_siena_ops;
117e948693eSPhilip Paeps 		break;
118e948693eSPhilip Paeps #endif	/* EFSYS_OPT_SIENA */
119e948693eSPhilip Paeps 
1203c838a9fSAndrew Rybchenko #if EFSYS_OPT_HUNTINGTON
1213c838a9fSAndrew Rybchenko 	case EFX_FAMILY_HUNTINGTON:
122de9775adSAndrew Rybchenko 		envop = (efx_nvram_ops_t *)&__efx_nvram_ef10_ops;
1233c838a9fSAndrew Rybchenko 		break;
1243c838a9fSAndrew Rybchenko #endif	/* EFSYS_OPT_HUNTINGTON */
1253c838a9fSAndrew Rybchenko 
126de9775adSAndrew Rybchenko #if EFSYS_OPT_MEDFORD
127de9775adSAndrew Rybchenko 	case EFX_FAMILY_MEDFORD:
128de9775adSAndrew Rybchenko 		envop = (efx_nvram_ops_t *)&__efx_nvram_ef10_ops;
129de9775adSAndrew Rybchenko 		break;
130de9775adSAndrew Rybchenko #endif	/* EFSYS_OPT_MEDFORD */
131de9775adSAndrew Rybchenko 
132e948693eSPhilip Paeps 	default:
133e948693eSPhilip Paeps 		EFSYS_ASSERT(0);
134e948693eSPhilip Paeps 		rc = ENOTSUP;
135e948693eSPhilip Paeps 		goto fail1;
136e948693eSPhilip Paeps 	}
137e948693eSPhilip Paeps 
138e948693eSPhilip Paeps 	enp->en_envop = envop;
139e948693eSPhilip Paeps 	enp->en_mod_flags |= EFX_MOD_NVRAM;
140e948693eSPhilip Paeps 
141e948693eSPhilip Paeps 	return (0);
142e948693eSPhilip Paeps 
143e948693eSPhilip Paeps fail1:
144460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
145e948693eSPhilip Paeps 
146e948693eSPhilip Paeps 	return (rc);
147e948693eSPhilip Paeps }
148e948693eSPhilip Paeps 
149e948693eSPhilip Paeps #if EFSYS_OPT_DIAG
150e948693eSPhilip Paeps 
151460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
152e948693eSPhilip Paeps efx_nvram_test(
153e948693eSPhilip Paeps 	__in			efx_nic_t *enp)
154e948693eSPhilip Paeps {
155e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
156460cb568SAndrew Rybchenko 	efx_rc_t rc;
157e948693eSPhilip Paeps 
158e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
159e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
160e948693eSPhilip Paeps 
161e948693eSPhilip Paeps 	if ((rc = envop->envo_test(enp)) != 0)
162e948693eSPhilip Paeps 		goto fail1;
163e948693eSPhilip Paeps 
164e948693eSPhilip Paeps 	return (0);
165e948693eSPhilip Paeps 
166e948693eSPhilip Paeps fail1:
167460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
168e948693eSPhilip Paeps 
169e948693eSPhilip Paeps 	return (rc);
170e948693eSPhilip Paeps }
171e948693eSPhilip Paeps 
172e948693eSPhilip Paeps #endif	/* EFSYS_OPT_DIAG */
173e948693eSPhilip Paeps 
174460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
175e948693eSPhilip Paeps efx_nvram_size(
176e948693eSPhilip Paeps 	__in			efx_nic_t *enp,
177e948693eSPhilip Paeps 	__in			efx_nvram_type_t type,
178e948693eSPhilip Paeps 	__out			size_t *sizep)
179e948693eSPhilip Paeps {
180e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
18156bd83b0SAndrew Rybchenko 	uint32_t partn;
182460cb568SAndrew Rybchenko 	efx_rc_t rc;
183e948693eSPhilip Paeps 
184e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
185e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
186e948693eSPhilip Paeps 
187e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
188e948693eSPhilip Paeps 
18956bd83b0SAndrew Rybchenko 	if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
190e948693eSPhilip Paeps 		goto fail1;
191e948693eSPhilip Paeps 
19256bd83b0SAndrew Rybchenko 	if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0)
19356bd83b0SAndrew Rybchenko 		goto fail2;
19456bd83b0SAndrew Rybchenko 
195e948693eSPhilip Paeps 	return (0);
196e948693eSPhilip Paeps 
19756bd83b0SAndrew Rybchenko fail2:
19856bd83b0SAndrew Rybchenko 	EFSYS_PROBE(fail2);
199e948693eSPhilip Paeps fail1:
200460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
20156bd83b0SAndrew Rybchenko 	*sizep = 0;
202e948693eSPhilip Paeps 
203e948693eSPhilip Paeps 	return (rc);
204e948693eSPhilip Paeps }
205e948693eSPhilip Paeps 
206460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
207e948693eSPhilip Paeps efx_nvram_get_version(
208e948693eSPhilip Paeps 	__in			efx_nic_t *enp,
209e948693eSPhilip Paeps 	__in			efx_nvram_type_t type,
210e948693eSPhilip Paeps 	__out			uint32_t *subtypep,
211e948693eSPhilip Paeps 	__out_ecount(4)		uint16_t version[4])
212e948693eSPhilip Paeps {
213e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
214460cb568SAndrew Rybchenko 	efx_rc_t rc;
215e948693eSPhilip Paeps 
216e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
217e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
218e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
219e948693eSPhilip Paeps 
220e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
221e948693eSPhilip Paeps 
222e948693eSPhilip Paeps 	if ((rc = envop->envo_get_version(enp, type, subtypep, version)) != 0)
223e948693eSPhilip Paeps 		goto fail1;
224e948693eSPhilip Paeps 
225e948693eSPhilip Paeps 	return (0);
226e948693eSPhilip Paeps 
227e948693eSPhilip Paeps fail1:
228460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
229e948693eSPhilip Paeps 
230e948693eSPhilip Paeps 	return (rc);
231e948693eSPhilip Paeps }
232e948693eSPhilip Paeps 
233460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
234e948693eSPhilip Paeps efx_nvram_rw_start(
235e948693eSPhilip Paeps 	__in			efx_nic_t *enp,
236e948693eSPhilip Paeps 	__in			efx_nvram_type_t type,
237e948693eSPhilip Paeps 	__out_opt		size_t *chunk_sizep)
238e948693eSPhilip Paeps {
239e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
2405d846e87SAndrew Rybchenko 	uint32_t partn;
241460cb568SAndrew Rybchenko 	efx_rc_t rc;
242e948693eSPhilip Paeps 
243e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
244e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
245e948693eSPhilip Paeps 
246e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
247e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
248e948693eSPhilip Paeps 
249e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
250e948693eSPhilip Paeps 
2515d846e87SAndrew Rybchenko 	if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
252e948693eSPhilip Paeps 		goto fail1;
253e948693eSPhilip Paeps 
2545d846e87SAndrew Rybchenko 	if ((rc = envop->envo_partn_rw_start(enp, partn, chunk_sizep)) != 0)
2555d846e87SAndrew Rybchenko 		goto fail2;
2565d846e87SAndrew Rybchenko 
257e948693eSPhilip Paeps 	enp->en_nvram_locked = type;
258e948693eSPhilip Paeps 
259e948693eSPhilip Paeps 	return (0);
260e948693eSPhilip Paeps 
2615d846e87SAndrew Rybchenko fail2:
2625d846e87SAndrew Rybchenko 	EFSYS_PROBE(fail2);
263e948693eSPhilip Paeps fail1:
264460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
265e948693eSPhilip Paeps 
266e948693eSPhilip Paeps 	return (rc);
267e948693eSPhilip Paeps }
268e948693eSPhilip Paeps 
269460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
270e948693eSPhilip Paeps efx_nvram_read_chunk(
271e948693eSPhilip Paeps 	__in			efx_nic_t *enp,
272e948693eSPhilip Paeps 	__in			efx_nvram_type_t type,
273e948693eSPhilip Paeps 	__in			unsigned int offset,
274e948693eSPhilip Paeps 	__out_bcount(size)	caddr_t data,
275e948693eSPhilip Paeps 	__in			size_t size)
276e948693eSPhilip Paeps {
277e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
2780afdf29cSAndrew Rybchenko 	uint32_t partn;
279460cb568SAndrew Rybchenko 	efx_rc_t rc;
280e948693eSPhilip Paeps 
281e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
282e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
283e948693eSPhilip Paeps 
284e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
285e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
286e948693eSPhilip Paeps 
287e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
288e948693eSPhilip Paeps 
2890afdf29cSAndrew Rybchenko 	if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
290e948693eSPhilip Paeps 		goto fail1;
291e948693eSPhilip Paeps 
2920afdf29cSAndrew Rybchenko 	if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
2930afdf29cSAndrew Rybchenko 		goto fail2;
2940afdf29cSAndrew Rybchenko 
295e948693eSPhilip Paeps 	return (0);
296e948693eSPhilip Paeps 
2970afdf29cSAndrew Rybchenko fail2:
2980afdf29cSAndrew Rybchenko 	EFSYS_PROBE(fail2);
299e948693eSPhilip Paeps fail1:
300460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
301e948693eSPhilip Paeps 
302e948693eSPhilip Paeps 	return (rc);
303e948693eSPhilip Paeps }
304e948693eSPhilip Paeps 
305460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
306e948693eSPhilip Paeps efx_nvram_erase(
307e948693eSPhilip Paeps 	__in			efx_nic_t *enp,
308e948693eSPhilip Paeps 	__in			efx_nvram_type_t type)
309e948693eSPhilip Paeps {
310e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
311b60ff840SAndrew Rybchenko 	unsigned int offset = 0;
312b60ff840SAndrew Rybchenko 	size_t size = 0;
313b60ff840SAndrew Rybchenko 	uint32_t partn;
314460cb568SAndrew Rybchenko 	efx_rc_t rc;
315e948693eSPhilip Paeps 
316e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
317e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
318e948693eSPhilip Paeps 
319e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
320e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
321e948693eSPhilip Paeps 
322e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
323e948693eSPhilip Paeps 
324b60ff840SAndrew Rybchenko 	if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
325e948693eSPhilip Paeps 		goto fail1;
326e948693eSPhilip Paeps 
327b60ff840SAndrew Rybchenko 	if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0)
328b60ff840SAndrew Rybchenko 		goto fail2;
329b60ff840SAndrew Rybchenko 
330b60ff840SAndrew Rybchenko 	if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0)
331b60ff840SAndrew Rybchenko 		goto fail3;
332b60ff840SAndrew Rybchenko 
333e948693eSPhilip Paeps 	return (0);
334e948693eSPhilip Paeps 
335b60ff840SAndrew Rybchenko fail3:
336b60ff840SAndrew Rybchenko 	EFSYS_PROBE(fail3);
337b60ff840SAndrew Rybchenko fail2:
338b60ff840SAndrew Rybchenko 	EFSYS_PROBE(fail2);
339e948693eSPhilip Paeps fail1:
340460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
341e948693eSPhilip Paeps 
342e948693eSPhilip Paeps 	return (rc);
343e948693eSPhilip Paeps }
344e948693eSPhilip Paeps 
345460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
346e948693eSPhilip Paeps efx_nvram_write_chunk(
347e948693eSPhilip Paeps 	__in			efx_nic_t *enp,
348e948693eSPhilip Paeps 	__in			efx_nvram_type_t type,
349e948693eSPhilip Paeps 	__in			unsigned int offset,
350e948693eSPhilip Paeps 	__in_bcount(size)	caddr_t data,
351e948693eSPhilip Paeps 	__in			size_t size)
352e948693eSPhilip Paeps {
353e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
354*134c4c4aSAndrew Rybchenko 	uint32_t partn;
355460cb568SAndrew Rybchenko 	efx_rc_t rc;
356e948693eSPhilip Paeps 
357e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
358e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
359e948693eSPhilip Paeps 
360e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
361e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
362e948693eSPhilip Paeps 
363e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
364e948693eSPhilip Paeps 
365*134c4c4aSAndrew Rybchenko 	if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
366e948693eSPhilip Paeps 		goto fail1;
367e948693eSPhilip Paeps 
368*134c4c4aSAndrew Rybchenko 	if ((rc = envop->envo_partn_write(enp, partn, offset, data, size)) != 0)
369*134c4c4aSAndrew Rybchenko 		goto fail2;
370*134c4c4aSAndrew Rybchenko 
371e948693eSPhilip Paeps 	return (0);
372e948693eSPhilip Paeps 
373*134c4c4aSAndrew Rybchenko fail2:
374*134c4c4aSAndrew Rybchenko 	EFSYS_PROBE(fail2);
375e948693eSPhilip Paeps fail1:
376460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
377e948693eSPhilip Paeps 
378e948693eSPhilip Paeps 	return (rc);
379e948693eSPhilip Paeps }
380e948693eSPhilip Paeps 
381e948693eSPhilip Paeps 				void
382e948693eSPhilip Paeps efx_nvram_rw_finish(
383e948693eSPhilip Paeps 	__in			efx_nic_t *enp,
384e948693eSPhilip Paeps 	__in			efx_nvram_type_t type)
385e948693eSPhilip Paeps {
386e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
387e948693eSPhilip Paeps 
388e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
389e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
390e948693eSPhilip Paeps 
391e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
392e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
393e948693eSPhilip Paeps 
394e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
395e948693eSPhilip Paeps 
396e948693eSPhilip Paeps 	envop->envo_rw_finish(enp, type);
397e948693eSPhilip Paeps 
398e948693eSPhilip Paeps 	enp->en_nvram_locked = EFX_NVRAM_INVALID;
399e948693eSPhilip Paeps }
400e948693eSPhilip Paeps 
401460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
402e948693eSPhilip Paeps efx_nvram_set_version(
403e948693eSPhilip Paeps 	__in			efx_nic_t *enp,
404e948693eSPhilip Paeps 	__in			efx_nvram_type_t type,
4053c838a9fSAndrew Rybchenko 	__in_ecount(4)		uint16_t version[4])
406e948693eSPhilip Paeps {
407e948693eSPhilip Paeps 	efx_nvram_ops_t *envop = enp->en_envop;
408460cb568SAndrew Rybchenko 	efx_rc_t rc;
409e948693eSPhilip Paeps 
410e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
411e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
412e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
413e948693eSPhilip Paeps 
414e948693eSPhilip Paeps 	EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
415e948693eSPhilip Paeps 
416e948693eSPhilip Paeps 	/*
417e948693eSPhilip Paeps 	 * The Siena implementation of envo_set_version() will attempt to
418e948693eSPhilip Paeps 	 * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector.
419e948693eSPhilip Paeps 	 * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
420e948693eSPhilip Paeps 	 */
421e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
422e948693eSPhilip Paeps 
423e948693eSPhilip Paeps 	if ((rc = envop->envo_set_version(enp, type, version)) != 0)
424e948693eSPhilip Paeps 		goto fail1;
425e948693eSPhilip Paeps 
426e948693eSPhilip Paeps 	return (0);
427e948693eSPhilip Paeps 
428e948693eSPhilip Paeps fail1:
429460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
430e948693eSPhilip Paeps 
431e948693eSPhilip Paeps 	return (rc);
432e948693eSPhilip Paeps }
433e948693eSPhilip Paeps 
434e948693eSPhilip Paeps void
435e948693eSPhilip Paeps efx_nvram_fini(
436e948693eSPhilip Paeps 	__in		efx_nic_t *enp)
437e948693eSPhilip Paeps {
438e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
439e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
440e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
441e948693eSPhilip Paeps 
442e948693eSPhilip Paeps 	EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
443e948693eSPhilip Paeps 
444e948693eSPhilip Paeps 	enp->en_envop = NULL;
445e948693eSPhilip Paeps 	enp->en_mod_flags &= ~EFX_MOD_NVRAM;
446e948693eSPhilip Paeps }
447e948693eSPhilip Paeps 
448e948693eSPhilip Paeps #endif	/* EFSYS_OPT_NVRAM */
4493c838a9fSAndrew Rybchenko 
4503c838a9fSAndrew Rybchenko #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
4513c838a9fSAndrew Rybchenko 
4523c838a9fSAndrew Rybchenko /*
4533c838a9fSAndrew Rybchenko  * Internal MCDI request handling
4543c838a9fSAndrew Rybchenko  */
4553c838a9fSAndrew Rybchenko 
456460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
4573c838a9fSAndrew Rybchenko efx_mcdi_nvram_partitions(
4583c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
4593c838a9fSAndrew Rybchenko 	__out_bcount(size)	caddr_t data,
4603c838a9fSAndrew Rybchenko 	__in			size_t size,
4613c838a9fSAndrew Rybchenko 	__out			unsigned int *npartnp)
4623c838a9fSAndrew Rybchenko {
4633c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
4643c838a9fSAndrew Rybchenko 	uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
4653c838a9fSAndrew Rybchenko 			    MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
4663c838a9fSAndrew Rybchenko 	unsigned int npartn;
467460cb568SAndrew Rybchenko 	efx_rc_t rc;
4683c838a9fSAndrew Rybchenko 
4693c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
4703c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
4713c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
4723c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
4733c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
4743c838a9fSAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
4753c838a9fSAndrew Rybchenko 
4763c838a9fSAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
4773c838a9fSAndrew Rybchenko 
4783c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
4793c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
4803c838a9fSAndrew Rybchenko 		goto fail1;
4813c838a9fSAndrew Rybchenko 	}
4823c838a9fSAndrew Rybchenko 
4833c838a9fSAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
4843c838a9fSAndrew Rybchenko 		rc = EMSGSIZE;
4853c838a9fSAndrew Rybchenko 		goto fail2;
4863c838a9fSAndrew Rybchenko 	}
4873c838a9fSAndrew Rybchenko 	npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
4883c838a9fSAndrew Rybchenko 
4893c838a9fSAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
4903c838a9fSAndrew Rybchenko 		rc = ENOENT;
4913c838a9fSAndrew Rybchenko 		goto fail3;
4923c838a9fSAndrew Rybchenko 	}
4933c838a9fSAndrew Rybchenko 
4943c838a9fSAndrew Rybchenko 	if (size < npartn * sizeof (uint32_t)) {
4953c838a9fSAndrew Rybchenko 		rc = ENOSPC;
4963c838a9fSAndrew Rybchenko 		goto fail3;
4973c838a9fSAndrew Rybchenko 	}
4983c838a9fSAndrew Rybchenko 
4993c838a9fSAndrew Rybchenko 	*npartnp = npartn;
5003c838a9fSAndrew Rybchenko 
5013c838a9fSAndrew Rybchenko 	memcpy(data,
5023c838a9fSAndrew Rybchenko 	    MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
5033c838a9fSAndrew Rybchenko 	    (npartn * sizeof (uint32_t)));
5043c838a9fSAndrew Rybchenko 
5053c838a9fSAndrew Rybchenko 	return (0);
5063c838a9fSAndrew Rybchenko 
5073c838a9fSAndrew Rybchenko fail3:
5083c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail3);
5093c838a9fSAndrew Rybchenko fail2:
5103c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail2);
5113c838a9fSAndrew Rybchenko fail1:
512460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
5133c838a9fSAndrew Rybchenko 
5143c838a9fSAndrew Rybchenko 	return (rc);
5153c838a9fSAndrew Rybchenko }
5163c838a9fSAndrew Rybchenko 
517460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
5183c838a9fSAndrew Rybchenko efx_mcdi_nvram_metadata(
5193c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
5203c838a9fSAndrew Rybchenko 	__in			uint32_t partn,
5213c838a9fSAndrew Rybchenko 	__out			uint32_t *subtypep,
5223c838a9fSAndrew Rybchenko 	__out_ecount(4)		uint16_t version[4],
5233c838a9fSAndrew Rybchenko 	__out_bcount_opt(size)	char *descp,
5243c838a9fSAndrew Rybchenko 	__in			size_t size)
5253c838a9fSAndrew Rybchenko {
5263c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
5273c838a9fSAndrew Rybchenko 	uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
5283c838a9fSAndrew Rybchenko 			    MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
529460cb568SAndrew Rybchenko 	efx_rc_t rc;
5303c838a9fSAndrew Rybchenko 
5313c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
5323c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_METADATA;
5333c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
5343c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
5353c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
5363c838a9fSAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
5373c838a9fSAndrew Rybchenko 
5383c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
5393c838a9fSAndrew Rybchenko 
5403c838a9fSAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
5413c838a9fSAndrew Rybchenko 
5423c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
5433c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
5443c838a9fSAndrew Rybchenko 		goto fail1;
5453c838a9fSAndrew Rybchenko 	}
5463c838a9fSAndrew Rybchenko 
5473c838a9fSAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
5483c838a9fSAndrew Rybchenko 		rc = EMSGSIZE;
5493c838a9fSAndrew Rybchenko 		goto fail2;
5503c838a9fSAndrew Rybchenko 	}
5513c838a9fSAndrew Rybchenko 
5523c838a9fSAndrew Rybchenko 	if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
5533c838a9fSAndrew Rybchenko 		NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
5543c838a9fSAndrew Rybchenko 		*subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
5553c838a9fSAndrew Rybchenko 	} else {
5563c838a9fSAndrew Rybchenko 		*subtypep = 0;
5573c838a9fSAndrew Rybchenko 	}
5583c838a9fSAndrew Rybchenko 
5593c838a9fSAndrew Rybchenko 	if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
5603c838a9fSAndrew Rybchenko 		NVRAM_METADATA_OUT_VERSION_VALID)) {
5613c838a9fSAndrew Rybchenko 		version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
5623c838a9fSAndrew Rybchenko 		version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
5633c838a9fSAndrew Rybchenko 		version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
5643c838a9fSAndrew Rybchenko 		version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
5653c838a9fSAndrew Rybchenko 	} else {
5663c838a9fSAndrew Rybchenko 		version[0] = version[1] = version[2] = version[3] = 0;
5673c838a9fSAndrew Rybchenko 	}
5683c838a9fSAndrew Rybchenko 
5693c838a9fSAndrew Rybchenko 	if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
5703c838a9fSAndrew Rybchenko 		NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
5713c838a9fSAndrew Rybchenko 		/* Return optional descrition string */
5723c838a9fSAndrew Rybchenko 		if ((descp != NULL) && (size > 0)) {
5733c838a9fSAndrew Rybchenko 			size_t desclen;
5743c838a9fSAndrew Rybchenko 
5753c838a9fSAndrew Rybchenko 			descp[0] = '\0';
5763c838a9fSAndrew Rybchenko 			desclen = (req.emr_out_length_used
5773c838a9fSAndrew Rybchenko 			    - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
5783c838a9fSAndrew Rybchenko 
5793c838a9fSAndrew Rybchenko 			EFSYS_ASSERT3U(desclen, <=,
5803c838a9fSAndrew Rybchenko 			    MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
5813c838a9fSAndrew Rybchenko 
5823c838a9fSAndrew Rybchenko 			if (size < desclen) {
5833c838a9fSAndrew Rybchenko 				rc = ENOSPC;
5843c838a9fSAndrew Rybchenko 				goto fail3;
5853c838a9fSAndrew Rybchenko 			}
5863c838a9fSAndrew Rybchenko 
5873c838a9fSAndrew Rybchenko 			memcpy(descp, MCDI_OUT2(req, char,
5883c838a9fSAndrew Rybchenko 				NVRAM_METADATA_OUT_DESCRIPTION),
5893c838a9fSAndrew Rybchenko 			    desclen);
5903c838a9fSAndrew Rybchenko 
5913c838a9fSAndrew Rybchenko 			/* Ensure string is NUL terminated */
5923c838a9fSAndrew Rybchenko 			descp[desclen] = '\0';
5933c838a9fSAndrew Rybchenko 		}
5943c838a9fSAndrew Rybchenko 	}
5953c838a9fSAndrew Rybchenko 
5963c838a9fSAndrew Rybchenko 	return (0);
5973c838a9fSAndrew Rybchenko 
5983c838a9fSAndrew Rybchenko fail3:
5993c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail3);
6003c838a9fSAndrew Rybchenko fail2:
6013c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail2);
6023c838a9fSAndrew Rybchenko fail1:
603460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
6043c838a9fSAndrew Rybchenko 
6053c838a9fSAndrew Rybchenko 	return (rc);
6063c838a9fSAndrew Rybchenko }
6073c838a9fSAndrew Rybchenko 
608460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
6093c838a9fSAndrew Rybchenko efx_mcdi_nvram_info(
6103c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
6113c838a9fSAndrew Rybchenko 	__in			uint32_t partn,
6123c838a9fSAndrew Rybchenko 	__out_opt		size_t *sizep,
6133c838a9fSAndrew Rybchenko 	__out_opt		uint32_t *addressp,
6149cb71b16SAndrew Rybchenko 	__out_opt		uint32_t *erase_sizep,
6159cb71b16SAndrew Rybchenko 	__out_opt		uint32_t *write_sizep)
6163c838a9fSAndrew Rybchenko {
6173c838a9fSAndrew Rybchenko 	uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
6189cb71b16SAndrew Rybchenko 			    MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
6193c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
620460cb568SAndrew Rybchenko 	efx_rc_t rc;
6213c838a9fSAndrew Rybchenko 
6223c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
6233c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_INFO;
6243c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
6253c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
6263c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
6279cb71b16SAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_INFO_V2_OUT_LEN;
6283c838a9fSAndrew Rybchenko 
6293c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
6303c838a9fSAndrew Rybchenko 
6313c838a9fSAndrew Rybchenko 	efx_mcdi_execute_quiet(enp, &req);
6323c838a9fSAndrew Rybchenko 
6333c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
6343c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
6353c838a9fSAndrew Rybchenko 		goto fail1;
6363c838a9fSAndrew Rybchenko 	}
6373c838a9fSAndrew Rybchenko 
6383c838a9fSAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
6393c838a9fSAndrew Rybchenko 		rc = EMSGSIZE;
6403c838a9fSAndrew Rybchenko 		goto fail2;
6413c838a9fSAndrew Rybchenko 	}
6423c838a9fSAndrew Rybchenko 
6433c838a9fSAndrew Rybchenko 	if (sizep)
6443c838a9fSAndrew Rybchenko 		*sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
6453c838a9fSAndrew Rybchenko 
6463c838a9fSAndrew Rybchenko 	if (addressp)
6473c838a9fSAndrew Rybchenko 		*addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
6483c838a9fSAndrew Rybchenko 
6493c838a9fSAndrew Rybchenko 	if (erase_sizep)
6503c838a9fSAndrew Rybchenko 		*erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
6513c838a9fSAndrew Rybchenko 
6529cb71b16SAndrew Rybchenko 	if (write_sizep) {
6539cb71b16SAndrew Rybchenko 		*write_sizep =
6549cb71b16SAndrew Rybchenko 			(req.emr_out_length_used <
6559cb71b16SAndrew Rybchenko 			    MC_CMD_NVRAM_INFO_V2_OUT_LEN) ?
6569cb71b16SAndrew Rybchenko 			0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE);
6579cb71b16SAndrew Rybchenko 	}
6589cb71b16SAndrew Rybchenko 
6593c838a9fSAndrew Rybchenko 	return (0);
6603c838a9fSAndrew Rybchenko 
6613c838a9fSAndrew Rybchenko fail2:
6623c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail2);
6633c838a9fSAndrew Rybchenko fail1:
664460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
6653c838a9fSAndrew Rybchenko 
6663c838a9fSAndrew Rybchenko 	return (rc);
6673c838a9fSAndrew Rybchenko }
6683c838a9fSAndrew Rybchenko 
669460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
6703c838a9fSAndrew Rybchenko efx_mcdi_nvram_update_start(
6713c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
6723c838a9fSAndrew Rybchenko 	__in			uint32_t partn)
6733c838a9fSAndrew Rybchenko {
6743c838a9fSAndrew Rybchenko 	uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_IN_LEN,
6753c838a9fSAndrew Rybchenko 			    MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
6763c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
677460cb568SAndrew Rybchenko 	efx_rc_t rc;
6783c838a9fSAndrew Rybchenko 
6793c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
6803c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
6813c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
6823c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
6833c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
6843c838a9fSAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
6853c838a9fSAndrew Rybchenko 
6863c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
6873c838a9fSAndrew Rybchenko 
6883c838a9fSAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
6893c838a9fSAndrew Rybchenko 
6903c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
6913c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
6923c838a9fSAndrew Rybchenko 		goto fail1;
6933c838a9fSAndrew Rybchenko 	}
6943c838a9fSAndrew Rybchenko 
6953c838a9fSAndrew Rybchenko 	return (0);
6963c838a9fSAndrew Rybchenko 
6973c838a9fSAndrew Rybchenko fail1:
698460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
6993c838a9fSAndrew Rybchenko 
7003c838a9fSAndrew Rybchenko 	return (rc);
7013c838a9fSAndrew Rybchenko }
7023c838a9fSAndrew Rybchenko 
703460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
7043c838a9fSAndrew Rybchenko efx_mcdi_nvram_read(
7053c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
7063c838a9fSAndrew Rybchenko 	__in			uint32_t partn,
7073c838a9fSAndrew Rybchenko 	__in			uint32_t offset,
7083c838a9fSAndrew Rybchenko 	__out_bcount(size)	caddr_t data,
7093c838a9fSAndrew Rybchenko 	__in			size_t size)
7103c838a9fSAndrew Rybchenko {
7113c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
7123c838a9fSAndrew Rybchenko 	uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_LEN,
7133c838a9fSAndrew Rybchenko 			    MC_CMD_NVRAM_READ_OUT_LENMAX)];
714460cb568SAndrew Rybchenko 	efx_rc_t rc;
7153c838a9fSAndrew Rybchenko 
7163c838a9fSAndrew Rybchenko 	if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
7173c838a9fSAndrew Rybchenko 		rc = EINVAL;
7183c838a9fSAndrew Rybchenko 		goto fail1;
7193c838a9fSAndrew Rybchenko 	}
7203c838a9fSAndrew Rybchenko 
7213c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
7223c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_READ;
7233c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
7243c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_READ_IN_LEN;
7253c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
7263c838a9fSAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
7273c838a9fSAndrew Rybchenko 
7283c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_TYPE, partn);
7293c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_OFFSET, offset);
7303c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_LENGTH, size);
7313c838a9fSAndrew Rybchenko 
7323c838a9fSAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
7333c838a9fSAndrew Rybchenko 
7343c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
7353c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
7363c838a9fSAndrew Rybchenko 		goto fail1;
7373c838a9fSAndrew Rybchenko 	}
7383c838a9fSAndrew Rybchenko 
7393c838a9fSAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
7403c838a9fSAndrew Rybchenko 		rc = EMSGSIZE;
7413c838a9fSAndrew Rybchenko 		goto fail2;
7423c838a9fSAndrew Rybchenko 	}
7433c838a9fSAndrew Rybchenko 
7443c838a9fSAndrew Rybchenko 	memcpy(data,
7453c838a9fSAndrew Rybchenko 	    MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
7463c838a9fSAndrew Rybchenko 	    size);
7473c838a9fSAndrew Rybchenko 
7483c838a9fSAndrew Rybchenko 	return (0);
7493c838a9fSAndrew Rybchenko 
7503c838a9fSAndrew Rybchenko fail2:
7513c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail2);
7523c838a9fSAndrew Rybchenko fail1:
753460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
7543c838a9fSAndrew Rybchenko 
7553c838a9fSAndrew Rybchenko 	return (rc);
7563c838a9fSAndrew Rybchenko }
7573c838a9fSAndrew Rybchenko 
758460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
7593c838a9fSAndrew Rybchenko efx_mcdi_nvram_erase(
7603c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
7613c838a9fSAndrew Rybchenko 	__in			uint32_t partn,
7623c838a9fSAndrew Rybchenko 	__in			uint32_t offset,
7633c838a9fSAndrew Rybchenko 	__in			size_t size)
7643c838a9fSAndrew Rybchenko {
7653c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
7663c838a9fSAndrew Rybchenko 	uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
7673c838a9fSAndrew Rybchenko 			    MC_CMD_NVRAM_ERASE_OUT_LEN)];
768460cb568SAndrew Rybchenko 	efx_rc_t rc;
7693c838a9fSAndrew Rybchenko 
7703c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
7713c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_ERASE;
7723c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
7733c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
7743c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
7753c838a9fSAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
7763c838a9fSAndrew Rybchenko 
7773c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
7783c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
7793c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
7803c838a9fSAndrew Rybchenko 
7813c838a9fSAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
7823c838a9fSAndrew Rybchenko 
7833c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
7843c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
7853c838a9fSAndrew Rybchenko 		goto fail1;
7863c838a9fSAndrew Rybchenko 	}
7873c838a9fSAndrew Rybchenko 
7883c838a9fSAndrew Rybchenko 	return (0);
7893c838a9fSAndrew Rybchenko 
7903c838a9fSAndrew Rybchenko fail1:
791460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
7923c838a9fSAndrew Rybchenko 
7933c838a9fSAndrew Rybchenko 	return (rc);
7943c838a9fSAndrew Rybchenko }
7953c838a9fSAndrew Rybchenko 
79657396b7aSAndrew Rybchenko /*
79757396b7aSAndrew Rybchenko  * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
79857396b7aSAndrew Rybchenko  * Sienna and EF10 based boards.  However EF10 based boards support the use
79957396b7aSAndrew Rybchenko  * of this command with payloads up to the maximum MCDI V2 payload length.
80057396b7aSAndrew Rybchenko  */
801460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
8023c838a9fSAndrew Rybchenko efx_mcdi_nvram_write(
8033c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
8043c838a9fSAndrew Rybchenko 	__in			uint32_t partn,
8053c838a9fSAndrew Rybchenko 	__in			uint32_t offset,
8063c838a9fSAndrew Rybchenko 	__out_bcount(size)	caddr_t data,
8073c838a9fSAndrew Rybchenko 	__in			size_t size)
8083c838a9fSAndrew Rybchenko {
8093c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
81057396b7aSAndrew Rybchenko 	uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
81157396b7aSAndrew Rybchenko 			    MCDI_CTL_SDU_LEN_MAX_V2)];
812460cb568SAndrew Rybchenko 	efx_rc_t rc;
81357396b7aSAndrew Rybchenko 	size_t max_data_size;
8143c838a9fSAndrew Rybchenko 
81557396b7aSAndrew Rybchenko 	max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
81657396b7aSAndrew Rybchenko 	    - MC_CMD_NVRAM_WRITE_IN_LEN(0);
81757396b7aSAndrew Rybchenko 	EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
81857396b7aSAndrew Rybchenko 	EFSYS_ASSERT3U(max_data_size, <,
81957396b7aSAndrew Rybchenko 		    enp->en_nic_cfg.enc_mcdi_max_payload_length);
82057396b7aSAndrew Rybchenko 
82157396b7aSAndrew Rybchenko 	if (size > max_data_size) {
8223c838a9fSAndrew Rybchenko 		rc = EINVAL;
8233c838a9fSAndrew Rybchenko 		goto fail1;
8243c838a9fSAndrew Rybchenko 	}
8253c838a9fSAndrew Rybchenko 
8263c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
8273c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_WRITE;
8283c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
8293c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
8303c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
8313c838a9fSAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
8323c838a9fSAndrew Rybchenko 
8333c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
8343c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
8353c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
8363c838a9fSAndrew Rybchenko 
8373c838a9fSAndrew Rybchenko 	memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
8383c838a9fSAndrew Rybchenko 	    data, size);
8393c838a9fSAndrew Rybchenko 
8403c838a9fSAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
8413c838a9fSAndrew Rybchenko 
8423c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
8433c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
8443c838a9fSAndrew Rybchenko 		goto fail2;
8453c838a9fSAndrew Rybchenko 	}
8463c838a9fSAndrew Rybchenko 
8473c838a9fSAndrew Rybchenko 	return (0);
8483c838a9fSAndrew Rybchenko 
8493c838a9fSAndrew Rybchenko fail2:
8503c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail2);
8513c838a9fSAndrew Rybchenko fail1:
852460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
8533c838a9fSAndrew Rybchenko 
8543c838a9fSAndrew Rybchenko 	return (rc);
8553c838a9fSAndrew Rybchenko }
8563c838a9fSAndrew Rybchenko 
857460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
8583c838a9fSAndrew Rybchenko efx_mcdi_nvram_update_finish(
8593c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
8603c838a9fSAndrew Rybchenko 	__in			uint32_t partn,
8613c838a9fSAndrew Rybchenko 	__in			boolean_t reboot)
8623c838a9fSAndrew Rybchenko {
8633c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
8643c838a9fSAndrew Rybchenko 	uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN,
8653c838a9fSAndrew Rybchenko 			    MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN)];
866460cb568SAndrew Rybchenko 	efx_rc_t rc;
8673c838a9fSAndrew Rybchenko 
8683c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
8693c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
8703c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
8713c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
8723c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
8733c838a9fSAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN;
8743c838a9fSAndrew Rybchenko 
8753c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
8763c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
8773c838a9fSAndrew Rybchenko 
8783c838a9fSAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
8793c838a9fSAndrew Rybchenko 
8803c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
8813c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
8823c838a9fSAndrew Rybchenko 		goto fail1;
8833c838a9fSAndrew Rybchenko 	}
8843c838a9fSAndrew Rybchenko 
8853c838a9fSAndrew Rybchenko 	return (0);
8863c838a9fSAndrew Rybchenko 
8873c838a9fSAndrew Rybchenko fail1:
888460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
8893c838a9fSAndrew Rybchenko 
8903c838a9fSAndrew Rybchenko 	return (rc);
8913c838a9fSAndrew Rybchenko }
8923c838a9fSAndrew Rybchenko 
8933c838a9fSAndrew Rybchenko #if EFSYS_OPT_DIAG
8943c838a9fSAndrew Rybchenko 
895460cb568SAndrew Rybchenko 	__checkReturn		efx_rc_t
8963c838a9fSAndrew Rybchenko efx_mcdi_nvram_test(
8973c838a9fSAndrew Rybchenko 	__in			efx_nic_t *enp,
8983c838a9fSAndrew Rybchenko 	__in			uint32_t partn)
8993c838a9fSAndrew Rybchenko {
9003c838a9fSAndrew Rybchenko 	efx_mcdi_req_t req;
9013c838a9fSAndrew Rybchenko 	uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
9023c838a9fSAndrew Rybchenko 			    MC_CMD_NVRAM_TEST_OUT_LEN)];
9033c838a9fSAndrew Rybchenko 	int result;
904460cb568SAndrew Rybchenko 	efx_rc_t rc;
9053c838a9fSAndrew Rybchenko 
9063c838a9fSAndrew Rybchenko 	(void) memset(payload, 0, sizeof (payload));
9073c838a9fSAndrew Rybchenko 	req.emr_cmd = MC_CMD_NVRAM_TEST;
9083c838a9fSAndrew Rybchenko 	req.emr_in_buf = payload;
9093c838a9fSAndrew Rybchenko 	req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
9103c838a9fSAndrew Rybchenko 	req.emr_out_buf = payload;
9113c838a9fSAndrew Rybchenko 	req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
9123c838a9fSAndrew Rybchenko 
9133c838a9fSAndrew Rybchenko 	MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
9143c838a9fSAndrew Rybchenko 
9153c838a9fSAndrew Rybchenko 	efx_mcdi_execute(enp, &req);
9163c838a9fSAndrew Rybchenko 
9173c838a9fSAndrew Rybchenko 	if (req.emr_rc != 0) {
9183c838a9fSAndrew Rybchenko 		rc = req.emr_rc;
9193c838a9fSAndrew Rybchenko 		goto fail1;
9203c838a9fSAndrew Rybchenko 	}
9213c838a9fSAndrew Rybchenko 
9223c838a9fSAndrew Rybchenko 	if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
9233c838a9fSAndrew Rybchenko 		rc = EMSGSIZE;
9243c838a9fSAndrew Rybchenko 		goto fail2;
9253c838a9fSAndrew Rybchenko 	}
9263c838a9fSAndrew Rybchenko 
9273c838a9fSAndrew Rybchenko 	result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
9283c838a9fSAndrew Rybchenko 	if (result == MC_CMD_NVRAM_TEST_FAIL) {
9293c838a9fSAndrew Rybchenko 
9303c838a9fSAndrew Rybchenko 		EFSYS_PROBE1(nvram_test_failure, int, partn);
9313c838a9fSAndrew Rybchenko 
9323c838a9fSAndrew Rybchenko 		rc = (EINVAL);
9333c838a9fSAndrew Rybchenko 		goto fail3;
9343c838a9fSAndrew Rybchenko 	}
9353c838a9fSAndrew Rybchenko 
9363c838a9fSAndrew Rybchenko 	return (0);
9373c838a9fSAndrew Rybchenko 
9383c838a9fSAndrew Rybchenko fail3:
9393c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail3);
9403c838a9fSAndrew Rybchenko fail2:
9413c838a9fSAndrew Rybchenko 	EFSYS_PROBE(fail2);
9423c838a9fSAndrew Rybchenko fail1:
943460cb568SAndrew Rybchenko 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
9443c838a9fSAndrew Rybchenko 
9453c838a9fSAndrew Rybchenko 	return (rc);
9463c838a9fSAndrew Rybchenko }
9473c838a9fSAndrew Rybchenko 
9483c838a9fSAndrew Rybchenko #endif	/* EFSYS_OPT_DIAG */
9493c838a9fSAndrew Rybchenko 
9503c838a9fSAndrew Rybchenko 
9513c838a9fSAndrew Rybchenko #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */
952