-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On Jun 24, 2008, at 19:03 PM, Pavel Roskin wrote:
> Hello, Dale!
>
> It would be great if you write in plain text without HTML. It would
> make it easier to quote your message.
>
> On Tue, 2008-06-24 at 17:14 -0400, Dale Walsh wrote:
>
>> Since I can't be sure which version I actually have I started with
>> what I had with the fix for the subsystem product code and moved
>> forward from there.
>
> Please don't do it this way. In general case, it would be
> dangerous to
> integrate your changes in nobody, even you, knows what was changed by
> you and what was present in the base code. That's why patches are
> used
> to send code changes.
>
>> Other than adding some checking that seemed to be going on with the
>> "sprom_rev 4", (I added similar checking in a couple of places) the
>> "sprom_rev 4" is still broken but "sprom_rev 2" appears to now works
>> properly.
>
> I understand you are talking about your code, not about my patch?
>
>> case VALUE_ANTGA:
>> if (sprom_rev == 4)
>> sprom[SPROM4_ANTENNA_GAIN + 2] = (v & 0xFF);
>> else
>> sprom[SPROM_ANTENNA_GAIN + 2] = (v & 0xFF);
>> break;
>
> Do you have any reason to believe that antenna gain for 802.11a is
> located there? That's a separate 16-bit register.
>
>> case VALUE_ANTGBG:
>> if (sprom_rev == 4)
>> sprom[SPROM4_ANTENNA_GAIN + 0] = (v & 0xFF);
>> else
>> sprom[SPROM_ANTENNA_GAIN + 0] = (v & 0xFF);
>> break;
>
> The same question about 802.11bg. Do you actually see any changes if
> you modify SPROM?
>
>> case VALUE_ANTGA:
>> 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];
>
> That's misleading. You are telling users that the data is at offset
> 0x75, but you are reading it at 0x76.
>
> Your code is consistent, but I don't see any evidence that it's
> correct.
>
> --
> Regards,
> Pavel Roskin
I apologize, I was working in a Developer Environment as it makes the
source much easier to read and follow and it allows me to change the
code during run-time, reposting in plain-text.
Your patch did not restore all functionality to rev 2.
As I stated, since I do not have anything concrete to work from I am
guessing at the expected locations and registers (bits) but after
close examination, I concluded the bytes are at "SPROM_BOARDREV + 2"
as seen in the html post and now this more legible post.
I added similar board rev logic in additional locations (ex. added to
anta1 cause it existed in anta0 and worked properly).
The logic behind some of the math was a little confusing so I added a
simple bit decoder to display the bits for the registers so I could
see what was changing as I went along and removed it after I was
satisfied with the results.
Now, since I don't have an actual decode of the bytes I can only
assume that the bits (registers) currently used for anta0, anta1,
antbg0, antbg1, antga and antbgb are correct and have made my
modifications based on this assumption.
With regards to the rev 4, assuming that antgbg corresponds to "(B/G
PHY antenna gain - Antenna 0 Gain)" and antga corresponds to "(A PHY
antenna gain - Antenna 1 Gain)", I made changes to the appropriate
sections and these appear to be functioning properly.
I would like to note that there should be 3 antenna entries in rev 4
as reported to me by Broadcom however they did not provide a decode
of the bytes or the sprom data.
My currently ploy with Broadcom since they are manufacturing (or
working with a manufacturer) an N-PHY card to my specifications is
that the custom OS requires a driver and I'll need the N-PHY
information to generate the driver but this seemed to have done
little to help me obtain it since they are claiming I should be able
to use existing drivers with an ndis type wrapper.
The current attached source appears to display and modify the correct
bits and as far as I can tell, modification of the rev 2 data is
proper although I have not tested everything.
This source is based on code Larry provided
___________________________________________________
/*
Broadcom Sonics Silicon Backplane bus SPROM data modification tool
Copyright (c) 2006-2007 Michael Buesch <[EMAIL PROTECTED]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "ssb_sprom.h"
#include "utils.h"
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
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,
[VALUE_SUBP] = 16,
[VALUE_SUBV] = 16,
[VALUE_PPID] = 16,
[VALUE_BFLHI] = 16,
[VALUE_BFL] = 16,
[VALUE_BGMAC] = -1,
[VALUE_ETMAC] = -1,
[VALUE_AMAC] = -1,
[VALUE_ET0PHY] = 8,
[VALUE_ET1PHY] = 8,
[VALUE_ET0MDC] = 1,
[VALUE_ET1MDC] = 1,
[VALUE_BREV] = 8,
[VALUE_LOC] = 4,
[VALUE_ANTA0] = 1,
[VALUE_ANTA1] = 1,
[VALUE_ANTBG0] = 1,
[VALUE_ANTBG1] = 1,
[VALUE_ANTGA] = 8,
[VALUE_ANTGBG] = 8,
[VALUE_PA0B0] = 16,
[VALUE_PA0B1] = 16,
[VALUE_PA0B2] = 16,
[VALUE_PA1B0] = 16,
[VALUE_PA1B1] = 16,
[VALUE_PA1B2] = 16,
[VALUE_WL0GPIO0] = 8,
[VALUE_WL0GPIO1] = 8,
[VALUE_WL0GPIO2] = 8,
[VALUE_WL0GPIO3] = 8,
[VALUE_MAXPA] = 8,
[VALUE_MAXPBG] = 8,
[VALUE_ITSSIA] = 8,
[VALUE_ITSSIBG] = 8,
[VALUE_SVER] = 8,
};
static int hexdump_sprom(const uint8_t *sprom, char *buffer, size_t
bsize)
{
int i, pos = 0;
for (i = 0; i < sprom_size; i++) {
pos += snprintf(buffer + pos, bsize - pos - 1,
"%02X", sprom[i] & 0xFF);
}
return pos + 1;
}
static uint8_t sprom_crc(const uint8_t *sprom)
{
int i;
uint8_t crc = 0xFF;
for (i = 0; i < sprom_size - 1; i++)
crc = crc8(crc, sprom[i]);
crc ^= 0xFF;
return crc;
}
static int write_output_binary(int fd, const uint8_t *sprom)
{
ssize_t w;
w = write(fd, sprom, sprom_size);
if (w < 0)
return -1;
return 0;
}
static int write_output_hex(int fd, const uint8_t *sprom)
{
ssize_t w;
char tmp[SPROM4_SIZE * 2 + 10] = { 0 };
hexdump_sprom(sprom, tmp, sizeof(tmp));
prinfo("Raw output: %s\n", tmp);
w = write(fd, tmp, sprom_size * 2);
if (w < 0)
return -1;
return 0;
}
static int write_output(int fd, const uint8_t *sprom)
{
int err;
if (cmdargs.outfile) {
err = ftruncate(fd, 0);
if (err) {
prerror("Could not truncate --outfile %s\n",
cmdargs.outfile);
return -1;
}
}
if (cmdargs.bin_mode)
err = write_output_binary(fd, sprom);
else
err = write_output_hex(fd, sprom);
if (err)
prerror("Could not write output data.\n");
return err;
}
static int modify_value(uint8_t *sprom,
struct cmdline_vparm *vparm)
{
const uint16_t v = vparm->u.value;
uint16_t tmp = 0;
uint16_t offset;
switch (vparm->type) {
case VALUE_RAW:
sprom[vparm->u.raw.offset] = vparm->u.raw.value;
break;
case VALUE_SUBP:
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:
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);
sprom[SPROM_BFLHI + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_BFL:
sprom[SPROM_BOARDFLAGS + 0] = (v & 0x00FF);
sprom[SPROM_BOARDFLAGS + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_BGMAC:
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];
break;
case VALUE_ETMAC:
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];
break;
case VALUE_AMAC:
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];
tmp |= sprom[SPROM_ETHPHY + 1] << 8;
tmp = ((tmp & 0x001F) | (v & 0x1F));
sprom[SPROM_ETHPHY + 0] = (tmp & 0x00FF);
sprom[SPROM_ETHPHY + 1] = (tmp & 0xFF00) >> 8;
break;
case VALUE_ET1PHY:
tmp |= sprom[SPROM_ETHPHY + 0];
tmp |= sprom[SPROM_ETHPHY + 1] << 8;
tmp = ((tmp & 0x03E0) | ((v & 0x1F) << 5));
sprom[SPROM_ETHPHY + 0] = (tmp & 0x00FF);
sprom[SPROM_ETHPHY + 1] = (tmp & 0xFF00) >> 8;
break;
case VALUE_ET0MDC:
sprom[SPROM_ETHPHY + 1] &= ~(1 << 6);
if (v)
sprom[SPROM_ETHPHY + 1] |= (1 << 6);
break;
case VALUE_ET1MDC:
sprom[SPROM_ETHPHY + 1] &= ~(1 << 7);
if (v)
sprom[SPROM_ETHPHY + 1] |= (1 << 7);
break;
case VALUE_BREV:
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);
tmp |= (v & 0x0F);
sprom[SPROM_BOARDREV + 1] = (tmp & 0xFF);
break;
case VALUE_ANTA0:
if (sprom_rev == 4)
sprom[SPROM4_BOARDREV + 1] &= ~(1 << 6);
else
sprom[SPROM_BOARDREV + 2] &= ~(1 << 6);
if (v) {
if (sprom_rev == 4) {
sprom[SPROM4_BOARDREV + 1] |= (1 << 6);
} else {
sprom[SPROM_BOARDREV + 2] |= (1 << 6);
}
}
break;
case VALUE_ANTA1:
if (sprom_rev == 4)
sprom[SPROM4_BOARDREV + 1] &= ~(1 << 7);
else
sprom[SPROM_BOARDREV + 2] &= ~(1 << 7);
if (v)
if (sprom_rev == 4) {
sprom[SPROM4_BOARDREV + 1] |= (1 << 7);
} else {
sprom[SPROM_BOARDREV + 2] |= (1 << 7);
}
break;
case VALUE_ANTBG0:
if (sprom_rev == 4)
sprom[SPROM4_BOARDREV + 1] &= ~(1 << 4);
else
sprom[SPROM_BOARDREV + 2] &= ~(1 << 4);
if (v)
if (sprom_rev == 4) {
sprom[SPROM4_BOARDREV + 1] |= (1 << 4);
} else {
sprom[SPROM_BOARDREV + 2] |= (1 << 4);
}
break;
case VALUE_ANTBG1:
if (sprom_rev == 4)
sprom[SPROM4_BOARDREV + 1] &= ~(1 << 5);
else
sprom[SPROM_BOARDREV + 2] &= ~(1 << 5);
if (v)
if (sprom_rev == 4) {
sprom[SPROM4_BOARDREV + 1] |= (1 << 5);
} else {
sprom[SPROM_BOARDREV + 2] |= (1 << 5);
}
break;
case VALUE_ANTGA:
if (sprom_rev == 4)
sprom[SPROM4_ANTENNA_GAIN + 1] = (v & 0xFF);
else
sprom[SPROM_ANTENNA_GAIN + 2] = (v & 0xFF);
break;
case VALUE_ANTGBG:
if (sprom_rev == 4)
sprom[SPROM4_ANTENNA_GAIN + 0] = (v & 0xFF);
else
sprom[SPROM_ANTENNA_GAIN + 0] = (v & 0xFF);
break;
case VALUE_PA0B0:
sprom[SPROM_PA0B0 + 0] = (v & 0x00FF);
sprom[SPROM_PA0B0 + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_PA0B1:
sprom[SPROM_PA0B1 + 0] = (v & 0x00FF);
sprom[SPROM_PA0B1 + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_PA0B2:
sprom[SPROM_PA0B2 + 0] = (v & 0x00FF);
sprom[SPROM_PA0B2 + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_PA1B0:
sprom[SPROM_PA1B0 + 0] = (v & 0x00FF);
sprom[SPROM_PA1B0 + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_PA1B1:
sprom[SPROM_PA1B1 + 0] = (v & 0x00FF);
sprom[SPROM_PA1B1 + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_PA1B2:
sprom[SPROM_PA1B2 + 0] = (v & 0x00FF);
sprom[SPROM_PA1B2 + 1] = (v & 0xFF00) >> 8;
break;
case VALUE_WL0GPIO0:
sprom[SPROM_WL0GPIO0 + 0] = (v & 0xFF);
break;
case VALUE_WL0GPIO1:
sprom[SPROM_WL0GPIO0 + 1] = (v & 0xFF);
break;
case VALUE_WL0GPIO2:
sprom[SPROM_WL0GPIO2 + 0] = (v & 0xFF);
break;
case VALUE_WL0GPIO3:
sprom[SPROM_WL0GPIO2 + 1] = (v & 0xFF);
break;
case VALUE_MAXPA:
sprom[SPROM_MAXPWR + 0] = (v & 0xFF);
break;
case VALUE_MAXPBG:
sprom[SPROM_MAXPWR + 1] = (v & 0xFF);
break;
case VALUE_ITSSIA:
sprom[SPROM_IDL_TSSI_TGT + 0] = (v & 0xFF);
break;
case VALUE_ITSSIBG:
sprom[SPROM_IDL_TSSI_TGT + 1] = (v & 0xFF);
break;
case VALUE_SVER:
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");
exit(1);
}
return 0;
}
static int modify_sprom(uint8_t *sprom)
{
struct cmdline_vparm *vparm;
int i;
int modified = 0;
uint8_t crc;
for (i = 0; i < cmdargs.nr_vparm; i++) {
vparm = &(cmdargs.vparm[i]);
if (!vparm->set)
continue;
modify_value(sprom, vparm);
modified = 1;
}
if (modified) {
/* Recalculate the CRC. */
crc = sprom_crc(sprom);
sprom[sprom_size - 1] = crc;
}
return modified;
}
static void display_value(const uint8_t *sprom,
struct cmdline_vparm *vparm)
{
const char *desc;
uint16_t offset;
uint16_t value;
uint16_t tmp;
switch (vparm->type) {
case VALUE_RAW:
desc = "RAW";
offset = vparm->u.raw.offset;
value = sprom[offset];
break;
case VALUE_SUBP:
desc = "Subsytem product ID";
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";
offset = SPROM_SUBV;
value = sprom[SPROM_SUBV + 0];
value |= sprom[SPROM_SUBV + 1] << 8;
break;
case VALUE_PPID:
desc = "PCI Product ID";
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";
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";
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";
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";
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";
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:
desc = "Ethernet phy settings (0)";
offset = SPROM_ETHPHY;
tmp = sprom[SPROM_ETHPHY + 0];
tmp |= sprom[SPROM_ETHPHY + 1] << 8;
value = (tmp & 0x001F);
break;
case VALUE_ET1PHY:
desc = "Ethernet phy settings (1)";
offset = SPROM_ETHPHY;
tmp = sprom[SPROM_ETHPHY + 0];
tmp |= sprom[SPROM_ETHPHY + 1] << 8;
value = (tmp & 0x03E0) >> 5;
break;
case VALUE_ET0MDC:
desc = "et0mdcport";
offset = SPROM_ETHPHY + 1;
value = 0;
if (sprom[SPROM_ETHPHY + 1] & (1 << 6))
value = 1;
break;
case VALUE_ET1MDC:
desc = "et1mdcport";
offset = SPROM_ETHPHY + 1;
value = 0;
if (sprom[SPROM_ETHPHY + 1] & (1 << 7))
value = 1;
break;
case VALUE_BREV:
desc = "Board revision";
if (sprom_rev == 4)
offset = SPROM4_BOARDREV;
else
offset = SPROM_BOARDREV;
value = sprom[offset];
break;
case VALUE_LOC:
desc = "Locale / Country Code";
if (sprom_rev == 4) {
offset = SPROM4_COUNTRY;
value = sprom[offset] | (sprom[offset + 1] << 8);
} else {
offset = SPROM_COUNTRY;
value = (sprom[offset] & 0x0F);
}
break;
case VALUE_ANTA0:
desc = "A PHY antenna 0 available";
value = 0;
if (sprom_rev == 4) {
offset = SPROM4_ANTAVAIL + 1;
if (sprom[offset] & 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";
value = 0;
if (sprom_rev == 4) {
offset = SPROM4_ANTAVAIL + 1;
if (sprom[offset] & 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";
value = 0;
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";
value = 0;
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;
}
break;
case VALUE_ANTGA:
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:
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";
offset = SPROM_PA0B0;
value = sprom[offset + 0];
value |= sprom[offset + 1] << 8;
break;
case VALUE_PA0B1:
desc = "pa0b1";
offset = SPROM_PA0B1;
value = sprom[offset + 0];
value |= sprom[offset + 1] << 8;
break;
case VALUE_PA0B2:
desc = "pa0b2";
offset = SPROM_PA0B2;
value = sprom[offset + 0];
value |= sprom[offset + 1] << 8;
break;
case VALUE_PA1B0:
desc = "pa1b0";
offset = SPROM_PA1B0;
value = sprom[offset + 0];
value |= sprom[offset + 1] << 8;
break;
case VALUE_PA1B1:
desc = "pa1b1";
offset = SPROM_PA1B1;
value = sprom[offset + 0];
value |= sprom[offset + 1] << 8;
break;
case VALUE_PA1B2:
desc = "pa1b2";
offset = SPROM_PA1B2;
value = sprom[offset + 0];
value |= sprom[offset + 1] << 8;
break;
case VALUE_WL0GPIO0:
desc = "LED 0 behaviour";
if (sprom_rev != 4)
offset = SPROM_WL0GPIO0 + 0;
else
offset = SPROM4_WL0GPIO0 + 0;
value = sprom[offset];
break;
case VALUE_WL0GPIO1:
desc = "LED 1 behaviour";
if (sprom_rev != 4)
offset = SPROM_WL0GPIO0 + 1;
else
offset = SPROM4_WL0GPIO0 + 1;
value = sprom[offset];
break;
case VALUE_WL0GPIO2:
desc = "LED 2 behaviour";
if (sprom_rev != 4)
offset = SPROM_WL0GPIO2 + 0;
else
offset = SPROM4_WL0GPIO2 + 0;
value = sprom[offset];
break;
case VALUE_WL0GPIO3:
desc = "LED 3 behaviour";
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";
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";
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";
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";
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";
if (sprom_rev != 4)
offset = SPROM_VERSION;
else
offset = SPROM4_VERSION;
value = sprom[offset];
break;
default:
prerror("vparm->type internal error (1)\n");
exit(1);
}
switch (vparm->bits) {
case 1:
prdata("SPROM(0x%02X, %s) = %s\n",
offset, desc, value ? "ON" : "OFF");
break;
case 4:
prdata("SPROM(0x%02X, %s) = 0x%01X\n",
offset, desc, (value & 0xF));
break;
case 8:
prdata("SPROM(0x%02X, %s) = 0x%02X\n",
offset, desc, (value & 0xFF));
break;
case 16:
prdata("SPROM(0x%02X, %s) = 0x%04X\n",
offset, desc, (value & 0xFFFF));
break;
case -1: {
/* MAC address. */
const uint8_t *p = &(sprom[offset]);
prdata("SPROM(0x%02X, %s) = %02x:%02x:%02x:%02x:%02x:%02x\n",
offset, desc,
p[1], p[0], p[3], p[2], p[5], p[4]);
break;
}
default:
prerror("vparm->bits internal error (%d)\n",
vparm->bits);
exit(1);
}
}
static int display_sprom(const uint8_t *sprom)
{
struct cmdline_vparm *vparm;
int i;
for (i = 0; i < cmdargs.nr_vparm; i++) {
vparm = &(cmdargs.vparm[i]);
if (vparm->set)
continue;
display_value(sprom, vparm);
}
return 0;
}
static int validate_input(const uint8_t *sprom)
{
uint8_t crc, expected_crc;
crc = sprom_crc(sprom);
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 (!cmdargs.force)
return 1;
}
return 0;
}
static int parse_input(uint8_t *sprom, char *buffer, size_t bsize)
{
char *input;
size_t inlen;
size_t cnt;
unsigned long parsed;
char tmp[SPROM4_SIZE * 2 + 10] = { 0 };
if (cmdargs.bin_mode) {
/* The input buffer already contains
* the binary sprom data.
*/
internal_error_on(bsize != SPROM_SIZE && bsize != SPROM4_SIZE);
memcpy(sprom, buffer, bsize);
return 0;
}
inlen = bsize;
input = strchr(buffer, ':');
if (input) {
input++;
inlen -= input - buffer;
} else
input = buffer;
if (inlen < SPROM_SIZE * 2) {
prerror("Input data too short\n");
return -1;
}
for (cnt = 0; cnt < inlen / 2; cnt++) {
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));
prinfo("Raw input: %s\n", tmp);
}
return 0;
}
static int read_infile(int fd, char **buffer, size_t *bsize)
{
struct stat s;
int err;
ssize_t r;
err = fstat(fd, &s);
if (err) {
prerror("Could not stat input file.\n");
return err;
}
if (s.st_size == 0) {
prerror("No input data\n");
return -1;
}
if (cmdargs.bin_mode) {
if (s.st_size != SPROM_SIZE && s.st_size != SPROM4_SIZE) {
prerror("The input data is no SPROM Binary data. "
"The size must be exactly %d (V1-3) "
"or %d (V4) bytes, "
"but it is %u bytes\n",
SPROM_SIZE, SPROM4_SIZE,
(unsigned int)(s.st_size));
return -1;
}
} else {
if (s.st_size > 1024 * 1024) {
prerror("The input data does not look "
"like SPROM HEX data (too long).\n");
return -1;
}
}
*bsize = s.st_size;
if (!cmdargs.bin_mode)
(*bsize)++;
*buffer = malloce(*bsize);
r = read(fd, *buffer, s.st_size);
if (r != s.st_size) {
prerror("Could not read input data.\n");
return -1;
}
if (!cmdargs.bin_mode)
(*buffer)[r] = '\0';
return 0;
}
static void close_infile(int fd)
{
if (cmdargs.infile)
close(fd);
}
static void close_outfile(int fd)
{
if (cmdargs.outfile)
close(fd);
}
static int open_infile(int *fd)
{
*fd = STDIN_FILENO;
if (!cmdargs.infile)
return 0;
*fd = open(cmdargs.infile, O_RDONLY);
if (*fd < 0) {
prerror("Could not open --infile %s\n",
cmdargs.infile);
return -1;
}
return 0;
}
static int open_outfile(int *fd)
{
*fd = STDOUT_FILENO;
if (!cmdargs.outfile)
return 0;
*fd = open(cmdargs.outfile, O_RDWR | O_CREAT, 0644);
if (*fd < 0) {
prerror("Could not open --outfile %s\n",
cmdargs.outfile);
return -1;
}
return 0;
}
static void print_banner(int forceprint)
{
const char *str = "Broadcom-SSB SPROM data modification tool version
" VERSION "\n";
if (forceprint)
prdata(str);
else
prinfo(str);
}
static void print_usage(int argc, char *argv[])
{
print_banner(1);
prdata("\nUsage: %s [OPTION]\n", argv[0]);
prdata(" -i|--input FILE Input file\n");
prdata(" -o|--output FILE Output file\n");
prdata(" -b|--binmode The Input data is plain binary data
and Output will be binary\n");
prdata(" -V|--verbose Be verbose\n");
prdata(" -f|--force Override error checks\n");
prdata(" -v|--version Print version\n");
prdata(" -h|--help Print this help\n");
prdata("\n");
prdata("Value Parameters:\n");
prdata("\n");
prdata(" -s|--rawset OFF,VAL Set a VALue at a byte-OFFset\n");
prdata(" -g|--rawget OFF Get a value at a byte-OFFset\n");
prdata("\n");
prdata("Predefined values (for displaying (GET) or modification):\n");
prdata(" --subp [0xFFFF] Subsytem product ID for PCI\n");
prdata(" --subv [0xFFFF] Subsystem vendor ID for PCI\n");
prdata(" --ppid [0xFFFF] Product ID for PCI\n");
prdata(" --bflhi [0xFFFF] High 16 bits of boardflags (only if
spromversion > 1)\n");
prdata(" --bfl [0xFFFF] Low 16 bits of boardflags\n");
prdata(" --bgmac [MAC-ADDR] MAC address for 802.11b/g\n");
prdata(" --etmac [MAC-ADDR] MAC address for ethernet, see b44
driver\n");
prdata(" --amac [MAC-ADDR] Mac address for 802.11a\n");
prdata(" --et0phy [0xFF]\n");
prdata(" --et1phy [0xFF]\n");
prdata(" --et0mdc [BOOL]\n");
prdata(" --et1mdc [BOOL]\n");
prdata(" --brev [0xFF] Board revision\n");
prdata(" --loc [0xF] Country code\n");
prdata(" --anta0 [BOOL] Antenna 0 available for A PHY\n");
prdata(" --anta1 [BOOL] Antenna 1 available for A PHY\n");
prdata(" --antbg0 [BOOL] Antenna 0 available for B/G PHY\n");
prdata(" --antbg1 [BOOL] Antenna 1 available for B/G PHY\n");
prdata(" --antga [0xFF] Antenna gain for A PHY\n");
prdata(" --antgbg [0xFF] Antenna gain for B/G PHY\n");
prdata(" --pa0b0 [0xFFFF]\n");
prdata(" --pa0b1 [0xFFFF]\n");
prdata(" --pa0b2 [0xFFFF]\n");
prdata(" --pa1b0 [0xFFFF]\n");
prdata(" --pa1b1 [0xFFFF]\n");
prdata(" --pa1b2 [0xFFFF]\n");
prdata(" --wl0gpio0 [0xFF] LED 0 behaviour\n");
prdata(" --wl0gpio1 [0xFF] LED 1 behaviour\n");
prdata(" --wl0gpio2 [0xFF] LED 2 behaviour\n");
prdata(" --wl0gpio3 [0xFF] LED 3 behaviour\n");
prdata(" --maxpa [0xFF] A PHY max power\n");
prdata(" --maxpbg [0xFF] B/G PHY max power\n");
prdata(" --itssia [0xFF] Idle tssi target for A PHY\n");
prdata(" --itssibg [0xFF] Idle tssi target for B/G PHY\n");
prdata(" --sver [0xFF] SPROM-version\n");
prdata("\n");
prdata(" -P|--print-all Display all values\n");
prdata("\n");
prdata(" BOOL is a boolean value. Either 0 or 1\n");
prdata(" 0xF.. is a hexadecimal value\n");
prdata(" MAC-ADDR is a MAC address in the format 00:00:00:00:00:00
\n");
prdata(" If the value parameter is \"GET\", the value will be
printed;\n");
prdata(" otherwise it is modified.\n");
}
#define ARG_MATCH 0
#define ARG_NOMATCH 1
#define ARG_ERROR -1
static int do_cmp_arg(char **argv, int *pos,
const char *template,
int allow_merged,
char **param)
{
char *arg;
char *next_arg;
size_t arg_len, template_len;
arg = argv[*pos];
next_arg = argv[*pos + 1];
arg_len = strlen(arg);
template_len = strlen(template);
if (param) {
/* Maybe we have a merged parameter here.
* A merged parameter is "-pfoobar" for example.
*/
if (allow_merged && arg_len > template_len) {
if (memcmp(arg, template, template_len) == 0) {
*param = arg + template_len;
return ARG_MATCH;
}
return ARG_NOMATCH;
} else if (arg_len != template_len)
return ARG_NOMATCH;
*param = next_arg;
}
if (strcmp(arg, template) == 0) {
if (param) {
/* Skip the parameter on the next iteration. */
(*pos)++;
if (*param == 0) {
prerror("%s needs a parameter\n", arg);
return ARG_ERROR;
}
}
return ARG_MATCH;
}
return ARG_NOMATCH;
}
/* Simple and lean command line argument parsing. */
static int cmp_arg(char **argv, int *pos,
const char *long_template,
const char *short_template,
char **param)
{
int err;
if (long_template) {
err = do_cmp_arg(argv, pos, long_template, 0, param);
if (err == ARG_MATCH || err == ARG_ERROR)
return err;
}
err = ARG_NOMATCH;
if (short_template)
err = do_cmp_arg(argv, pos, short_template, 1, param);
return err;
}
static int parse_err;
static int arg_match(char **argv, int *i,
const char *long_template,
const char *short_template,
char **param)
{
int res;
res = cmp_arg(argv, i, long_template,
short_template, param);
if (res == ARG_ERROR) {
parse_err = 1;
return 0;
}
return (res == ARG_MATCH);
}
static int parse_value(const char *str,
struct cmdline_vparm *vparm,
const char *param)
{
unsigned long v;
int i;
vparm->bits = value_length_map[vparm->type];
vparm->set = 1;
if (strcmp(str, "GET") == 0 || strcmp(str, "get") == 0) {
vparm->set = 0;
return 0;
}
if (vparm->bits == 1) {
/* This is a boolean value. */
if (strcmp(str, "0") == 0)
vparm->u.value = 0;
else if (strcmp(str, "1") == 0)
vparm->u.value = 1;
else
goto error_bool;
return 1;
}
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;
}
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)
goto error;
vparm->u.value = v;
return 1;
error:
if (param) {
prerror("%s value parsing error. Format: 0x", param);
for (i = 0; i < vparm->bits / 4; i++)
prerror("F");
prerror("\n");
}
return -1;
error_bool:
if (param)
prerror("%s value parsing error. Format: 0 or 1 (boolean)\n",
param);
return -1;
}
static int parse_mac(const char *str,
struct cmdline_vparm *vparm,
const char *param)
{
int i;
char *delim;
const char *in = str;
uint8_t *out = vparm->u.mac;
vparm->bits = -1;
vparm->set = 1;
if (strcmp(str, "GET") == 0 || strcmp(str, "get") == 0) {
vparm->set = 0;
return 0;
}
for (i = 0; ; i++) {
errno = 0;
out[i] = strtoul(in, NULL, 16);
if (errno)
goto error;
if (i == 5) {
if (in[1] != '\0' && in[2] != '\0')
goto error;
break;
}
delim = strchr(in, ':');
if (!delim)
goto error;
in = delim + 1;
}
return 1;
error:
prerror("%s MAC parsing error. Format: 00:00:00:00:00:00\n", param);
return -1;
}
static int parse_rawset(const char *str,
struct cmdline_vparm *vparm)
{
char *delim;
uint8_t value;
uint16_t offset;
int err;
vparm->type = VALUE_RAW;
delim = strchr(str, ',');
if (!delim)
goto error;
*delim = '\0';
err = parse_value(str, vparm, NULL);
if (err != 1)
goto error;
offset = vparm->u.value;
if (offset >= SPROM4_SIZE) {
prerror("--rawset offset too big (>= 0x%02X)\n",
SPROM4_SIZE);
return -1;
}
err = parse_value(delim + 1, vparm, NULL);
if (err != 1)
goto error;
value = vparm->u.value;
vparm->u.raw.value = value;
vparm->u.raw.offset = offset;
vparm->set = 1;
return 0;
error:
prerror("--rawset value parsing error. Format: 0xFF,0xFF "
"(first Offset, second Value)\n");
return -1;
}
static int parse_rawget(const char *str,
struct cmdline_vparm *vparm)
{
int err;
uint16_t offset;
vparm->type = VALUE_RAW;
err = parse_value(str, vparm, "--rawget");
if (err != 1)
return -1;
offset = vparm->u.value;
if (offset >= SPROM4_SIZE) {
prerror("--rawget offset too big (>= 0x%02X)\n",
SPROM4_SIZE);
return -1;
}
vparm->u.raw.offset = offset;
vparm->type = VALUE_RAW;
vparm->set = 0;
return 0;
}
static int generate_printall(void)
{
struct cmdline_vparm *vparm;
int count, i;
enum valuetype vt = VALUE_FIRST;
count = VALUE_LAST - VALUE_FIRST + 1;
for (i = 0; i < count; i++, vt++) {
if (cmdargs.nr_vparm == MAX_VPARM) {
prerror("Too many value parameters.\n");
return -1;
}
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = vt;
vparm->set = 0;
vparm->bits = value_length_map[vt];
}
return 0;
}
static int parse_args(int argc, char *argv[])
{
struct cmdline_vparm *vparm;
int i, err;
char *param;
parse_err = 0;
for (i = 1; i < argc; i++) {
if (cmdargs.nr_vparm == MAX_VPARM) {
prerror("Too many value parameters.\n");
return -1;
}
if (arg_match(argv, &i, "--version", "-v", 0)) {
print_banner(1);
return 1;
} else if (arg_match(argv, &i, "--help", "-h", 0)) {
goto out_usage;
} else if (arg_match(argv, &i, "--input", "-i", ¶m)) {
cmdargs.infile = param;
} else if (arg_match(argv, &i, "--output", "-o", ¶m)) {
cmdargs.outfile = param;
} else if (arg_match(argv, &i, "--verbose", "-V", 0)) {
cmdargs.verbose = 1;
} else if (arg_match(argv, &i, "--force", "-n", 0)) {
cmdargs.force = 1;
} else if (arg_match(argv, &i, "--binmode", "-b", 0)) {
cmdargs.bin_mode = 1;
} else if (arg_match(argv, &i, "--rawset", "-s", ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
err = parse_rawset(param, vparm);
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--rawget", "-g", ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
err = parse_rawget(param, vparm);
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--subp", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_SUBP;
err = parse_value(param, vparm, "--subp");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--subv", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_SUBV;
err = parse_value(param, vparm, "--subv");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--ppid", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_PPID;
err = parse_value(param, vparm, "--ppid");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--bflhi", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_BFLHI;
err = parse_value(param, vparm, "--bflhi");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--bfl", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_BFL;
err = parse_value(param, vparm, "--bfl");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--bgmac", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_BGMAC;
err = parse_mac(param, vparm, "--bgmac");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--etmac", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ETMAC;
err = parse_mac(param, vparm, "--etmac");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--amac", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_AMAC;
err = parse_mac(param, vparm, "--amac");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--et0phy", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ET0PHY;
err = parse_value(param, vparm, "--et0phy");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--et1phy", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ET1PHY;
err = parse_value(param, vparm, "--et1phy");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--et0mdc", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ET0MDC;
err = parse_value(param, vparm, "--et0mdc");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--et1mdc", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ET1MDC;
err = parse_value(param, vparm, "--et1mdc");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--brev", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_BREV;
err = parse_value(param, vparm, "--brev");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--loc", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_LOC;
err = parse_value(param, vparm, "--loc");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--anta0", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ANTA0;
err = parse_value(param, vparm, "--anta0");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--anta1", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ANTA1;
err = parse_value(param, vparm, "--anta1");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--antbg0", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ANTBG0;
err = parse_value(param, vparm, "--antbg0");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--antbg1", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ANTBG1;
err = parse_value(param, vparm, "--antbg1");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--antga", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ANTGA;
err = parse_value(param, vparm, "--antga");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--antgbg", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ANTGBG;
err = parse_value(param, vparm, "--antgbg");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--pa0b0", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_PA0B0;
err = parse_value(param, vparm, "--pa0b0");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--pa0b1", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_PA0B1;
err = parse_value(param, vparm, "--pa0b1");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--pa0b2", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_PA0B2;
err = parse_value(param, vparm, "--pa0b2");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--pa1b0", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_PA1B0;
err = parse_value(param, vparm, "--pa1b0");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--pa1b1", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_PA1B1;
err = parse_value(param, vparm, "--pa1b1");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--pa1b2", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_PA1B2;
err = parse_value(param, vparm, "--pa1b2");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--wl0gpio0", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_WL0GPIO0;
err = parse_value(param, vparm, "--wl0gpio0");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--wl0gpio1", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_WL0GPIO1;
err = parse_value(param, vparm, "--wl0gpio1");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--wl0gpio2", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_WL0GPIO2;
err = parse_value(param, vparm, "--wl0gpio2");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--wl0gpio3", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_WL0GPIO3;
err = parse_value(param, vparm, "--wl0gpio3");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--maxpa", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_MAXPA;
err = parse_value(param, vparm, "--maxpa");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--maxpbg", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_MAXPBG;
err = parse_value(param, vparm, "--maxpbg");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--itssia", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ITSSIA;
err = parse_value(param, vparm, "--itssia");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--itssibg", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_ITSSIBG;
err = parse_value(param, vparm, "--itssibg");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--sver", 0, ¶m)) {
vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
vparm->type = VALUE_SVER;
err = parse_value(param, vparm, "--sver");
if (err < 0)
goto error;
} else if (arg_match(argv, &i, "--print-all", "-P", 0)) {
err = generate_printall();
if (err)
goto error;
} else {
prerror("Unrecognized argument: %s\n", argv[i]);
goto out_usage;
}
if (parse_err)
goto out_usage;
}
if (cmdargs.nr_vparm == 0) {
prerror("No Value parameter given. See --help.\n");
return -1;
}
return 0;
out_usage:
print_usage(argc, argv);
error:
return -1;
}
int main(int argc, char **argv)
{
int err;
int fd;
uint8_t sprom[SPROM4_SIZE + 10];
char *buffer = NULL;
size_t buffer_size = 0;
err = parse_args(argc, argv);
if (err == 1)
return 0;
else if (err != 0)
goto out;
print_banner(0);
prinfo("\nReading input from \"%s\"...\n",
cmdargs.infile ? cmdargs.infile : "stdin");
err = open_infile(&fd);
if (err)
goto out;
err = read_infile(fd, &buffer, &buffer_size);
close_infile(fd);
if (err)
goto out;
err = parse_input(sprom, buffer, buffer_size);
free(buffer);
if (err)
goto out;
err = validate_input(sprom);
if (err)
goto out;
err = display_sprom(sprom);
if (err)
goto out;
err = modify_sprom(sprom);
if (err < 0)
goto out;
if (err) {
err = open_outfile(&fd);
if (err)
goto out;
err = write_output(fd, sprom);
close_outfile(fd);
if (err)
goto out;
prinfo("SPROM modified.\n");
}
out:
return err;
}
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (Darwin)
iD8DBQFIYdUuiD9DTPch4RQRAnqRAKC3I4ikPuo4o7qTGQ8hXTBUeMNooACfUa0z
qZmfxJVwji3L8WKsSMbfoxs=
=LDMD
-----END PGP SIGNATURE-----
_______________________________________________
Bcm43xx-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev