diff options
author | Moritz Fischer <moritz.fischer@ettus.com> | 2018-04-25 18:01:09 -0700 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-06-20 17:10:05 -0500 |
commit | 91a5518443f4ff938f67a2f1bd1b09b24bceecd5 (patch) | |
tree | eb4adccd6d3c687d157d4a4073e76970a5ed0a69 | |
parent | 0935bf5c2a6952fd07bc4b6c618d12b0bd79ca78 (diff) | |
download | uhd-91a5518443f4ff938f67a2f1bd1b09b24bceecd5.tar.gz uhd-91a5518443f4ff938f67a2f1bd1b09b24bceecd5.tar.bz2 uhd-91a5518443f4ff938f67a2f1bd1b09b24bceecd5.zip |
mpm: tools: Introduce dt-compat and mcu-compat fields
Introduce dt-compat and mcu-compat fields into the eeprom
structure.
For the motherboard eeprom this is straightforward, since
there's still padding bytes that could be (ab)used for this.
On the dboard side more creativity is required and the
original revision field of 2 bytes is reduced to only
one byte revision and one byte dt-compat.
Since this will only affect new units being backwards
compatible with older versions of the bootloader is not
an issue.
Reviewed-by: Brent Stapleton <brent.stapleton@ettus.com>
Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
-rw-r--r-- | mpm/python/usrp_mpm/eeprom.py | 28 | ||||
-rw-r--r-- | mpm/tools/db-id.c | 11 | ||||
-rw-r--r-- | mpm/tools/db-init.c | 23 | ||||
-rw-r--r-- | mpm/tools/eeprom-init.c | 52 | ||||
-rw-r--r-- | mpm/tools/eeprom.c | 30 | ||||
-rw-r--r-- | mpm/tools/eeprom.h | 26 |
6 files changed, 140 insertions, 30 deletions
diff --git a/mpm/python/usrp_mpm/eeprom.py b/mpm/python/usrp_mpm/eeprom.py index 79532f9f8..d189f7a8b 100644 --- a/mpm/python/usrp_mpm/eeprom.py +++ b/mpm/python/usrp_mpm/eeprom.py @@ -39,6 +39,20 @@ class MboardEEPROM(object): - 2 bytes padding - 4 bytes CRC + Version 2: (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 padding + - 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. @@ -47,10 +61,12 @@ 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) ) 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 1 + ('magic', 'eeprom_version', 'mcu_flags', 'pid', 'rev', 'serial', 'mac_addresses', 'CRC') # Version 2 (Ignore the extra fields, it doesn't matter to MPM) ) class DboardEEPROM(object): @@ -71,6 +87,14 @@ class DboardEEPROM(object): - 8 bytes serial number (zero-terminated string of 7 characters) - 4 bytes CRC + Version 2: + + - 2 bytes hw_pid + - 1 byte hw_rev (starting at 0) + - 1 byte dt_compat (starting at 0, MPM can ignore that) + - 8 bytes serial number (zero-terminated string of 7 characters) + - 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. @@ -79,10 +103,12 @@ class DboardEEPROM(object): eeprom_header_format = ( None, # For laziness, we start at version 1 and thus index 0 stays empty "!I I H H 7s 1x I", # Version 1 + "!I I H B 1x 7s 1x I", # Version 2 ) eeprom_header_keys = ( None, # For laziness, we start at version 1 and thus index 0 stays empty ('magic', 'eeprom_version', 'pid', 'rev', 'serial', 'CRC'), # Version 1 + ('magic', 'eeprom_version', 'pid', 'rev', 'serial', 'CRC'), # Version 2 (Ignore the extra field, it doesn't matter to MPM) ) diff --git a/mpm/tools/db-id.c b/mpm/tools/db-id.c index 53501e0df..87c06392b 100644 --- a/mpm/tools/db-id.c +++ b/mpm/tools/db-id.c @@ -10,10 +10,17 @@ static void usrp_sulfur_db_eeprom_print_id(struct usrp_sulfur_db_eeprom *ep) { + int rev; + + if (ntohl(ep->version) == 1) + rev = ntohs(ep->rev.v1_rev); + else + rev = ep->rev.v2_rev.rev; + if (ntohs(ep->pid) == 0x150) - printf("product=ni,magnesium-rev%x\n", ntohs(ep->rev)+1); + printf("product=ni,magnesium-rev%x\n", rev + 1); else if (ntohs(ep->pid) == 0x180) - printf("product=ni,eiscat-rev%x\n", ntohs(ep->rev)+1); + printf("product=ni,eiscat-rev%x\n", rev + 1); else printf("product=unknown-(%04x)\n", ep->pid); diff --git a/mpm/tools/db-init.c b/mpm/tools/db-init.c index fdf8dcd87..20f71915e 100644 --- a/mpm/tools/db-init.c +++ b/mpm/tools/db-init.c @@ -8,14 +8,24 @@ #include <stdlib.h> #include <stdio.h> +int get_dt_compat(int rev) +{ + if (rev > 3) + return 3; + + return rev; +} + void usage(char *argv[]) { printf("-- Usage -- \n"); - printf("%s slot pid rev serial#\n\n", argv[0]); + printf("%s slot pid rev serial [dt-compat]#\n\n", argv[0]); printf("Example:\n"); printf("$ %s 0 0x0150 0 310A850\n", argv[0]); - + printf("or specifying a dt-compat explicitly:\n"); + printf("$ %s 0 0x0150 0 310A850 3\n", + argv[0]); } @@ -23,15 +33,20 @@ int main(int argc, char *argv[]) { struct usrp_sulfur_db_eeprom *ep; int which_slot = 0; + u8 dt_compat = 0; - if (argc != 5) { + if (argc < 5) { usage(argv); return EXIT_FAILURE; } + if (argc >= 6) + dt_compat = atoi(argv[5]); + which_slot = atoi(argv[1]); - ep = usrp_sulfur_db_eeprom_new(strtol(argv[2], NULL, 16), atoi(argv[3]), argv[4]); + ep = usrp_sulfur_db_eeprom_new(strtol(argv[2], NULL, 16), atoi(argv[3]), argv[4], + dt_compat ? dt_compat : get_dt_compat(atoi(argv[3]))); usrp_sulfur_db_eeprom_print(ep); if (!which_slot) diff --git a/mpm/tools/eeprom-init.c b/mpm/tools/eeprom-init.c index a2b608464..87dc26a6b 100644 --- a/mpm/tools/eeprom-init.c +++ b/mpm/tools/eeprom-init.c @@ -8,39 +8,75 @@ #include <stdio.h> #include <stdlib.h> +int derive_dt_compat(int rev) +{ + /* up to rev6 they were individual dts */ + if (rev > 5) + return 5; + + return rev; +} + +int derive_mcu_compat(int rev) +{ + /* up to rev6 they were individual firmware */ + if (rev > 5) + return 5; + + return rev; +} + void usage(char *argv[]) { printf("-- Usage -- \n"); - printf("%s serial# revision eth0 eth1 eth2 pid\n\n", argv[0]); + printf("%s serial# revision eth0 eth1 eth2 [pid] [dt-compat] [mcu-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", + argv[0]); } int main(int argc, char *argv[]) { struct usrp_sulfur_eeprom *ep, *ep2; + u16 dt_compat = 0; + u16 mcu_compat = 0; - if (argc < 6 || argc > 7) { + if (argc < 6 || argc > 9) { usage(argv); return EXIT_FAILURE; } - printf("sizeof(*ep)=%lu\n", sizeof(*ep)); - long pid = 0x4242; - if (argc == 7) { + if (argc >= 7) { pid = strtol(argv[6], NULL, 0); } + if (argc >= 8) { + dt_compat = strtol(argv[7], NULL, 0); + printf("dt_compat=%u\n", dt_compat); + } + + if (argc == 9) { + mcu_compat = strtol(argv[8], NULL, 0); + printf("mcu_compat=%u\n", mcu_compat); + } + if (pid < 0 || pid > 0xFFFF) { printf("Invalid PID: %lX\n", pid); return EXIT_FAILURE; } - ep = usrp_sulfur_eeprom_new(NULL, (u16) pid, atoi(argv[2]), (const u8*) argv[1], - argv[3], argv[4], argv[5]); + /* If no MCU or DT compat specified, derive based on rule up there, + * i.e. everything newer than 5 will be 5, assuming we don't change + * anything software visible anymore + */ + ep = usrp_sulfur_eeprom_new(NULL, (u16) pid, atoi(argv[2]), argv[1], + argv[3], argv[4], argv[5], dt_compat ? dt_compat : derive_dt_compat(atoi(argv[2])), + mcu_compat ? mcu_compat : derive_mcu_compat(atoi(argv[2]))); + usrp_sulfur_eeprom_print(ep); usrp_sulfur_eeprom_to_i2c(ep, "/dev/i2c-2"); free(ep); diff --git a/mpm/tools/eeprom.c b/mpm/tools/eeprom.c index ce4c76277..c2bf3705e 100644 --- a/mpm/tools/eeprom.c +++ b/mpm/tools/eeprom.c @@ -31,8 +31,8 @@ static const u32 USRP_EEPROM_MAGIC = 0xF008AD10; static const u32 USRP_EEPROM_DB_MAGIC = 0xF008AD11; -static const u32 USRP_EEPROM_VERSION = 1; -static const u32 USRP_EEPROM_DB_VERSION = 1; +static const u32 USRP_EEPROM_VERSION = 2; +static const u32 USRP_EEPROM_DB_VERSION = 2; static const u32 USRP_EEPROM_DEFAULT_MCU_FLAGS[4] = {0x0, 0x0, 0x0, 0x0}; @@ -122,10 +122,12 @@ static int __eth_addr_parse(uint8_t *out, const char *in) struct usrp_sulfur_eeprom *usrp_sulfur_eeprom_new(const u32 *mcu_flags, const u16 pid, const u16 rev, - const u8 *serial, + const char *serial, const char *eth_addr0, const char *eth_addr1, - const char *eth_addr2) + const char *eth_addr2, + const u16 dt_compat, + const u16 mcu_compat) { struct usrp_sulfur_eeprom *ep; int i; @@ -169,6 +171,9 @@ struct usrp_sulfur_eeprom *usrp_sulfur_eeprom_new(const u32 *mcu_flags, if (eth_addr2) __eth_addr_parse(ep->eth_addr2, eth_addr2); + ep->dt_compat = htons(dt_compat); + ep->mcu_compat = htons(mcu_compat); + ep->crc = htonl(crc32(0, &ep->magic, sizeof(*ep)-4)); return ep; @@ -217,6 +222,10 @@ 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) + printf("-- DT-Compat/MCU-Compat: %04x %04x\n", + ntohs(ep->dt_compat), ntohs(ep->mcu_compat)); + printf("-- CRC: %08x (%s)\n", ntohl(ep->crc), __usrp_sulfur_eeprom_check_crc(ep) ? "matches": "doesn't match!"); } @@ -400,7 +409,8 @@ void usrp_sulfur_eeprom_to_i2c(struct usrp_sulfur_eeprom *ep, const char *path) struct usrp_sulfur_db_eeprom *usrp_sulfur_db_eeprom_new(const u16 pid, const u16 rev, - const u8 *serial) + const char *serial, + const u16 dt_compat) { struct usrp_sulfur_db_eeprom *ep; int i; @@ -418,7 +428,8 @@ struct usrp_sulfur_db_eeprom *usrp_sulfur_db_eeprom_new(const u16 pid, ep->version = htonl(USRP_EEPROM_DB_VERSION); ep->pid = htons(pid); - ep->rev = htons(rev); + ep->rev.v2_rev.rev = rev; + ep->rev.v2_rev.dt_compat = dt_compat; if (strlen(serial) > 8) { fprintf(stderr, "Serial# too long\n"); @@ -476,8 +487,13 @@ void usrp_sulfur_db_eeprom_print(const struct usrp_sulfur_db_eeprom *ep) return; } - printf("-- PID/REV: %04x %04x\n", ntohs(ep->pid), ntohs(ep->rev)); + if (ntohl(ep->version) == 1) + printf("-- PID/REV: %04x %04x\n", ntohs(ep->pid), ntohs(ep->rev.v1_rev)); + else + printf("-- PID/REV: %04x %02x\n", ntohs(ep->pid), ep->rev.v2_rev.rev); printf("-- Serial: %s\n", ep->serial); + if (ntohl(ep->version) == 2) + printf("-- DT-Compat: %02x\n", ep->rev.v2_rev.dt_compat); printf("-- CRC: %08x (%s)\n", ntohl(ep->crc), __usrp_sulfur_db_eeprom_check_crc(ep) ? "matches": "doesn't match!"); } diff --git a/mpm/tools/eeprom.h b/mpm/tools/eeprom.h index fc5b47426..04f468dd9 100644 --- a/mpm/tools/eeprom.h +++ b/mpm/tools/eeprom.h @@ -29,32 +29,41 @@ struct usrp_sulfur_eeprom { u16 rev; u8 serial[8]; u8 eth_addr0[ETH_ALEN]; - u8 __pad_0[2]; + u16 dt_compat; u8 eth_addr1[ETH_ALEN]; - u8 __pad_1[2]; + u16 mcu_compat; u8 eth_addr2[ETH_ALEN]; u8 __pad_2[2]; u32 crc; } __attribute__((packed)); +struct db_rev { + u8 rev; + u8 dt_compat; +} __attribute__((packed)); + struct usrp_sulfur_db_eeprom { u32 magic; u32 version; u16 pid; - u16 rev; - u8 serial[8]; + union rev { + u16 v1_rev; + struct db_rev v2_rev; + } rev; + char serial[8]; u32 crc; - } __attribute__((packed)); /* Motherboard EEPROM stuff */ struct usrp_sulfur_eeprom *usrp_sulfur_eeprom_new(const u32 *mcu_flags, const u16 pid, const u16 rev, - const u8 *serial, + const char *serial, const char *eth_addr0, const char *eth_addr1, - const char *eth_addr2); + const char *eth_addr2, + const u16 dt_compat, + const u16 mcu_compat); void usrp_sulfur_eeprom_to_i2c(struct usrp_sulfur_eeprom *ep, const char *path); @@ -70,7 +79,8 @@ void usrp_sulfur_eeprom_print(const struct usrp_sulfur_eeprom *ep); /* Daughterboard EEPROM stuff */ struct usrp_sulfur_db_eeprom *usrp_sulfur_db_eeprom_new(const u16 pid, const u16 rev, - const u8 *serial); + const char *serial, + const u16 dt_compat); void usrp_sulfur_db_eeprom_to_file(struct usrp_sulfur_db_eeprom *ep, const char *path); |