2 * Copyright (c) 2009-2016 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.
38 static const efx_nvram_ops_t __efx_nvram_siena_ops = {
40 siena_nvram_test, /* envo_test */
41 #endif /* EFSYS_OPT_DIAG */
42 siena_nvram_type_to_partn, /* envo_type_to_partn */
43 siena_nvram_partn_size, /* envo_partn_size */
44 siena_nvram_partn_rw_start, /* envo_partn_rw_start */
45 siena_nvram_partn_read, /* envo_partn_read */
46 siena_nvram_partn_erase, /* envo_partn_erase */
47 siena_nvram_partn_write, /* envo_partn_write */
48 siena_nvram_partn_rw_finish, /* envo_partn_rw_finish */
49 siena_nvram_partn_get_version, /* envo_partn_get_version */
50 siena_nvram_partn_set_version, /* envo_partn_set_version */
51 NULL, /* envo_partn_validate */
54 #endif /* EFSYS_OPT_SIENA */
56 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
58 static const efx_nvram_ops_t __efx_nvram_ef10_ops = {
60 ef10_nvram_test, /* envo_test */
61 #endif /* EFSYS_OPT_DIAG */
62 ef10_nvram_type_to_partn, /* envo_type_to_partn */
63 ef10_nvram_partn_size, /* envo_partn_size */
64 ef10_nvram_partn_rw_start, /* envo_partn_rw_start */
65 ef10_nvram_partn_read, /* envo_partn_read */
66 ef10_nvram_partn_erase, /* envo_partn_erase */
67 ef10_nvram_partn_write, /* envo_partn_write */
68 ef10_nvram_partn_rw_finish, /* envo_partn_rw_finish */
69 ef10_nvram_partn_get_version, /* envo_partn_get_version */
70 ef10_nvram_partn_set_version, /* envo_partn_set_version */
71 ef10_nvram_buffer_validate, /* envo_buffer_validate */
74 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
76 __checkReturn efx_rc_t
80 const efx_nvram_ops_t *envop;
83 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
84 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
85 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NVRAM));
87 switch (enp->en_family) {
89 case EFX_FAMILY_SIENA:
90 envop = &__efx_nvram_siena_ops;
92 #endif /* EFSYS_OPT_SIENA */
94 #if EFSYS_OPT_HUNTINGTON
95 case EFX_FAMILY_HUNTINGTON:
96 envop = &__efx_nvram_ef10_ops;
98 #endif /* EFSYS_OPT_HUNTINGTON */
100 #if EFSYS_OPT_MEDFORD
101 case EFX_FAMILY_MEDFORD:
102 envop = &__efx_nvram_ef10_ops;
104 #endif /* EFSYS_OPT_MEDFORD */
112 enp->en_envop = envop;
113 enp->en_mod_flags |= EFX_MOD_NVRAM;
118 EFSYS_PROBE1(fail1, efx_rc_t, rc);
125 __checkReturn efx_rc_t
129 const efx_nvram_ops_t *envop = enp->en_envop;
132 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
133 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
135 if ((rc = envop->envo_test(enp)) != 0)
141 EFSYS_PROBE1(fail1, efx_rc_t, rc);
146 #endif /* EFSYS_OPT_DIAG */
148 __checkReturn efx_rc_t
151 __in efx_nvram_type_t type,
154 const efx_nvram_ops_t *envop = enp->en_envop;
158 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
159 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
161 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
163 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
166 if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0)
174 EFSYS_PROBE1(fail1, efx_rc_t, rc);
180 __checkReturn efx_rc_t
181 efx_nvram_get_version(
183 __in efx_nvram_type_t type,
184 __out uint32_t *subtypep,
185 __out_ecount(4) uint16_t version[4])
187 const efx_nvram_ops_t *envop = enp->en_envop;
191 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
192 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
193 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
195 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
197 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
200 if ((rc = envop->envo_partn_get_version(enp, partn,
201 subtypep, version)) != 0)
209 EFSYS_PROBE1(fail1, efx_rc_t, rc);
214 __checkReturn efx_rc_t
217 __in efx_nvram_type_t type,
218 __out_opt size_t *chunk_sizep)
220 const efx_nvram_ops_t *envop = enp->en_envop;
224 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
225 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
227 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
228 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
230 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
232 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
235 if ((rc = envop->envo_partn_rw_start(enp, partn, chunk_sizep)) != 0)
238 enp->en_nvram_locked = type;
245 EFSYS_PROBE1(fail1, efx_rc_t, rc);
250 __checkReturn efx_rc_t
251 efx_nvram_read_chunk(
253 __in efx_nvram_type_t type,
254 __in unsigned int offset,
255 __out_bcount(size) caddr_t data,
258 const efx_nvram_ops_t *envop = enp->en_envop;
262 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
263 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
265 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
266 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
268 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
270 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
273 if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
281 EFSYS_PROBE1(fail1, efx_rc_t, rc);
286 __checkReturn efx_rc_t
289 __in efx_nvram_type_t type)
291 const efx_nvram_ops_t *envop = enp->en_envop;
292 unsigned int offset = 0;
297 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
298 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
300 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
301 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
303 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
305 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
308 if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0)
311 if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0)
321 EFSYS_PROBE1(fail1, efx_rc_t, rc);
326 __checkReturn efx_rc_t
327 efx_nvram_write_chunk(
329 __in efx_nvram_type_t type,
330 __in unsigned int offset,
331 __in_bcount(size) caddr_t data,
334 const efx_nvram_ops_t *envop = enp->en_envop;
338 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
339 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
341 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
342 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
344 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
346 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
349 if ((rc = envop->envo_partn_write(enp, partn, offset, data, size)) != 0)
357 EFSYS_PROBE1(fail1, efx_rc_t, rc);
362 __checkReturn efx_rc_t
365 __in efx_nvram_type_t type,
366 __out_opt uint32_t *verify_resultp)
368 const efx_nvram_ops_t *envop = enp->en_envop;
370 uint32_t verify_result = 0;
373 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
374 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
376 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
377 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
379 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
381 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
384 if ((rc = envop->envo_partn_rw_finish(enp, partn, &verify_result)) != 0)
387 enp->en_nvram_locked = EFX_NVRAM_INVALID;
389 if (verify_resultp != NULL)
390 *verify_resultp = verify_result;
396 enp->en_nvram_locked = EFX_NVRAM_INVALID;
399 EFSYS_PROBE1(fail1, efx_rc_t, rc);
401 /* Always report verification result */
402 if (verify_resultp != NULL)
403 *verify_resultp = verify_result;
408 __checkReturn efx_rc_t
409 efx_nvram_set_version(
411 __in efx_nvram_type_t type,
412 __in_ecount(4) uint16_t version[4])
414 const efx_nvram_ops_t *envop = enp->en_envop;
418 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
419 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
420 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
422 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
425 * The Siena implementation of envo_set_version() will attempt to
426 * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector.
427 * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
429 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
431 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
434 if ((rc = envop->envo_partn_set_version(enp, partn, version)) != 0)
442 EFSYS_PROBE1(fail1, efx_rc_t, rc);
447 /* Validate buffer contents (before writing to flash) */
448 __checkReturn efx_rc_t
451 __in efx_nvram_type_t type,
452 __in_bcount(partn_size) caddr_t partn_data,
453 __in size_t partn_size)
455 const efx_nvram_ops_t *envop = enp->en_envop;
459 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
460 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
461 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
463 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
466 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
469 if (envop->envo_type_to_partn != NULL &&
470 ((rc = envop->envo_buffer_validate(enp, partn,
471 partn_data, partn_size)) != 0))
479 EFSYS_PROBE1(fail1, efx_rc_t, rc);
489 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
490 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
491 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
493 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
495 enp->en_envop = NULL;
496 enp->en_mod_flags &= ~EFX_MOD_NVRAM;
499 #endif /* EFSYS_OPT_NVRAM */
501 #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
504 * Internal MCDI request handling
507 __checkReturn efx_rc_t
508 efx_mcdi_nvram_partitions(
510 __out_bcount(size) caddr_t data,
512 __out unsigned int *npartnp)
515 uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
516 MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
520 (void) memset(payload, 0, sizeof (payload));
521 req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
522 req.emr_in_buf = payload;
523 req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
524 req.emr_out_buf = payload;
525 req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
527 efx_mcdi_execute(enp, &req);
529 if (req.emr_rc != 0) {
534 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
538 npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
540 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
545 if (size < npartn * sizeof (uint32_t)) {
553 MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
554 (npartn * sizeof (uint32_t)));
563 EFSYS_PROBE1(fail1, efx_rc_t, rc);
568 __checkReturn efx_rc_t
569 efx_mcdi_nvram_metadata(
572 __out uint32_t *subtypep,
573 __out_ecount(4) uint16_t version[4],
574 __out_bcount_opt(size) char *descp,
578 uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
579 MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
582 (void) memset(payload, 0, sizeof (payload));
583 req.emr_cmd = MC_CMD_NVRAM_METADATA;
584 req.emr_in_buf = payload;
585 req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
586 req.emr_out_buf = payload;
587 req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
589 MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
591 efx_mcdi_execute(enp, &req);
593 if (req.emr_rc != 0) {
598 if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
603 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
604 NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
605 *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
610 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
611 NVRAM_METADATA_OUT_VERSION_VALID)) {
612 version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
613 version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
614 version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
615 version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
617 version[0] = version[1] = version[2] = version[3] = 0;
620 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
621 NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
622 /* Return optional descrition string */
623 if ((descp != NULL) && (size > 0)) {
627 desclen = (req.emr_out_length_used
628 - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
630 EFSYS_ASSERT3U(desclen, <=,
631 MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
633 if (size < desclen) {
638 memcpy(descp, MCDI_OUT2(req, char,
639 NVRAM_METADATA_OUT_DESCRIPTION),
642 /* Ensure string is NUL terminated */
643 descp[desclen] = '\0';
654 EFSYS_PROBE1(fail1, efx_rc_t, rc);
659 __checkReturn efx_rc_t
663 __out_opt size_t *sizep,
664 __out_opt uint32_t *addressp,
665 __out_opt uint32_t *erase_sizep,
666 __out_opt uint32_t *write_sizep)
668 uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
669 MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
673 (void) memset(payload, 0, sizeof (payload));
674 req.emr_cmd = MC_CMD_NVRAM_INFO;
675 req.emr_in_buf = payload;
676 req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
677 req.emr_out_buf = payload;
678 req.emr_out_length = MC_CMD_NVRAM_INFO_V2_OUT_LEN;
680 MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
682 efx_mcdi_execute_quiet(enp, &req);
684 if (req.emr_rc != 0) {
689 if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
695 *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
698 *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
701 *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
705 (req.emr_out_length_used <
706 MC_CMD_NVRAM_INFO_V2_OUT_LEN) ?
707 0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE);
715 EFSYS_PROBE1(fail1, efx_rc_t, rc);
721 * MC_CMD_NVRAM_UPDATE_START_V2 must be used to support firmware-verified
722 * NVRAM updates. Older firmware will ignore the flags field in the request.
724 __checkReturn efx_rc_t
725 efx_mcdi_nvram_update_start(
729 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN,
730 MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
734 (void) memset(payload, 0, sizeof (payload));
735 req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
736 req.emr_in_buf = payload;
737 req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN;
738 req.emr_out_buf = payload;
739 req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
741 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_V2_IN_TYPE, partn);
743 MCDI_IN_POPULATE_DWORD_1(req, NVRAM_UPDATE_START_V2_IN_FLAGS,
744 NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT, 1);
746 efx_mcdi_execute(enp, &req);
748 if (req.emr_rc != 0) {
756 EFSYS_PROBE1(fail1, efx_rc_t, rc);
761 __checkReturn efx_rc_t
765 __in uint32_t offset,
766 __out_bcount(size) caddr_t data,
771 uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
772 MC_CMD_NVRAM_READ_OUT_LENMAX)];
775 if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
780 (void) memset(payload, 0, sizeof (payload));
781 req.emr_cmd = MC_CMD_NVRAM_READ;
782 req.emr_in_buf = payload;
783 req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
784 req.emr_out_buf = payload;
785 req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
787 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_TYPE, partn);
788 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_OFFSET, offset);
789 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_LENGTH, size);
790 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_MODE, mode);
792 efx_mcdi_execute(enp, &req);
794 if (req.emr_rc != 0) {
799 if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
805 MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
813 EFSYS_PROBE1(fail1, efx_rc_t, rc);
818 __checkReturn efx_rc_t
819 efx_mcdi_nvram_erase(
822 __in uint32_t offset,
826 uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
827 MC_CMD_NVRAM_ERASE_OUT_LEN)];
830 (void) memset(payload, 0, sizeof (payload));
831 req.emr_cmd = MC_CMD_NVRAM_ERASE;
832 req.emr_in_buf = payload;
833 req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
834 req.emr_out_buf = payload;
835 req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
837 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
838 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
839 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
841 efx_mcdi_execute(enp, &req);
843 if (req.emr_rc != 0) {
851 EFSYS_PROBE1(fail1, efx_rc_t, rc);
857 * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
858 * Sienna and EF10 based boards. However EF10 based boards support the use
859 * of this command with payloads up to the maximum MCDI V2 payload length.
861 __checkReturn efx_rc_t
862 efx_mcdi_nvram_write(
865 __in uint32_t offset,
866 __out_bcount(size) caddr_t data,
870 uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
871 MCDI_CTL_SDU_LEN_MAX_V2)];
873 size_t max_data_size;
875 max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
876 - MC_CMD_NVRAM_WRITE_IN_LEN(0);
877 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
878 EFSYS_ASSERT3U(max_data_size, <,
879 enp->en_nic_cfg.enc_mcdi_max_payload_length);
881 if (size > max_data_size) {
886 (void) memset(payload, 0, sizeof (payload));
887 req.emr_cmd = MC_CMD_NVRAM_WRITE;
888 req.emr_in_buf = payload;
889 req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
890 req.emr_out_buf = payload;
891 req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
893 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
894 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
895 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
897 memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
900 efx_mcdi_execute(enp, &req);
902 if (req.emr_rc != 0) {
912 EFSYS_PROBE1(fail1, efx_rc_t, rc);
919 * MC_CMD_NVRAM_UPDATE_FINISH_V2 must be used to support firmware-verified
920 * NVRAM updates. Older firmware will ignore the flags field in the request.
922 __checkReturn efx_rc_t
923 efx_mcdi_nvram_update_finish(
926 __in boolean_t reboot,
927 __out_opt uint32_t *verify_resultp)
929 const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
931 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN,
932 MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN)];
933 uint32_t verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
936 (void) memset(payload, 0, sizeof (payload));
937 req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
938 req.emr_in_buf = payload;
939 req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN;
940 req.emr_out_buf = payload;
941 req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN;
943 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_TYPE, partn);
944 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_REBOOT, reboot);
946 MCDI_IN_POPULATE_DWORD_1(req, NVRAM_UPDATE_FINISH_V2_IN_FLAGS,
947 NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT, 1);
949 efx_mcdi_execute(enp, &req);
951 if (req.emr_rc != 0) {
956 if (req.emr_out_length_used < MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN) {
957 verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
958 if (encp->enc_nvram_update_verify_result_supported) {
959 /* Result of update verification is missing */
965 MCDI_OUT_DWORD(req, NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE);
968 if ((encp->enc_nvram_update_verify_result_supported) &&
969 (verify_result != MC_CMD_NVRAM_VERIFY_RC_SUCCESS)) {
970 /* Update verification failed */
975 if (verify_resultp != NULL)
976 *verify_resultp = verify_result;
985 EFSYS_PROBE1(fail1, efx_rc_t, rc);
987 /* Always report verification result */
988 if (verify_resultp != NULL)
989 *verify_resultp = verify_result;
996 __checkReturn efx_rc_t
1002 uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
1003 MC_CMD_NVRAM_TEST_OUT_LEN)];
1007 (void) memset(payload, 0, sizeof (payload));
1008 req.emr_cmd = MC_CMD_NVRAM_TEST;
1009 req.emr_in_buf = payload;
1010 req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
1011 req.emr_out_buf = payload;
1012 req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
1014 MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
1016 efx_mcdi_execute(enp, &req);
1018 if (req.emr_rc != 0) {
1023 if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
1028 result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
1029 if (result == MC_CMD_NVRAM_TEST_FAIL) {
1031 EFSYS_PROBE1(nvram_test_failure, int, partn);
1044 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1049 #endif /* EFSYS_OPT_DIAG */
1052 #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */