]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/sfxge/common/efx_nvram.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / sfxge / common / efx_nvram.c
1 /*-
2  * Copyright 2009 Solarflare Communications Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
28
29 #include "efsys.h"
30 #include "efx.h"
31 #include "efx_types.h"
32 #include "efx_regs.h"
33 #include "efx_impl.h"
34
35 #if EFSYS_OPT_NVRAM
36
37 #if EFSYS_OPT_FALCON
38
39 static efx_nvram_ops_t  __cs    __efx_nvram_falcon_ops = {
40 #if EFSYS_OPT_DIAG
41         falcon_nvram_test,              /* envo_test */
42 #endif  /* EFSYS_OPT_DIAG */
43         falcon_nvram_size,              /* envo_size */
44         falcon_nvram_get_version,       /* envo_get_version */
45         falcon_nvram_rw_start,          /* envo_rw_start */
46         falcon_nvram_read_chunk,        /* envo_read_chunk */
47         falcon_nvram_erase,             /* envo_erase */
48         falcon_nvram_write_chunk,       /* envo_write_chunk */
49         falcon_nvram_rw_finish,         /* envo_rw_finish */
50         falcon_nvram_set_version,       /* envo_set_version */
51 };
52
53 #endif  /* EFSYS_OPT_FALCON */
54
55 #if EFSYS_OPT_SIENA
56
57 static efx_nvram_ops_t  __cs    __efx_nvram_siena_ops = {
58 #if EFSYS_OPT_DIAG
59         siena_nvram_test,               /* envo_test */
60 #endif  /* EFSYS_OPT_DIAG */
61         siena_nvram_size,               /* envo_size */
62         siena_nvram_get_version,        /* envo_get_version */
63         siena_nvram_rw_start,           /* envo_rw_start */
64         siena_nvram_read_chunk,         /* envo_read_chunk */
65         siena_nvram_erase,              /* envo_erase */
66         siena_nvram_write_chunk,        /* envo_write_chunk */
67         siena_nvram_rw_finish,          /* envo_rw_finish */
68         siena_nvram_set_version,        /* envo_set_version */
69 };
70
71 #endif  /* EFSYS_OPT_SIENA */
72
73         __checkReturn   int
74 efx_nvram_init(
75         __in            efx_nic_t *enp)
76 {
77         efx_nvram_ops_t *envop;
78         int rc;
79
80         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
81         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
82         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NVRAM));
83
84         switch (enp->en_family) {
85 #if EFSYS_OPT_FALCON
86         case EFX_FAMILY_FALCON:
87                 envop = (efx_nvram_ops_t *)&__efx_nvram_falcon_ops;
88                 break;
89 #endif  /* EFSYS_OPT_FALCON */
90
91 #if EFSYS_OPT_SIENA
92         case EFX_FAMILY_SIENA:
93                 envop = (efx_nvram_ops_t *)&__efx_nvram_siena_ops;
94                 break;
95 #endif  /* EFSYS_OPT_SIENA */
96
97         default:
98                 EFSYS_ASSERT(0);
99                 rc = ENOTSUP;
100                 goto fail1;
101         }
102
103         enp->en_envop = envop;
104         enp->en_mod_flags |= EFX_MOD_NVRAM;
105
106         return (0);
107
108 fail1:
109         EFSYS_PROBE1(fail1, int, rc);
110
111         return (rc);
112 }
113
114 #if EFSYS_OPT_DIAG
115
116         __checkReturn           int
117 efx_nvram_test(
118         __in                    efx_nic_t *enp)
119 {
120         efx_nvram_ops_t *envop = enp->en_envop;
121         int rc;
122
123         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
124         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
125
126         if ((rc = envop->envo_test(enp)) != 0)
127                 goto fail1;
128
129         return (0);
130
131 fail1:
132         EFSYS_PROBE1(fail1, int, rc);
133
134         return (rc);
135 }
136
137 #endif  /* EFSYS_OPT_DIAG */
138
139         __checkReturn           int
140 efx_nvram_size(
141         __in                    efx_nic_t *enp,
142         __in                    efx_nvram_type_t type,
143         __out                   size_t *sizep)
144 {
145         efx_nvram_ops_t *envop = enp->en_envop;
146         int rc;
147
148         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
149         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
150
151         EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
152
153         if ((rc = envop->envo_size(enp, type, sizep)) != 0)
154                 goto fail1;
155
156         return (0);
157
158 fail1:
159         EFSYS_PROBE1(fail1, int, rc);
160
161         return (rc);
162 }
163
164         __checkReturn           int
165 efx_nvram_get_version(
166         __in                    efx_nic_t *enp,
167         __in                    efx_nvram_type_t type,
168         __out                   uint32_t *subtypep,
169         __out_ecount(4)         uint16_t version[4])
170 {
171         efx_nvram_ops_t *envop = enp->en_envop;
172         int rc;
173
174         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
175         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
176         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
177
178         EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
179
180         if ((rc = envop->envo_get_version(enp, type, subtypep, version)) != 0)
181                 goto fail1;
182
183         return (0);
184
185 fail1:
186         EFSYS_PROBE1(fail1, int, rc);
187
188         return (rc);
189 }
190
191         __checkReturn           int
192 efx_nvram_rw_start(
193         __in                    efx_nic_t *enp,
194         __in                    efx_nvram_type_t type,
195         __out_opt               size_t *chunk_sizep)
196 {
197         efx_nvram_ops_t *envop = enp->en_envop;
198         int rc;
199
200         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
201         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
202
203         EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
204         EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
205
206         EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
207
208         if ((rc = envop->envo_rw_start(enp, type, chunk_sizep)) != 0)
209                 goto fail1;
210
211         enp->en_nvram_locked = type;
212
213         return (0);
214
215 fail1:
216         EFSYS_PROBE1(fail1, int, rc);
217
218         return (rc);
219 }
220
221         __checkReturn           int
222 efx_nvram_read_chunk(
223         __in                    efx_nic_t *enp,
224         __in                    efx_nvram_type_t type,
225         __in                    unsigned int offset,
226         __out_bcount(size)      caddr_t data,
227         __in                    size_t size)
228 {
229         efx_nvram_ops_t *envop = enp->en_envop;
230         int rc;
231
232         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
233         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
234
235         EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
236         EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
237
238         EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
239
240         if ((rc = envop->envo_read_chunk(enp, type, offset, data, size)) != 0)
241                 goto fail1;
242
243         return (0);
244
245 fail1:
246         EFSYS_PROBE1(fail1, int, rc);
247
248         return (rc);
249 }
250
251         __checkReturn           int
252 efx_nvram_erase(
253         __in                    efx_nic_t *enp,
254         __in                    efx_nvram_type_t type)
255 {
256         efx_nvram_ops_t *envop = enp->en_envop;
257         int rc;
258
259         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
260         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
261
262         EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
263         EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
264
265         EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
266
267         if ((rc = envop->envo_erase(enp, type)) != 0)
268                 goto fail1;
269
270         return (0);
271
272 fail1:
273         EFSYS_PROBE1(fail1, int, rc);
274
275         return (rc);
276 }
277
278         __checkReturn           int
279 efx_nvram_write_chunk(
280         __in                    efx_nic_t *enp,
281         __in                    efx_nvram_type_t type,
282         __in                    unsigned int offset,
283         __in_bcount(size)       caddr_t data,
284         __in                    size_t size)
285 {
286         efx_nvram_ops_t *envop = enp->en_envop;
287         int rc;
288
289         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
290         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
291
292         EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
293         EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
294
295         EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
296
297         if ((rc = envop->envo_write_chunk(enp, type, offset, data, size)) != 0)
298                 goto fail1;
299
300         return (0);
301
302 fail1:
303         EFSYS_PROBE1(fail1, int, rc);
304
305         return (rc);
306 }
307
308                                 void
309 efx_nvram_rw_finish(
310         __in                    efx_nic_t *enp,
311         __in                    efx_nvram_type_t type)
312 {
313         efx_nvram_ops_t *envop = enp->en_envop;
314
315         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
316         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
317
318         EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
319         EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
320
321         EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
322
323         envop->envo_rw_finish(enp, type);
324
325         enp->en_nvram_locked = EFX_NVRAM_INVALID;
326 }
327
328         __checkReturn           int
329 efx_nvram_set_version(
330         __in                    efx_nic_t *enp,
331         __in                    efx_nvram_type_t type,
332         __out                   uint16_t version[4])
333 {
334         efx_nvram_ops_t *envop = enp->en_envop;
335         int rc;
336
337         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
338         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
339         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
340
341         EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
342
343         /*
344          * The Siena implementation of envo_set_version() will attempt to
345          * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector.
346          * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
347          */
348         EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
349
350         if ((rc = envop->envo_set_version(enp, type, version)) != 0)
351                 goto fail1;
352
353         return (0);
354
355 fail1:
356         EFSYS_PROBE1(fail1, int, rc);
357
358         return (rc);
359 }
360
361 void
362 efx_nvram_fini(
363         __in            efx_nic_t *enp)
364 {
365         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
366         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
367         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
368
369         EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
370
371         enp->en_envop = NULL;
372         enp->en_mod_flags &= ~EFX_MOD_NVRAM;
373 }
374
375 #endif  /* EFSYS_OPT_NVRAM */