diff options
author | Martin Braun <martin.braun@ettus.com> | 2022-01-28 11:56:11 +0100 |
---|---|---|
committer | Aaron Rossetto <aaron.rossetto@ni.com> | 2022-02-24 14:00:07 -0600 |
commit | 8ca640b922700276abb86adde1b5ad46f3d2af07 (patch) | |
tree | 13190bed0163c696039cd00be4e33b9a79036d4e /mpm/tools/eeprom-init.c | |
parent | 1d0806092491dc172ba31312840df02d8ec0b11a (diff) | |
download | uhd-8ca640b922700276abb86adde1b5ad46f3d2af07.tar.gz uhd-8ca640b922700276abb86adde1b5ad46f3d2af07.tar.bz2 uhd-8ca640b922700276abb86adde1b5ad46f3d2af07.zip |
mpm: eeprom: Fix default values in EEPROM utilities
When executing eeprom-init on E320 (which was originally written for
N310), it would use defaults from N310, potentially causing issues.
These issues would have arisen if we letter-revved the E320 one more
time (because at rev 5, N310 had a compatibility cutover).
Summary of changes:
- eeprom-init will now read values *not* given on the command line from
the existing content of the EEPROM, if it contains valid data. This
means that DT, MCU, and rev compat values will no longer get
auto-derived if the EEPROM already contained "good" values.
- If the EEPROM is empty or corrupted, eeprom-init will no longer run if
the pid value is not provided. This is to avoid N310 defaults being
written to E320 EEPROMs.
- A README is added to explain which devices use which utilities.
- PID checks are more strict now. It is unlikely we'll build new devices
using the old EEPROM format (prior to TLV), so we can check
specifically for E320, N3x0.
- The hard-coded list of PIDs for the EEPROM tools are moved to
a central location (eeprom-pids.h).
- The code to derive values for DT/MCU/rev compat from the rev is now
pid-specific and no longer device-agnostic.
Diffstat (limited to 'mpm/tools/eeprom-init.c')
-rw-r--r-- | mpm/tools/eeprom-init.c | 101 |
1 files changed, 71 insertions, 30 deletions
diff --git a/mpm/tools/eeprom-init.c b/mpm/tools/eeprom-init.c index 6ef5ccf45..b5997f222 100644 --- a/mpm/tools/eeprom-init.c +++ b/mpm/tools/eeprom-init.c @@ -5,31 +5,43 @@ // #include "eeprom.h" +#include "eeprom-pids.h" #include <stdio.h> #include <stdlib.h> -int derive_rev_compat(int rev) +int derive_rev_compat(int rev, long pid) { - if (rev > 5) - return 5; - + if (pid == E320_PID) { + if (rev >= 2) + return 2; + } else { /* N3x0 */ + if (rev > 5) + return 5; + } return rev; } -int derive_dt_compat(int rev) +int derive_dt_compat(int rev, long pid) { - /* up to rev6 they were individual dts */ - if (rev > 5) - return 5; - + if (pid == E320_PID) { + return 0; + } else { /* N3x0 */ + /* up to rev5 they were individual dts */ + if (rev > 5) + return 5; + } return rev; } -int derive_mcu_compat(int rev) +int derive_mcu_compat(int rev, long pid) { - /* up to rev6 they were individual firmware */ - if (rev > 5) - return 5; + if (pid == E320_PID) { + return 2; + } else { /* N3x0 */ + /* up to rev5 they were individual firmware */ + if (rev > 5) + return 5; + } return rev; } @@ -44,56 +56,85 @@ void usage(char *argv[]) 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]); + printf("\n"); + printf("Note: 'pid' must be specified when initializing EEPROM for the first time.\n"); + printf("Valid values are: 0x4242 (N310, N320), 0x4240 (N300), 0xe320 (E320).\n"); } int main(int argc, char *argv[]) { - struct usrp_sulfur_eeprom *ep, *ep2; + struct usrp_sulfur_eeprom *ep, *ep_stored; + u16 rev; u16 mcu_compat; u16 dt_compat; u16 rev_compat; + long pid = 0; if (argc < 6 || argc > 10) { usage(argv); return EXIT_FAILURE; } + rev = atoi(argv[2]); + + /* First, we try reading the existing EEPROM contents. This may fail, + * and that's fine. But if it works, we can use it to fill in missing + * defaults based on the existing data. + */ + ep_stored = usrp_sulfur_eeprom_from_file(NVMEM_PATH_MB); + if (!ep_stored) { + printf("-- EEPROM is either uninitialized or corrupt. Initializing all fields...\n"); + } - long pid = 0x4242; if (argc >= 7) { pid = strtol(argv[6], NULL, 0); + } else if (ep_stored) { + pid = ntohs(ep_stored->pid); + } else { + printf("-- ERROR: Cannot derive PID from existing EEPROM or command line!\n"); + return EXIT_FAILURE; + } + if (pid != N310_PID && pid != N300_PID && pid != E320_PID) { + printf("Invalid PID: %lX\n", pid); + return EXIT_FAILURE; } + /* If no MCU or DT compat specified, either use existing values, or + * derive based on rules defined at the top of this file. + */ if (argc >= 8) { dt_compat = strtol(argv[7], NULL, 0); printf("dt_compat=%u\n", dt_compat); + } else if (ep_stored) { + dt_compat = ntohs(ep_stored->dt_compat); + printf("dt_compat=%u\n", dt_compat); } else { - dt_compat = derive_dt_compat(atoi(argv[2])); + dt_compat = derive_dt_compat(rev, pid); } if (argc >= 9) { mcu_compat = strtol(argv[8], NULL, 0); printf("mcu_compat=%u\n", mcu_compat); + } else if (ep_stored) { + mcu_compat = ntohs(ep_stored->mcu_compat); + printf("mcu_compat=%u\n", mcu_compat); } else { - mcu_compat = derive_mcu_compat(atoi(argv[2])); + mcu_compat = derive_mcu_compat(rev, pid); } if (argc >= 10) { rev_compat = strtol(argv[9], NULL, 0); printf("rev_compat=%u\n", rev_compat); + } else if (ep_stored && rev == ep_stored->rev) { + rev_compat = ntohs(ep_stored->rev_compat); + printf("rev_compat=%u\n", rev_compat); } else { - rev_compat = derive_rev_compat(atoi(argv[2])); + rev_compat = derive_rev_compat(rev, pid); } - if (pid < 0 || pid > 0xFFFF) { - printf("Invalid PID: %lX\n", pid); - return EXIT_FAILURE; - } + if (ep_stored) + free(ep_stored); - /* 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], + ep = usrp_sulfur_eeprom_new(NULL, (u16) pid, rev, argv[1], argv[3], argv[4], argv[5], dt_compat, mcu_compat, rev_compat); @@ -102,7 +143,7 @@ int main(int argc, char *argv[]) free(ep); printf("-- Reading back \n"); - ep2 = usrp_sulfur_eeprom_from_file(NVMEM_PATH_MB); - usrp_sulfur_eeprom_print(ep2); - free(ep2); + ep_stored = usrp_sulfur_eeprom_from_file(NVMEM_PATH_MB); + usrp_sulfur_eeprom_print(ep_stored); + free(ep_stored); } |