From: Larry Finger <larry.finger@lwfinger.net>
Signed-off-by: Michael Buesch <mb@bu3sch.de>
struct cmdline_args cmdargs;
struct cmdline_args cmdargs;
+uint8_t sprom_rev;
+uint16_t sprom_size;
static int value_length_map[] = { /* value to number of bits */
[VALUE_RAW] = 8,
static int value_length_map[] = { /* value to number of bits */
[VALUE_RAW] = 8,
- for (i = 0; i < SPROM_SIZE; i++) {
+ for (i = 0; i < sprom_size; i++) {
pos += snprintf(buffer + pos, bsize - pos - 1,
"%02X", sprom[i] & 0xFF);
}
pos += snprintf(buffer + pos, bsize - pos - 1,
"%02X", sprom[i] & 0xFF);
}
int i;
uint8_t crc = 0xFF;
int i;
uint8_t crc = 0xFF;
- for (i = 0; i < SPROM_SIZE - 1; i++)
+ for (i = 0; i < sprom_size - 1; i++)
crc = crc8(crc, sprom[i]);
crc ^= 0xFF;
crc = crc8(crc, sprom[i]);
crc ^= 0xFF;
- w = write(fd, sprom, SPROM_SIZE);
+ w = write(fd, sprom, sprom_size);
static int write_output_hex(int fd, const uint8_t *sprom)
{
ssize_t w;
static int write_output_hex(int fd, const uint8_t *sprom)
{
ssize_t w;
- char tmp[SPROM_SIZE * 2 + 10] = { 0 };
+ char tmp[SPROM4_SIZE * 2 + 10] = { 0 };
hexdump_sprom(sprom, tmp, sizeof(tmp));
prinfo("Raw output: %s\n", tmp);
hexdump_sprom(sprom, tmp, sizeof(tmp));
prinfo("Raw output: %s\n", tmp);
- w = write(fd, tmp, SPROM_SIZE * 2);
+ w = write(fd, tmp, sprom_size * 2);
{
const uint16_t v = vparm->u.value;
uint16_t tmp = 0;
{
const uint16_t v = vparm->u.value;
uint16_t tmp = 0;
switch (vparm->type) {
case VALUE_RAW:
sprom[vparm->u.raw.offset] = vparm->u.raw.value;
break;
case VALUE_SUBP:
switch (vparm->type) {
case VALUE_RAW:
sprom[vparm->u.raw.offset] = vparm->u.raw.value;
break;
case VALUE_SUBP:
- sprom[SPROM_SUBP + 0] = (v & 0x00FF);
- sprom[SPROM_SUBP + 1] = (v & 0xFF00) >> 8;
+ if (sprom_rev == 4)
+ offset = SPROM4_SUBP;
+ else
+ offset = SPROM_SUBP;
+ sprom[offset + 0] = (v & 0x00FF);
+ sprom[offset + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_SUBV:
sprom[SPROM_SUBV + 0] = (v & 0x00FF);
sprom[SPROM_SUBV + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_PPID:
break;
case VALUE_SUBV:
sprom[SPROM_SUBV + 0] = (v & 0x00FF);
sprom[SPROM_SUBV + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_PPID:
- sprom[SPROM_PPID + 0] = (v & 0x00FF);
- sprom[SPROM_PPID + 1] = (v & 0xFF00) >> 8;
+ if (sprom_rev == 4)
+ offset = SPROM4_PPID;
+ else
+ offset = SPROM_PPID;
+ sprom[offset + 0] = (v & 0x00FF);
+ sprom[offset + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_BFLHI:
sprom[SPROM_BFLHI + 0] = (v & 0x00FF);
break;
case VALUE_BFLHI:
sprom[SPROM_BFLHI + 0] = (v & 0x00FF);
sprom[SPROM_BOARDFLAGS + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_BGMAC:
sprom[SPROM_BOARDFLAGS + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_BGMAC:
- sprom[SPROM_IL0MACADDR + 1] = vparm->u.mac[0];
- sprom[SPROM_IL0MACADDR + 0] = vparm->u.mac[1];
- sprom[SPROM_IL0MACADDR + 3] = vparm->u.mac[2];
- sprom[SPROM_IL0MACADDR + 2] = vparm->u.mac[3];
- sprom[SPROM_IL0MACADDR + 5] = vparm->u.mac[4];
- sprom[SPROM_IL0MACADDR + 4] = vparm->u.mac[5];
+ if (sprom_rev == 3)
+ offset = SPROM3_IL0MACADDR;
+ else if (sprom_rev == 4)
+ offset = SPROM4_IL0MACADDR;
+ else
+ offset = SPROM_IL0MACADDR;
+ sprom[offset + 1] = vparm->u.mac[0];
+ sprom[offset + 0] = vparm->u.mac[1];
+ sprom[offset + 3] = vparm->u.mac[2];
+ sprom[offset + 2] = vparm->u.mac[3];
+ sprom[offset + 5] = vparm->u.mac[4];
+ sprom[offset + 4] = vparm->u.mac[5];
- sprom[SPROM_ET0MACADDR + 1] = vparm->u.mac[0];
- sprom[SPROM_ET0MACADDR + 0] = vparm->u.mac[1];
- sprom[SPROM_ET0MACADDR + 3] = vparm->u.mac[2];
- sprom[SPROM_ET0MACADDR + 2] = vparm->u.mac[3];
- sprom[SPROM_ET0MACADDR + 5] = vparm->u.mac[4];
- sprom[SPROM_ET0MACADDR + 4] = vparm->u.mac[5];
+ if (sprom_rev == 3)
+ offset = SPROM3_ET0MACADDR;
+ else if (sprom_rev == 4)
+ offset = SPROM4_ET0MACADDR;
+ else
+ offset = SPROM_ET0MACADDR;
+ sprom[offset + 1] = vparm->u.mac[0];
+ sprom[offset + 0] = vparm->u.mac[1];
+ sprom[offset + 3] = vparm->u.mac[2];
+ sprom[offset + 2] = vparm->u.mac[3];
+ sprom[offset + 5] = vparm->u.mac[4];
+ sprom[offset + 4] = vparm->u.mac[5];
- sprom[SPROM_ET1MACADDR + 1] = vparm->u.mac[0];
- sprom[SPROM_ET1MACADDR + 0] = vparm->u.mac[1];
- sprom[SPROM_ET1MACADDR + 3] = vparm->u.mac[2];
- sprom[SPROM_ET1MACADDR + 2] = vparm->u.mac[3];
- sprom[SPROM_ET1MACADDR + 5] = vparm->u.mac[4];
- sprom[SPROM_ET1MACADDR + 4] = vparm->u.mac[5];
+ if (sprom_rev == 3)
+ offset = SPROM3_ET1MACADDR;
+ else if (sprom_rev == 4)
+ offset = SPROM4_ET1MACADDR;
+ else
+ offset = SPROM_ET1MACADDR;
+ sprom[offset + 1] = vparm->u.mac[0];
+ sprom[offset + 0] = vparm->u.mac[1];
+ sprom[offset + 3] = vparm->u.mac[2];
+ sprom[offset + 2] = vparm->u.mac[3];
+ sprom[offset + 5] = vparm->u.mac[4];
+ sprom[offset + 4] = vparm->u.mac[5];
break;
case VALUE_ET0PHY:
tmp |= sprom[SPROM_ETHPHY + 0];
break;
case VALUE_ET0PHY:
tmp |= sprom[SPROM_ETHPHY + 0];
sprom[SPROM_ETHPHY + 1] |= (1 << 7);
break;
case VALUE_BREV:
sprom[SPROM_ETHPHY + 1] |= (1 << 7);
break;
case VALUE_BREV:
- sprom[SPROM_BOARDREV + 0] = v;
+ if (sprom_rev == 4)
+ sprom[SPROM4_BOARDREV + 0] = v;
+ else
+ sprom[SPROM_BOARDREV + 0] = v;
break;
case VALUE_LOC:
tmp = (sprom[SPROM_BOARDREV + 1] & 0xF0);
break;
case VALUE_LOC:
tmp = (sprom[SPROM_BOARDREV + 1] & 0xF0);
sprom[SPROM_BOARDREV + 1] = (tmp & 0xFF);
break;
case VALUE_ANTA0:
sprom[SPROM_BOARDREV + 1] = (tmp & 0xFF);
break;
case VALUE_ANTA0:
- sprom[SPROM_BOARDREV + 1] &= ~(1 << 4);
- if (v)
- sprom[SPROM_BOARDREV + 1] |= (1 << 4);
+ if (sprom_rev == 4)
+ sprom[SPROM4_BOARDREV + 1] &= ~(1 << 6);
+ else
+ sprom[SPROM_BOARDREV + 1] &= ~(1 << 6);
+ if (v) {
+ if (sprom_rev == 4) {
+ if (sprom_rev == 4)
+ sprom[SPROM4_BOARDREV + 1] |= ~(1 << 6);
+ else
+ sprom[SPROM_BOARDREV + 1] |= (1 << 6);
+ }
+ }
- sprom[SPROM_BOARDREV + 1] &= ~(1 << 5);
+ sprom[SPROM_BOARDREV + 1] &= ~(1 << 7);
- sprom[SPROM_BOARDREV + 1] |= (1 << 5);
+ sprom[SPROM_BOARDREV + 1] |= (1 << 7);
break;
case VALUE_ANTBG0:
break;
case VALUE_ANTBG0:
- sprom[SPROM_BOARDREV + 1] &= ~(1 << 6);
+ sprom[SPROM_BOARDREV + 1] &= ~(1 << 4);
- sprom[SPROM_BOARDREV + 1] |= (1 << 6);
+ sprom[SPROM_BOARDREV + 1] |= (1 << 4);
break;
case VALUE_ANTBG1:
break;
case VALUE_ANTBG1:
- sprom[SPROM_BOARDREV + 1] &= ~(1 << 7);
+ sprom[SPROM_BOARDREV + 1] &= ~(1 << 5);
- sprom[SPROM_BOARDREV + 1] |= (1 << 7);
+ sprom[SPROM_BOARDREV + 1] |= (1 << 5);
break;
case VALUE_ANTGA:
sprom[SPROM_ANTENNA_GAIN + 0] = (v & 0xFF);
break;
case VALUE_ANTGA:
sprom[SPROM_ANTENNA_GAIN + 0] = (v & 0xFF);
sprom[SPROM_IDL_TSSI_TGT + 1] = (v & 0xFF);
break;
case VALUE_SVER:
sprom[SPROM_IDL_TSSI_TGT + 1] = (v & 0xFF);
break;
case VALUE_SVER:
- sprom[SPROM_VERSION + 0] = (v & 0xFF);
+ if (sprom_rev != 4)
+ sprom[SPROM_VERSION + 0] = (v & 0xFF);
+ else
+ sprom[SPROM4_VERSION + 0] = (v & 0xFF);
break;
default:
prerror("vparm->type internal error (0)\n");
break;
default:
prerror("vparm->type internal error (0)\n");
if (modified) {
/* Recalculate the CRC. */
crc = sprom_crc(sprom);
if (modified) {
/* Recalculate the CRC. */
crc = sprom_crc(sprom);
- sprom[SPROM_VERSION + 1] = crc;
+ sprom[sprom_size - 1] = crc;
struct cmdline_vparm *vparm)
{
const char *desc;
struct cmdline_vparm *vparm)
{
const char *desc;
uint16_t value;
uint16_t tmp;
uint16_t value;
uint16_t tmp;
break;
case VALUE_SUBP:
desc = "Subsytem product ID";
break;
case VALUE_SUBP:
desc = "Subsytem product ID";
- offset = SPROM_SUBP;
- value = sprom[SPROM_SUBP + 0];
- value |= sprom[SPROM_SUBP + 1] << 8;
+ if (sprom_rev == 4)
+ offset = SPROM4_SUBP;
+ else
+ offset = SPROM_SUBP;
+ value = sprom[offset + 0];
+ value |= sprom[offset + 1] << 8;
break;
case VALUE_SUBV:
desc = "Subsystem vendor ID";
break;
case VALUE_SUBV:
desc = "Subsystem vendor ID";
break;
case VALUE_PPID:
desc = "PCI Product ID";
break;
case VALUE_PPID:
desc = "PCI Product ID";
- offset = SPROM_PPID;
- value = sprom[SPROM_PPID + 0];
- value |= sprom[SPROM_PPID + 1] << 8;
+ if (sprom_rev == 4)
+ offset = SPROM4_PPID;
+ else
+ offset = SPROM_PPID;
+ value = sprom[offset + 0];
+ value |= sprom[offset + 1] << 8;
break;
case VALUE_BFLHI:
desc = "High 16 bits of Boardflags";
break;
case VALUE_BFLHI:
desc = "High 16 bits of Boardflags";
- offset = SPROM_BFLHI;
- value = sprom[SPROM_BFLHI + 0];
- value |= sprom[SPROM_BFLHI + 1] << 8;
+ if (sprom_rev == 4)
+ offset = SPROM4_BOARDFLAGS + 2;
+ else
+ offset = SPROM_BFLHI;
+ value = sprom[offset + 0];
+ value |= sprom[offset + 1] << 8;
break;
case VALUE_BFL:
desc = "Low 16 bits of Boardflags";
break;
case VALUE_BFL:
desc = "Low 16 bits of Boardflags";
- offset = SPROM_BOARDFLAGS;
- value = sprom[SPROM_BOARDFLAGS + 0];
- value |= sprom[SPROM_BOARDFLAGS + 1] << 8;
+ if (sprom_rev == 4)
+ offset = SPROM4_BOARDFLAGS;
+ else
+ offset = SPROM_BOARDFLAGS;
+ value = sprom[offset + 0];
+ value |= sprom[offset + 1] << 8;
break;
case VALUE_BGMAC:
desc = "MAC address for 802.11b/g";
break;
case VALUE_BGMAC:
desc = "MAC address for 802.11b/g";
- offset = SPROM_IL0MACADDR;
+ if (sprom_rev == 3)
+ offset = SPROM3_IL0MACADDR;
+ else if (sprom_rev == 4)
+ offset = SPROM4_IL0MACADDR;
+ else
+ offset = SPROM_IL0MACADDR;
value = 0;
break;
case VALUE_ETMAC:
desc = "MAC address for ethernet";
value = 0;
break;
case VALUE_ETMAC:
desc = "MAC address for ethernet";
- offset = SPROM_ET0MACADDR;
+ if (sprom_rev == 3)
+ offset = SPROM3_ET0MACADDR;
+ else if (sprom_rev == 4)
+ offset = SPROM4_ET0MACADDR;
+ else
+ offset = SPROM_ET0MACADDR;
value = 0;
break;
case VALUE_AMAC:
desc = "MAC address for 802.11a";
value = 0;
break;
case VALUE_AMAC:
desc = "MAC address for 802.11a";
- offset = SPROM_ET1MACADDR;
+ if (sprom_rev == 3)
+ offset = SPROM3_ET1MACADDR;
+ else if (sprom_rev == 4)
+ offset = SPROM4_ET1MACADDR;
+ else
+ offset = SPROM_ET1MACADDR;
value = 0;
break;
case VALUE_ET0PHY:
value = 0;
break;
case VALUE_ET0PHY:
break;
case VALUE_BREV:
desc = "Board revision";
break;
case VALUE_BREV:
desc = "Board revision";
- offset = SPROM_BOARDREV;
- value = sprom[SPROM_BOARDREV + 0];
+ if (sprom_rev == 4)
+ offset = SPROM4_BOARDREV;
+ else
+ offset = SPROM_BOARDREV;
+ value = sprom[offset + 0];
break;
case VALUE_LOC:
desc = "Locale / Country Code";
break;
case VALUE_LOC:
desc = "Locale / Country Code";
- offset = SPROM_BOARDREV + 1;
- value = (sprom[SPROM_BOARDREV + 1] & 0x0F);
+ if (sprom_rev == 4) {
+ offset = SPROM4_COUNTRY;
+ value = sprom[offset] | (sprom[offset + 1] << 8);
+ } else {
+ offset = SPROM_BOARDREV;
+ value = (sprom[offset + 1] & 0x0F);
+ }
break;
case VALUE_ANTA0:
desc = "A PHY antenna 0 available";
break;
case VALUE_ANTA0:
desc = "A PHY antenna 0 available";
- offset = SPROM_BOARDREV + 1;
- if (sprom[SPROM_BOARDREV + 1] & (1 << 4))
- value = 1;
+ if (sprom_rev == 4) {
+ offset = SPROM4_ANTAVAIL;
+ if (sprom[offset + 1] & 1)
+ value = 1;
+ } else {
+ offset = SPROM_BOARDREV;
+ value = 0;
+ if (sprom[offset + 2] & (1 << 6))
+ value = 1;
+ }
break;
case VALUE_ANTA1:
desc = "A PHY antenna 1 available";
break;
case VALUE_ANTA1:
desc = "A PHY antenna 1 available";
- offset = SPROM_BOARDREV + 1;
- if (sprom[SPROM_BOARDREV + 1] & (1 << 5))
- value = 1;
+ if (sprom_rev == 4) {
+ offset = SPROM4_ANTAVAIL;
+ if (sprom[offset + 1] & 2)
+ value = 1;
+ } else {
+ offset = SPROM_BOARDREV;
+ value = 0;
+ if (sprom[offset + 2] & (1 << 7))
+ value = 1;
+ }
break;
case VALUE_ANTBG0:
desc = "B/G PHY antenna 0 available";
break;
case VALUE_ANTBG0:
desc = "B/G PHY antenna 0 available";
- offset = SPROM_BOARDREV + 1;
- if (sprom[SPROM_BOARDREV + 1] & (1 << 6))
- value = 1;
+ if (sprom_rev == 4) {
+ offset = SPROM4_ANTAVAIL;
+ if (sprom[offset] & 1)
+ value = 1;
+ } else {
+ offset = SPROM_BOARDREV;
+ value = 0;
+ if (sprom[offset + 2] & (1 << 4))
+ value = 1;
+ }
break;
case VALUE_ANTBG1:
desc = "B/G PHY antenna 1 available";
break;
case VALUE_ANTBG1:
desc = "B/G PHY antenna 1 available";
- offset = SPROM_BOARDREV + 1;
- if (sprom[SPROM_BOARDREV + 1] & (1 << 7))
- value = 1;
+ if (sprom_rev == 4) {
+ offset = SPROM4_ANTAVAIL;
+ if (sprom[offset] & 2)
+ value = 1;
+ } else {
+ offset = SPROM_BOARDREV;
+ value = 0;
+ if (sprom[offset + 2] & (1 << 5))
+ value = 1;
+ }
- desc = "A PHY antenna gain";
- offset = SPROM_ANTENNA_GAIN;
- value = sprom[SPROM_ANTENNA_GAIN];
+ if (sprom_rev != 4) {
+ desc = "A PHY antenna gain";
+ offset = SPROM_ANTENNA_GAIN + 1;
+ } else {
+ desc = "Antenna 1 Gain";
+ offset = SPROM4_ANTENNA_GAIN;
+ }
+ value = sprom[offset + 1];
break;
case VALUE_ANTGBG:
break;
case VALUE_ANTGBG:
- desc = "B/G PHY antenna gain";
- offset = SPROM_ANTENNA_GAIN + 1;
- value = sprom[SPROM_ANTENNA_GAIN + 1];
+ if (sprom_rev != 4) {
+ desc = "B/G PHY antenna gain";
+ offset = SPROM_ANTENNA_GAIN;
+ } else {
+ desc = "Antenna 0 Gain";
+ offset = SPROM4_ANTENNA_GAIN;
+ }
+ value = sprom[offset];
break;
case VALUE_PA0B0:
desc = "pa0b0";
break;
case VALUE_PA0B0:
desc = "pa0b0";
break;
case VALUE_WL0GPIO0:
desc = "LED 0 behaviour";
break;
case VALUE_WL0GPIO0:
desc = "LED 0 behaviour";
- offset = SPROM_WL0GPIO0 + 0;
+ if (sprom_rev != 4)
+ offset = SPROM_WL0GPIO0 + 0;
+ else
+ offset = SPROM4_WL0GPIO0 + 0;
value = sprom[offset];
break;
case VALUE_WL0GPIO1:
desc = "LED 1 behaviour";
value = sprom[offset];
break;
case VALUE_WL0GPIO1:
desc = "LED 1 behaviour";
- offset = SPROM_WL0GPIO0 + 1;
+ if (sprom_rev != 4)
+ offset = SPROM_WL0GPIO0 + 1;
+ else
+ offset = SPROM4_WL0GPIO0 + 1;
value = sprom[offset];
break;
case VALUE_WL0GPIO2:
desc = "LED 2 behaviour";
value = sprom[offset];
break;
case VALUE_WL0GPIO2:
desc = "LED 2 behaviour";
- offset = SPROM_WL0GPIO2 + 0;
+ if (sprom_rev != 4)
+ offset = SPROM_WL0GPIO2 + 0;
+ else
+ offset = SPROM4_WL0GPIO2 + 0;
value = sprom[offset];
break;
case VALUE_WL0GPIO3:
desc = "LED 3 behaviour";
value = sprom[offset];
break;
case VALUE_WL0GPIO3:
desc = "LED 3 behaviour";
- offset = SPROM_WL0GPIO2 + 1;
+ if (sprom_rev != 4)
+ offset = SPROM_WL0GPIO2 + 1;
+ else
+ offset = SPROM4_WL0GPIO2 + 1;
value = sprom[offset];
break;
case VALUE_MAXPA:
desc = "A PHY max powerout";
value = sprom[offset];
break;
case VALUE_MAXPA:
desc = "A PHY max powerout";
- offset = SPROM_MAXPWR + 0;
+ if (sprom_rev != 4)
+ offset = SPROM_MAXPWR + 1;
+ else
+ offset = SPROM4_MAXPWR + 1;
value = sprom[offset];
break;
case VALUE_MAXPBG:
desc = "B/G PHY max powerout";
value = sprom[offset];
break;
case VALUE_MAXPBG:
desc = "B/G PHY max powerout";
- offset = SPROM_MAXPWR + 1;
+ if (sprom_rev != 4)
+ offset = SPROM_MAXPWR + 0;
+ else
+ offset = SPROM4_MAXPWR + 0;
value = sprom[offset];
break;
case VALUE_ITSSIA:
desc = "A PHY idle TSSI target";
value = sprom[offset];
break;
case VALUE_ITSSIA:
desc = "A PHY idle TSSI target";
- offset = SPROM_IDL_TSSI_TGT + 0;
+ if (sprom_rev != 4)
+ offset = SPROM_IDL_TSSI_TGT + 1;
+ else
+ offset = SPROM4_IDL_TSSI_TGT + 1;
value = sprom[offset];
break;
case VALUE_ITSSIBG:
desc = "B/G PHY idle TSSI target";
value = sprom[offset];
break;
case VALUE_ITSSIBG:
desc = "B/G PHY idle TSSI target";
- offset = SPROM_IDL_TSSI_TGT + 1;
+ if (sprom_rev != 4)
+ offset = SPROM_IDL_TSSI_TGT + 0;
+ else
+ offset = SPROM4_IDL_TSSI_TGT + 0;
value = sprom[offset];
break;
case VALUE_SVER:
desc = "SPROM version";
value = sprom[offset];
break;
case VALUE_SVER:
desc = "SPROM version";
- offset = SPROM_VERSION;
+ if (sprom_rev != 4)
+ offset = SPROM_VERSION;
+ else
+ offset = SPROM4_VERSION;
value = sprom[offset];
break;
default:
value = sprom[offset];
break;
default:
uint8_t crc, expected_crc;
crc = sprom_crc(sprom);
uint8_t crc, expected_crc;
crc = sprom_crc(sprom);
- expected_crc = sprom[SPROM_VERSION + 1];
+ expected_crc = sprom[sprom_size - 1];
+
if (crc != expected_crc) {
prerror("Corrupt input data (crc: 0x%02X, expected: 0x%02X)\n",
crc, expected_crc);
if (crc != expected_crc) {
prerror("Corrupt input data (crc: 0x%02X, expected: 0x%02X)\n",
crc, expected_crc);
size_t inlen;
size_t cnt;
unsigned long parsed;
size_t inlen;
size_t cnt;
unsigned long parsed;
- char tmp[SPROM_SIZE * 2 + 10] = { 0 };
+ char tmp[SPROM4_SIZE * 2 + 10] = { 0 };
if (cmdargs.bin_mode) {
/* The input buffer already contains
* the binary sprom data.
*/
if (cmdargs.bin_mode) {
/* The input buffer already contains
* the binary sprom data.
*/
- internal_error_on(bsize != SPROM_SIZE);
- memcpy(sprom, buffer, SPROM_SIZE);
+ internal_error_on(bsize != SPROM_SIZE && bsize != SPROM4_SIZE);
+ memcpy(sprom, buffer, bsize);
prerror("Input data too short\n");
return -1;
}
prerror("Input data too short\n");
return -1;
}
- for (cnt = 0; cnt < SPROM_SIZE; cnt++) {
+ for (cnt = 0; cnt < inlen / 2; cnt++) {
memcpy(tmp, input + cnt * 2, 2);
parsed = strtoul(tmp, NULL, 16);
sprom[cnt] = parsed & 0xFF;
}
memcpy(tmp, input + cnt * 2, 2);
parsed = strtoul(tmp, NULL, 16);
sprom[cnt] = parsed & 0xFF;
}
+ /* check for "magic" data for V4 SPROM */
+ if (sprom[0x40] == 0x72 && sprom[0x41] == 0x53) {
+ sprom_rev = sprom[SPROM4_VERSION];
+ sprom_size = SPROM4_SIZE;
+ } else {
+ sprom_rev = sprom[SPROM_VERSION];
+ sprom_size = SPROM_SIZE;
+ }
if (cmdargs.verbose) {
hexdump_sprom(sprom, tmp, sizeof(tmp));
if (cmdargs.verbose) {
hexdump_sprom(sprom, tmp, sizeof(tmp));
return -1;
}
if (cmdargs.bin_mode) {
return -1;
}
if (cmdargs.bin_mode) {
- if (s.st_size != SPROM_SIZE) {
+ if (s.st_size != SPROM_SIZE && s.st_size != SPROM4_SIZE) {
prerror("The input data is no SPROM Binary data. "
prerror("The input data is no SPROM Binary data. "
- "The size must be exactly %d bytes, "
+ "The size must be exactly %d (V1-3) "
+ "or %d (V4) bytes, "
- SPROM_SIZE, (unsigned int)(s.st_size));
+ SPROM_SIZE, SPROM4_SIZE,
+ (unsigned int)(s.st_size));
if (strncmp(str, "0x", 2) != 0)
goto error;
str += 2;
if (strncmp(str, "0x", 2) != 0)
goto error;
str += 2;
+ /* The following logic presents a problem because the offsets
+ * for V4 SPROMs can be greater than 0xFF; however, the arguments
+ * are parsed before the SPROM revision is known. To fix this
+ * problem, if an input is expecting 0xFF-type input, then input
+ * of 0xFFF will be permitted */
for (i = 0; i < vparm->bits / 4; i++) {
if (str[i] == '\0')
goto error;
}
for (i = 0; i < vparm->bits / 4; i++) {
if (str[i] == '\0')
goto error;
}
- if (str[i] != '\0')
- goto error;
+ if (str[i] != '\0') {
+ if (i == 2)
+ i++; /* add an extra character */
+ if (str[i] != '\0')
+ goto error;
+ }
errno = 0;
v = strtoul(str, NULL, 16);
if (errno)
errno = 0;
v = strtoul(str, NULL, 16);
if (errno)
{
char *delim;
uint8_t value;
{
char *delim;
uint8_t value;
int err;
vparm->type = VALUE_RAW;
int err;
vparm->type = VALUE_RAW;
if (err != 1)
goto error;
offset = vparm->u.value;
if (err != 1)
goto error;
offset = vparm->u.value;
- if (offset >= SPROM_SIZE) {
+ if (offset >= SPROM4_SIZE) {
prerror("--rawset offset too big (>= 0x%02X)\n",
prerror("--rawset offset too big (>= 0x%02X)\n",
return -1;
}
err = parse_value(delim + 1, vparm, NULL);
return -1;
}
err = parse_value(delim + 1, vparm, NULL);
struct cmdline_vparm *vparm)
{
int err;
struct cmdline_vparm *vparm)
{
int err;
if (err != 1)
return -1;
offset = vparm->u.value;
if (err != 1)
return -1;
offset = vparm->u.value;
- if (offset >= SPROM_SIZE) {
+ if (offset >= SPROM4_SIZE) {
prerror("--rawget offset too big (>= 0x%02X)\n",
prerror("--rawget offset too big (>= 0x%02X)\n",
- uint8_t sprom[SPROM_SIZE];
+ uint8_t sprom[SPROM4_SIZE + 10];
char *buffer = NULL;
size_t buffer_size = 0;
char *buffer = NULL;
size_t buffer_size = 0;
#define VERSION ssb_stringify(VERSION_)
#define SPROM_SIZE 128 /* bytes */
#define VERSION ssb_stringify(VERSION_)
#define SPROM_SIZE 128 /* bytes */
/* byte offsets */
#define SPROM_SUBP (0x02 * 2)
/* byte offsets */
#define SPROM_SUBP (0x02 * 2)
+#define SPROM4_SUBP (0x00 * 2)
#define SPROM_SUBV (0x03 * 2)
#define SPROM_PPID (0x04 * 2)
#define SPROM_SUBV (0x03 * 2)
#define SPROM_PPID (0x04 * 2)
+#define SPROM4_PPID (0x02 * 2)
#define SPROM_BFLHI (0x1C * 2)
#define SPROM_IL0MACADDR (0x24 * 2)
#define SPROM_ET0MACADDR (0x27 * 2)
#define SPROM_ET1MACADDR (0x2a * 2)
#define SPROM_BFLHI (0x1C * 2)
#define SPROM_IL0MACADDR (0x24 * 2)
#define SPROM_ET0MACADDR (0x27 * 2)
#define SPROM_ET1MACADDR (0x2a * 2)
+#define SPROM3_IL0MACADDR (0x25 * 2)
+#define SPROM3_ET0MACADDR (0x28 * 2)
+#define SPROM3_ET1MACADDR (0x28 * 2)
+#define SPROM4_IL0MACADDR (0x26 * 2)
+#define SPROM4_ET0MACADDR (0x18 * 2)
+#define SPROM4_ET1MACADDR (0x26 * 2)
#define SPROM_ETHPHY (0x2d * 2)
#define SPROM_BOARDREV (0x2e * 2)
#define SPROM_ETHPHY (0x2d * 2)
#define SPROM_BOARDREV (0x2e * 2)
+#define SPROM4_BOARDREV (0x21 * 2)
+#define SPROM4_ANTAVAIL (0x2e * 2)
+#define SPROM4_COUNTRY (0x29 * 2)
#define SPROM_PA0B0 (0x2f * 2)
#define SPROM_PA0B1 (0x30 * 2)
#define SPROM_PA0B2 (0x31 * 2)
#define SPROM_WL0GPIO0 (0x32 * 2)
#define SPROM_WL0GPIO2 (0x33 * 2)
#define SPROM_PA0B0 (0x2f * 2)
#define SPROM_PA0B1 (0x30 * 2)
#define SPROM_PA0B2 (0x31 * 2)
#define SPROM_WL0GPIO0 (0x32 * 2)
#define SPROM_WL0GPIO2 (0x33 * 2)
+#define SPROM4_WL0GPIO0 (0x2b * 2)
+#define SPROM4_WL0GPIO2 (0x2c * 2)
#define SPROM_MAXPWR (0x34 * 2)
#define SPROM_MAXPWR (0x34 * 2)
+#define SPROM4_MAXPWR (0x45 * 2)
#define SPROM_PA1B0 (0x35 * 2)
#define SPROM_PA1B1 (0x36 * 2)
#define SPROM_PA1B2 (0x37 * 2)
#define SPROM_IDL_TSSI_TGT (0x38 * 2)
#define SPROM_PA1B0 (0x35 * 2)
#define SPROM_PA1B1 (0x36 * 2)
#define SPROM_PA1B2 (0x37 * 2)
#define SPROM_IDL_TSSI_TGT (0x38 * 2)
+#define SPROM4_IDL_TSSI_TGT (0x40 * 2)
#define SPROM_BOARDFLAGS (0x39 * 2)
#define SPROM_BOARDFLAGS (0x39 * 2)
+#define SPROM4_BOARDFLAGS (0x22 * 2)
#define SPROM_ANTENNA_GAIN (0x3a * 2)
#define SPROM_ANTENNA_GAIN (0x3a * 2)
+#define SPROM4_ANTENNA_GAIN (0x2f * 2)
#define SPROM_VERSION (0x3f * 2)
#define SPROM_VERSION (0x3f * 2)
+#define SPROM4_VERSION (0xdb * 2)
enum valuetype {
VALUE_RAW,
enum valuetype {
VALUE_RAW,
VALUE_ET1MDC,
VALUE_BREV,
VALUE_LOC,
VALUE_ET1MDC,
VALUE_BREV,
VALUE_LOC,
- VALUE_ANTA0,
- VALUE_ANTA1,
VALUE_ANTBG0,
VALUE_ANTBG1,
VALUE_ANTBG0,
VALUE_ANTBG1,
+ VALUE_ANTA0,
+ VALUE_ANTA1,
VALUE_PA0B0,
VALUE_PA0B1,
VALUE_PA0B2,
VALUE_PA0B0,
VALUE_PA0B1,
VALUE_PA0B2,
VALUE_WL0GPIO1,
VALUE_WL0GPIO2,
VALUE_WL0GPIO3,
VALUE_WL0GPIO1,
VALUE_WL0GPIO2,
VALUE_WL0GPIO3,
VALUE_SVER,
VALUE_LAST = VALUE_SVER,
};
VALUE_SVER,
VALUE_LAST = VALUE_SVER,
};
uint16_t value;
uint8_t mac[6];
struct {
uint16_t value;
uint8_t mac[6];
struct {
- uint8_t value;
- uint8_t offset;
+ uint16_t value;
+ uint16_t offset;