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;
115 enp->en_nvram_partn_locked = EFX_NVRAM_PARTN_INVALID;
120 EFSYS_PROBE1(fail1, efx_rc_t, rc);
127 __checkReturn efx_rc_t
131 const efx_nvram_ops_t *envop = enp->en_envop;
134 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
135 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
137 if ((rc = envop->envo_test(enp)) != 0)
143 EFSYS_PROBE1(fail1, efx_rc_t, rc);
148 #endif /* EFSYS_OPT_DIAG */
150 __checkReturn efx_rc_t
153 __in efx_nvram_type_t type,
156 const efx_nvram_ops_t *envop = enp->en_envop;
160 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
161 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
163 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
165 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
168 if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0)
176 EFSYS_PROBE1(fail1, efx_rc_t, rc);
182 __checkReturn efx_rc_t
183 efx_nvram_get_version(
185 __in efx_nvram_type_t type,
186 __out uint32_t *subtypep,
187 __out_ecount(4) uint16_t version[4])
189 const efx_nvram_ops_t *envop = enp->en_envop;
193 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
194 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
195 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
197 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
199 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
202 if ((rc = envop->envo_partn_get_version(enp, partn,
203 subtypep, version)) != 0)
211 EFSYS_PROBE1(fail1, efx_rc_t, rc);
216 __checkReturn efx_rc_t
219 __in efx_nvram_type_t type,
220 __out_opt size_t *chunk_sizep)
222 const efx_nvram_ops_t *envop = enp->en_envop;
226 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
227 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
229 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
230 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
232 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
235 EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, EFX_NVRAM_PARTN_INVALID);
237 if ((rc = envop->envo_partn_rw_start(enp, partn, chunk_sizep)) != 0)
240 enp->en_nvram_partn_locked = partn;
247 EFSYS_PROBE1(fail1, efx_rc_t, rc);
252 __checkReturn efx_rc_t
253 efx_nvram_read_chunk(
255 __in efx_nvram_type_t type,
256 __in unsigned int offset,
257 __out_bcount(size) caddr_t data,
260 const efx_nvram_ops_t *envop = enp->en_envop;
264 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
265 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
267 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
268 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
270 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
273 EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, partn);
275 if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
283 EFSYS_PROBE1(fail1, efx_rc_t, rc);
288 __checkReturn efx_rc_t
291 __in efx_nvram_type_t type)
293 const efx_nvram_ops_t *envop = enp->en_envop;
294 unsigned int offset = 0;
299 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
300 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
302 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
303 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
305 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
308 EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, partn);
310 if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0)
313 if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0)
323 EFSYS_PROBE1(fail1, efx_rc_t, rc);
328 __checkReturn efx_rc_t
329 efx_nvram_write_chunk(
331 __in efx_nvram_type_t type,
332 __in unsigned int offset,
333 __in_bcount(size) caddr_t data,
336 const efx_nvram_ops_t *envop = enp->en_envop;
340 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
341 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
343 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
344 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
346 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
349 EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, partn);
351 if ((rc = envop->envo_partn_write(enp, partn, offset, data, size)) != 0)
359 EFSYS_PROBE1(fail1, efx_rc_t, rc);
364 __checkReturn efx_rc_t
367 __in efx_nvram_type_t type,
368 __out_opt uint32_t *verify_resultp)
370 const efx_nvram_ops_t *envop = enp->en_envop;
372 uint32_t verify_result = 0;
375 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
376 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
378 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
379 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
381 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
384 EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, partn);
386 if ((rc = envop->envo_partn_rw_finish(enp, partn, &verify_result)) != 0)
389 enp->en_nvram_partn_locked = EFX_NVRAM_PARTN_INVALID;
391 if (verify_resultp != NULL)
392 *verify_resultp = verify_result;
398 enp->en_nvram_partn_locked = EFX_NVRAM_PARTN_INVALID;
401 EFSYS_PROBE1(fail1, efx_rc_t, rc);
403 /* Always report verification result */
404 if (verify_resultp != NULL)
405 *verify_resultp = verify_result;
410 __checkReturn efx_rc_t
411 efx_nvram_set_version(
413 __in efx_nvram_type_t type,
414 __in_ecount(4) uint16_t version[4])
416 const efx_nvram_ops_t *envop = enp->en_envop;
420 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
421 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
422 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
424 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
426 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
430 * The Siena implementation of envo_set_version() will attempt to
431 * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG partition.
432 * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
434 EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, EFX_NVRAM_PARTN_INVALID);
436 if ((rc = envop->envo_partn_set_version(enp, partn, version)) != 0)
444 EFSYS_PROBE1(fail1, efx_rc_t, rc);
449 /* Validate buffer contents (before writing to flash) */
450 __checkReturn efx_rc_t
453 __in efx_nvram_type_t type,
454 __in_bcount(partn_size) caddr_t partn_data,
455 __in size_t partn_size)
457 const efx_nvram_ops_t *envop = enp->en_envop;
461 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
462 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
463 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
465 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
468 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
471 if (envop->envo_buffer_validate != NULL) {
472 if ((rc = envop->envo_buffer_validate(enp, partn,
473 partn_data, partn_size)) != 0)
482 EFSYS_PROBE1(fail1, efx_rc_t, rc);
492 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
493 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
494 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
496 EFSYS_ASSERT3U(enp->en_nvram_partn_locked, ==, EFX_NVRAM_PARTN_INVALID);
498 enp->en_envop = NULL;
499 enp->en_mod_flags &= ~EFX_MOD_NVRAM;
502 #endif /* EFSYS_OPT_NVRAM */
504 #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
507 * Internal MCDI request handling
510 __checkReturn efx_rc_t
511 efx_mcdi_nvram_partitions(
513 __out_bcount(size) caddr_t data,
515 __out unsigned int *npartnp)
518 uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
519 MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
523 (void) memset(payload, 0, sizeof (payload));
524 req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
525 req.emr_in_buf = payload;
526 req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
527 req.emr_out_buf = payload;
528 req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
530 efx_mcdi_execute(enp, &req);
532 if (req.emr_rc != 0) {
537 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
541 npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
543 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
548 if (size < npartn * sizeof (uint32_t)) {
556 MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
557 (npartn * sizeof (uint32_t)));
566 EFSYS_PROBE1(fail1, efx_rc_t, rc);
571 __checkReturn efx_rc_t
572 efx_mcdi_nvram_metadata(
575 __out uint32_t *subtypep,
576 __out_ecount(4) uint16_t version[4],
577 __out_bcount_opt(size) char *descp,
581 uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
582 MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
585 (void) memset(payload, 0, sizeof (payload));
586 req.emr_cmd = MC_CMD_NVRAM_METADATA;
587 req.emr_in_buf = payload;
588 req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
589 req.emr_out_buf = payload;
590 req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
592 MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
594 efx_mcdi_execute(enp, &req);
596 if (req.emr_rc != 0) {
601 if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
606 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
607 NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
608 *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
613 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
614 NVRAM_METADATA_OUT_VERSION_VALID)) {
615 version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
616 version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
617 version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
618 version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
620 version[0] = version[1] = version[2] = version[3] = 0;
623 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
624 NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
625 /* Return optional descrition string */
626 if ((descp != NULL) && (size > 0)) {
630 desclen = (req.emr_out_length_used
631 - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
633 EFSYS_ASSERT3U(desclen, <=,
634 MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
636 if (size < desclen) {
641 memcpy(descp, MCDI_OUT2(req, char,
642 NVRAM_METADATA_OUT_DESCRIPTION),
645 /* Ensure string is NUL terminated */
646 descp[desclen] = '\0';
657 EFSYS_PROBE1(fail1, efx_rc_t, rc);
662 __checkReturn efx_rc_t
666 __out_opt size_t *sizep,
667 __out_opt uint32_t *addressp,
668 __out_opt uint32_t *erase_sizep,
669 __out_opt uint32_t *write_sizep)
671 uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
672 MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
676 (void) memset(payload, 0, sizeof (payload));
677 req.emr_cmd = MC_CMD_NVRAM_INFO;
678 req.emr_in_buf = payload;
679 req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
680 req.emr_out_buf = payload;
681 req.emr_out_length = MC_CMD_NVRAM_INFO_V2_OUT_LEN;
683 MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
685 efx_mcdi_execute_quiet(enp, &req);
687 if (req.emr_rc != 0) {
692 if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
698 *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
701 *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
704 *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
708 (req.emr_out_length_used <
709 MC_CMD_NVRAM_INFO_V2_OUT_LEN) ?
710 0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE);
718 EFSYS_PROBE1(fail1, efx_rc_t, rc);
724 * MC_CMD_NVRAM_UPDATE_START_V2 must be used to support firmware-verified
725 * NVRAM updates. Older firmware will ignore the flags field in the request.
727 __checkReturn efx_rc_t
728 efx_mcdi_nvram_update_start(
732 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN,
733 MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
737 (void) memset(payload, 0, sizeof (payload));
738 req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
739 req.emr_in_buf = payload;
740 req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN;
741 req.emr_out_buf = payload;
742 req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
744 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_V2_IN_TYPE, partn);
746 MCDI_IN_POPULATE_DWORD_1(req, NVRAM_UPDATE_START_V2_IN_FLAGS,
747 NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT, 1);
749 efx_mcdi_execute(enp, &req);
751 if (req.emr_rc != 0) {
759 EFSYS_PROBE1(fail1, efx_rc_t, rc);
764 __checkReturn efx_rc_t
768 __in uint32_t offset,
769 __out_bcount(size) caddr_t data,
774 uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
775 MC_CMD_NVRAM_READ_OUT_LENMAX)];
778 if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
783 (void) memset(payload, 0, sizeof (payload));
784 req.emr_cmd = MC_CMD_NVRAM_READ;
785 req.emr_in_buf = payload;
786 req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
787 req.emr_out_buf = payload;
788 req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
790 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_TYPE, partn);
791 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_OFFSET, offset);
792 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_LENGTH, size);
793 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_MODE, mode);
795 efx_mcdi_execute(enp, &req);
797 if (req.emr_rc != 0) {
802 if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
808 MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
816 EFSYS_PROBE1(fail1, efx_rc_t, rc);
821 __checkReturn efx_rc_t
822 efx_mcdi_nvram_erase(
825 __in uint32_t offset,
829 uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
830 MC_CMD_NVRAM_ERASE_OUT_LEN)];
833 (void) memset(payload, 0, sizeof (payload));
834 req.emr_cmd = MC_CMD_NVRAM_ERASE;
835 req.emr_in_buf = payload;
836 req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
837 req.emr_out_buf = payload;
838 req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
840 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
841 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
842 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
844 efx_mcdi_execute(enp, &req);
846 if (req.emr_rc != 0) {
854 EFSYS_PROBE1(fail1, efx_rc_t, rc);
860 * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
861 * Sienna and EF10 based boards. However EF10 based boards support the use
862 * of this command with payloads up to the maximum MCDI V2 payload length.
864 __checkReturn efx_rc_t
865 efx_mcdi_nvram_write(
868 __in uint32_t offset,
869 __out_bcount(size) caddr_t data,
873 uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
874 MCDI_CTL_SDU_LEN_MAX_V2)];
876 size_t max_data_size;
878 max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
879 - MC_CMD_NVRAM_WRITE_IN_LEN(0);
880 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
881 EFSYS_ASSERT3U(max_data_size, <,
882 enp->en_nic_cfg.enc_mcdi_max_payload_length);
884 if (size > max_data_size) {
889 (void) memset(payload, 0, sizeof (payload));
890 req.emr_cmd = MC_CMD_NVRAM_WRITE;
891 req.emr_in_buf = payload;
892 req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
893 req.emr_out_buf = payload;
894 req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
896 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
897 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
898 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
900 memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
903 efx_mcdi_execute(enp, &req);
905 if (req.emr_rc != 0) {
915 EFSYS_PROBE1(fail1, efx_rc_t, rc);
922 * MC_CMD_NVRAM_UPDATE_FINISH_V2 must be used to support firmware-verified
923 * NVRAM updates. Older firmware will ignore the flags field in the request.
925 __checkReturn efx_rc_t
926 efx_mcdi_nvram_update_finish(
929 __in boolean_t reboot,
930 __out_opt uint32_t *verify_resultp)
932 const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
934 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN,
935 MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN)];
936 uint32_t verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
939 (void) memset(payload, 0, sizeof (payload));
940 req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
941 req.emr_in_buf = payload;
942 req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN;
943 req.emr_out_buf = payload;
944 req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN;
946 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_TYPE, partn);
947 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_REBOOT, reboot);
949 MCDI_IN_POPULATE_DWORD_1(req, NVRAM_UPDATE_FINISH_V2_IN_FLAGS,
950 NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT, 1);
952 efx_mcdi_execute(enp, &req);
954 if (req.emr_rc != 0) {
959 if (req.emr_out_length_used < MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN) {
960 verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
961 if (encp->enc_nvram_update_verify_result_supported) {
962 /* Result of update verification is missing */
968 MCDI_OUT_DWORD(req, NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE);
971 if ((encp->enc_nvram_update_verify_result_supported) &&
972 (verify_result != MC_CMD_NVRAM_VERIFY_RC_SUCCESS)) {
973 /* Update verification failed */
978 if (verify_resultp != NULL)
979 *verify_resultp = verify_result;
988 EFSYS_PROBE1(fail1, efx_rc_t, rc);
990 /* Always report verification result */
991 if (verify_resultp != NULL)
992 *verify_resultp = verify_result;
999 __checkReturn efx_rc_t
1000 efx_mcdi_nvram_test(
1001 __in efx_nic_t *enp,
1002 __in uint32_t partn)
1005 uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
1006 MC_CMD_NVRAM_TEST_OUT_LEN)];
1010 (void) memset(payload, 0, sizeof (payload));
1011 req.emr_cmd = MC_CMD_NVRAM_TEST;
1012 req.emr_in_buf = payload;
1013 req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
1014 req.emr_out_buf = payload;
1015 req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
1017 MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
1019 efx_mcdi_execute(enp, &req);
1021 if (req.emr_rc != 0) {
1026 if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
1031 result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
1032 if (result == MC_CMD_NVRAM_TEST_FAIL) {
1034 EFSYS_PROBE1(nvram_test_failure, int, partn);
1047 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1052 #endif /* EFSYS_OPT_DIAG */
1055 #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */