diff options
Diffstat (limited to 'board/CZ.NIC')
-rw-r--r-- | board/CZ.NIC/turris_omnia/eeprom.c | 11 | ||||
-rw-r--r-- | board/CZ.NIC/turris_omnia/turris_omnia.c | 42 |
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; } |