summaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/base/ef10_nvram.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc/base/ef10_nvram.c')
-rw-r--r--drivers/net/sfc/base/ef10_nvram.c161
1 files changed, 131 insertions, 30 deletions
diff --git a/drivers/net/sfc/base/ef10_nvram.c b/drivers/net/sfc/base/ef10_nvram.c
index 2883ec8f..8d1b64f2 100644
--- a/drivers/net/sfc/base/ef10_nvram.c
+++ b/drivers/net/sfc/base/ef10_nvram.c
@@ -203,14 +203,14 @@ tlv_validate_state(
if (tlv_tag(cursor) != TLV_TAG_END) {
/* Check current item has space for tag and length */
- if (cursor->current > (cursor->limit - 2)) {
+ if (cursor->current > (cursor->limit - 1)) {
cursor->current = NULL;
rc = EFAULT;
goto fail3;
}
- /* Check we have value data for current item and another tag */
- if (tlv_next_item_ptr(cursor) > (cursor->limit - 1)) {
+ /* Check we have value data for current item and an END tag */
+ if (tlv_next_item_ptr(cursor) > cursor->limit) {
cursor->current = NULL;
rc = EFAULT;
goto fail4;
@@ -635,7 +635,6 @@ fail1:
/* Validate buffer contents (before writing to flash) */
__checkReturn efx_rc_t
ef10_nvram_buffer_validate(
- __in efx_nic_t *enp,
__in uint32_t partn,
__in_bcount(partn_size) caddr_t partn_data,
__in size_t partn_size)
@@ -648,7 +647,6 @@ ef10_nvram_buffer_validate(
int pos;
efx_rc_t rc;
- _NOTE(ARGUNUSED(enp, partn))
EFX_STATIC_ASSERT(sizeof (*header) <= EF10_NVRAM_CHUNK);
if ((partn_data == NULL) || (partn_size == 0)) {
@@ -675,26 +673,32 @@ ef10_nvram_buffer_validate(
goto fail4;
}
+ /* Check partition header matches partn */
+ if (__LE_TO_CPU_16(header->type_id) != partn) {
+ rc = EINVAL;
+ goto fail5;
+ }
+
/* Check partition ends with PARTITION_TRAILER and END tags */
if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
rc = EINVAL;
- goto fail5;
+ goto fail6;
}
trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
if ((rc = tlv_advance(&cursor)) != 0) {
rc = EINVAL;
- goto fail6;
+ goto fail7;
}
if (tlv_tag(&cursor) != TLV_TAG_END) {
rc = EINVAL;
- goto fail7;
+ goto fail8;
}
/* Check generation counts are consistent */
if (trailer->generation != header->generation) {
rc = EINVAL;
- goto fail8;
+ goto fail9;
}
/* Verify partition checksum */
@@ -704,11 +708,13 @@ ef10_nvram_buffer_validate(
}
if (cksum != 0) {
rc = EINVAL;
- goto fail9;
+ goto fail10;
}
return (0);
+fail10:
+ EFSYS_PROBE(fail10);
fail9:
EFSYS_PROBE(fail9);
fail8:
@@ -731,13 +737,24 @@ fail1:
return (rc);
}
+ void
+ef10_nvram_buffer_init(
+ __out_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size)
+{
+ uint32_t *buf = (uint32_t *)bufferp;
+
+ memset(buf, 0xff, buffer_size);
+ tlv_init_block(buf);
+}
__checkReturn efx_rc_t
ef10_nvram_buffer_create(
- __in efx_nic_t *enp,
- __in uint16_t partn_type,
- __in_bcount(partn_size) caddr_t partn_data,
+ __in uint32_t partn_type,
+ __out_bcount(partn_size)
+ caddr_t partn_data,
__in size_t partn_size)
{
uint32_t *buf = (uint32_t *)partn_data;
@@ -753,9 +770,8 @@ ef10_nvram_buffer_create(
goto fail1;
}
- memset(buf, 0xff, partn_size);
+ ef10_nvram_buffer_init(partn_data, partn_size);
- tlv_init_block(buf);
if ((rc = tlv_init_cursor(&cursor, buf,
(uint32_t *)((uint8_t *)buf + partn_size),
buf)) != 0) {
@@ -787,7 +803,7 @@ ef10_nvram_buffer_create(
goto fail6;
/* Check that the partition is valid. */
- if ((rc = ef10_nvram_buffer_validate(enp, partn_type,
+ if ((rc = ef10_nvram_buffer_validate(partn_type,
partn_data, partn_size)) != 0)
goto fail7;
@@ -959,22 +975,65 @@ ef10_nvram_buffer_find_item(
}
__checkReturn efx_rc_t
+ef10_nvram_buffer_peek_item(
+ __in_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size,
+ __in uint32_t offset,
+ __out uint32_t *tagp,
+ __out uint32_t *lengthp,
+ __out uint32_t *value_offsetp)
+{
+ efx_rc_t rc;
+ tlv_cursor_t cursor;
+ uint32_t tag;
+
+ if ((rc = tlv_init_cursor_at_offset(&cursor, (uint8_t *)bufferp,
+ buffer_size, offset)) != 0) {
+ goto fail1;
+ }
+
+ tag = tlv_tag(&cursor);
+ *tagp = tag;
+ if (tag == TLV_TAG_END) {
+ /*
+ * To allow stepping over the END tag, report the full tag
+ * length and a zero length value.
+ */
+ *lengthp = sizeof (tag);
+ *value_offsetp = sizeof (tag);
+ } else {
+ *lengthp = byte_offset(tlv_next_item_ptr(&cursor),
+ cursor.current);
+ *value_offsetp = byte_offset((uint32_t *)tlv_value(&cursor),
+ cursor.current);
+ }
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
ef10_nvram_buffer_get_item(
__in_bcount(buffer_size)
caddr_t bufferp,
__in size_t buffer_size,
__in uint32_t offset,
__in uint32_t length,
- __out_bcount_part(item_max_size, *lengthp)
- caddr_t itemp,
- __in size_t item_max_size,
+ __out uint32_t *tagp,
+ __out_bcount_part(value_max_size, *lengthp)
+ caddr_t valuep,
+ __in size_t value_max_size,
__out uint32_t *lengthp)
{
efx_rc_t rc;
tlv_cursor_t cursor;
- uint32_t item_length;
+ uint32_t value_length;
- if (item_max_size < length) {
+ if (buffer_size < (offset + length)) {
rc = ENOSPC;
goto fail1;
}
@@ -984,14 +1043,15 @@ ef10_nvram_buffer_get_item(
goto fail2;
}
- item_length = tlv_length(&cursor);
- if (length < item_length) {
+ value_length = tlv_length(&cursor);
+ if (value_max_size < value_length) {
rc = ENOSPC;
goto fail3;
}
- memcpy(itemp, tlv_value(&cursor), item_length);
+ memcpy(valuep, tlv_value(&cursor), value_length);
- *lengthp = item_length;
+ *tagp = tlv_tag(&cursor);
+ *lengthp = value_length;
return (0);
@@ -1011,7 +1071,45 @@ ef10_nvram_buffer_insert_item(
caddr_t bufferp,
__in size_t buffer_size,
__in uint32_t offset,
- __in_bcount(length) caddr_t keyp,
+ __in uint32_t tag,
+ __in_bcount(length) caddr_t valuep,
+ __in uint32_t length,
+ __out uint32_t *lengthp)
+{
+ efx_rc_t rc;
+ tlv_cursor_t cursor;
+
+ if ((rc = tlv_init_cursor_at_offset(&cursor, (uint8_t *)bufferp,
+ buffer_size, offset)) != 0) {
+ goto fail1;
+ }
+
+ rc = tlv_insert(&cursor, tag, (uint8_t *)valuep, length);
+
+ if (rc != 0)
+ goto fail2;
+
+ *lengthp = byte_offset(tlv_next_item_ptr(&cursor),
+ cursor.current);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+ return (rc);
+}
+
+ __checkReturn efx_rc_t
+ef10_nvram_buffer_modify_item(
+ __in_bcount(buffer_size)
+ caddr_t bufferp,
+ __in size_t buffer_size,
+ __in uint32_t offset,
+ __in uint32_t tag,
+ __in_bcount(length) caddr_t valuep,
__in uint32_t length,
__out uint32_t *lengthp)
{
@@ -1023,7 +1121,7 @@ ef10_nvram_buffer_insert_item(
goto fail1;
}
- rc = tlv_insert(&cursor, TLV_TAG_LICENSE, (uint8_t *)keyp, length);
+ rc = tlv_modify(&cursor, tag, (uint8_t *)valuep, length);
if (rc != 0) {
goto fail2;
@@ -1042,6 +1140,7 @@ fail1:
return (rc);
}
+
__checkReturn efx_rc_t
ef10_nvram_buffer_delete_item(
__in_bcount(buffer_size)
@@ -1808,7 +1907,7 @@ ef10_nvram_partn_write_segment_tlv(
goto fail7;
/* Unlock the partition */
- ef10_nvram_partn_unlock(enp, partn, NULL);
+ (void) ef10_nvram_partn_unlock(enp, partn, NULL);
EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
@@ -1823,7 +1922,7 @@ fail5:
fail4:
EFSYS_PROBE(fail4);
- ef10_nvram_partn_unlock(enp, partn, NULL);
+ (void) ef10_nvram_partn_unlock(enp, partn, NULL);
fail3:
EFSYS_PROBE(fail3);
@@ -2000,7 +2099,7 @@ ef10_nvram_partn_write(
__in efx_nic_t *enp,
__in uint32_t partn,
__in unsigned int offset,
- __out_bcount(size) caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size)
{
size_t chunk;
@@ -2168,6 +2267,8 @@ static ef10_parttbl_entry_t medford2_parttbl[] = {
PARTN_MAP_ENTRY(LICENSE, ALL, LICENSE),
PARTN_MAP_ENTRY(EXPANSION_UEFI, ALL, UEFIROM),
PARTN_MAP_ENTRY(MUM_FIRMWARE, ALL, MUM_FIRMWARE),
+ PARTN_MAP_ENTRY(DYNCONFIG_DEFAULTS, ALL, DYNCONFIG_DEFAULTS),
+ PARTN_MAP_ENTRY(ROMCONFIG_DEFAULTS, ALL, ROMCONFIG_DEFAULTS),
};
static __checkReturn efx_rc_t