summaryrefslogtreecommitdiff
path: root/board/CZ.NIC
diff options
context:
space:
mode:
Diffstat (limited to 'board/CZ.NIC')
-rw-r--r--board/CZ.NIC/turris_omnia/eeprom.c11
-rw-r--r--board/CZ.NIC/turris_omnia/turris_omnia.c42
2 files changed, 46 insertions, 7 deletions
diff --git a/board/CZ.NIC/turris_omnia/eeprom.c b/board/CZ.NIC/turris_omnia/eeprom.c
index a4f1dab469..ea13e95b37 100644
--- a/board/CZ.NIC/turris_omnia/eeprom.c
+++ b/board/CZ.NIC/turris_omnia/eeprom.c
@@ -60,9 +60,13 @@ static struct eeprom_field omnia_layout[] = {
_DEF_FIELD("RAM size in GB", 4, ramsz),
_DEF_FIELD("Wi-Fi Region", 4, region),
_DEF_FIELD("CRC32 checksum", 4, bin),
+ _DEF_FIELD("Extended reserved fields", 44, reserved),
+ _DEF_FIELD("Extended CRC32 checksum", 4, bin),
};
static struct eeprom_field *crc_field = &omnia_layout[3];
+static struct eeprom_field *ext_crc_field =
+ &omnia_layout[ARRAY_SIZE(omnia_layout) - 1];
static int omnia_update_field(struct eeprom_layout *layout, char *field_name,
char *new_data)
@@ -91,6 +95,11 @@ static int omnia_update_field(struct eeprom_layout *layout, char *field_name,
put_unaligned_le32(crc, crc_field->buf);
}
+ if (field < ext_crc_field) {
+ u32 crc = crc32(0, layout->data, 44);
+ put_unaligned_le32(crc, ext_crc_field->buf);
+ }
+
return 0;
}
@@ -99,7 +108,7 @@ void eeprom_layout_assign(struct eeprom_layout *layout, int)
layout->fields = omnia_layout;
layout->num_of_fields = ARRAY_SIZE(omnia_layout);
layout->update = omnia_update_field;
- layout->data_size = 16;
+ layout->data_size = 64;
}
int eeprom_layout_detect(unsigned char *)
diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c
index 100a991406..c2f91b762f 100644
--- a/board/CZ.NIC/turris_omnia/turris_omnia.c
+++ b/board/CZ.NIC/turris_omnia/turris_omnia.c
@@ -429,12 +429,40 @@ struct omnia_eeprom {
u32 ramsize;
char region[4];
u32 crc;
+
+ /* second part (only considered if crc2 is not all-ones) */
+ u8 reserved[44];
+ u32 crc2;
};
+static bool is_omnia_eeprom_second_part_valid(const struct omnia_eeprom *oep)
+{
+ return oep->crc2 != 0xffffffff;
+}
+
+static void make_omnia_eeprom_second_part_invalid(struct omnia_eeprom *oep)
+{
+ oep->crc2 = 0xffffffff;
+}
+
+static bool check_eeprom_crc(const void *buf, size_t size, u32 expected,
+ const char *name)
+{
+ u32 crc;
+
+ crc = crc32(0, buf, size);
+ if (crc != expected) {
+ printf("bad %s EEPROM CRC (stored %08x, computed %08x)\n",
+ name, expected, crc);
+ return false;
+ }
+
+ return true;
+}
+
static bool omnia_read_eeprom(struct omnia_eeprom *oep)
{
struct udevice *chip;
- u32 crc;
int ret;
chip = omnia_get_i2c_chip("EEPROM", OMNIA_I2C_EEPROM_CHIP_ADDR,
@@ -455,12 +483,14 @@ static bool omnia_read_eeprom(struct omnia_eeprom *oep)
return false;
}
- crc = crc32(0, (void *)oep, sizeof(*oep) - 4);
- if (crc != oep->crc) {
- printf("bad EEPROM CRC (stored %08x, computed %08x)\n",
- oep->crc, crc);
+ if (!check_eeprom_crc(oep, offsetof(struct omnia_eeprom, crc), oep->crc,
+ "first"))
return false;
- }
+
+ if (is_omnia_eeprom_second_part_valid(oep) &&
+ !check_eeprom_crc(oep, offsetof(struct omnia_eeprom, crc2),
+ oep->crc2, "second"))
+ make_omnia_eeprom_second_part_invalid(oep);
return true;
}