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 const efx_nvram_ops_t __efx_nvram_siena_ops = {
43 siena_nvram_test, /* envo_test */
44 #endif /* EFSYS_OPT_DIAG */
45 siena_nvram_type_to_partn, /* envo_type_to_partn */
46 siena_nvram_partn_size, /* envo_partn_size */
47 siena_nvram_partn_rw_start, /* envo_partn_rw_start */
48 siena_nvram_partn_read, /* envo_partn_read */
49 siena_nvram_partn_erase, /* envo_partn_erase */
50 siena_nvram_partn_write, /* envo_partn_write */
51 siena_nvram_partn_rw_finish, /* envo_partn_rw_finish */
52 siena_nvram_partn_get_version, /* envo_partn_get_version */
53 siena_nvram_partn_set_version, /* envo_partn_set_version */
54 NULL, /* envo_partn_validate */
57 #endif /* EFSYS_OPT_SIENA */
59 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
61 static const efx_nvram_ops_t __efx_nvram_ef10_ops = {
63 ef10_nvram_test, /* envo_test */
64 #endif /* EFSYS_OPT_DIAG */
65 ef10_nvram_type_to_partn, /* envo_type_to_partn */
66 ef10_nvram_partn_size, /* envo_partn_size */
67 ef10_nvram_partn_rw_start, /* envo_partn_rw_start */
68 ef10_nvram_partn_read, /* envo_partn_read */
69 ef10_nvram_partn_erase, /* envo_partn_erase */
70 ef10_nvram_partn_write, /* envo_partn_write */
71 ef10_nvram_partn_rw_finish, /* envo_partn_rw_finish */
72 ef10_nvram_partn_get_version, /* envo_partn_get_version */
73 ef10_nvram_partn_set_version, /* envo_partn_set_version */
74 ef10_nvram_buffer_validate, /* envo_buffer_validate */
77 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
79 __checkReturn efx_rc_t
83 const efx_nvram_ops_t *envop;
86 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
87 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
88 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NVRAM));
90 switch (enp->en_family) {
92 case EFX_FAMILY_SIENA:
93 envop = &__efx_nvram_siena_ops;
95 #endif /* EFSYS_OPT_SIENA */
97 #if EFSYS_OPT_HUNTINGTON
98 case EFX_FAMILY_HUNTINGTON:
99 envop = &__efx_nvram_ef10_ops;
101 #endif /* EFSYS_OPT_HUNTINGTON */
103 #if EFSYS_OPT_MEDFORD
104 case EFX_FAMILY_MEDFORD:
105 envop = &__efx_nvram_ef10_ops;
107 #endif /* EFSYS_OPT_MEDFORD */
115 enp->en_envop = envop;
116 enp->en_mod_flags |= EFX_MOD_NVRAM;
121 EFSYS_PROBE1(fail1, efx_rc_t, rc);
128 __checkReturn efx_rc_t
132 const efx_nvram_ops_t *envop = enp->en_envop;
135 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
136 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
138 if ((rc = envop->envo_test(enp)) != 0)
144 EFSYS_PROBE1(fail1, efx_rc_t, rc);
149 #endif /* EFSYS_OPT_DIAG */
151 __checkReturn efx_rc_t
154 __in efx_nvram_type_t type,
157 const 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 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
166 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
169 if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0)
177 EFSYS_PROBE1(fail1, efx_rc_t, rc);
183 __checkReturn efx_rc_t
184 efx_nvram_get_version(
186 __in efx_nvram_type_t type,
187 __out uint32_t *subtypep,
188 __out_ecount(4) uint16_t version[4])
190 const efx_nvram_ops_t *envop = enp->en_envop;
194 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
195 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
196 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
198 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
200 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
203 if ((rc = envop->envo_partn_get_version(enp, partn,
204 subtypep, version)) != 0)
212 EFSYS_PROBE1(fail1, efx_rc_t, rc);
217 __checkReturn efx_rc_t
220 __in efx_nvram_type_t type,
221 __out_opt size_t *chunk_sizep)
223 const efx_nvram_ops_t *envop = enp->en_envop;
227 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
228 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
230 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
231 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
233 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
235 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
238 if ((rc = envop->envo_partn_rw_start(enp, partn, chunk_sizep)) != 0)
241 enp->en_nvram_locked = type;
248 EFSYS_PROBE1(fail1, efx_rc_t, rc);
253 __checkReturn efx_rc_t
254 efx_nvram_read_chunk(
256 __in efx_nvram_type_t type,
257 __in unsigned int offset,
258 __out_bcount(size) caddr_t data,
261 const efx_nvram_ops_t *envop = enp->en_envop;
265 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
266 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
268 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
269 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
271 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
273 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
276 if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
284 EFSYS_PROBE1(fail1, efx_rc_t, rc);
289 __checkReturn efx_rc_t
292 __in efx_nvram_type_t type)
294 const efx_nvram_ops_t *envop = enp->en_envop;
295 unsigned int offset = 0;
300 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
301 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
303 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
304 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
306 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
308 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
311 if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0)
314 if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0)
324 EFSYS_PROBE1(fail1, efx_rc_t, rc);
329 __checkReturn efx_rc_t
330 efx_nvram_write_chunk(
332 __in efx_nvram_type_t type,
333 __in unsigned int offset,
334 __in_bcount(size) caddr_t data,
337 const efx_nvram_ops_t *envop = enp->en_envop;
341 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
342 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
344 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
345 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
347 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
349 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
352 if ((rc = envop->envo_partn_write(enp, partn, offset, data, size)) != 0)
360 EFSYS_PROBE1(fail1, efx_rc_t, rc);
368 __in efx_nvram_type_t type)
370 const efx_nvram_ops_t *envop = enp->en_envop;
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 (envop->envo_type_to_partn(enp, type, &partn) == 0)
382 envop->envo_partn_rw_finish(enp, partn);
384 enp->en_nvram_locked = EFX_NVRAM_INVALID;
387 __checkReturn efx_rc_t
388 efx_nvram_set_version(
390 __in efx_nvram_type_t type,
391 __in_ecount(4) uint16_t version[4])
393 const efx_nvram_ops_t *envop = enp->en_envop;
397 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
398 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
399 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
401 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
404 * The Siena implementation of envo_set_version() will attempt to
405 * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector.
406 * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
408 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
410 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
413 if ((rc = envop->envo_partn_set_version(enp, partn, version)) != 0)
421 EFSYS_PROBE1(fail1, efx_rc_t, rc);
426 /* Validate buffer contents (before writing to flash) */
427 __checkReturn efx_rc_t
430 __in efx_nvram_type_t type,
431 __in_bcount(partn_size) caddr_t partn_data,
432 __in size_t partn_size)
434 const efx_nvram_ops_t *envop = enp->en_envop;
438 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
439 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
440 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
442 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
445 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
448 if (envop->envo_type_to_partn != NULL &&
449 ((rc = envop->envo_buffer_validate(enp, partn,
450 partn_data, partn_size)) != 0))
458 EFSYS_PROBE1(fail1, efx_rc_t, rc);
468 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
469 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
470 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
472 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
474 enp->en_envop = NULL;
475 enp->en_mod_flags &= ~EFX_MOD_NVRAM;
478 #endif /* EFSYS_OPT_NVRAM */
480 #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
483 * Internal MCDI request handling
486 __checkReturn efx_rc_t
487 efx_mcdi_nvram_partitions(
489 __out_bcount(size) caddr_t data,
491 __out unsigned int *npartnp)
494 uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
495 MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
499 (void) memset(payload, 0, sizeof (payload));
500 req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
501 req.emr_in_buf = payload;
502 req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
503 req.emr_out_buf = payload;
504 req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
506 efx_mcdi_execute(enp, &req);
508 if (req.emr_rc != 0) {
513 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
517 npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
519 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
524 if (size < npartn * sizeof (uint32_t)) {
532 MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
533 (npartn * sizeof (uint32_t)));
542 EFSYS_PROBE1(fail1, efx_rc_t, rc);
547 __checkReturn efx_rc_t
548 efx_mcdi_nvram_metadata(
551 __out uint32_t *subtypep,
552 __out_ecount(4) uint16_t version[4],
553 __out_bcount_opt(size) char *descp,
557 uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
558 MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
561 (void) memset(payload, 0, sizeof (payload));
562 req.emr_cmd = MC_CMD_NVRAM_METADATA;
563 req.emr_in_buf = payload;
564 req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
565 req.emr_out_buf = payload;
566 req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
568 MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
570 efx_mcdi_execute(enp, &req);
572 if (req.emr_rc != 0) {
577 if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
582 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
583 NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
584 *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
589 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
590 NVRAM_METADATA_OUT_VERSION_VALID)) {
591 version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
592 version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
593 version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
594 version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
596 version[0] = version[1] = version[2] = version[3] = 0;
599 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
600 NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
601 /* Return optional descrition string */
602 if ((descp != NULL) && (size > 0)) {
606 desclen = (req.emr_out_length_used
607 - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
609 EFSYS_ASSERT3U(desclen, <=,
610 MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
612 if (size < desclen) {
617 memcpy(descp, MCDI_OUT2(req, char,
618 NVRAM_METADATA_OUT_DESCRIPTION),
621 /* Ensure string is NUL terminated */
622 descp[desclen] = '\0';
633 EFSYS_PROBE1(fail1, efx_rc_t, rc);
638 __checkReturn efx_rc_t
642 __out_opt size_t *sizep,
643 __out_opt uint32_t *addressp,
644 __out_opt uint32_t *erase_sizep,
645 __out_opt uint32_t *write_sizep)
647 uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
648 MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
652 (void) memset(payload, 0, sizeof (payload));
653 req.emr_cmd = MC_CMD_NVRAM_INFO;
654 req.emr_in_buf = payload;
655 req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
656 req.emr_out_buf = payload;
657 req.emr_out_length = MC_CMD_NVRAM_INFO_V2_OUT_LEN;
659 MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
661 efx_mcdi_execute_quiet(enp, &req);
663 if (req.emr_rc != 0) {
668 if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
674 *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
677 *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
680 *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
684 (req.emr_out_length_used <
685 MC_CMD_NVRAM_INFO_V2_OUT_LEN) ?
686 0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE);
694 EFSYS_PROBE1(fail1, efx_rc_t, rc);
699 __checkReturn efx_rc_t
700 efx_mcdi_nvram_update_start(
704 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_IN_LEN,
705 MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
709 (void) memset(payload, 0, sizeof (payload));
710 req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
711 req.emr_in_buf = payload;
712 req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
713 req.emr_out_buf = payload;
714 req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
716 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
718 efx_mcdi_execute(enp, &req);
720 if (req.emr_rc != 0) {
728 EFSYS_PROBE1(fail1, efx_rc_t, rc);
733 __checkReturn efx_rc_t
737 __in uint32_t offset,
738 __out_bcount(size) caddr_t data,
743 uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
744 MC_CMD_NVRAM_READ_OUT_LENMAX)];
747 if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
752 (void) memset(payload, 0, sizeof (payload));
753 req.emr_cmd = MC_CMD_NVRAM_READ;
754 req.emr_in_buf = payload;
755 req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
756 req.emr_out_buf = payload;
757 req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
759 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_TYPE, partn);
760 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_OFFSET, offset);
761 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_LENGTH, size);
762 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_MODE, mode);
764 efx_mcdi_execute(enp, &req);
766 if (req.emr_rc != 0) {
771 if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
777 MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
785 EFSYS_PROBE1(fail1, efx_rc_t, rc);
790 __checkReturn efx_rc_t
791 efx_mcdi_nvram_erase(
794 __in uint32_t offset,
798 uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
799 MC_CMD_NVRAM_ERASE_OUT_LEN)];
802 (void) memset(payload, 0, sizeof (payload));
803 req.emr_cmd = MC_CMD_NVRAM_ERASE;
804 req.emr_in_buf = payload;
805 req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
806 req.emr_out_buf = payload;
807 req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
809 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
810 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
811 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
813 efx_mcdi_execute(enp, &req);
815 if (req.emr_rc != 0) {
823 EFSYS_PROBE1(fail1, efx_rc_t, rc);
829 * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
830 * Sienna and EF10 based boards. However EF10 based boards support the use
831 * of this command with payloads up to the maximum MCDI V2 payload length.
833 __checkReturn efx_rc_t
834 efx_mcdi_nvram_write(
837 __in uint32_t offset,
838 __out_bcount(size) caddr_t data,
842 uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
843 MCDI_CTL_SDU_LEN_MAX_V2)];
845 size_t max_data_size;
847 max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
848 - MC_CMD_NVRAM_WRITE_IN_LEN(0);
849 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
850 EFSYS_ASSERT3U(max_data_size, <,
851 enp->en_nic_cfg.enc_mcdi_max_payload_length);
853 if (size > max_data_size) {
858 (void) memset(payload, 0, sizeof (payload));
859 req.emr_cmd = MC_CMD_NVRAM_WRITE;
860 req.emr_in_buf = payload;
861 req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
862 req.emr_out_buf = payload;
863 req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
865 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
866 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
867 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
869 memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
872 efx_mcdi_execute(enp, &req);
874 if (req.emr_rc != 0) {
884 EFSYS_PROBE1(fail1, efx_rc_t, rc);
889 __checkReturn efx_rc_t
890 efx_mcdi_nvram_update_finish(
893 __in boolean_t reboot)
896 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN,
897 MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN)];
900 (void) memset(payload, 0, sizeof (payload));
901 req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
902 req.emr_in_buf = payload;
903 req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
904 req.emr_out_buf = payload;
905 req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN;
907 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
908 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
910 efx_mcdi_execute(enp, &req);
912 if (req.emr_rc != 0) {
920 EFSYS_PROBE1(fail1, efx_rc_t, rc);
927 __checkReturn efx_rc_t
933 uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
934 MC_CMD_NVRAM_TEST_OUT_LEN)];
938 (void) memset(payload, 0, sizeof (payload));
939 req.emr_cmd = MC_CMD_NVRAM_TEST;
940 req.emr_in_buf = payload;
941 req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
942 req.emr_out_buf = payload;
943 req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
945 MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
947 efx_mcdi_execute(enp, &req);
949 if (req.emr_rc != 0) {
954 if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
959 result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
960 if (result == MC_CMD_NVRAM_TEST_FAIL) {
962 EFSYS_PROBE1(nvram_test_failure, int, partn);
975 EFSYS_PROBE1(fail1, efx_rc_t, rc);
980 #endif /* EFSYS_OPT_DIAG */
983 #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */