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 */
56 #endif /* EFSYS_OPT_FALCON */
60 static efx_nvram_ops_t __efx_nvram_siena_ops = {
62 siena_nvram_test, /* envo_test */
63 #endif /* EFSYS_OPT_DIAG */
64 siena_nvram_type_to_partn, /* envo_type_to_partn */
65 siena_nvram_partn_size, /* envo_partn_size */
66 siena_nvram_partn_rw_start, /* envo_partn_rw_start */
67 siena_nvram_partn_read, /* envo_partn_read */
68 siena_nvram_partn_erase, /* envo_partn_erase */
69 siena_nvram_partn_write, /* envo_partn_write */
70 siena_nvram_partn_rw_finish, /* envo_partn_rw_finish */
71 siena_nvram_partn_get_version, /* envo_partn_get_version */
72 siena_nvram_partn_set_version, /* envo_partn_set_version */
75 #endif /* EFSYS_OPT_SIENA */
77 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
79 static efx_nvram_ops_t __efx_nvram_ef10_ops = {
81 ef10_nvram_test, /* envo_test */
82 #endif /* EFSYS_OPT_DIAG */
83 ef10_nvram_type_to_partn, /* envo_type_to_partn */
84 ef10_nvram_partn_size, /* envo_partn_size */
85 ef10_nvram_partn_rw_start, /* envo_partn_rw_start */
86 ef10_nvram_partn_read, /* envo_partn_read */
87 ef10_nvram_partn_erase, /* envo_partn_erase */
88 ef10_nvram_partn_write, /* envo_partn_write */
89 ef10_nvram_partn_rw_finish, /* envo_partn_rw_finish */
90 ef10_nvram_partn_get_version, /* envo_partn_get_version */
91 ef10_nvram_partn_set_version, /* envo_partn_set_version */
94 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
96 __checkReturn efx_rc_t
100 efx_nvram_ops_t *envop;
103 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
104 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
105 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NVRAM));
107 switch (enp->en_family) {
109 case EFX_FAMILY_FALCON:
110 envop = (efx_nvram_ops_t *)&__efx_nvram_falcon_ops;
112 #endif /* EFSYS_OPT_FALCON */
115 case EFX_FAMILY_SIENA:
116 envop = (efx_nvram_ops_t *)&__efx_nvram_siena_ops;
118 #endif /* EFSYS_OPT_SIENA */
120 #if EFSYS_OPT_HUNTINGTON
121 case EFX_FAMILY_HUNTINGTON:
122 envop = (efx_nvram_ops_t *)&__efx_nvram_ef10_ops;
124 #endif /* EFSYS_OPT_HUNTINGTON */
126 #if EFSYS_OPT_MEDFORD
127 case EFX_FAMILY_MEDFORD:
128 envop = (efx_nvram_ops_t *)&__efx_nvram_ef10_ops;
130 #endif /* EFSYS_OPT_MEDFORD */
138 enp->en_envop = envop;
139 enp->en_mod_flags |= EFX_MOD_NVRAM;
144 EFSYS_PROBE1(fail1, efx_rc_t, rc);
151 __checkReturn efx_rc_t
155 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 if ((rc = envop->envo_test(enp)) != 0)
167 EFSYS_PROBE1(fail1, efx_rc_t, rc);
172 #endif /* EFSYS_OPT_DIAG */
174 __checkReturn efx_rc_t
177 __in efx_nvram_type_t type,
180 efx_nvram_ops_t *envop = enp->en_envop;
184 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
185 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
187 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
189 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
192 if ((rc = envop->envo_partn_size(enp, partn, sizep)) != 0)
200 EFSYS_PROBE1(fail1, efx_rc_t, rc);
206 __checkReturn efx_rc_t
207 efx_nvram_get_version(
209 __in efx_nvram_type_t type,
210 __out uint32_t *subtypep,
211 __out_ecount(4) uint16_t version[4])
213 efx_nvram_ops_t *envop = enp->en_envop;
217 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
218 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
219 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
221 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
223 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
226 if ((rc = envop->envo_partn_get_version(enp, partn,
227 subtypep, version)) != 0)
235 EFSYS_PROBE1(fail1, efx_rc_t, rc);
240 __checkReturn efx_rc_t
243 __in efx_nvram_type_t type,
244 __out_opt size_t *chunk_sizep)
246 efx_nvram_ops_t *envop = enp->en_envop;
250 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
251 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
253 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
254 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
256 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
258 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
261 if ((rc = envop->envo_partn_rw_start(enp, partn, chunk_sizep)) != 0)
264 enp->en_nvram_locked = type;
271 EFSYS_PROBE1(fail1, efx_rc_t, rc);
276 __checkReturn efx_rc_t
277 efx_nvram_read_chunk(
279 __in efx_nvram_type_t type,
280 __in unsigned int offset,
281 __out_bcount(size) caddr_t data,
284 efx_nvram_ops_t *envop = enp->en_envop;
288 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
289 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
291 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
292 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
294 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
296 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
299 if ((rc = envop->envo_partn_read(enp, partn, offset, data, size)) != 0)
307 EFSYS_PROBE1(fail1, efx_rc_t, rc);
312 __checkReturn efx_rc_t
315 __in efx_nvram_type_t type)
317 efx_nvram_ops_t *envop = enp->en_envop;
318 unsigned int offset = 0;
323 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
324 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
326 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
327 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
329 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
331 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
334 if ((rc = envop->envo_partn_size(enp, partn, &size)) != 0)
337 if ((rc = envop->envo_partn_erase(enp, partn, offset, size)) != 0)
347 EFSYS_PROBE1(fail1, efx_rc_t, rc);
352 __checkReturn efx_rc_t
353 efx_nvram_write_chunk(
355 __in efx_nvram_type_t type,
356 __in unsigned int offset,
357 __in_bcount(size) caddr_t data,
360 efx_nvram_ops_t *envop = enp->en_envop;
364 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
365 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
367 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
368 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
370 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
372 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
375 if ((rc = envop->envo_partn_write(enp, partn, offset, data, size)) != 0)
383 EFSYS_PROBE1(fail1, efx_rc_t, rc);
391 __in efx_nvram_type_t type)
393 efx_nvram_ops_t *envop = enp->en_envop;
396 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
397 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
399 EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
400 EFSYS_ASSERT3U(type, !=, EFX_NVRAM_INVALID);
402 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, type);
404 if (envop->envo_type_to_partn(enp, type, &partn) == 0)
405 envop->envo_partn_rw_finish(enp, partn);
407 enp->en_nvram_locked = EFX_NVRAM_INVALID;
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 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);
427 * The Siena implementation of envo_set_version() will attempt to
428 * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG sector.
429 * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
431 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
433 if ((rc = envop->envo_type_to_partn(enp, type, &partn)) != 0)
436 if ((rc = envop->envo_partn_set_version(enp, partn, version)) != 0)
444 EFSYS_PROBE1(fail1, efx_rc_t, rc);
453 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
454 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
455 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NVRAM);
457 EFSYS_ASSERT3U(enp->en_nvram_locked, ==, EFX_NVRAM_INVALID);
459 enp->en_envop = NULL;
460 enp->en_mod_flags &= ~EFX_MOD_NVRAM;
463 #endif /* EFSYS_OPT_NVRAM */
465 #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
468 * Internal MCDI request handling
471 __checkReturn efx_rc_t
472 efx_mcdi_nvram_partitions(
474 __out_bcount(size) caddr_t data,
476 __out unsigned int *npartnp)
479 uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
480 MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
484 (void) memset(payload, 0, sizeof (payload));
485 req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
486 req.emr_in_buf = payload;
487 req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
488 req.emr_out_buf = payload;
489 req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
491 efx_mcdi_execute(enp, &req);
493 if (req.emr_rc != 0) {
498 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
502 npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
504 if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
509 if (size < npartn * sizeof (uint32_t)) {
517 MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
518 (npartn * sizeof (uint32_t)));
527 EFSYS_PROBE1(fail1, efx_rc_t, rc);
532 __checkReturn efx_rc_t
533 efx_mcdi_nvram_metadata(
536 __out uint32_t *subtypep,
537 __out_ecount(4) uint16_t version[4],
538 __out_bcount_opt(size) char *descp,
542 uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
543 MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
546 (void) memset(payload, 0, sizeof (payload));
547 req.emr_cmd = MC_CMD_NVRAM_METADATA;
548 req.emr_in_buf = payload;
549 req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
550 req.emr_out_buf = payload;
551 req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
553 MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
555 efx_mcdi_execute(enp, &req);
557 if (req.emr_rc != 0) {
562 if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
567 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
568 NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
569 *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
574 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
575 NVRAM_METADATA_OUT_VERSION_VALID)) {
576 version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
577 version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
578 version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
579 version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
581 version[0] = version[1] = version[2] = version[3] = 0;
584 if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
585 NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
586 /* Return optional descrition string */
587 if ((descp != NULL) && (size > 0)) {
591 desclen = (req.emr_out_length_used
592 - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
594 EFSYS_ASSERT3U(desclen, <=,
595 MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
597 if (size < desclen) {
602 memcpy(descp, MCDI_OUT2(req, char,
603 NVRAM_METADATA_OUT_DESCRIPTION),
606 /* Ensure string is NUL terminated */
607 descp[desclen] = '\0';
618 EFSYS_PROBE1(fail1, efx_rc_t, rc);
623 __checkReturn efx_rc_t
627 __out_opt size_t *sizep,
628 __out_opt uint32_t *addressp,
629 __out_opt uint32_t *erase_sizep,
630 __out_opt uint32_t *write_sizep)
632 uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
633 MC_CMD_NVRAM_INFO_V2_OUT_LEN)];
637 (void) memset(payload, 0, sizeof (payload));
638 req.emr_cmd = MC_CMD_NVRAM_INFO;
639 req.emr_in_buf = payload;
640 req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
641 req.emr_out_buf = payload;
642 req.emr_out_length = MC_CMD_NVRAM_INFO_V2_OUT_LEN;
644 MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
646 efx_mcdi_execute_quiet(enp, &req);
648 if (req.emr_rc != 0) {
653 if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
659 *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
662 *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
665 *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
669 (req.emr_out_length_used <
670 MC_CMD_NVRAM_INFO_V2_OUT_LEN) ?
671 0 : MCDI_OUT_DWORD(req, NVRAM_INFO_V2_OUT_WRITESIZE);
679 EFSYS_PROBE1(fail1, efx_rc_t, rc);
684 __checkReturn efx_rc_t
685 efx_mcdi_nvram_update_start(
689 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_IN_LEN,
690 MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
694 (void) memset(payload, 0, sizeof (payload));
695 req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
696 req.emr_in_buf = payload;
697 req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
698 req.emr_out_buf = payload;
699 req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
701 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
703 efx_mcdi_execute(enp, &req);
705 if (req.emr_rc != 0) {
713 EFSYS_PROBE1(fail1, efx_rc_t, rc);
718 __checkReturn efx_rc_t
722 __in uint32_t offset,
723 __out_bcount(size) caddr_t data,
728 uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN,
729 MC_CMD_NVRAM_READ_OUT_LENMAX)];
732 if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
737 (void) memset(payload, 0, sizeof (payload));
738 req.emr_cmd = MC_CMD_NVRAM_READ;
739 req.emr_in_buf = payload;
740 req.emr_in_length = MC_CMD_NVRAM_READ_IN_V2_LEN;
741 req.emr_out_buf = payload;
742 req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
744 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_TYPE, partn);
745 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_OFFSET, offset);
746 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_LENGTH, size);
747 MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_V2_MODE, mode);
749 efx_mcdi_execute(enp, &req);
751 if (req.emr_rc != 0) {
756 if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
762 MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
770 EFSYS_PROBE1(fail1, efx_rc_t, rc);
775 __checkReturn efx_rc_t
776 efx_mcdi_nvram_erase(
779 __in uint32_t offset,
783 uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
784 MC_CMD_NVRAM_ERASE_OUT_LEN)];
787 (void) memset(payload, 0, sizeof (payload));
788 req.emr_cmd = MC_CMD_NVRAM_ERASE;
789 req.emr_in_buf = payload;
790 req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
791 req.emr_out_buf = payload;
792 req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
794 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
795 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
796 MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
798 efx_mcdi_execute(enp, &req);
800 if (req.emr_rc != 0) {
808 EFSYS_PROBE1(fail1, efx_rc_t, rc);
814 * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
815 * Sienna and EF10 based boards. However EF10 based boards support the use
816 * of this command with payloads up to the maximum MCDI V2 payload length.
818 __checkReturn efx_rc_t
819 efx_mcdi_nvram_write(
822 __in uint32_t offset,
823 __out_bcount(size) caddr_t data,
827 uint8_t payload[MAX(MCDI_CTL_SDU_LEN_MAX_V1,
828 MCDI_CTL_SDU_LEN_MAX_V2)];
830 size_t max_data_size;
832 max_data_size = enp->en_nic_cfg.enc_mcdi_max_payload_length
833 - MC_CMD_NVRAM_WRITE_IN_LEN(0);
834 EFSYS_ASSERT3U(enp->en_nic_cfg.enc_mcdi_max_payload_length, >, 0);
835 EFSYS_ASSERT3U(max_data_size, <,
836 enp->en_nic_cfg.enc_mcdi_max_payload_length);
838 if (size > max_data_size) {
843 (void) memset(payload, 0, sizeof (payload));
844 req.emr_cmd = MC_CMD_NVRAM_WRITE;
845 req.emr_in_buf = payload;
846 req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
847 req.emr_out_buf = payload;
848 req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
850 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
851 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
852 MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
854 memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
857 efx_mcdi_execute(enp, &req);
859 if (req.emr_rc != 0) {
869 EFSYS_PROBE1(fail1, efx_rc_t, rc);
874 __checkReturn efx_rc_t
875 efx_mcdi_nvram_update_finish(
878 __in boolean_t reboot)
881 uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN,
882 MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN)];
885 (void) memset(payload, 0, sizeof (payload));
886 req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
887 req.emr_in_buf = payload;
888 req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
889 req.emr_out_buf = payload;
890 req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN;
892 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
893 MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
895 efx_mcdi_execute(enp, &req);
897 if (req.emr_rc != 0) {
905 EFSYS_PROBE1(fail1, efx_rc_t, rc);
912 __checkReturn efx_rc_t
918 uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
919 MC_CMD_NVRAM_TEST_OUT_LEN)];
923 (void) memset(payload, 0, sizeof (payload));
924 req.emr_cmd = MC_CMD_NVRAM_TEST;
925 req.emr_in_buf = payload;
926 req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
927 req.emr_out_buf = payload;
928 req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
930 MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
932 efx_mcdi_execute(enp, &req);
934 if (req.emr_rc != 0) {
939 if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
944 result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
945 if (result == MC_CMD_NVRAM_TEST_FAIL) {
947 EFSYS_PROBE1(nvram_test_failure, int, partn);
960 EFSYS_PROBE1(fail1, efx_rc_t, rc);
965 #endif /* EFSYS_OPT_DIAG */
968 #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */