1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2009-2018 Solarflare Communications Inc.
14 static const efx_nvram_ops_t __efx_nvram_siena_ops
= {
16 siena_nvram_test
, /* envo_test */
17 #endif /* EFSYS_OPT_DIAG */
18 siena_nvram_type_to_partn
, /* envo_type_to_partn */
19 siena_nvram_partn_size
, /* envo_partn_size */
20 siena_nvram_partn_rw_start
, /* envo_partn_rw_start */
21 siena_nvram_partn_read
, /* envo_partn_read */
22 siena_nvram_partn_read
, /* envo_partn_read_backup */
23 siena_nvram_partn_erase
, /* envo_partn_erase */
24 siena_nvram_partn_write
, /* envo_partn_write */
25 siena_nvram_partn_rw_finish
, /* envo_partn_rw_finish */
26 siena_nvram_partn_get_version
, /* envo_partn_get_version */
27 siena_nvram_partn_set_version
, /* envo_partn_set_version */
28 NULL
, /* envo_partn_validate */
31 #endif /* EFSYS_OPT_SIENA */
33 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
35 static const efx_nvram_ops_t __efx_nvram_ef10_ops
= {
37 ef10_nvram_test
, /* envo_test */
38 #endif /* EFSYS_OPT_DIAG */
39 ef10_nvram_type_to_partn
, /* envo_type_to_partn */
40 ef10_nvram_partn_size
, /* envo_partn_size */
41 ef10_nvram_partn_rw_start
, /* envo_partn_rw_start */
42 ef10_nvram_partn_read
, /* envo_partn_read */
43 ef10_nvram_partn_read_backup
, /* envo_partn_read_backup */
44 ef10_nvram_partn_erase
, /* envo_partn_erase */
45 ef10_nvram_partn_write
, /* envo_partn_write */
46 ef10_nvram_partn_rw_finish
, /* envo_partn_rw_finish */
47 ef10_nvram_partn_get_version
, /* envo_partn_get_version */
48 ef10_nvram_partn_set_version
, /* envo_partn_set_version */
49 ef10_nvram_buffer_validate
, /* envo_buffer_validate */
52 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
54 __checkReturn efx_rc_t
58 const efx_nvram_ops_t
*envop
;
61 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
62 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PROBE
);
63 EFSYS_ASSERT(!(enp
->en_mod_flags
& EFX_MOD_NVRAM
));
65 switch (enp
->en_family
) {
67 case EFX_FAMILY_SIENA
:
68 envop
= &__efx_nvram_siena_ops
;
70 #endif /* EFSYS_OPT_SIENA */
72 #if EFSYS_OPT_HUNTINGTON
73 case EFX_FAMILY_HUNTINGTON
:
74 envop
= &__efx_nvram_ef10_ops
;
76 #endif /* EFSYS_OPT_HUNTINGTON */
79 case EFX_FAMILY_MEDFORD
:
80 envop
= &__efx_nvram_ef10_ops
;
82 #endif /* EFSYS_OPT_MEDFORD */
84 #if EFSYS_OPT_MEDFORD2
85 case EFX_FAMILY_MEDFORD2
:
86 envop
= &__efx_nvram_ef10_ops
;
88 #endif /* EFSYS_OPT_MEDFORD2 */
96 enp
->en_envop
= envop
;
97 enp
->en_mod_flags
|= EFX_MOD_NVRAM
;
99 enp
->en_nvram_partn_locked
= EFX_NVRAM_PARTN_INVALID
;
104 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
111 __checkReturn efx_rc_t
115 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
118 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
119 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
121 if ((rc
= envop
->envo_test(enp
)) != 0)
127 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
132 #endif /* EFSYS_OPT_DIAG */
134 __checkReturn efx_rc_t
137 __in efx_nvram_type_t type
,
140 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
144 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
145 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
147 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
150 if ((rc
= envop
->envo_partn_size(enp
, partn
, sizep
)) != 0)
158 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
164 __checkReturn efx_rc_t
165 efx_nvram_get_version(
167 __in efx_nvram_type_t type
,
168 __out
uint32_t *subtypep
,
169 __out_ecount(4) uint16_t version
[4])
171 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
175 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
176 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PROBE
);
177 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
179 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
182 if ((rc
= envop
->envo_partn_get_version(enp
, partn
,
183 subtypep
, version
)) != 0)
191 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
196 __checkReturn efx_rc_t
199 __in efx_nvram_type_t type
,
200 __out_opt
size_t *chunk_sizep
)
202 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
206 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
207 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
209 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
212 EFSYS_ASSERT3U(enp
->en_nvram_partn_locked
, ==, EFX_NVRAM_PARTN_INVALID
);
214 if ((rc
= envop
->envo_partn_rw_start(enp
, partn
, chunk_sizep
)) != 0)
217 enp
->en_nvram_partn_locked
= partn
;
224 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
229 __checkReturn efx_rc_t
230 efx_nvram_read_chunk(
232 __in efx_nvram_type_t type
,
233 __in
unsigned int offset
,
234 __out_bcount(size
) caddr_t data
,
237 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
241 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
242 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
244 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
247 EFSYS_ASSERT3U(enp
->en_nvram_partn_locked
, ==, partn
);
249 if ((rc
= envop
->envo_partn_read(enp
, partn
, offset
, data
, size
)) != 0)
257 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
263 * Read from the backup (writeable) store of an A/B partition.
264 * For non A/B partitions, there is only a single store, and so this
265 * function has the same behaviour as efx_nvram_read_chunk().
267 __checkReturn efx_rc_t
268 efx_nvram_read_backup(
270 __in efx_nvram_type_t type
,
271 __in
unsigned int offset
,
272 __out_bcount(size
) caddr_t data
,
275 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
279 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
280 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
282 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
285 EFSYS_ASSERT3U(enp
->en_nvram_partn_locked
, ==, partn
);
287 if ((rc
= envop
->envo_partn_read_backup(enp
, partn
, offset
,
296 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
301 __checkReturn efx_rc_t
304 __in efx_nvram_type_t type
)
306 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
307 unsigned int offset
= 0;
312 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
313 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
315 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
318 EFSYS_ASSERT3U(enp
->en_nvram_partn_locked
, ==, partn
);
320 if ((rc
= envop
->envo_partn_size(enp
, partn
, &size
)) != 0)
323 if ((rc
= envop
->envo_partn_erase(enp
, partn
, offset
, size
)) != 0)
333 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
338 __checkReturn efx_rc_t
339 efx_nvram_write_chunk(
341 __in efx_nvram_type_t type
,
342 __in
unsigned int offset
,
343 __in_bcount(size
) caddr_t data
,
346 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
350 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
351 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
353 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
356 EFSYS_ASSERT3U(enp
->en_nvram_partn_locked
, ==, partn
);
358 if ((rc
= envop
->envo_partn_write(enp
, partn
, offset
, data
, size
)) != 0)
366 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
371 __checkReturn efx_rc_t
374 __in efx_nvram_type_t type
,
375 __out_opt
uint32_t *verify_resultp
)
377 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
379 uint32_t verify_result
= 0;
382 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
383 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
385 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
388 EFSYS_ASSERT3U(enp
->en_nvram_partn_locked
, ==, partn
);
390 if ((rc
= envop
->envo_partn_rw_finish(enp
, partn
, &verify_result
)) != 0)
393 enp
->en_nvram_partn_locked
= EFX_NVRAM_PARTN_INVALID
;
395 if (verify_resultp
!= NULL
)
396 *verify_resultp
= verify_result
;
402 enp
->en_nvram_partn_locked
= EFX_NVRAM_PARTN_INVALID
;
405 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
407 /* Always report verification result */
408 if (verify_resultp
!= NULL
)
409 *verify_resultp
= verify_result
;
414 __checkReturn efx_rc_t
415 efx_nvram_set_version(
417 __in efx_nvram_type_t type
,
418 __in_ecount(4) uint16_t version
[4])
420 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
424 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
425 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PROBE
);
426 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
428 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
432 * The Siena implementation of envo_set_version() will attempt to
433 * acquire the NVRAM_UPDATE lock for the DYNAMIC_CONFIG partition.
434 * Therefore, you can't have already acquired the NVRAM_UPDATE lock.
436 EFSYS_ASSERT3U(enp
->en_nvram_partn_locked
, ==, EFX_NVRAM_PARTN_INVALID
);
438 if ((rc
= envop
->envo_partn_set_version(enp
, partn
, version
)) != 0)
446 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
451 /* Validate buffer contents (before writing to flash) */
452 __checkReturn efx_rc_t
455 __in efx_nvram_type_t type
,
456 __in_bcount(partn_size
) caddr_t partn_data
,
457 __in
size_t partn_size
)
459 const efx_nvram_ops_t
*envop
= enp
->en_envop
;
463 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
464 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PROBE
);
465 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
467 if ((rc
= envop
->envo_type_to_partn(enp
, type
, &partn
)) != 0)
470 if (envop
->envo_buffer_validate
!= NULL
) {
471 if ((rc
= envop
->envo_buffer_validate(enp
, partn
,
472 partn_data
, partn_size
)) != 0)
481 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
491 EFSYS_ASSERT3U(enp
->en_magic
, ==, EFX_NIC_MAGIC
);
492 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_PROBE
);
493 EFSYS_ASSERT3U(enp
->en_mod_flags
, &, EFX_MOD_NVRAM
);
495 EFSYS_ASSERT3U(enp
->en_nvram_partn_locked
, ==, EFX_NVRAM_PARTN_INVALID
);
497 enp
->en_envop
= NULL
;
498 enp
->en_mod_flags
&= ~EFX_MOD_NVRAM
;
501 #endif /* EFSYS_OPT_NVRAM */
503 #if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
506 * Internal MCDI request handling
509 __checkReturn efx_rc_t
510 efx_mcdi_nvram_partitions(
512 __out_bcount(size
) caddr_t data
,
514 __out
unsigned int *npartnp
)
517 uint8_t payload
[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN
,
518 MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX
)];
522 (void) memset(payload
, 0, sizeof (payload
));
523 req
.emr_cmd
= MC_CMD_NVRAM_PARTITIONS
;
524 req
.emr_in_buf
= payload
;
525 req
.emr_in_length
= MC_CMD_NVRAM_PARTITIONS_IN_LEN
;
526 req
.emr_out_buf
= payload
;
527 req
.emr_out_length
= MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX
;
529 efx_mcdi_execute(enp
, &req
);
531 if (req
.emr_rc
!= 0) {
536 if (req
.emr_out_length_used
< MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN
) {
540 npartn
= MCDI_OUT_DWORD(req
, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS
);
542 if (req
.emr_out_length_used
< MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn
)) {
547 if (size
< npartn
* sizeof (uint32_t)) {
555 MCDI_OUT2(req
, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID
),
556 (npartn
* sizeof (uint32_t)));
565 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
570 __checkReturn efx_rc_t
571 efx_mcdi_nvram_metadata(
574 __out
uint32_t *subtypep
,
575 __out_ecount(4) uint16_t version
[4],
576 __out_bcount_opt(size
) char *descp
,
580 uint8_t payload
[MAX(MC_CMD_NVRAM_METADATA_IN_LEN
,
581 MC_CMD_NVRAM_METADATA_OUT_LENMAX
)];
584 (void) memset(payload
, 0, sizeof (payload
));
585 req
.emr_cmd
= MC_CMD_NVRAM_METADATA
;
586 req
.emr_in_buf
= payload
;
587 req
.emr_in_length
= MC_CMD_NVRAM_METADATA_IN_LEN
;
588 req
.emr_out_buf
= payload
;
589 req
.emr_out_length
= MC_CMD_NVRAM_METADATA_OUT_LENMAX
;
591 MCDI_IN_SET_DWORD(req
, NVRAM_METADATA_IN_TYPE
, partn
);
593 efx_mcdi_execute_quiet(enp
, &req
);
595 if (req
.emr_rc
!= 0) {
600 if (req
.emr_out_length_used
< MC_CMD_NVRAM_METADATA_OUT_LENMIN
) {
605 if (MCDI_OUT_DWORD_FIELD(req
, NVRAM_METADATA_OUT_FLAGS
,
606 NVRAM_METADATA_OUT_SUBTYPE_VALID
)) {
607 *subtypep
= MCDI_OUT_DWORD(req
, NVRAM_METADATA_OUT_SUBTYPE
);
612 if (MCDI_OUT_DWORD_FIELD(req
, NVRAM_METADATA_OUT_FLAGS
,
613 NVRAM_METADATA_OUT_VERSION_VALID
)) {
614 version
[0] = MCDI_OUT_WORD(req
, NVRAM_METADATA_OUT_VERSION_W
);
615 version
[1] = MCDI_OUT_WORD(req
, NVRAM_METADATA_OUT_VERSION_X
);
616 version
[2] = MCDI_OUT_WORD(req
, NVRAM_METADATA_OUT_VERSION_Y
);
617 version
[3] = MCDI_OUT_WORD(req
, NVRAM_METADATA_OUT_VERSION_Z
);
619 version
[0] = version
[1] = version
[2] = version
[3] = 0;
622 if (MCDI_OUT_DWORD_FIELD(req
, NVRAM_METADATA_OUT_FLAGS
,
623 NVRAM_METADATA_OUT_DESCRIPTION_VALID
)) {
624 /* Return optional descrition string */
625 if ((descp
!= NULL
) && (size
> 0)) {
629 desclen
= (req
.emr_out_length_used
630 - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
632 EFSYS_ASSERT3U(desclen
, <=,
633 MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM
);
635 if (size
< desclen
) {
640 memcpy(descp
, MCDI_OUT2(req
, char,
641 NVRAM_METADATA_OUT_DESCRIPTION
),
644 /* Ensure string is NUL terminated */
645 descp
[desclen
] = '\0';
656 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
661 __checkReturn efx_rc_t
665 __out_opt
size_t *sizep
,
666 __out_opt
uint32_t *addressp
,
667 __out_opt
uint32_t *erase_sizep
,
668 __out_opt
uint32_t *write_sizep
)
670 uint8_t payload
[MAX(MC_CMD_NVRAM_INFO_IN_LEN
,
671 MC_CMD_NVRAM_INFO_V2_OUT_LEN
)];
675 (void) memset(payload
, 0, sizeof (payload
));
676 req
.emr_cmd
= MC_CMD_NVRAM_INFO
;
677 req
.emr_in_buf
= payload
;
678 req
.emr_in_length
= MC_CMD_NVRAM_INFO_IN_LEN
;
679 req
.emr_out_buf
= payload
;
680 req
.emr_out_length
= MC_CMD_NVRAM_INFO_V2_OUT_LEN
;
682 MCDI_IN_SET_DWORD(req
, NVRAM_INFO_IN_TYPE
, partn
);
684 efx_mcdi_execute_quiet(enp
, &req
);
686 if (req
.emr_rc
!= 0) {
691 if (req
.emr_out_length_used
< MC_CMD_NVRAM_INFO_OUT_LEN
) {
697 *sizep
= MCDI_OUT_DWORD(req
, NVRAM_INFO_OUT_SIZE
);
700 *addressp
= MCDI_OUT_DWORD(req
, NVRAM_INFO_OUT_PHYSADDR
);
703 *erase_sizep
= MCDI_OUT_DWORD(req
, NVRAM_INFO_OUT_ERASESIZE
);
707 (req
.emr_out_length_used
<
708 MC_CMD_NVRAM_INFO_V2_OUT_LEN
) ?
709 0 : MCDI_OUT_DWORD(req
, NVRAM_INFO_V2_OUT_WRITESIZE
);
717 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
723 * MC_CMD_NVRAM_UPDATE_START_V2 must be used to support firmware-verified
724 * NVRAM updates. Older firmware will ignore the flags field in the request.
726 __checkReturn efx_rc_t
727 efx_mcdi_nvram_update_start(
731 uint8_t payload
[MAX(MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN
,
732 MC_CMD_NVRAM_UPDATE_START_OUT_LEN
)];
736 (void) memset(payload
, 0, sizeof (payload
));
737 req
.emr_cmd
= MC_CMD_NVRAM_UPDATE_START
;
738 req
.emr_in_buf
= payload
;
739 req
.emr_in_length
= MC_CMD_NVRAM_UPDATE_START_V2_IN_LEN
;
740 req
.emr_out_buf
= payload
;
741 req
.emr_out_length
= MC_CMD_NVRAM_UPDATE_START_OUT_LEN
;
743 MCDI_IN_SET_DWORD(req
, NVRAM_UPDATE_START_V2_IN_TYPE
, partn
);
745 MCDI_IN_POPULATE_DWORD_1(req
, NVRAM_UPDATE_START_V2_IN_FLAGS
,
746 NVRAM_UPDATE_START_V2_IN_FLAG_REPORT_VERIFY_RESULT
, 1);
748 efx_mcdi_execute(enp
, &req
);
750 if (req
.emr_rc
!= 0) {
758 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
763 __checkReturn efx_rc_t
767 __in
uint32_t offset
,
768 __out_bcount(size
) caddr_t data
,
773 uint8_t payload
[MAX(MC_CMD_NVRAM_READ_IN_V2_LEN
,
774 MC_CMD_NVRAM_READ_OUT_LENMAX
)];
777 if (size
> MC_CMD_NVRAM_READ_OUT_LENMAX
) {
782 (void) memset(payload
, 0, sizeof (payload
));
783 req
.emr_cmd
= MC_CMD_NVRAM_READ
;
784 req
.emr_in_buf
= payload
;
785 req
.emr_in_length
= MC_CMD_NVRAM_READ_IN_V2_LEN
;
786 req
.emr_out_buf
= payload
;
787 req
.emr_out_length
= MC_CMD_NVRAM_READ_OUT_LENMAX
;
789 MCDI_IN_SET_DWORD(req
, NVRAM_READ_IN_V2_TYPE
, partn
);
790 MCDI_IN_SET_DWORD(req
, NVRAM_READ_IN_V2_OFFSET
, offset
);
791 MCDI_IN_SET_DWORD(req
, NVRAM_READ_IN_V2_LENGTH
, size
);
792 MCDI_IN_SET_DWORD(req
, NVRAM_READ_IN_V2_MODE
, mode
);
794 efx_mcdi_execute(enp
, &req
);
796 if (req
.emr_rc
!= 0) {
801 if (req
.emr_out_length_used
< MC_CMD_NVRAM_READ_OUT_LEN(size
)) {
807 MCDI_OUT2(req
, uint8_t, NVRAM_READ_OUT_READ_BUFFER
),
815 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
820 __checkReturn efx_rc_t
821 efx_mcdi_nvram_erase(
824 __in
uint32_t offset
,
828 uint8_t payload
[MAX(MC_CMD_NVRAM_ERASE_IN_LEN
,
829 MC_CMD_NVRAM_ERASE_OUT_LEN
)];
832 (void) memset(payload
, 0, sizeof (payload
));
833 req
.emr_cmd
= MC_CMD_NVRAM_ERASE
;
834 req
.emr_in_buf
= payload
;
835 req
.emr_in_length
= MC_CMD_NVRAM_ERASE_IN_LEN
;
836 req
.emr_out_buf
= payload
;
837 req
.emr_out_length
= MC_CMD_NVRAM_ERASE_OUT_LEN
;
839 MCDI_IN_SET_DWORD(req
, NVRAM_ERASE_IN_TYPE
, partn
);
840 MCDI_IN_SET_DWORD(req
, NVRAM_ERASE_IN_OFFSET
, offset
);
841 MCDI_IN_SET_DWORD(req
, NVRAM_ERASE_IN_LENGTH
, size
);
843 efx_mcdi_execute(enp
, &req
);
845 if (req
.emr_rc
!= 0) {
853 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
859 * The NVRAM_WRITE MCDI command is a V1 command and so is supported by both
860 * Sienna and EF10 based boards. However EF10 based boards support the use
861 * of this command with payloads up to the maximum MCDI V2 payload length.
863 __checkReturn efx_rc_t
864 efx_mcdi_nvram_write(
867 __in
uint32_t offset
,
868 __out_bcount(size
) caddr_t data
,
872 uint8_t payload
[MAX(MCDI_CTL_SDU_LEN_MAX_V1
,
873 MCDI_CTL_SDU_LEN_MAX_V2
)];
875 size_t max_data_size
;
877 max_data_size
= enp
->en_nic_cfg
.enc_mcdi_max_payload_length
878 - MC_CMD_NVRAM_WRITE_IN_LEN(0);
879 EFSYS_ASSERT3U(enp
->en_nic_cfg
.enc_mcdi_max_payload_length
, >, 0);
880 EFSYS_ASSERT3U(max_data_size
, <,
881 enp
->en_nic_cfg
.enc_mcdi_max_payload_length
);
883 if (size
> max_data_size
) {
888 (void) memset(payload
, 0, sizeof (payload
));
889 req
.emr_cmd
= MC_CMD_NVRAM_WRITE
;
890 req
.emr_in_buf
= payload
;
891 req
.emr_in_length
= MC_CMD_NVRAM_WRITE_IN_LEN(size
);
892 req
.emr_out_buf
= payload
;
893 req
.emr_out_length
= MC_CMD_NVRAM_WRITE_OUT_LEN
;
895 MCDI_IN_SET_DWORD(req
, NVRAM_WRITE_IN_TYPE
, partn
);
896 MCDI_IN_SET_DWORD(req
, NVRAM_WRITE_IN_OFFSET
, offset
);
897 MCDI_IN_SET_DWORD(req
, NVRAM_WRITE_IN_LENGTH
, size
);
899 memcpy(MCDI_IN2(req
, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER
),
902 efx_mcdi_execute(enp
, &req
);
904 if (req
.emr_rc
!= 0) {
914 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
921 * MC_CMD_NVRAM_UPDATE_FINISH_V2 must be used to support firmware-verified
922 * NVRAM updates. Older firmware will ignore the flags field in the request.
924 __checkReturn efx_rc_t
925 efx_mcdi_nvram_update_finish(
928 __in boolean_t reboot
,
929 __out_opt
uint32_t *verify_resultp
)
931 const efx_nic_cfg_t
*encp
= &enp
->en_nic_cfg
;
933 uint8_t payload
[MAX(MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN
,
934 MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN
)];
935 uint32_t verify_result
= MC_CMD_NVRAM_VERIFY_RC_UNKNOWN
;
938 (void) memset(payload
, 0, sizeof (payload
));
939 req
.emr_cmd
= MC_CMD_NVRAM_UPDATE_FINISH
;
940 req
.emr_in_buf
= payload
;
941 req
.emr_in_length
= MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN
;
942 req
.emr_out_buf
= payload
;
943 req
.emr_out_length
= MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN
;
945 MCDI_IN_SET_DWORD(req
, NVRAM_UPDATE_FINISH_V2_IN_TYPE
, partn
);
946 MCDI_IN_SET_DWORD(req
, NVRAM_UPDATE_FINISH_V2_IN_REBOOT
, reboot
);
948 MCDI_IN_POPULATE_DWORD_1(req
, NVRAM_UPDATE_FINISH_V2_IN_FLAGS
,
949 NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT
, 1);
951 efx_mcdi_execute(enp
, &req
);
953 if (req
.emr_rc
!= 0) {
958 if (req
.emr_out_length_used
< MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN
) {
959 verify_result
= MC_CMD_NVRAM_VERIFY_RC_UNKNOWN
;
960 if (encp
->enc_nvram_update_verify_result_supported
) {
961 /* Result of update verification is missing */
967 MCDI_OUT_DWORD(req
, NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE
);
970 if ((encp
->enc_nvram_update_verify_result_supported
) &&
971 (verify_result
!= MC_CMD_NVRAM_VERIFY_RC_SUCCESS
)) {
972 /* Update verification failed */
977 if (verify_resultp
!= NULL
)
978 *verify_resultp
= verify_result
;
987 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
989 /* Always report verification result */
990 if (verify_resultp
!= NULL
)
991 *verify_resultp
= verify_result
;
998 __checkReturn efx_rc_t
1000 __in efx_nic_t
*enp
,
1001 __in
uint32_t partn
)
1004 uint8_t payload
[MAX(MC_CMD_NVRAM_TEST_IN_LEN
,
1005 MC_CMD_NVRAM_TEST_OUT_LEN
)];
1009 (void) memset(payload
, 0, sizeof (payload
));
1010 req
.emr_cmd
= MC_CMD_NVRAM_TEST
;
1011 req
.emr_in_buf
= payload
;
1012 req
.emr_in_length
= MC_CMD_NVRAM_TEST_IN_LEN
;
1013 req
.emr_out_buf
= payload
;
1014 req
.emr_out_length
= MC_CMD_NVRAM_TEST_OUT_LEN
;
1016 MCDI_IN_SET_DWORD(req
, NVRAM_TEST_IN_TYPE
, partn
);
1018 efx_mcdi_execute(enp
, &req
);
1020 if (req
.emr_rc
!= 0) {
1025 if (req
.emr_out_length_used
< MC_CMD_NVRAM_TEST_OUT_LEN
) {
1030 result
= MCDI_OUT_DWORD(req
, NVRAM_TEST_OUT_RESULT
);
1031 if (result
== MC_CMD_NVRAM_TEST_FAIL
) {
1033 EFSYS_PROBE1(nvram_test_failure
, int, partn
);
1046 EFSYS_PROBE1(fail1
, efx_rc_t
, rc
);
1051 #endif /* EFSYS_OPT_DIAG */
1054 #endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */