2 * Copyright (c) 2009-2015 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * The views and conclusions contained in the software and documentation are
27 * those of the authors and should not be interpreted as representing official
28 * policies, either expressed or implied, of the FreeBSD Project.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
41 static efx_nvram_ops_t __efx_nvram_falcon_ops = {
43 falcon_nvram_test, /* envo_test */
44 #endif /* EFSYS_OPT_DIAG */
45 falcon_nvram_type_to_partn, /* envo_type_to_partn */
46 falcon_nvram_partn_size, /* envo_partn_size */
47 falcon_nvram_partn_rw_start, /* envo_partn_rw_start */
48 falcon_nvram_partn_read, /* envo_partn_read */
49 falcon_nvram_partn_erase, /* envo_partn_erase */
50 falcon_nvram_partn_write, /* envo_partn_write */
51 falcon_nvram_partn_rw_finish, /* envo_partn_rw_finish */
52 falcon_nvram_partn_get_version, /* envo_partn_get_version */
53 falcon_nvram_partn_set_version, /* envo_partn_set_version */
54 NULL, /* envo_partn_validate */
57 #endif /* EFSYS_OPT_FALCON */
61 static efx_nvram_ops_t __efx_nvram_siena_ops = {
63 siena_nvram_test, /* envo_test */
64 #endif /* EFSYS_OPT_DIAG */
65 siena_nvram_type_to_partn, /* envo_type_to_partn */
66 siena_nvram_partn_size, /* envo_partn_size */
67 siena_nvram_partn_rw_start, /* envo_partn_rw_start */
68 siena_nvram_partn_read, /* envo_partn_read */
69 siena_nvram_partn_erase, /* envo_partn_erase */
70 siena_nvram_partn_write, /* envo_partn_write */
71 siena_nvram_partn_rw_finish, /* envo_partn_rw_finish */
72 siena_nvram_partn_get_version, /* envo_partn_get_version */
73 siena_nvram_partn_set_version, /* envo_partn_set_version */
74 NULL, /* envo_partn_validate */
77 #endif /* EFSYS_OPT_SIENA */
79 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
81 static efx_nvram_ops_t __efx_nvram_ef10_ops = {
83 ef10_nvram_test, /* envo_test */
84 #endif /* EFSYS_OPT_DIAG */
85 ef10_nvram_type_to_partn, /* envo_type_to_partn */
86 ef10_nvram_partn_size, /* envo_partn_size */
87 ef10_nvram_partn_rw_start, /* envo_partn_rw_start */
88 ef10_nvram_partn_read, /* envo_partn_read */
89 ef10_nvram_partn_erase, /* envo_partn_erase */
90 ef10_nvram_partn_write, /* envo_partn_write */
91 ef10_nvram_partn_rw_finish, /* envo_partn_rw_finish */
92 ef10_nvram_partn_get_version, /* envo_partn_get_version */
93 ef10_nvram_partn_set_version, /* envo_partn_set_version */
94 ef10_nvram_buffer_validate, /* envo_buffer_validate */
97 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
99 __checkReturn efx_rc_t
103 efx_nvram_ops_t *envop;
106 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
107 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
108 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NVRAM));
110 switch (enp->en_family) {
112 case EFX_FAMILY_FALCON:
113 envop = (efx_nvram_ops_t *)&__efx_nvram_falcon_ops;
115 #endif /* EFSYS_OPT_FALCON */
118 case EFX_FAMILY_SIENA:
119 envop = (efx_nvram_ops_t *)&__efx_nvram_siena_ops;
121 #endif /* EFSYS_OPT_SIENA */
123 #if EFSYS_OPT_HUNTINGTON
124 case EFX_FAMILY_HUNTINGTON:
125 envop = (efx_nvram_ops_t *)&__efx_nvram_ef10_ops;
127 #endif /* EFSYS_OPT_HUNTINGTON */
129 #if EFSYS_OPT_MEDFORD
130 case EFX_FAMILY_MEDFORD:
131 envop = (efx_nvram_ops_t *)&__efx_nvram_ef10_ops;
133 #endif /* EFSYS_OPT_MEDFORD */
141 enp->en_envop = envop;
142 enp->en_mod_flags |= EFX_MOD_NVRAM;
147 EFSYS_PROBE1(fail1, efx_rc_t, rc);
154 __checkReturn efx_rc_t
158 efx_nvram_ops_t *envop = enp->en_envop;
161 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
162 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
164 if ((rc = envop->envo_test(enp)) != 0)
170 EFSYS_PROBE1(fail1, efx_rc_t, rc);
175 #endif /* EFSYS_OPT_DIAG */
177 __checkReturn efx_rc_t
180 __in efx_nvram_type_t type,
183 efx_nvram_ops_t *envop = enp->en_envop;
187 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
188 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
190 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
192 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
195 if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0)
203 EFSYS_PROBE1(fail1, efx_rc_t, rc);
209 __checkReturn efx_rc_t
210 efx_nvram_get_version(
212 __in efx_nvram_type_t type,
213 __out uint32_t *subtypep,
214 __out_ecount(4) uint16_t version[4])
216 efx_nvram_ops_t *envop = enp->en_envop;
220 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
221 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
222 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
224 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
226 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
229 if ((rc = envop->envo_partn_get_version(enp, partn,
230 subtypep, version)) != 0)
238 EFSYS_PROBE1(fail1, efx_rc_t, rc);
243 __checkReturn efx_rc_t
246 __in efx_nvram_type_t type,
247 __out_opt size_t *chunk_sizep)
249 efx_nvram_ops_t *envop = enp->en_envop;
253 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
254 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
256 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
257 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
259 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
261 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
264 if ((rc = envop->envo_partn_rw_start(enp, partn, chunk_sizep)) != 0)
267 enp->en_nvram_locked = type;
274 EFSYS_PROBE1(fail1, efx_rc_t, rc);
279 __checkReturn efx_rc_t
280 efx_nvram_read_chunk(
282 __in efx_nvram_type_t type,
283 __in unsigned int offset,
284 __out_bcount(size) caddr_t data,
287 efx_nvram_ops_t *envop = enp->en_envop;
291 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
292 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
294 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
295 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
297 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
299 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
302 if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
310 EFSYS_PROBE1(fail1, efx_rc_t, rc);
315 __checkReturn efx_rc_t
318 __in efx_nvram_type_t type)
320 efx_nvram_ops_t *envop = enp->en_envop;
321 unsigned int offset = 0;
326 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
327 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
329 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
330 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
332 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
334 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
337 if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0)
340 if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0)
350 EFSYS_PROBE1(fail1, efx_rc_t, rc);
355 __checkReturn efx_rc_t
356 efx_nvram_write_chunk(
358 __in efx_nvram_type_t type,
359 __in unsigned int offset,
360 __in_bcount(size) caddr_t data,
363 efx_nvram_ops_t *envop = enp->en_envop;
367 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
368 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
370 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
371 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
373 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
375 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
378 if ((rc = envop->envo_partn_write(enp, partn, offset, data, size)) != 0)
386 EFSYS_PROBE1(fail1, efx_rc_t, rc);
394 __in efx_nvram_type_t type)
396 efx_nvram_ops_t *envop = enp->en_envop;
399 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
400 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
402 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
403 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
405 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
407 if (envop->envo_type_to_partn(enp, type, &partn) == 0)
408 envop->envo_partn_rw_finish(enp, partn);
410 enp->en_nvram_locked = EFX_NVRAM_INVALID;
413 __checkReturn efx_rc_t
414 efx_nvram_set_version(
416 __in efx_nvram_type_t type,
417 __in_ecount(4) uint16_t version[4])
419 efx_nvram_ops_t *envop = enp->en_envop;
423 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
424 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
425 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
427 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
430 * The Siena implementation of envo_set_version() will attempt to
431 * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector.
432 * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
434 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
436 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
439 if ((rc = envop->envo_partn_set_version(enp, partn, version)) != 0)
447 EFSYS_PROBE1(fail1, efx_rc_t, rc);
452 /* Validate buffer contents (before writing to flash) */
453 __checkReturn efx_rc_t
456 __in efx_nvram_type_t type,
457 __in_bcount(partn_size) caddr_t partn_data,
458 __in size_t partn_size)
460 efx_nvram_ops_t *envop = enp->en_envop;
464 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
465 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
466 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
468 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
471 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
474 if (envop->envo_type_to_partn != NULL &&
475 ((rc = envop->envo_buffer_validate(enp, partn,
476 partn_data, partn_size)) != 0))
484 EFSYS_PROBE1(fail1, efx_rc_t, rc);
494 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
495 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
496 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
498 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
500 enp->en_envop = NULL;
501 enp->en_mod_flags &= ~EFX_MOD_NVRAM;
504 #endif /* EFSYS_OPT_NVRAM */
506 #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
509 * Internal MCDI request handling
512 __checkReturn efx_rc_t
513 efx_mcdi_nvram_partitions(
515 __out_bcount(size) caddr_t data,
517 __out unsigned int *npartnp)
520 uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
521 MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
525 (void) memset(payload, 0, sizeof (payload));
526 req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
527 req.emr_in_buf = payload;
528 req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
529 req.emr_out_buf = payload;
530 req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
532 efx_mcdi_execute(enp, &req);
534 if (req.emr_rc != 0) {
539 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
543 npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
545 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
550 if (size < npartn * sizeof (uint32_t)) {
558 MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
559 (npartn * sizeof (uint32_t)));
568 EFSYS_PROBE1(fail1, efx_rc_t, rc);
573 __checkReturn efx_rc_t
574 efx_mcdi_nvram_metadata(
577 __out uint32_t *subtypep,
578 __out_ecount(4) uint16_t version[4],
579 __out_bcount_opt(size) char *descp,
583 uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
584 MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
587 (void) memset(payload, 0, sizeof (payload));
588 req.emr_cmd = MC_CMD_NVRAM_METADATA;
589 req.emr_in_buf = payload;
590 req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
591 req.emr_out_buf = payload;
592 req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
594 MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
596 efx_mcdi_execute(enp, &req);
598 if (req.emr_rc != 0) {
603 if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
608 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
609 NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
610 *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
615 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
616 NVRAM_METADATA_OUT_VERSION_VALID)) {
617 version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
618 version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
619 version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
620 version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
622 version[0] = version[1] = version[2] = version[3] = 0;
625 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
626 NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
627 /* Return optional descrition string */
628 if ((descp != NULL) && (size > 0)) {
632 desclen = (req.emr_out_length_used
633 - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
635 EFSYS_ASSERT3U(desclen, <=,
636 MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
638 if (size < desclen) {
643 memcpy(descp, MCDI_OUT2(req, char,
644 NVRAM_METADATA_OUT_DESCRIPTION),
647 /* Ensure string is NUL terminated */
648 descp[desclen] = '\0';
659 EFSYS_PROBE1(fail1, efx_rc_t, rc);
664 __checkReturn efx_rc_t
668 __out_opt size_t *sizep,
669 __out_opt uint32_t *addressp,
670 __out_opt uint32_t *erase_sizep,
671 __out_opt uint32_t *write_sizep)
673 uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
674 MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
678 (void) memset(payload, 0, sizeof (payload));
679 req.emr_cmd = MC_CMD_NVRAM_INFO;
680 req.emr_in_buf = payload;
681 req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
682 req.emr_out_buf = payload;
683 req.emr_out_length = MC_CMD_NVRAM_INFO_V2_OUT_LEN;
685 MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
687 efx_mcdi_execute_quiet(enp, &req);
689 if (req.emr_rc != 0) {
694 if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
700 *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
703 *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
706 *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
710 (req.emr_out_length_used <
711 MC_CMD_NVRAM_INFO_V2_OUT_LEN) ?
712 0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE);
720 EFSYS_PROBE1(fail1, efx_rc_t, rc);
725 __checkReturn efx_rc_t
726 efx_mcdi_nvram_update_start(
730 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_IN_LEN,
731 MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
735 (void) memset(payload, 0, sizeof (payload));
736 req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
737 req.emr_in_buf = payload;
738 req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
739 req.emr_out_buf = payload;
740 req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
742 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
744 efx_mcdi_execute(enp, &req);
746 if (req.emr_rc != 0) {
754 EFSYS_PROBE1(fail1, efx_rc_t, rc);
759 __checkReturn efx_rc_t
763 __in uint32_t offset,
764 __out_bcount(size) caddr_t data,
769 uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
770 MC_CMD_NVRAM_READ_OUT_LENMAX)];
773 if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
778 (void) memset(payload, 0, sizeof (payload));
779 req.emr_cmd = MC_CMD_NVRAM_READ;
780 req.emr_in_buf = payload;
781 req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
782 req.emr_out_buf = payload;
783 req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
785 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_TYPE, partn);
786 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_OFFSET, offset);
787 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_LENGTH, size);
788 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_MODE, mode);
790 efx_mcdi_execute(enp, &req);
792 if (req.emr_rc != 0) {
797 if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
803 MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
811 EFSYS_PROBE1(fail1, efx_rc_t, rc);
816 __checkReturn efx_rc_t
817 efx_mcdi_nvram_erase(
820 __in uint32_t offset,
824 uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
825 MC_CMD_NVRAM_ERASE_OUT_LEN)];
828 (void) memset(payload, 0, sizeof (payload));
829 req.emr_cmd = MC_CMD_NVRAM_ERASE;
830 req.emr_in_buf = payload;
831 req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
832 req.emr_out_buf = payload;
833 req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
835 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
836 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
837 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
839 efx_mcdi_execute(enp, &req);
841 if (req.emr_rc != 0) {
849 EFSYS_PROBE1(fail1, efx_rc_t, rc);
855 * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
856 * Sienna and EF10 based boards. However EF10 based boards support the use
857 * of this command with payloads up to the maximum MCDI V2 payload length.
859 __checkReturn efx_rc_t
860 efx_mcdi_nvram_write(
863 __in uint32_t offset,
864 __out_bcount(size) caddr_t data,
868 uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
869 MCDI_CTL_SDU_LEN_MAX_V2)];
871 size_t max_data_size;
873 max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
874 - MC_CMD_NVRAM_WRITE_IN_LEN(0);
875 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
876 EFSYS_ASSERT3U(max_data_size, <,
877 enp->en_nic_cfg.enc_mcdi_max_payload_length);
879 if (size > max_data_size) {
884 (void) memset(payload, 0, sizeof (payload));
885 req.emr_cmd = MC_CMD_NVRAM_WRITE;
886 req.emr_in_buf = payload;
887 req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
888 req.emr_out_buf = payload;
889 req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
891 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
892 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
893 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
895 memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
898 efx_mcdi_execute(enp, &req);
900 if (req.emr_rc != 0) {
910 EFSYS_PROBE1(fail1, efx_rc_t, rc);
915 __checkReturn efx_rc_t
916 efx_mcdi_nvram_update_finish(
919 __in boolean_t reboot)
922 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN,
923 MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN)];
926 (void) memset(payload, 0, sizeof (payload));
927 req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
928 req.emr_in_buf = payload;
929 req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
930 req.emr_out_buf = payload;
931 req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN;
933 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
934 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
936 efx_mcdi_execute(enp, &req);
938 if (req.emr_rc != 0) {
946 EFSYS_PROBE1(fail1, efx_rc_t, rc);
953 __checkReturn efx_rc_t
959 uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
960 MC_CMD_NVRAM_TEST_OUT_LEN)];
964 (void) memset(payload, 0, sizeof (payload));
965 req.emr_cmd = MC_CMD_NVRAM_TEST;
966 req.emr_in_buf = payload;
967 req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
968 req.emr_out_buf = payload;
969 req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
971 MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
973 efx_mcdi_execute(enp, &req);
975 if (req.emr_rc != 0) {
980 if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
985 result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
986 if (result == MC_CMD_NVRAM_TEST_FAIL) {
988 EFSYS_PROBE1(nvram_test_failure, int, partn);
1001 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1006 #endif /* EFSYS_OPT_DIAG */
1009 #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */