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)
367 const efx_nvram_ops_t *envop = enp->en_envop;
371 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
372 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
374 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
375 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
377 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
379 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
382 if ((rc = envop->envo_partn_rw_finish(enp, partn)) != 0)
385 enp->en_nvram_locked = EFX_NVRAM_INVALID;
391 enp->en_nvram_locked = EFX_NVRAM_INVALID;
394 EFSYS_PROBE1(fail1, efx_rc_t, rc);
399 __checkReturn efx_rc_t
400 efx_nvram_set_version(
402 __in efx_nvram_type_t type,
403 __in_ecount(4) uint16_t version[4])
405 const efx_nvram_ops_t *envop = enp->en_envop;
409 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
410 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
411 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
413 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
416 * The Siena implementation of envo_set_version() will attempt to
417 * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector.
418 * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
420 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
422 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
425 if ((rc = envop->envo_partn_set_version(enp, partn, version)) != 0)
433 EFSYS_PROBE1(fail1, efx_rc_t, rc);
438 /* Validate buffer contents (before writing to flash) */
439 __checkReturn efx_rc_t
442 __in efx_nvram_type_t type,
443 __in_bcount(partn_size) caddr_t partn_data,
444 __in size_t partn_size)
446 const efx_nvram_ops_t *envop = enp->en_envop;
450 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
451 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
452 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
454 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
457 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
460 if (envop->envo_type_to_partn != NULL &&
461 ((rc = envop->envo_buffer_validate(enp, partn,
462 partn_data, partn_size)) != 0))
470 EFSYS_PROBE1(fail1, efx_rc_t, rc);
480 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
481 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
482 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
484 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
486 enp->en_envop = NULL;
487 enp->en_mod_flags &= ~EFX_MOD_NVRAM;
490 #endif /* EFSYS_OPT_NVRAM */
492 #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
495 * Internal MCDI request handling
498 __checkReturn efx_rc_t
499 efx_mcdi_nvram_partitions(
501 __out_bcount(size) caddr_t data,
503 __out unsigned int *npartnp)
506 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_PARTITIONS_IN_LEN,
507 MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX);
511 req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
512 req.emr_in_buf = payload;
513 req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
514 req.emr_out_buf = payload;
515 req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
517 efx_mcdi_execute(enp, &req);
519 if (req.emr_rc != 0) {
524 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
528 npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
530 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
535 if (size < npartn * sizeof (uint32_t)) {
543 MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
544 (npartn * sizeof (uint32_t)));
553 EFSYS_PROBE1(fail1, efx_rc_t, rc);
558 __checkReturn efx_rc_t
559 efx_mcdi_nvram_metadata(
562 __out uint32_t *subtypep,
563 __out_ecount(4) uint16_t version[4],
564 __out_bcount_opt(size) char *descp,
568 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_METADATA_IN_LEN,
569 MC_CMD_NVRAM_METADATA_OUT_LENMAX);
572 req.emr_cmd = MC_CMD_NVRAM_METADATA;
573 req.emr_in_buf = payload;
574 req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
575 req.emr_out_buf = payload;
576 req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
578 MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
580 efx_mcdi_execute(enp, &req);
582 if (req.emr_rc != 0) {
587 if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
592 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
593 NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
594 *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
599 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
600 NVRAM_METADATA_OUT_VERSION_VALID)) {
601 version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
602 version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
603 version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
604 version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
606 version[0] = version[1] = version[2] = version[3] = 0;
609 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
610 NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
611 /* Return optional descrition string */
612 if ((descp != NULL) && (size > 0)) {
616 desclen = (req.emr_out_length_used
617 - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
619 EFSYS_ASSERT3U(desclen, <=,
620 MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
622 if (size < desclen) {
627 memcpy(descp, MCDI_OUT2(req, char,
628 NVRAM_METADATA_OUT_DESCRIPTION),
631 /* Ensure string is NUL terminated */
632 descp[desclen] = '\0';
643 EFSYS_PROBE1(fail1, efx_rc_t, rc);
648 __checkReturn efx_rc_t
652 __out_opt size_t *sizep,
653 __out_opt uint32_t *addressp,
654 __out_opt uint32_t *erase_sizep,
655 __out_opt uint32_t *write_sizep)
657 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_INFO_IN_LEN,
658 MC_CMD_NVRAM_INFO_V2_OUT_LEN);
662 req.emr_cmd = MC_CMD_NVRAM_INFO;
663 req.emr_in_buf = payload;
664 req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
665 req.emr_out_buf = payload;
666 req.emr_out_length = MC_CMD_NVRAM_INFO_V2_OUT_LEN;
668 MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
670 efx_mcdi_execute_quiet(enp, &req);
672 if (req.emr_rc != 0) {
677 if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
683 *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
686 *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
689 *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
693 (req.emr_out_length_used <
694 MC_CMD_NVRAM_INFO_V2_OUT_LEN) ?
695 0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE);
703 EFSYS_PROBE1(fail1, efx_rc_t, rc);
709 * MC_CMD_NVRAM_UPDATE_START_V2 must be used to support firmware-verified
710 * NVRAM updates. Older firmware will ignore the flags field in the request.
712 __checkReturn efx_rc_t
713 efx_mcdi_nvram_update_start(
717 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN,
718 MC_CMD_NVRAM_UPDATE_START_OUT_LEN);
722 req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
723 req.emr_in_buf = payload;
724 req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN;
725 req.emr_out_buf = payload;
726 req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
728 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_V2_IN_TYPE, partn);
730 MCDI_IN_POPULATE_DWORD_1(req, NVRAM_UPDATE_START_V2_IN_FLAGS,
731 NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT, 1);
733 efx_mcdi_execute(enp, &req);
735 if (req.emr_rc != 0) {
743 EFSYS_PROBE1(fail1, efx_rc_t, rc);
748 __checkReturn efx_rc_t
752 __in uint32_t offset,
753 __out_bcount(size) caddr_t data,
758 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_READ_IN_V2_LEN,
759 MC_CMD_NVRAM_READ_OUT_LENMAX);
762 if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
767 req.emr_cmd = MC_CMD_NVRAM_READ;
768 req.emr_in_buf = payload;
769 req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
770 req.emr_out_buf = payload;
771 req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
773 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_TYPE, partn);
774 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_OFFSET, offset);
775 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_LENGTH, size);
776 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_MODE, mode);
778 efx_mcdi_execute(enp, &req);
780 if (req.emr_rc != 0) {
785 if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
791 MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
799 EFSYS_PROBE1(fail1, efx_rc_t, rc);
804 __checkReturn efx_rc_t
805 efx_mcdi_nvram_erase(
808 __in uint32_t offset,
812 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_ERASE_IN_LEN,
813 MC_CMD_NVRAM_ERASE_OUT_LEN);
816 req.emr_cmd = MC_CMD_NVRAM_ERASE;
817 req.emr_in_buf = payload;
818 req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
819 req.emr_out_buf = payload;
820 req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
822 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
823 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
824 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
826 efx_mcdi_execute(enp, &req);
828 if (req.emr_rc != 0) {
836 EFSYS_PROBE1(fail1, efx_rc_t, rc);
842 * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
843 * Sienna and EF10 based boards. However EF10 based boards support the use
844 * of this command with payloads up to the maximum MCDI V2 payload length.
846 __checkReturn efx_rc_t
847 efx_mcdi_nvram_write(
850 __in uint32_t offset,
851 __in_bcount(size) caddr_t data,
857 size_t max_data_size;
858 size_t payload_len = enp->en_nic_cfg.enc_mcdi_max_payload_length;
860 max_data_size = payload_len - MC_CMD_NVRAM_WRITE_IN_LEN(0);
861 EFSYS_ASSERT3U(payload_len, >, 0);
862 EFSYS_ASSERT3U(max_data_size, <, payload_len);
864 if (size > max_data_size) {
869 EFSYS_KMEM_ALLOC(enp->en_esip, payload_len, payload);
870 if (payload == NULL) {
875 (void) memset(payload, 0, payload_len);
876 req.emr_cmd = MC_CMD_NVRAM_WRITE;
877 req.emr_in_buf = payload;
878 req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
879 req.emr_out_buf = payload;
880 req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
882 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
883 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
884 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
886 memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
889 efx_mcdi_execute(enp, &req);
891 if (req.emr_rc != 0) {
896 EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload);
902 EFSYS_KMEM_FREE(enp->en_esip, payload_len, payload);
906 EFSYS_PROBE1(fail1, efx_rc_t, rc);
913 * MC_CMD_NVRAM_UPDATE_FINISH_V2 must be used to support firmware-verified
914 * NVRAM updates. Older firmware will ignore the flags field in the request.
916 __checkReturn efx_rc_t
917 efx_mcdi_nvram_update_finish(
920 __in boolean_t reboot,
921 __out_opt uint32_t *resultp)
923 const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
925 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN,
926 MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN);
927 uint32_t result = 0; /* FIXME: use MC_CMD_NVRAM_VERIFY_RC_UNKNOWN */
930 req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
931 req.emr_in_buf = payload;
932 req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN;
933 req.emr_out_buf = payload;
934 req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN;
936 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_TYPE, partn);
937 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_REBOOT, reboot);
939 MCDI_IN_POPULATE_DWORD_1(req, NVRAM_UPDATE_FINISH_V2_IN_FLAGS,
940 NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT, 1);
942 efx_mcdi_execute(enp, &req);
944 if (req.emr_rc != 0) {
949 if (encp->enc_fw_verified_nvram_update_required == B_FALSE) {
950 /* Report success if verified updates are not supported. */
951 result = MC_CMD_NVRAM_VERIFY_RC_SUCCESS;
953 /* Firmware-verified NVRAM updates are required */
954 if (req.emr_out_length_used <
955 MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN) {
960 MCDI_OUT_DWORD(req, NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE);
962 if (result != MC_CMD_NVRAM_VERIFY_RC_SUCCESS) {
963 /* Mandatory verification failed */
979 EFSYS_PROBE1(fail1, efx_rc_t, rc);
981 /* Always report verification result */
990 __checkReturn efx_rc_t
996 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_TEST_IN_LEN,
997 MC_CMD_NVRAM_TEST_OUT_LEN);
1001 req.emr_cmd = MC_CMD_NVRAM_TEST;
1002 req.emr_in_buf = payload;
1003 req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
1004 req.emr_out_buf = payload;
1005 req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
1007 MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
1009 efx_mcdi_execute(enp, &req);
1011 if (req.emr_rc != 0) {
1016 if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
1021 result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
1022 if (result == MC_CMD_NVRAM_TEST_FAIL) {
1024 EFSYS_PROBE1(nvram_test_failure, int, partn);
1037 EFSYS_PROBE1(fail1, efx_rc_t, rc);
1042 #endif /* EFSYS_OPT_DIAG */
1045 #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */