Extend the Omnia EEPROM information structure in preparation for more
variables to be stored there.

Signed-off-by: Marek Behún <ka...@kernel.org>
---
 board/CZ.NIC/turris_omnia/eeprom.c       | 11 ++++++-
 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;
 }
-- 
2.44.2

Reply via email to