Skip to content

Commit

Permalink
eep9300: RAW EEPROM/OTP reading support
Browse files Browse the repository at this point in the history
Add support for RAW EEPROM and OTP contents loading if it is requested
by the caller. It assumes complete contents ignoring, including I/O
byteswapping check bypassing and decompression avoidance.

A WNIC can contain two data sources: EEPROM and OTP, with EEPROM being
tried first in the common case. So the EEPROM RAW reading code has been
augmented with empty/missed EEPROM checks to skip the EEPROM and
automatically continue with OTP memory as the data souce. The user can
still explicitly specify which memory should be read using the
appropriate utiltiy command: saveraweep or saverawotp.

The change was runtime tested with QCA9565 based card. The card contains
data only in the OTP memory, but the EEPROM reading should be reliable
as well.

Refs: gh-4
  • Loading branch information
rsa9000 committed Sep 19, 2022
1 parent 9286e6d commit c26858b
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions eep_9300.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,40 @@ static bool eep_9300_load_blob(struct atheepmgr *aem)
return true;
}

/**
* Special handler for RAW EEPROM data loading
*/
static bool eep_9300_load_raw_eeprom(struct atheepmgr *aem)
{
const int eepsz = 0x1000; /* Max EEPROM read length in words */
int i;

if (aem->verbose)
printf("RAW EEPROM read [0x0000...0x%04x] words\n", eepsz - 1);
if (ar9300_eep2buf(aem, eepsz) != 0)
return false;

/* Check for unsoldered EEPROM */
for (i = 0; i < aem->eep_len; ++i)
if (aem->eep_buf[i] != 0x0000)
break;
if (i == aem->eep_len) {
fprintf(stderr, "EEPROM contains only 0x0000 words and looks unsoldered, ignoring.\n");
return false;
}

/* Check for empty EEPROM */
for (i = 0; i < aem->eep_len; ++i)
if (aem->eep_buf[i] != 0xffff)
break;
if (i == aem->eep_len) {
fprintf(stderr, "EEPROM contains only 0xffff words and looks empty, ignoring.\n");
return false;
}

return true;
}

/*
* Read the configuration data from the eeprom uncompress it if necessary.
*/
Expand All @@ -284,6 +318,9 @@ static bool eep_9300_load_eeprom(struct atheepmgr *aem, bool raw)
emp->buf_is_be = 0; /* EEPROM is always in Little-endians */
aem->eep_len = 0; /* Reset internal buffer contents */

if (raw) /* RAW reading is a bit special case */
return eep_9300_load_raw_eeprom(aem);

/* Check byteswaping requirements */
if (!EEP_READ(AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
fprintf(stderr, "EEPROM magic read failed\n");
Expand Down Expand Up @@ -331,6 +368,25 @@ static bool eep_9300_load_eeprom(struct atheepmgr *aem, bool raw)
return true;
}

/**
* Special handler for RAW OTP data loading
*/
static bool eep_9300_load_raw_otp(struct atheepmgr *aem)
{
const int otpsz = 0x400; /* Max OTP read length in bytes */

if (aem->verbose)
printf("RAW OTP read [0x0000...0x%04x] bytes\n", otpsz - 1);
if (ar9300_otp2buf(aem, otpsz) != 0)
return false;

/* NB: OTP loading is called in last order, so do not check for
* OTP memory emptiness and return the buffer as-is.
*/

return true;
}

/*
* Read the configuration data from the OTP memory uncompress it if necessary.
*/
Expand All @@ -342,6 +398,9 @@ static bool eep_9300_load_otp(struct atheepmgr *aem, bool raw)
emp->buf_is_be = aem->host_is_be; /* OTP utilize native-endians */
aem->eep_len = 0; /* Reset internal buffer contents */

if (raw) /* RAW reading is a bit special case */
return eep_9300_load_raw_otp(aem);

cptr = AR9300_BASE_ADDR;
if (aem->verbose)
printf("Trying OTP access at Address 0x%04x\n", cptr);
Expand Down Expand Up @@ -822,6 +881,7 @@ static bool eep_9300_update_eeprom(struct atheepmgr *aem, int param,
const struct eepmap eepmap_9300 = {
.name = "9300",
.desc = "EEPROM map for modern .11n chips (AR93xx/AR94xx/AR95xx/etc.)",
.features = EEPMAP_F_RAW_EEP | EEPMAP_F_RAW_OTP,
.chip_regs = {
.srev = 0x4020,
},
Expand Down

0 comments on commit c26858b

Please sign in to comment.