From b14adeaae605cbb1c1af592ae0a7f58e40f28776 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Thu, 9 May 2019 16:25:11 -0700 Subject: mpm: Add MB-EEPROMv3 This includes a rev_compat field, which we can use to identify the last hardware revision this hardware is compatible with. Example: Say the current hardware revision is 7, but it is compatible with version 5, then we store 7 as the current rev, and 5 as the rev_compat. Software can now check the rev_compat rather than the current rev for compatibility. This makes MPM more future-proof against minor, compatible hardware changes. --- mpm/python/usrp_mpm/eeprom.py | 20 ++++++++++++++++++-- mpm/tools/eeprom-init.c | 28 ++++++++++++++++++++++------ mpm/tools/eeprom.c | 12 +++++++++--- mpm/tools/eeprom.h | 5 +++-- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/mpm/python/usrp_mpm/eeprom.py b/mpm/python/usrp_mpm/eeprom.py index 97a450ca6..3a839d3a6 100644 --- a/mpm/python/usrp_mpm/eeprom.py +++ b/mpm/python/usrp_mpm/eeprom.py @@ -53,6 +53,20 @@ class MboardEEPROM(object): - 2 bytes padding - 4 bytes CRC + Version 3: (FWIW MPM doesn't care about the extra bytes) + + - 4x4 bytes mcu_flags -> throw them away + - 2 bytes hw_pid + - 2 bytes hw_rev (starting at 0) + - 8 bytes serial number (zero-terminated string of 7 characters) + - 6 bytes MAC address for eth0 + - 2 bytes Devicetree compatible -> throw them away + - 6 bytes MAC address for eth1 + - 2 bytes EC compatible -> throw them away + - 6 bytes MAC address for eth2 + - 2 bytes rev_compat + - 4 bytes CRC + MAC addresses are ignored here; they are read elsewhere. If we really need to know the MAC address of an interface, we can fish it out the raw data, or ask the system. @@ -61,12 +75,14 @@ class MboardEEPROM(object): eeprom_header_format = ( None, # For laziness, we start at version 1 and thus index 0 stays empty "!I I 16s H H 7s 1x 24s I", # Version 1 - "!I I 16s H H 7s 1x 24s I", # Version 2 (Ignore the extra fields, it doesn't matter to MPM) + "!I I 16s H H 7s 1x 6s H 6s H 6s 2x I", # Version 2 (Ignore the extra fields, it doesn't matter to MPM) + "!I I 16s H H 7s 1x 6s H 6s H 6s H I", # Version 3 (Ignore the extra fields, it doesn't matter to MPM) ) eeprom_header_keys = ( None, # For laziness, we start at version 1 and thus index 0 stays empty ('magic', 'eeprom_version', 'mcu_flags', 'pid', 'rev', 'serial', 'mac_addresses', 'CRC'), # Version 1 - ('magic', 'eeprom_version', 'mcu_flags', 'pid', 'rev', 'serial', 'mac_addresses', 'CRC') # Version 2 (Ignore the extra fields, it doesn't matter to MPM) + ('magic', 'eeprom_version', 'mcu_flags', 'pid', 'rev', 'serial', 'mac_eth0', 'dt_compat', 'mac_eth1', 'ec_compat', 'mac_eth2', 'CRC'), # Version 2 (Ignore the extra fields, it doesn't matter to MPM) + ('magic', 'eeprom_version', 'mcu_flags', 'pid', 'rev', 'serial', 'mac_eth0', 'dt_compat', 'mac_eth1', 'ec_compat', 'mac_eth2', 'rev_compat', 'CRC'), # Version 3 ) class DboardEEPROM(object): diff --git a/mpm/tools/eeprom-init.c b/mpm/tools/eeprom-init.c index 0a410ae9e..6ef5ccf45 100644 --- a/mpm/tools/eeprom-init.c +++ b/mpm/tools/eeprom-init.c @@ -8,6 +8,14 @@ #include #include +int derive_rev_compat(int rev) +{ + if (rev > 5) + return 5; + + return rev; +} + int derive_dt_compat(int rev) { /* up to rev6 they were individual dts */ @@ -29,12 +37,12 @@ int derive_mcu_compat(int rev) void usage(char *argv[]) { printf("-- Usage -- \n"); - printf("%s serial# revision eth0 eth1 eth2 [pid] [dt-compat] [mcu-compat]\n\n", argv[0]); + printf("%s serial# revision eth0 eth1 eth2 [pid] [dt-compat] [mcu-compat] [rev-compat]\n\n", argv[0]); printf("Example:\n"); printf("$ %s 310A850 2 0c:22:cc:1a:25:c1 0c:22:cc:1a:25:c2 0c:22:cc:1a:25:c3 0x4242\n", argv[0]); - printf("or specifying dt-compat and mcu-compat explicitly:\n"); - printf("$ %s 310A850 2 0c:22:cc:1a:25:c1 0c:22:cc:1a:25:c2 0c:22:cc:1a:25:c3 0x4242 5 5\n", + printf("or specifying dt-compat, mcu-compat, and rev-compat explicitly:\n"); + printf("$ %s 310A850 2 0c:22:cc:1a:25:c1 0c:22:cc:1a:25:c2 0c:22:cc:1a:25:c3 0x4242 5 5 5\n", argv[0]); } @@ -43,8 +51,9 @@ int main(int argc, char *argv[]) struct usrp_sulfur_eeprom *ep, *ep2; u16 mcu_compat; u16 dt_compat; + u16 rev_compat; - if (argc < 6 || argc > 9) { + if (argc < 6 || argc > 10) { usage(argv); return EXIT_FAILURE; } @@ -61,13 +70,20 @@ int main(int argc, char *argv[]) dt_compat = derive_dt_compat(atoi(argv[2])); } - if (argc == 9) { + if (argc >= 9) { mcu_compat = strtol(argv[8], NULL, 0); printf("mcu_compat=%u\n", mcu_compat); } else { mcu_compat = derive_mcu_compat(atoi(argv[2])); } + if (argc >= 10) { + rev_compat = strtol(argv[9], NULL, 0); + printf("rev_compat=%u\n", rev_compat); + } else { + rev_compat = derive_rev_compat(atoi(argv[2])); + } + if (pid < 0 || pid > 0xFFFF) { printf("Invalid PID: %lX\n", pid); return EXIT_FAILURE; @@ -79,7 +95,7 @@ int main(int argc, char *argv[]) */ ep = usrp_sulfur_eeprom_new(NULL, (u16) pid, atoi(argv[2]), argv[1], argv[3], argv[4], argv[5], dt_compat, - mcu_compat); + mcu_compat, rev_compat); usrp_sulfur_eeprom_print(ep); usrp_sulfur_eeprom_to_i2c(ep, "/dev/i2c-2"); diff --git a/mpm/tools/eeprom.c b/mpm/tools/eeprom.c index c2bf3705e..ae036ac43 100644 --- a/mpm/tools/eeprom.c +++ b/mpm/tools/eeprom.c @@ -31,7 +31,7 @@ static const u32 USRP_EEPROM_MAGIC = 0xF008AD10; static const u32 USRP_EEPROM_DB_MAGIC = 0xF008AD11; -static const u32 USRP_EEPROM_VERSION = 2; +static const u32 USRP_EEPROM_VERSION = 3; static const u32 USRP_EEPROM_DB_VERSION = 2; static const u32 USRP_EEPROM_DEFAULT_MCU_FLAGS[4] = {0x0, 0x0, 0x0, 0x0}; @@ -127,7 +127,8 @@ struct usrp_sulfur_eeprom *usrp_sulfur_eeprom_new(const u32 *mcu_flags, const char *eth_addr1, const char *eth_addr2, const u16 dt_compat, - const u16 mcu_compat) + const u16 mcu_compat, + const u16 rev_compat) { struct usrp_sulfur_eeprom *ep; int i; @@ -173,6 +174,7 @@ struct usrp_sulfur_eeprom *usrp_sulfur_eeprom_new(const u32 *mcu_flags, ep->dt_compat = htons(dt_compat); ep->mcu_compat = htons(mcu_compat); + ep->rev_compat = htons(rev_compat); ep->crc = htonl(crc32(0, &ep->magic, sizeof(*ep)-4)); @@ -222,10 +224,14 @@ void usrp_sulfur_eeprom_print(const struct usrp_sulfur_eeprom *ep) ep->eth_addr2[0], ep->eth_addr2[1], ep->eth_addr2[2], ep->eth_addr2[3], ep->eth_addr2[4], ep->eth_addr2[5]); - if (ntohl(ep->version) == 2) + if (ntohl(ep->version) >= 2) printf("-- DT-Compat/MCU-Compat: %04x %04x\n", ntohs(ep->dt_compat), ntohs(ep->mcu_compat)); + if (ntohl(ep->version) >= 3) { + printf("-- Max-REV: %04x\n", ntohs(ep->rev_compat)); + } + printf("-- CRC: %08x (%s)\n", ntohl(ep->crc), __usrp_sulfur_eeprom_check_crc(ep) ? "matches": "doesn't match!"); } diff --git a/mpm/tools/eeprom.h b/mpm/tools/eeprom.h index 04f468dd9..39301327f 100644 --- a/mpm/tools/eeprom.h +++ b/mpm/tools/eeprom.h @@ -33,7 +33,7 @@ struct usrp_sulfur_eeprom { u8 eth_addr1[ETH_ALEN]; u16 mcu_compat; u8 eth_addr2[ETH_ALEN]; - u8 __pad_2[2]; + u16 rev_compat; u32 crc; } __attribute__((packed)); @@ -63,7 +63,8 @@ struct usrp_sulfur_eeprom *usrp_sulfur_eeprom_new(const u32 *mcu_flags, const char *eth_addr1, const char *eth_addr2, const u16 dt_compat, - const u16 mcu_compat); + const u16 mcu_compat, + const u16 rev_compat); void usrp_sulfur_eeprom_to_i2c(struct usrp_sulfur_eeprom *ep, const char *path); -- cgit v1.2.3