1*49ef7e06SGarrett D'Amore /*
2*49ef7e06SGarrett D'Amore * Copyright (c) 2009-2015 Solarflare Communications Inc.
3*49ef7e06SGarrett D'Amore * All rights reserved.
4*49ef7e06SGarrett D'Amore *
5*49ef7e06SGarrett D'Amore * Redistribution and use in source and binary forms, with or without
6*49ef7e06SGarrett D'Amore * modification, are permitted provided that the following conditions are met:
7*49ef7e06SGarrett D'Amore *
8*49ef7e06SGarrett D'Amore * 1. Redistributions of source code must retain the above copyright notice,
9*49ef7e06SGarrett D'Amore * this list of conditions and the following disclaimer.
10*49ef7e06SGarrett D'Amore * 2. Redistributions in binary form must reproduce the above copyright notice,
11*49ef7e06SGarrett D'Amore * this list of conditions and the following disclaimer in the documentation
12*49ef7e06SGarrett D'Amore * and/or other materials provided with the distribution.
13*49ef7e06SGarrett D'Amore *
14*49ef7e06SGarrett D'Amore * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15*49ef7e06SGarrett D'Amore * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16*49ef7e06SGarrett D'Amore * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17*49ef7e06SGarrett D'Amore * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18*49ef7e06SGarrett D'Amore * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19*49ef7e06SGarrett D'Amore * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20*49ef7e06SGarrett D'Amore * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21*49ef7e06SGarrett D'Amore * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22*49ef7e06SGarrett D'Amore * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23*49ef7e06SGarrett D'Amore * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24*49ef7e06SGarrett D'Amore * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*49ef7e06SGarrett D'Amore *
26*49ef7e06SGarrett D'Amore * The views and conclusions contained in the software and documentation are
27*49ef7e06SGarrett D'Amore * those of the authors and should not be interpreted as representing official
28*49ef7e06SGarrett D'Amore * policies, either expressed or implied, of the FreeBSD Project.
29*49ef7e06SGarrett D'Amore */
30*49ef7e06SGarrett D'Amore
31*49ef7e06SGarrett D'Amore #include "efx.h"
32*49ef7e06SGarrett D'Amore #include "efx_impl.h"
33*49ef7e06SGarrett D'Amore
34*49ef7e06SGarrett D'Amore #if EFSYS_OPT_NVRAM
35*49ef7e06SGarrett D'Amore
36*49ef7e06SGarrett D'Amore #if EFSYS_OPT_SIENA
37*49ef7e06SGarrett D'Amore
38*49ef7e06SGarrett D'Amore static const efx_nvram_ops_t __efx_nvram_siena_ops = {
39*49ef7e06SGarrett D'Amore #if EFSYS_OPT_DIAG
40*49ef7e06SGarrett D'Amore siena_nvram_test, /* envo_test */
41*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_DIAG */
42*49ef7e06SGarrett D'Amore siena_nvram_type_to_partn, /* envo_type_to_partn */
43*49ef7e06SGarrett D'Amore siena_nvram_partn_size, /* envo_partn_size */
44*49ef7e06SGarrett D'Amore siena_nvram_partn_rw_start, /* envo_partn_rw_start */
45*49ef7e06SGarrett D'Amore siena_nvram_partn_read, /* envo_partn_read */
46*49ef7e06SGarrett D'Amore siena_nvram_partn_erase, /* envo_partn_erase */
47*49ef7e06SGarrett D'Amore siena_nvram_partn_write, /* envo_partn_write */
48*49ef7e06SGarrett D'Amore siena_nvram_partn_rw_finish, /* envo_partn_rw_finish */
49*49ef7e06SGarrett D'Amore siena_nvram_partn_get_version, /* envo_partn_get_version */
50*49ef7e06SGarrett D'Amore siena_nvram_partn_set_version, /* envo_partn_set_version */
51*49ef7e06SGarrett D'Amore NULL, /* envo_partn_validate */
52*49ef7e06SGarrett D'Amore };
53*49ef7e06SGarrett D'Amore
54*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_SIENA */
55*49ef7e06SGarrett D'Amore
56*49ef7e06SGarrett D'Amore #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
57*49ef7e06SGarrett D'Amore
58*49ef7e06SGarrett D'Amore static const efx_nvram_ops_t __efx_nvram_ef10_ops = {
59*49ef7e06SGarrett D'Amore #if EFSYS_OPT_DIAG
60*49ef7e06SGarrett D'Amore ef10_nvram_test, /* envo_test */
61*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_DIAG */
62*49ef7e06SGarrett D'Amore ef10_nvram_type_to_partn, /* envo_type_to_partn */
63*49ef7e06SGarrett D'Amore ef10_nvram_partn_size, /* envo_partn_size */
64*49ef7e06SGarrett D'Amore ef10_nvram_partn_rw_start, /* envo_partn_rw_start */
65*49ef7e06SGarrett D'Amore ef10_nvram_partn_read, /* envo_partn_read */
66*49ef7e06SGarrett D'Amore ef10_nvram_partn_erase, /* envo_partn_erase */
67*49ef7e06SGarrett D'Amore ef10_nvram_partn_write, /* envo_partn_write */
68*49ef7e06SGarrett D'Amore ef10_nvram_partn_rw_finish, /* envo_partn_rw_finish */
69*49ef7e06SGarrett D'Amore ef10_nvram_partn_get_version, /* envo_partn_get_version */
70*49ef7e06SGarrett D'Amore ef10_nvram_partn_set_version, /* envo_partn_set_version */
71*49ef7e06SGarrett D'Amore ef10_nvram_buffer_validate, /* envo_buffer_validate */
72*49ef7e06SGarrett D'Amore };
73*49ef7e06SGarrett D'Amore
74*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
75*49ef7e06SGarrett D'Amore
76*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_nvram_init(__in efx_nic_t * enp)77*49ef7e06SGarrett D'Amore efx_nvram_init(
78*49ef7e06SGarrett D'Amore __in efx_nic_t *enp)
79*49ef7e06SGarrett D'Amore {
80*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop;
81*49ef7e06SGarrett D'Amore efx_rc_t rc;
82*49ef7e06SGarrett D'Amore
83*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
84*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
85*49ef7e06SGarrett D'Amore EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NVRAM));
86*49ef7e06SGarrett D'Amore
87*49ef7e06SGarrett D'Amore switch (enp->en_family) {
88*49ef7e06SGarrett D'Amore #if EFSYS_OPT_SIENA
89*49ef7e06SGarrett D'Amore case EFX_FAMILY_SIENA:
90*49ef7e06SGarrett D'Amore envop = &__efx_nvram_siena_ops;
91*49ef7e06SGarrett D'Amore break;
92*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_SIENA */
93*49ef7e06SGarrett D'Amore
94*49ef7e06SGarrett D'Amore #if EFSYS_OPT_HUNTINGTON
95*49ef7e06SGarrett D'Amore case EFX_FAMILY_HUNTINGTON:
96*49ef7e06SGarrett D'Amore envop = &__efx_nvram_ef10_ops;
97*49ef7e06SGarrett D'Amore break;
98*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_HUNTINGTON */
99*49ef7e06SGarrett D'Amore
100*49ef7e06SGarrett D'Amore #if EFSYS_OPT_MEDFORD
101*49ef7e06SGarrett D'Amore case EFX_FAMILY_MEDFORD:
102*49ef7e06SGarrett D'Amore envop = &__efx_nvram_ef10_ops;
103*49ef7e06SGarrett D'Amore break;
104*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_MEDFORD */
105*49ef7e06SGarrett D'Amore
106*49ef7e06SGarrett D'Amore default:
107*49ef7e06SGarrett D'Amore EFSYS_ASSERT(0);
108*49ef7e06SGarrett D'Amore rc = ENOTSUP;
109*49ef7e06SGarrett D'Amore goto fail1;
110*49ef7e06SGarrett D'Amore }
111*49ef7e06SGarrett D'Amore
112*49ef7e06SGarrett D'Amore enp->en_envop = envop;
113*49ef7e06SGarrett D'Amore enp->en_mod_flags |= EFX_MOD_NVRAM;
114*49ef7e06SGarrett D'Amore
115*49ef7e06SGarrett D'Amore return (0);
116*49ef7e06SGarrett D'Amore
117*49ef7e06SGarrett D'Amore fail1:
118*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
119*49ef7e06SGarrett D'Amore
120*49ef7e06SGarrett D'Amore return (rc);
121*49ef7e06SGarrett D'Amore }
122*49ef7e06SGarrett D'Amore
123*49ef7e06SGarrett D'Amore #if EFSYS_OPT_DIAG
124*49ef7e06SGarrett D'Amore
125*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_nvram_test(__in efx_nic_t * enp)126*49ef7e06SGarrett D'Amore efx_nvram_test(
127*49ef7e06SGarrett D'Amore __in efx_nic_t *enp)
128*49ef7e06SGarrett D'Amore {
129*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
130*49ef7e06SGarrett D'Amore efx_rc_t rc;
131*49ef7e06SGarrett D'Amore
132*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
133*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
134*49ef7e06SGarrett D'Amore
135*49ef7e06SGarrett D'Amore if ((rc = envop->envo_test(enp)) != 0)
136*49ef7e06SGarrett D'Amore goto fail1;
137*49ef7e06SGarrett D'Amore
138*49ef7e06SGarrett D'Amore return (0);
139*49ef7e06SGarrett D'Amore
140*49ef7e06SGarrett D'Amore fail1:
141*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
142*49ef7e06SGarrett D'Amore
143*49ef7e06SGarrett D'Amore return (rc);
144*49ef7e06SGarrett D'Amore }
145*49ef7e06SGarrett D'Amore
146*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_DIAG */
147*49ef7e06SGarrett D'Amore
148*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_nvram_size(__in efx_nic_t * enp,__in efx_nvram_type_t type,__out size_t * sizep)149*49ef7e06SGarrett D'Amore efx_nvram_size(
150*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
151*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type,
152*49ef7e06SGarrett D'Amore __out size_t *sizep)
153*49ef7e06SGarrett D'Amore {
154*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
155*49ef7e06SGarrett D'Amore uint32_t partn;
156*49ef7e06SGarrett D'Amore efx_rc_t rc;
157*49ef7e06SGarrett D'Amore
158*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
159*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
160*49ef7e06SGarrett D'Amore
161*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
162*49ef7e06SGarrett D'Amore
163*49ef7e06SGarrett D'Amore if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
164*49ef7e06SGarrett D'Amore goto fail1;
165*49ef7e06SGarrett D'Amore
166*49ef7e06SGarrett D'Amore if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0)
167*49ef7e06SGarrett D'Amore goto fail2;
168*49ef7e06SGarrett D'Amore
169*49ef7e06SGarrett D'Amore return (0);
170*49ef7e06SGarrett D'Amore
171*49ef7e06SGarrett D'Amore fail2:
172*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
173*49ef7e06SGarrett D'Amore fail1:
174*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
175*49ef7e06SGarrett D'Amore *sizep = 0;
176*49ef7e06SGarrett D'Amore
177*49ef7e06SGarrett D'Amore return (rc);
178*49ef7e06SGarrett D'Amore }
179*49ef7e06SGarrett D'Amore
180*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
181*49ef7e06SGarrett D'Amore efx_nvram_get_version(
182*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
183*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type,
184*49ef7e06SGarrett D'Amore __out uint32_t *subtypep,
185*49ef7e06SGarrett D'Amore __out_ecount(4) uint16_t version[4])
186*49ef7e06SGarrett D'Amore {
187*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
188*49ef7e06SGarrett D'Amore uint32_t partn;
189*49ef7e06SGarrett D'Amore efx_rc_t rc;
190*49ef7e06SGarrett D'Amore
191*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
192*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
193*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
194*49ef7e06SGarrett D'Amore
195*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
196*49ef7e06SGarrett D'Amore
197*49ef7e06SGarrett D'Amore if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
198*49ef7e06SGarrett D'Amore goto fail1;
199*49ef7e06SGarrett D'Amore
200*49ef7e06SGarrett D'Amore if ((rc = envop->envo_partn_get_version(enp, partn,
201*49ef7e06SGarrett D'Amore subtypep, version)) != 0)
202*49ef7e06SGarrett D'Amore goto fail2;
203*49ef7e06SGarrett D'Amore
204*49ef7e06SGarrett D'Amore return (0);
205*49ef7e06SGarrett D'Amore
206*49ef7e06SGarrett D'Amore fail2:
207*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
208*49ef7e06SGarrett D'Amore fail1:
209*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
210*49ef7e06SGarrett D'Amore
211*49ef7e06SGarrett D'Amore return (rc);
212*49ef7e06SGarrett D'Amore }
213*49ef7e06SGarrett D'Amore
214*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_nvram_rw_start(__in efx_nic_t * enp,__in efx_nvram_type_t type,__out_opt size_t * chunk_sizep)215*49ef7e06SGarrett D'Amore efx_nvram_rw_start(
216*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
217*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type,
218*49ef7e06SGarrett D'Amore __out_opt size_t *chunk_sizep)
219*49ef7e06SGarrett D'Amore {
220*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
221*49ef7e06SGarrett D'Amore uint32_t partn;
222*49ef7e06SGarrett D'Amore efx_rc_t rc;
223*49ef7e06SGarrett D'Amore
224*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
225*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
226*49ef7e06SGarrett D'Amore
227*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
228*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
229*49ef7e06SGarrett D'Amore
230*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
231*49ef7e06SGarrett D'Amore
232*49ef7e06SGarrett D'Amore if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
233*49ef7e06SGarrett D'Amore goto fail1;
234*49ef7e06SGarrett D'Amore
235*49ef7e06SGarrett D'Amore if ((rc = envop->envo_partn_rw_start(enp, partn, chunk_sizep)) != 0)
236*49ef7e06SGarrett D'Amore goto fail2;
237*49ef7e06SGarrett D'Amore
238*49ef7e06SGarrett D'Amore enp->en_nvram_locked = type;
239*49ef7e06SGarrett D'Amore
240*49ef7e06SGarrett D'Amore return (0);
241*49ef7e06SGarrett D'Amore
242*49ef7e06SGarrett D'Amore fail2:
243*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
244*49ef7e06SGarrett D'Amore fail1:
245*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
246*49ef7e06SGarrett D'Amore
247*49ef7e06SGarrett D'Amore return (rc);
248*49ef7e06SGarrett D'Amore }
249*49ef7e06SGarrett D'Amore
250*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_nvram_read_chunk(__in efx_nic_t * enp,__in efx_nvram_type_t type,__in unsigned int offset,__out_bcount (size)caddr_t data,__in size_t size)251*49ef7e06SGarrett D'Amore efx_nvram_read_chunk(
252*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
253*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type,
254*49ef7e06SGarrett D'Amore __in unsigned int offset,
255*49ef7e06SGarrett D'Amore __out_bcount(size) caddr_t data,
256*49ef7e06SGarrett D'Amore __in size_t size)
257*49ef7e06SGarrett D'Amore {
258*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
259*49ef7e06SGarrett D'Amore uint32_t partn;
260*49ef7e06SGarrett D'Amore efx_rc_t rc;
261*49ef7e06SGarrett D'Amore
262*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
263*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
264*49ef7e06SGarrett D'Amore
265*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
266*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
267*49ef7e06SGarrett D'Amore
268*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
269*49ef7e06SGarrett D'Amore
270*49ef7e06SGarrett D'Amore if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
271*49ef7e06SGarrett D'Amore goto fail1;
272*49ef7e06SGarrett D'Amore
273*49ef7e06SGarrett D'Amore if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
274*49ef7e06SGarrett D'Amore goto fail2;
275*49ef7e06SGarrett D'Amore
276*49ef7e06SGarrett D'Amore return (0);
277*49ef7e06SGarrett D'Amore
278*49ef7e06SGarrett D'Amore fail2:
279*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
280*49ef7e06SGarrett D'Amore fail1:
281*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
282*49ef7e06SGarrett D'Amore
283*49ef7e06SGarrett D'Amore return (rc);
284*49ef7e06SGarrett D'Amore }
285*49ef7e06SGarrett D'Amore
286*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_nvram_erase(__in efx_nic_t * enp,__in efx_nvram_type_t type)287*49ef7e06SGarrett D'Amore efx_nvram_erase(
288*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
289*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type)
290*49ef7e06SGarrett D'Amore {
291*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
292*49ef7e06SGarrett D'Amore unsigned int offset = 0;
293*49ef7e06SGarrett D'Amore size_t size = 0;
294*49ef7e06SGarrett D'Amore uint32_t partn;
295*49ef7e06SGarrett D'Amore efx_rc_t rc;
296*49ef7e06SGarrett D'Amore
297*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
298*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
299*49ef7e06SGarrett D'Amore
300*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
301*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
302*49ef7e06SGarrett D'Amore
303*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
304*49ef7e06SGarrett D'Amore
305*49ef7e06SGarrett D'Amore if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
306*49ef7e06SGarrett D'Amore goto fail1;
307*49ef7e06SGarrett D'Amore
308*49ef7e06SGarrett D'Amore if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0)
309*49ef7e06SGarrett D'Amore goto fail2;
310*49ef7e06SGarrett D'Amore
311*49ef7e06SGarrett D'Amore if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0)
312*49ef7e06SGarrett D'Amore goto fail3;
313*49ef7e06SGarrett D'Amore
314*49ef7e06SGarrett D'Amore return (0);
315*49ef7e06SGarrett D'Amore
316*49ef7e06SGarrett D'Amore fail3:
317*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail3);
318*49ef7e06SGarrett D'Amore fail2:
319*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
320*49ef7e06SGarrett D'Amore fail1:
321*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
322*49ef7e06SGarrett D'Amore
323*49ef7e06SGarrett D'Amore return (rc);
324*49ef7e06SGarrett D'Amore }
325*49ef7e06SGarrett D'Amore
326*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_nvram_write_chunk(__in efx_nic_t * enp,__in efx_nvram_type_t type,__in unsigned int offset,__in_bcount (size)caddr_t data,__in size_t size)327*49ef7e06SGarrett D'Amore efx_nvram_write_chunk(
328*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
329*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type,
330*49ef7e06SGarrett D'Amore __in unsigned int offset,
331*49ef7e06SGarrett D'Amore __in_bcount(size) caddr_t data,
332*49ef7e06SGarrett D'Amore __in size_t size)
333*49ef7e06SGarrett D'Amore {
334*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
335*49ef7e06SGarrett D'Amore uint32_t partn;
336*49ef7e06SGarrett D'Amore efx_rc_t rc;
337*49ef7e06SGarrett D'Amore
338*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
339*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
340*49ef7e06SGarrett D'Amore
341*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
342*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
343*49ef7e06SGarrett D'Amore
344*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
345*49ef7e06SGarrett D'Amore
346*49ef7e06SGarrett D'Amore if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
347*49ef7e06SGarrett D'Amore goto fail1;
348*49ef7e06SGarrett D'Amore
349*49ef7e06SGarrett D'Amore if ((rc = envop->envo_partn_write(enp, partn, offset, data, size)) != 0)
350*49ef7e06SGarrett D'Amore goto fail2;
351*49ef7e06SGarrett D'Amore
352*49ef7e06SGarrett D'Amore return (0);
353*49ef7e06SGarrett D'Amore
354*49ef7e06SGarrett D'Amore fail2:
355*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
356*49ef7e06SGarrett D'Amore fail1:
357*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
358*49ef7e06SGarrett D'Amore
359*49ef7e06SGarrett D'Amore return (rc);
360*49ef7e06SGarrett D'Amore }
361*49ef7e06SGarrett D'Amore
362*49ef7e06SGarrett D'Amore void
efx_nvram_rw_finish(__in efx_nic_t * enp,__in efx_nvram_type_t type)363*49ef7e06SGarrett D'Amore efx_nvram_rw_finish(
364*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
365*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type)
366*49ef7e06SGarrett D'Amore {
367*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
368*49ef7e06SGarrett D'Amore uint32_t partn;
369*49ef7e06SGarrett D'Amore
370*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
371*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
372*49ef7e06SGarrett D'Amore
373*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
374*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
375*49ef7e06SGarrett D'Amore
376*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
377*49ef7e06SGarrett D'Amore
378*49ef7e06SGarrett D'Amore if (envop->envo_type_to_partn(enp, type, &partn) == 0)
379*49ef7e06SGarrett D'Amore envop->envo_partn_rw_finish(enp, partn);
380*49ef7e06SGarrett D'Amore
381*49ef7e06SGarrett D'Amore enp->en_nvram_locked = EFX_NVRAM_INVALID;
382*49ef7e06SGarrett D'Amore }
383*49ef7e06SGarrett D'Amore
384*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
385*49ef7e06SGarrett D'Amore efx_nvram_set_version(
386*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
387*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type,
388*49ef7e06SGarrett D'Amore __in_ecount(4) uint16_t version[4])
389*49ef7e06SGarrett D'Amore {
390*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
391*49ef7e06SGarrett D'Amore uint32_t partn;
392*49ef7e06SGarrett D'Amore efx_rc_t rc;
393*49ef7e06SGarrett D'Amore
394*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
395*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
396*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
397*49ef7e06SGarrett D'Amore
398*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
399*49ef7e06SGarrett D'Amore
400*49ef7e06SGarrett D'Amore /*
401*49ef7e06SGarrett D'Amore * The Siena implementation of envo_set_version() will attempt to
402*49ef7e06SGarrett D'Amore * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector.
403*49ef7e06SGarrett D'Amore * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
404*49ef7e06SGarrett D'Amore */
405*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
406*49ef7e06SGarrett D'Amore
407*49ef7e06SGarrett D'Amore if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
408*49ef7e06SGarrett D'Amore goto fail1;
409*49ef7e06SGarrett D'Amore
410*49ef7e06SGarrett D'Amore if ((rc = envop->envo_partn_set_version(enp, partn, version)) != 0)
411*49ef7e06SGarrett D'Amore goto fail2;
412*49ef7e06SGarrett D'Amore
413*49ef7e06SGarrett D'Amore return (0);
414*49ef7e06SGarrett D'Amore
415*49ef7e06SGarrett D'Amore fail2:
416*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
417*49ef7e06SGarrett D'Amore fail1:
418*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
419*49ef7e06SGarrett D'Amore
420*49ef7e06SGarrett D'Amore return (rc);
421*49ef7e06SGarrett D'Amore }
422*49ef7e06SGarrett D'Amore
423*49ef7e06SGarrett D'Amore /* Validate buffer contents (before writing to flash) */
424*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_nvram_validate(__in efx_nic_t * enp,__in efx_nvram_type_t type,__in_bcount (partn_size)caddr_t partn_data,__in size_t partn_size)425*49ef7e06SGarrett D'Amore efx_nvram_validate(
426*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
427*49ef7e06SGarrett D'Amore __in efx_nvram_type_t type,
428*49ef7e06SGarrett D'Amore __in_bcount(partn_size) caddr_t partn_data,
429*49ef7e06SGarrett D'Amore __in size_t partn_size)
430*49ef7e06SGarrett D'Amore {
431*49ef7e06SGarrett D'Amore const efx_nvram_ops_t *envop = enp->en_envop;
432*49ef7e06SGarrett D'Amore uint32_t partn;
433*49ef7e06SGarrett D'Amore efx_rc_t rc;
434*49ef7e06SGarrett D'Amore
435*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
436*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
437*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
438*49ef7e06SGarrett D'Amore
439*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
440*49ef7e06SGarrett D'Amore
441*49ef7e06SGarrett D'Amore
442*49ef7e06SGarrett D'Amore if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
443*49ef7e06SGarrett D'Amore goto fail1;
444*49ef7e06SGarrett D'Amore
445*49ef7e06SGarrett D'Amore if (envop->envo_type_to_partn != NULL &&
446*49ef7e06SGarrett D'Amore ((rc = envop->envo_buffer_validate(enp, partn,
447*49ef7e06SGarrett D'Amore partn_data, partn_size)) != 0))
448*49ef7e06SGarrett D'Amore goto fail2;
449*49ef7e06SGarrett D'Amore
450*49ef7e06SGarrett D'Amore return (0);
451*49ef7e06SGarrett D'Amore
452*49ef7e06SGarrett D'Amore fail2:
453*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
454*49ef7e06SGarrett D'Amore fail1:
455*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
456*49ef7e06SGarrett D'Amore
457*49ef7e06SGarrett D'Amore return (rc);
458*49ef7e06SGarrett D'Amore }
459*49ef7e06SGarrett D'Amore
460*49ef7e06SGarrett D'Amore
461*49ef7e06SGarrett D'Amore void
efx_nvram_fini(__in efx_nic_t * enp)462*49ef7e06SGarrett D'Amore efx_nvram_fini(
463*49ef7e06SGarrett D'Amore __in efx_nic_t *enp)
464*49ef7e06SGarrett D'Amore {
465*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
466*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
467*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
468*49ef7e06SGarrett D'Amore
469*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
470*49ef7e06SGarrett D'Amore
471*49ef7e06SGarrett D'Amore enp->en_envop = NULL;
472*49ef7e06SGarrett D'Amore enp->en_mod_flags &= ~EFX_MOD_NVRAM;
473*49ef7e06SGarrett D'Amore }
474*49ef7e06SGarrett D'Amore
475*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_NVRAM */
476*49ef7e06SGarrett D'Amore
477*49ef7e06SGarrett D'Amore #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
478*49ef7e06SGarrett D'Amore
479*49ef7e06SGarrett D'Amore /*
480*49ef7e06SGarrett D'Amore * Internal MCDI request handling
481*49ef7e06SGarrett D'Amore */
482*49ef7e06SGarrett D'Amore
483*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_mcdi_nvram_partitions(__in efx_nic_t * enp,__out_bcount (size)caddr_t data,__in size_t size,__out unsigned int * npartnp)484*49ef7e06SGarrett D'Amore efx_mcdi_nvram_partitions(
485*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
486*49ef7e06SGarrett D'Amore __out_bcount(size) caddr_t data,
487*49ef7e06SGarrett D'Amore __in size_t size,
488*49ef7e06SGarrett D'Amore __out unsigned int *npartnp)
489*49ef7e06SGarrett D'Amore {
490*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
491*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
492*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
493*49ef7e06SGarrett D'Amore unsigned int npartn;
494*49ef7e06SGarrett D'Amore efx_rc_t rc;
495*49ef7e06SGarrett D'Amore
496*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
497*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
498*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
499*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
500*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
501*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
502*49ef7e06SGarrett D'Amore
503*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
504*49ef7e06SGarrett D'Amore
505*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
506*49ef7e06SGarrett D'Amore rc = req.emr_rc;
507*49ef7e06SGarrett D'Amore goto fail1;
508*49ef7e06SGarrett D'Amore }
509*49ef7e06SGarrett D'Amore
510*49ef7e06SGarrett D'Amore if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
511*49ef7e06SGarrett D'Amore rc = EMSGSIZE;
512*49ef7e06SGarrett D'Amore goto fail2;
513*49ef7e06SGarrett D'Amore }
514*49ef7e06SGarrett D'Amore npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
515*49ef7e06SGarrett D'Amore
516*49ef7e06SGarrett D'Amore if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
517*49ef7e06SGarrett D'Amore rc = ENOENT;
518*49ef7e06SGarrett D'Amore goto fail3;
519*49ef7e06SGarrett D'Amore }
520*49ef7e06SGarrett D'Amore
521*49ef7e06SGarrett D'Amore if (size < npartn * sizeof (uint32_t)) {
522*49ef7e06SGarrett D'Amore rc = ENOSPC;
523*49ef7e06SGarrett D'Amore goto fail3;
524*49ef7e06SGarrett D'Amore }
525*49ef7e06SGarrett D'Amore
526*49ef7e06SGarrett D'Amore *npartnp = npartn;
527*49ef7e06SGarrett D'Amore
528*49ef7e06SGarrett D'Amore (void) memcpy(data,
529*49ef7e06SGarrett D'Amore MCDI_OUT2(req, void, NVRAM_PARTITIONS_OUT_TYPE_ID),
530*49ef7e06SGarrett D'Amore (npartn * sizeof (uint32_t)));
531*49ef7e06SGarrett D'Amore
532*49ef7e06SGarrett D'Amore return (0);
533*49ef7e06SGarrett D'Amore
534*49ef7e06SGarrett D'Amore fail3:
535*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail3);
536*49ef7e06SGarrett D'Amore fail2:
537*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
538*49ef7e06SGarrett D'Amore fail1:
539*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
540*49ef7e06SGarrett D'Amore
541*49ef7e06SGarrett D'Amore return (rc);
542*49ef7e06SGarrett D'Amore }
543*49ef7e06SGarrett D'Amore
544*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
545*49ef7e06SGarrett D'Amore efx_mcdi_nvram_metadata(
546*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
547*49ef7e06SGarrett D'Amore __in uint32_t partn,
548*49ef7e06SGarrett D'Amore __out uint32_t *subtypep,
549*49ef7e06SGarrett D'Amore __out_ecount(4) uint16_t version[4],
550*49ef7e06SGarrett D'Amore __out_bcount_opt(size) char *descp,
551*49ef7e06SGarrett D'Amore __in size_t size)
552*49ef7e06SGarrett D'Amore {
553*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
554*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
555*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
556*49ef7e06SGarrett D'Amore efx_rc_t rc;
557*49ef7e06SGarrett D'Amore
558*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
559*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_METADATA;
560*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
561*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
562*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
563*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
564*49ef7e06SGarrett D'Amore
565*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
566*49ef7e06SGarrett D'Amore
567*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
568*49ef7e06SGarrett D'Amore
569*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
570*49ef7e06SGarrett D'Amore rc = req.emr_rc;
571*49ef7e06SGarrett D'Amore goto fail1;
572*49ef7e06SGarrett D'Amore }
573*49ef7e06SGarrett D'Amore
574*49ef7e06SGarrett D'Amore if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
575*49ef7e06SGarrett D'Amore rc = EMSGSIZE;
576*49ef7e06SGarrett D'Amore goto fail2;
577*49ef7e06SGarrett D'Amore }
578*49ef7e06SGarrett D'Amore
579*49ef7e06SGarrett D'Amore if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
580*49ef7e06SGarrett D'Amore NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
581*49ef7e06SGarrett D'Amore *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
582*49ef7e06SGarrett D'Amore } else {
583*49ef7e06SGarrett D'Amore *subtypep = 0;
584*49ef7e06SGarrett D'Amore }
585*49ef7e06SGarrett D'Amore
586*49ef7e06SGarrett D'Amore if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
587*49ef7e06SGarrett D'Amore NVRAM_METADATA_OUT_VERSION_VALID)) {
588*49ef7e06SGarrett D'Amore version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
589*49ef7e06SGarrett D'Amore version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
590*49ef7e06SGarrett D'Amore version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
591*49ef7e06SGarrett D'Amore version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
592*49ef7e06SGarrett D'Amore } else {
593*49ef7e06SGarrett D'Amore version[0] = version[1] = version[2] = version[3] = 0;
594*49ef7e06SGarrett D'Amore }
595*49ef7e06SGarrett D'Amore
596*49ef7e06SGarrett D'Amore if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
597*49ef7e06SGarrett D'Amore NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
598*49ef7e06SGarrett D'Amore /* Return optional descrition string */
599*49ef7e06SGarrett D'Amore if ((descp != NULL) && (size > 0)) {
600*49ef7e06SGarrett D'Amore size_t desclen;
601*49ef7e06SGarrett D'Amore
602*49ef7e06SGarrett D'Amore descp[0] = '\0';
603*49ef7e06SGarrett D'Amore desclen = (req.emr_out_length_used
604*49ef7e06SGarrett D'Amore - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
605*49ef7e06SGarrett D'Amore
606*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(desclen, <=,
607*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
608*49ef7e06SGarrett D'Amore
609*49ef7e06SGarrett D'Amore if (size < desclen) {
610*49ef7e06SGarrett D'Amore rc = ENOSPC;
611*49ef7e06SGarrett D'Amore goto fail3;
612*49ef7e06SGarrett D'Amore }
613*49ef7e06SGarrett D'Amore
614*49ef7e06SGarrett D'Amore (void) memcpy(descp, MCDI_OUT2(req, char,
615*49ef7e06SGarrett D'Amore NVRAM_METADATA_OUT_DESCRIPTION),
616*49ef7e06SGarrett D'Amore desclen);
617*49ef7e06SGarrett D'Amore
618*49ef7e06SGarrett D'Amore /* Ensure string is NUL terminated */
619*49ef7e06SGarrett D'Amore descp[desclen] = '\0';
620*49ef7e06SGarrett D'Amore }
621*49ef7e06SGarrett D'Amore }
622*49ef7e06SGarrett D'Amore
623*49ef7e06SGarrett D'Amore return (0);
624*49ef7e06SGarrett D'Amore
625*49ef7e06SGarrett D'Amore fail3:
626*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail3);
627*49ef7e06SGarrett D'Amore fail2:
628*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
629*49ef7e06SGarrett D'Amore fail1:
630*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
631*49ef7e06SGarrett D'Amore
632*49ef7e06SGarrett D'Amore return (rc);
633*49ef7e06SGarrett D'Amore }
634*49ef7e06SGarrett D'Amore
635*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_mcdi_nvram_info(__in efx_nic_t * enp,__in uint32_t partn,__out_opt size_t * sizep,__out_opt uint32_t * addressp,__out_opt uint32_t * erase_sizep,__out_opt uint32_t * write_sizep)636*49ef7e06SGarrett D'Amore efx_mcdi_nvram_info(
637*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
638*49ef7e06SGarrett D'Amore __in uint32_t partn,
639*49ef7e06SGarrett D'Amore __out_opt size_t *sizep,
640*49ef7e06SGarrett D'Amore __out_opt uint32_t *addressp,
641*49ef7e06SGarrett D'Amore __out_opt uint32_t *erase_sizep,
642*49ef7e06SGarrett D'Amore __out_opt uint32_t *write_sizep)
643*49ef7e06SGarrett D'Amore {
644*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
645*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
646*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
647*49ef7e06SGarrett D'Amore efx_rc_t rc;
648*49ef7e06SGarrett D'Amore
649*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
650*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_INFO;
651*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
652*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
653*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
654*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_INFO_V2_OUT_LEN;
655*49ef7e06SGarrett D'Amore
656*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
657*49ef7e06SGarrett D'Amore
658*49ef7e06SGarrett D'Amore efx_mcdi_execute_quiet(enp, &req);
659*49ef7e06SGarrett D'Amore
660*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
661*49ef7e06SGarrett D'Amore rc = req.emr_rc;
662*49ef7e06SGarrett D'Amore goto fail1;
663*49ef7e06SGarrett D'Amore }
664*49ef7e06SGarrett D'Amore
665*49ef7e06SGarrett D'Amore if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
666*49ef7e06SGarrett D'Amore rc = EMSGSIZE;
667*49ef7e06SGarrett D'Amore goto fail2;
668*49ef7e06SGarrett D'Amore }
669*49ef7e06SGarrett D'Amore
670*49ef7e06SGarrett D'Amore if (sizep)
671*49ef7e06SGarrett D'Amore *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
672*49ef7e06SGarrett D'Amore
673*49ef7e06SGarrett D'Amore if (addressp)
674*49ef7e06SGarrett D'Amore *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
675*49ef7e06SGarrett D'Amore
676*49ef7e06SGarrett D'Amore if (erase_sizep)
677*49ef7e06SGarrett D'Amore *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
678*49ef7e06SGarrett D'Amore
679*49ef7e06SGarrett D'Amore if (write_sizep) {
680*49ef7e06SGarrett D'Amore *write_sizep =
681*49ef7e06SGarrett D'Amore (req.emr_out_length_used <
682*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_INFO_V2_OUT_LEN) ?
683*49ef7e06SGarrett D'Amore 0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE);
684*49ef7e06SGarrett D'Amore }
685*49ef7e06SGarrett D'Amore
686*49ef7e06SGarrett D'Amore return (0);
687*49ef7e06SGarrett D'Amore
688*49ef7e06SGarrett D'Amore fail2:
689*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
690*49ef7e06SGarrett D'Amore fail1:
691*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
692*49ef7e06SGarrett D'Amore
693*49ef7e06SGarrett D'Amore return (rc);
694*49ef7e06SGarrett D'Amore }
695*49ef7e06SGarrett D'Amore
696*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_mcdi_nvram_update_start(__in efx_nic_t * enp,__in uint32_t partn)697*49ef7e06SGarrett D'Amore efx_mcdi_nvram_update_start(
698*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
699*49ef7e06SGarrett D'Amore __in uint32_t partn)
700*49ef7e06SGarrett D'Amore {
701*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_IN_LEN,
702*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
703*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
704*49ef7e06SGarrett D'Amore efx_rc_t rc;
705*49ef7e06SGarrett D'Amore
706*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
707*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
708*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
709*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
710*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
711*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
712*49ef7e06SGarrett D'Amore
713*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
714*49ef7e06SGarrett D'Amore
715*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
716*49ef7e06SGarrett D'Amore
717*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
718*49ef7e06SGarrett D'Amore rc = req.emr_rc;
719*49ef7e06SGarrett D'Amore goto fail1;
720*49ef7e06SGarrett D'Amore }
721*49ef7e06SGarrett D'Amore
722*49ef7e06SGarrett D'Amore return (0);
723*49ef7e06SGarrett D'Amore
724*49ef7e06SGarrett D'Amore fail1:
725*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
726*49ef7e06SGarrett D'Amore
727*49ef7e06SGarrett D'Amore return (rc);
728*49ef7e06SGarrett D'Amore }
729*49ef7e06SGarrett D'Amore
730*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_mcdi_nvram_read(__in efx_nic_t * enp,__in uint32_t partn,__in uint32_t offset,__out_bcount (size)caddr_t data,__in size_t size,__in uint32_t mode)731*49ef7e06SGarrett D'Amore efx_mcdi_nvram_read(
732*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
733*49ef7e06SGarrett D'Amore __in uint32_t partn,
734*49ef7e06SGarrett D'Amore __in uint32_t offset,
735*49ef7e06SGarrett D'Amore __out_bcount(size) caddr_t data,
736*49ef7e06SGarrett D'Amore __in size_t size,
737*49ef7e06SGarrett D'Amore __in uint32_t mode)
738*49ef7e06SGarrett D'Amore {
739*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
740*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
741*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_READ_OUT_LENMAX)];
742*49ef7e06SGarrett D'Amore efx_rc_t rc;
743*49ef7e06SGarrett D'Amore
744*49ef7e06SGarrett D'Amore if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
745*49ef7e06SGarrett D'Amore rc = EINVAL;
746*49ef7e06SGarrett D'Amore goto fail1;
747*49ef7e06SGarrett D'Amore }
748*49ef7e06SGarrett D'Amore
749*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
750*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_READ;
751*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
752*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
753*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
754*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
755*49ef7e06SGarrett D'Amore
756*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_TYPE, partn);
757*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_OFFSET, offset);
758*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_LENGTH, size);
759*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_MODE, mode);
760*49ef7e06SGarrett D'Amore
761*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
762*49ef7e06SGarrett D'Amore
763*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
764*49ef7e06SGarrett D'Amore rc = req.emr_rc;
765*49ef7e06SGarrett D'Amore goto fail1;
766*49ef7e06SGarrett D'Amore }
767*49ef7e06SGarrett D'Amore
768*49ef7e06SGarrett D'Amore if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
769*49ef7e06SGarrett D'Amore rc = EMSGSIZE;
770*49ef7e06SGarrett D'Amore goto fail2;
771*49ef7e06SGarrett D'Amore }
772*49ef7e06SGarrett D'Amore
773*49ef7e06SGarrett D'Amore (void) memcpy(data,
774*49ef7e06SGarrett D'Amore MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
775*49ef7e06SGarrett D'Amore size);
776*49ef7e06SGarrett D'Amore
777*49ef7e06SGarrett D'Amore return (0);
778*49ef7e06SGarrett D'Amore
779*49ef7e06SGarrett D'Amore fail2:
780*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
781*49ef7e06SGarrett D'Amore fail1:
782*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
783*49ef7e06SGarrett D'Amore
784*49ef7e06SGarrett D'Amore return (rc);
785*49ef7e06SGarrett D'Amore }
786*49ef7e06SGarrett D'Amore
787*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_mcdi_nvram_erase(__in efx_nic_t * enp,__in uint32_t partn,__in uint32_t offset,__in size_t size)788*49ef7e06SGarrett D'Amore efx_mcdi_nvram_erase(
789*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
790*49ef7e06SGarrett D'Amore __in uint32_t partn,
791*49ef7e06SGarrett D'Amore __in uint32_t offset,
792*49ef7e06SGarrett D'Amore __in size_t size)
793*49ef7e06SGarrett D'Amore {
794*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
795*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
796*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_ERASE_OUT_LEN)];
797*49ef7e06SGarrett D'Amore efx_rc_t rc;
798*49ef7e06SGarrett D'Amore
799*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
800*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_ERASE;
801*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
802*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
803*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
804*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
805*49ef7e06SGarrett D'Amore
806*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
807*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
808*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
809*49ef7e06SGarrett D'Amore
810*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
811*49ef7e06SGarrett D'Amore
812*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
813*49ef7e06SGarrett D'Amore rc = req.emr_rc;
814*49ef7e06SGarrett D'Amore goto fail1;
815*49ef7e06SGarrett D'Amore }
816*49ef7e06SGarrett D'Amore
817*49ef7e06SGarrett D'Amore return (0);
818*49ef7e06SGarrett D'Amore
819*49ef7e06SGarrett D'Amore fail1:
820*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
821*49ef7e06SGarrett D'Amore
822*49ef7e06SGarrett D'Amore return (rc);
823*49ef7e06SGarrett D'Amore }
824*49ef7e06SGarrett D'Amore
825*49ef7e06SGarrett D'Amore /*
826*49ef7e06SGarrett D'Amore * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
827*49ef7e06SGarrett D'Amore * Sienna and EF10 based boards. However EF10 based boards support the use
828*49ef7e06SGarrett D'Amore * of this command with payloads up to the maximum MCDI V2 payload length.
829*49ef7e06SGarrett D'Amore */
830*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_mcdi_nvram_write(__in efx_nic_t * enp,__in uint32_t partn,__in uint32_t offset,__out_bcount (size)caddr_t data,__in size_t size)831*49ef7e06SGarrett D'Amore efx_mcdi_nvram_write(
832*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
833*49ef7e06SGarrett D'Amore __in uint32_t partn,
834*49ef7e06SGarrett D'Amore __in uint32_t offset,
835*49ef7e06SGarrett D'Amore __out_bcount(size) caddr_t data,
836*49ef7e06SGarrett D'Amore __in size_t size)
837*49ef7e06SGarrett D'Amore {
838*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
839*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
840*49ef7e06SGarrett D'Amore MCDI_CTL_SDU_LEN_MAX_V2)];
841*49ef7e06SGarrett D'Amore efx_rc_t rc;
842*49ef7e06SGarrett D'Amore size_t max_data_size;
843*49ef7e06SGarrett D'Amore
844*49ef7e06SGarrett D'Amore max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
845*49ef7e06SGarrett D'Amore - MC_CMD_NVRAM_WRITE_IN_LEN(0);
846*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
847*49ef7e06SGarrett D'Amore EFSYS_ASSERT3U(max_data_size, <,
848*49ef7e06SGarrett D'Amore enp->en_nic_cfg.enc_mcdi_max_payload_length);
849*49ef7e06SGarrett D'Amore
850*49ef7e06SGarrett D'Amore if (size > max_data_size) {
851*49ef7e06SGarrett D'Amore rc = EINVAL;
852*49ef7e06SGarrett D'Amore goto fail1;
853*49ef7e06SGarrett D'Amore }
854*49ef7e06SGarrett D'Amore
855*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
856*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_WRITE;
857*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
858*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
859*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
860*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
861*49ef7e06SGarrett D'Amore
862*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
863*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
864*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
865*49ef7e06SGarrett D'Amore
866*49ef7e06SGarrett D'Amore (void) memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
867*49ef7e06SGarrett D'Amore data, size);
868*49ef7e06SGarrett D'Amore
869*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
870*49ef7e06SGarrett D'Amore
871*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
872*49ef7e06SGarrett D'Amore rc = req.emr_rc;
873*49ef7e06SGarrett D'Amore goto fail2;
874*49ef7e06SGarrett D'Amore }
875*49ef7e06SGarrett D'Amore
876*49ef7e06SGarrett D'Amore return (0);
877*49ef7e06SGarrett D'Amore
878*49ef7e06SGarrett D'Amore fail2:
879*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
880*49ef7e06SGarrett D'Amore fail1:
881*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
882*49ef7e06SGarrett D'Amore
883*49ef7e06SGarrett D'Amore return (rc);
884*49ef7e06SGarrett D'Amore }
885*49ef7e06SGarrett D'Amore
886*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_mcdi_nvram_update_finish(__in efx_nic_t * enp,__in uint32_t partn,__in boolean_t reboot)887*49ef7e06SGarrett D'Amore efx_mcdi_nvram_update_finish(
888*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
889*49ef7e06SGarrett D'Amore __in uint32_t partn,
890*49ef7e06SGarrett D'Amore __in boolean_t reboot)
891*49ef7e06SGarrett D'Amore {
892*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
893*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN,
894*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN)];
895*49ef7e06SGarrett D'Amore efx_rc_t rc;
896*49ef7e06SGarrett D'Amore
897*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
898*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
899*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
900*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
901*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
902*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN;
903*49ef7e06SGarrett D'Amore
904*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
905*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
906*49ef7e06SGarrett D'Amore
907*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
908*49ef7e06SGarrett D'Amore
909*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
910*49ef7e06SGarrett D'Amore rc = req.emr_rc;
911*49ef7e06SGarrett D'Amore goto fail1;
912*49ef7e06SGarrett D'Amore }
913*49ef7e06SGarrett D'Amore
914*49ef7e06SGarrett D'Amore return (0);
915*49ef7e06SGarrett D'Amore
916*49ef7e06SGarrett D'Amore fail1:
917*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
918*49ef7e06SGarrett D'Amore
919*49ef7e06SGarrett D'Amore return (rc);
920*49ef7e06SGarrett D'Amore }
921*49ef7e06SGarrett D'Amore
922*49ef7e06SGarrett D'Amore #if EFSYS_OPT_DIAG
923*49ef7e06SGarrett D'Amore
924*49ef7e06SGarrett D'Amore __checkReturn efx_rc_t
efx_mcdi_nvram_test(__in efx_nic_t * enp,__in uint32_t partn)925*49ef7e06SGarrett D'Amore efx_mcdi_nvram_test(
926*49ef7e06SGarrett D'Amore __in efx_nic_t *enp,
927*49ef7e06SGarrett D'Amore __in uint32_t partn)
928*49ef7e06SGarrett D'Amore {
929*49ef7e06SGarrett D'Amore efx_mcdi_req_t req;
930*49ef7e06SGarrett D'Amore uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
931*49ef7e06SGarrett D'Amore MC_CMD_NVRAM_TEST_OUT_LEN)];
932*49ef7e06SGarrett D'Amore int result;
933*49ef7e06SGarrett D'Amore efx_rc_t rc;
934*49ef7e06SGarrett D'Amore
935*49ef7e06SGarrett D'Amore (void) memset(payload, 0, sizeof (payload));
936*49ef7e06SGarrett D'Amore req.emr_cmd = MC_CMD_NVRAM_TEST;
937*49ef7e06SGarrett D'Amore req.emr_in_buf = payload;
938*49ef7e06SGarrett D'Amore req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
939*49ef7e06SGarrett D'Amore req.emr_out_buf = payload;
940*49ef7e06SGarrett D'Amore req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
941*49ef7e06SGarrett D'Amore
942*49ef7e06SGarrett D'Amore MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
943*49ef7e06SGarrett D'Amore
944*49ef7e06SGarrett D'Amore efx_mcdi_execute(enp, &req);
945*49ef7e06SGarrett D'Amore
946*49ef7e06SGarrett D'Amore if (req.emr_rc != 0) {
947*49ef7e06SGarrett D'Amore rc = req.emr_rc;
948*49ef7e06SGarrett D'Amore goto fail1;
949*49ef7e06SGarrett D'Amore }
950*49ef7e06SGarrett D'Amore
951*49ef7e06SGarrett D'Amore if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
952*49ef7e06SGarrett D'Amore rc = EMSGSIZE;
953*49ef7e06SGarrett D'Amore goto fail2;
954*49ef7e06SGarrett D'Amore }
955*49ef7e06SGarrett D'Amore
956*49ef7e06SGarrett D'Amore result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
957*49ef7e06SGarrett D'Amore if (result == MC_CMD_NVRAM_TEST_FAIL) {
958*49ef7e06SGarrett D'Amore
959*49ef7e06SGarrett D'Amore EFSYS_PROBE1(nvram_test_failure, int, partn);
960*49ef7e06SGarrett D'Amore
961*49ef7e06SGarrett D'Amore rc = (EINVAL);
962*49ef7e06SGarrett D'Amore goto fail3;
963*49ef7e06SGarrett D'Amore }
964*49ef7e06SGarrett D'Amore
965*49ef7e06SGarrett D'Amore return (0);
966*49ef7e06SGarrett D'Amore
967*49ef7e06SGarrett D'Amore fail3:
968*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail3);
969*49ef7e06SGarrett D'Amore fail2:
970*49ef7e06SGarrett D'Amore EFSYS_PROBE(fail2);
971*49ef7e06SGarrett D'Amore fail1:
972*49ef7e06SGarrett D'Amore EFSYS_PROBE1(fail1, efx_rc_t, rc);
973*49ef7e06SGarrett D'Amore
974*49ef7e06SGarrett D'Amore return (rc);
975*49ef7e06SGarrett D'Amore }
976*49ef7e06SGarrett D'Amore
977*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_DIAG */
978*49ef7e06SGarrett D'Amore
979*49ef7e06SGarrett D'Amore
980*49ef7e06SGarrett D'Amore #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */
981