3 Broadcom Sonics Silicon Backplane bus SPROM data modification tool
5 Copyright (c) 2006-2007 Michael Buesch <mb@bu3sch.de>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
20 Boston, MA 02110-1301, USA.
24 #include "ssb_sprom.h"
34 struct cmdline_args cmdargs;
36 static int value_length_map[] = { /* value to number of bits */
76 static int hexdump_sprom(const uint8_t *sprom, char *buffer, size_t bsize)
80 for (i = 0; i < SPROM_SIZE; i++) {
81 pos += snprintf(buffer + pos, bsize - pos - 1,
82 "%02X", sprom[i] & 0xFF);
88 static uint8_t sprom_crc(const uint8_t *sprom)
93 for (i = 0; i < SPROM_SIZE - 1; i++)
94 crc = crc8(crc, sprom[i]);
100 static int write_output_binary(int fd, const uint8_t *sprom)
104 w = write(fd, sprom, SPROM_SIZE);
111 static int write_output_hex(int fd, const uint8_t *sprom)
114 char tmp[SPROM_SIZE * 2 + 10] = { 0 };
116 hexdump_sprom(sprom, tmp, sizeof(tmp));
117 prinfo("Raw output: %s\n", tmp);
118 w = write(fd, tmp, SPROM_SIZE * 2);
125 static int write_output(int fd, const uint8_t *sprom)
129 if (cmdargs.outfile) {
130 err = ftruncate(fd, 0);
132 prerror("Could not truncate --outfile %s\n",
138 if (cmdargs.bin_mode)
139 err = write_output_binary(fd, sprom);
141 err = write_output_hex(fd, sprom);
143 prerror("Could not write output data.\n");
148 static int modify_value(uint8_t *sprom,
149 struct cmdline_vparm *vparm)
151 const uint16_t v = vparm->u.value;
154 switch (vparm->type) {
156 sprom[vparm->u.raw.offset] = vparm->u.raw.value;
159 sprom[SPROM_SUBP + 0] = (v & 0x00FF);
160 sprom[SPROM_SUBP + 1] = (v & 0xFF00) >> 8;
163 sprom[SPROM_SUBV + 0] = (v & 0x00FF);
164 sprom[SPROM_SUBV + 1] = (v & 0xFF00) >> 8;
167 sprom[SPROM_PPID + 0] = (v & 0x00FF);
168 sprom[SPROM_PPID + 1] = (v & 0xFF00) >> 8;
171 sprom[SPROM_BFLHI + 0] = (v & 0x00FF);
172 sprom[SPROM_BFLHI + 1] = (v & 0xFF00) >> 8;
175 sprom[SPROM_BOARDFLAGS + 0] = (v & 0x00FF);
176 sprom[SPROM_BOARDFLAGS + 1] = (v & 0xFF00) >> 8;
179 sprom[SPROM_IL0MACADDR + 1] = vparm->u.mac[0];
180 sprom[SPROM_IL0MACADDR + 0] = vparm->u.mac[1];
181 sprom[SPROM_IL0MACADDR + 3] = vparm->u.mac[2];
182 sprom[SPROM_IL0MACADDR + 2] = vparm->u.mac[3];
183 sprom[SPROM_IL0MACADDR + 5] = vparm->u.mac[4];
184 sprom[SPROM_IL0MACADDR + 4] = vparm->u.mac[5];
187 sprom[SPROM_ET0MACADDR + 1] = vparm->u.mac[0];
188 sprom[SPROM_ET0MACADDR + 0] = vparm->u.mac[1];
189 sprom[SPROM_ET0MACADDR + 3] = vparm->u.mac[2];
190 sprom[SPROM_ET0MACADDR + 2] = vparm->u.mac[3];
191 sprom[SPROM_ET0MACADDR + 5] = vparm->u.mac[4];
192 sprom[SPROM_ET0MACADDR + 4] = vparm->u.mac[5];
195 sprom[SPROM_ET1MACADDR + 1] = vparm->u.mac[0];
196 sprom[SPROM_ET1MACADDR + 0] = vparm->u.mac[1];
197 sprom[SPROM_ET1MACADDR + 3] = vparm->u.mac[2];
198 sprom[SPROM_ET1MACADDR + 2] = vparm->u.mac[3];
199 sprom[SPROM_ET1MACADDR + 5] = vparm->u.mac[4];
200 sprom[SPROM_ET1MACADDR + 4] = vparm->u.mac[5];
203 tmp |= sprom[SPROM_ETHPHY + 0];
204 tmp |= sprom[SPROM_ETHPHY + 1] << 8;
205 tmp = ((tmp & 0x001F) | (v & 0x1F));
206 sprom[SPROM_ETHPHY + 0] = (tmp & 0x00FF);
207 sprom[SPROM_ETHPHY + 1] = (tmp & 0xFF00) >> 8;
210 tmp |= sprom[SPROM_ETHPHY + 0];
211 tmp |= sprom[SPROM_ETHPHY + 1] << 8;
212 tmp = ((tmp & 0x03E0) | ((v & 0x1F) << 5));
213 sprom[SPROM_ETHPHY + 0] = (tmp & 0x00FF);
214 sprom[SPROM_ETHPHY + 1] = (tmp & 0xFF00) >> 8;
217 sprom[SPROM_ETHPHY + 1] &= ~(1 << 6);
219 sprom[SPROM_ETHPHY + 1] |= (1 << 6);
222 sprom[SPROM_ETHPHY + 1] &= ~(1 << 7);
224 sprom[SPROM_ETHPHY + 1] |= (1 << 7);
227 sprom[SPROM_BOARDREV + 0] = v;
230 tmp = (sprom[SPROM_BOARDREV + 1] & 0xF0);
232 sprom[SPROM_BOARDREV + 1] = (tmp & 0xFF);
235 sprom[SPROM_BOARDREV + 1] &= ~(1 << 4);
237 sprom[SPROM_BOARDREV + 1] |= (1 << 4);
240 sprom[SPROM_BOARDREV + 1] &= ~(1 << 5);
242 sprom[SPROM_BOARDREV + 1] |= (1 << 5);
245 sprom[SPROM_BOARDREV + 1] &= ~(1 << 6);
247 sprom[SPROM_BOARDREV + 1] |= (1 << 6);
250 sprom[SPROM_BOARDREV + 1] &= ~(1 << 7);
252 sprom[SPROM_BOARDREV + 1] |= (1 << 7);
255 sprom[SPROM_ANTENNA_GAIN + 0] = (v & 0xFF);
258 sprom[SPROM_ANTENNA_GAIN + 1] = (v & 0xFF);
261 sprom[SPROM_PA0B0 + 0] = (v & 0x00FF);
262 sprom[SPROM_PA0B0 + 1] = (v & 0xFF00) >> 8;
265 sprom[SPROM_PA0B1 + 0] = (v & 0x00FF);
266 sprom[SPROM_PA0B1 + 1] = (v & 0xFF00) >> 8;
269 sprom[SPROM_PA0B2 + 0] = (v & 0x00FF);
270 sprom[SPROM_PA0B2 + 1] = (v & 0xFF00) >> 8;
273 sprom[SPROM_PA1B0 + 0] = (v & 0x00FF);
274 sprom[SPROM_PA1B0 + 1] = (v & 0xFF00) >> 8;
277 sprom[SPROM_PA1B1 + 0] = (v & 0x00FF);
278 sprom[SPROM_PA1B1 + 1] = (v & 0xFF00) >> 8;
281 sprom[SPROM_PA1B2 + 0] = (v & 0x00FF);
282 sprom[SPROM_PA1B2 + 1] = (v & 0xFF00) >> 8;
285 sprom[SPROM_WL0GPIO0 + 0] = (v & 0xFF);
288 sprom[SPROM_WL0GPIO0 + 1] = (v & 0xFF);
291 sprom[SPROM_WL0GPIO2 + 0] = (v & 0xFF);
294 sprom[SPROM_WL0GPIO2 + 1] = (v & 0xFF);
297 sprom[SPROM_MAXPWR + 0] = (v & 0xFF);
300 sprom[SPROM_MAXPWR + 1] = (v & 0xFF);
303 sprom[SPROM_IDL_TSSI_TGT + 0] = (v & 0xFF);
306 sprom[SPROM_IDL_TSSI_TGT + 1] = (v & 0xFF);
309 sprom[SPROM_VERSION + 0] = (v & 0xFF);
312 prerror("vparm->type internal error (0)\n");
319 static int modify_sprom(uint8_t *sprom)
321 struct cmdline_vparm *vparm;
326 for (i = 0; i < cmdargs.nr_vparm; i++) {
327 vparm = &(cmdargs.vparm[i]);
330 modify_value(sprom, vparm);
334 /* Recalculate the CRC. */
335 crc = sprom_crc(sprom);
336 sprom[SPROM_VERSION + 1] = crc;
342 static void display_value(const uint8_t *sprom,
343 struct cmdline_vparm *vparm)
350 switch (vparm->type) {
353 offset = vparm->u.raw.offset;
354 value = sprom[offset];
357 desc = "Subsytem product ID";
359 value = sprom[SPROM_SUBP + 0];
360 value |= sprom[SPROM_SUBP + 1] << 8;
363 desc = "Subsystem vendor ID";
365 value = sprom[SPROM_SUBV + 0];
366 value |= sprom[SPROM_SUBV + 1] << 8;
369 desc = "PCI Product ID";
371 value = sprom[SPROM_PPID + 0];
372 value |= sprom[SPROM_PPID + 1] << 8;
375 desc = "High 16 bits of Boardflags";
376 offset = SPROM_BFLHI;
377 value = sprom[SPROM_BFLHI + 0];
378 value |= sprom[SPROM_BFLHI + 1] << 8;
381 desc = "Low 16 bits of Boardflags";
382 offset = SPROM_BOARDFLAGS;
383 value = sprom[SPROM_BOARDFLAGS + 0];
384 value |= sprom[SPROM_BOARDFLAGS + 1] << 8;
387 desc = "MAC address for 802.11b/g";
388 offset = SPROM_IL0MACADDR;
392 desc = "MAC address for ethernet";
393 offset = SPROM_ET0MACADDR;
397 desc = "MAC address for 802.11a";
398 offset = SPROM_ET1MACADDR;
402 desc = "Ethernet phy settings (0)";
403 offset = SPROM_ETHPHY;
404 tmp = sprom[SPROM_ETHPHY + 0];
405 tmp |= sprom[SPROM_ETHPHY + 1] << 8;
406 value = (tmp & 0x001F);
409 desc = "Ethernet phy settings (1)";
410 offset = SPROM_ETHPHY;
411 tmp = sprom[SPROM_ETHPHY + 0];
412 tmp |= sprom[SPROM_ETHPHY + 1] << 8;
413 value = (tmp & 0x03E0) >> 5;
417 offset = SPROM_ETHPHY + 1;
419 if (sprom[SPROM_ETHPHY + 1] & (1 << 6))
424 offset = SPROM_ETHPHY + 1;
426 if (sprom[SPROM_ETHPHY + 1] & (1 << 7))
430 desc = "Board revision";
431 offset = SPROM_BOARDREV;
432 value = sprom[SPROM_BOARDREV + 0];
435 desc = "Locale / Country Code";
436 offset = SPROM_BOARDREV + 1;
437 value = (sprom[SPROM_BOARDREV + 1] & 0x0F);
440 desc = "A PHY antenna 0 available";
441 offset = SPROM_BOARDREV + 1;
443 if (sprom[SPROM_BOARDREV + 1] & (1 << 4))
447 desc = "A PHY antenna 1 available";
448 offset = SPROM_BOARDREV + 1;
450 if (sprom[SPROM_BOARDREV + 1] & (1 << 5))
454 desc = "B/G PHY antenna 0 available";
455 offset = SPROM_BOARDREV + 1;
457 if (sprom[SPROM_BOARDREV + 1] & (1 << 6))
461 desc = "B/G PHY antenna 1 available";
462 offset = SPROM_BOARDREV + 1;
464 if (sprom[SPROM_BOARDREV + 1] & (1 << 7))
468 desc = "A PHY antenna gain";
469 offset = SPROM_ANTENNA_GAIN;
470 value = sprom[SPROM_ANTENNA_GAIN];
473 desc = "B/G PHY antenna gain";
474 offset = SPROM_ANTENNA_GAIN + 1;
475 value = sprom[SPROM_ANTENNA_GAIN + 1];
479 offset = SPROM_PA0B0;
480 value = sprom[offset + 0];
481 value |= sprom[offset + 1] << 8;
485 offset = SPROM_PA0B1;
486 value = sprom[offset + 0];
487 value |= sprom[offset + 1] << 8;
491 offset = SPROM_PA0B2;
492 value = sprom[offset + 0];
493 value |= sprom[offset + 1] << 8;
497 offset = SPROM_PA1B0;
498 value = sprom[offset + 0];
499 value |= sprom[offset + 1] << 8;
503 offset = SPROM_PA1B1;
504 value = sprom[offset + 0];
505 value |= sprom[offset + 1] << 8;
509 offset = SPROM_PA1B2;
510 value = sprom[offset + 0];
511 value |= sprom[offset + 1] << 8;
514 desc = "LED 0 behaviour";
515 offset = SPROM_WL0GPIO0 + 0;
516 value = sprom[offset];
519 desc = "LED 1 behaviour";
520 offset = SPROM_WL0GPIO0 + 1;
521 value = sprom[offset];
524 desc = "LED 2 behaviour";
525 offset = SPROM_WL0GPIO2 + 0;
526 value = sprom[offset];
529 desc = "LED 3 behaviour";
530 offset = SPROM_WL0GPIO2 + 1;
531 value = sprom[offset];
534 desc = "A PHY max powerout";
535 offset = SPROM_MAXPWR + 0;
536 value = sprom[offset];
539 desc = "B/G PHY max powerout";
540 offset = SPROM_MAXPWR + 1;
541 value = sprom[offset];
544 desc = "A PHY idle TSSI target";
545 offset = SPROM_IDL_TSSI_TGT + 0;
546 value = sprom[offset];
549 desc = "B/G PHY idle TSSI target";
550 offset = SPROM_IDL_TSSI_TGT + 1;
551 value = sprom[offset];
554 desc = "SPROM version";
555 offset = SPROM_VERSION;
556 value = sprom[offset];
559 prerror("vparm->type internal error (1)\n");
563 switch (vparm->bits) {
565 prdata("SPROM(0x%02X, %s) = %s\n",
566 offset, desc, value ? "ON" : "OFF");
569 prdata("SPROM(0x%02X, %s) = 0x%01X\n",
570 offset, desc, (value & 0xF));
573 prdata("SPROM(0x%02X, %s) = 0x%02X\n",
574 offset, desc, (value & 0xFF));
577 prdata("SPROM(0x%02X, %s) = 0x%04X\n",
578 offset, desc, (value & 0xFFFF));
582 const uint8_t *p = &(sprom[offset]);
584 prdata("SPROM(0x%02X, %s) = %02x:%02x:%02x:%02x:%02x:%02x\n",
586 p[1], p[0], p[3], p[2], p[5], p[4]);
590 prerror("vparm->bits internal error (%d)\n",
596 static int display_sprom(const uint8_t *sprom)
598 struct cmdline_vparm *vparm;
601 for (i = 0; i < cmdargs.nr_vparm; i++) {
602 vparm = &(cmdargs.vparm[i]);
605 display_value(sprom, vparm);
611 static int validate_input(const uint8_t *sprom)
613 uint8_t crc, expected_crc;
615 crc = sprom_crc(sprom);
616 expected_crc = sprom[SPROM_VERSION + 1];
617 if (crc != expected_crc) {
618 prerror("Corrupt input data (crc: 0x%02X, expected: 0x%02X)\n",
627 static int parse_input(uint8_t *sprom, char *buffer, size_t bsize)
632 unsigned long parsed;
633 char tmp[SPROM_SIZE * 2 + 10] = { 0 };
635 if (cmdargs.bin_mode) {
636 /* The input buffer already contains
637 * the binary sprom data.
639 internal_error_on(bsize != SPROM_SIZE);
640 memcpy(sprom, buffer, SPROM_SIZE);
645 input = strchr(buffer, ':');
648 inlen -= input - buffer;
652 if (inlen < SPROM_SIZE * 2) {
653 prerror("Input data too short\n");
656 for (cnt = 0; cnt < SPROM_SIZE; cnt++) {
657 memcpy(tmp, input + cnt * 2, 2);
658 parsed = strtoul(tmp, NULL, 16);
659 sprom[cnt] = parsed & 0xFF;
662 if (cmdargs.verbose) {
663 hexdump_sprom(sprom, tmp, sizeof(tmp));
664 prinfo("Raw input: %s\n", tmp);
670 static int read_infile(int fd, char **buffer, size_t *bsize)
678 prerror("Could not stat input file.\n");
681 if (s.st_size == 0) {
682 prerror("No input data\n");
685 if (cmdargs.bin_mode) {
686 if (s.st_size != SPROM_SIZE) {
687 prerror("The input data is no SPROM Binary data. "
688 "The size must be exactly %d bytes, "
689 "but it is %u bytes\n",
690 SPROM_SIZE, (unsigned int)(s.st_size));
694 if (s.st_size > 1024 * 1024) {
695 prerror("The input data does not look "
696 "like SPROM HEX data (too long).\n");
702 if (!cmdargs.bin_mode)
704 *buffer = malloce(*bsize);
705 r = read(fd, *buffer, s.st_size);
706 if (r != s.st_size) {
707 prerror("Could not read input data.\n");
710 if (!cmdargs.bin_mode)
716 static void close_infile(int fd)
722 static void close_outfile(int fd)
728 static int open_infile(int *fd)
733 *fd = open(cmdargs.infile, O_RDONLY);
735 prerror("Could not open --infile %s\n",
743 static int open_outfile(int *fd)
746 if (!cmdargs.outfile)
748 *fd = open(cmdargs.outfile, O_RDWR | O_CREAT, 0644);
750 prerror("Could not open --outfile %s\n",
758 static void print_banner(int forceprint)
760 const char *str = "Broadcom-SSB SPROM data modification tool version " VERSION "\n";
767 static void print_usage(int argc, char *argv[])
770 prdata("\nUsage: %s [OPTION]\n", argv[0]);
771 prdata(" -i|--input FILE Input file\n");
772 prdata(" -o|--output FILE Output file\n");
773 prdata(" -b|--binmode The Input data is plain binary data and Output will be binary\n");
774 prdata(" -V|--verbose Be verbose\n");
775 prdata(" -f|--force Override error checks\n");
776 prdata(" -v|--version Print version\n");
777 prdata(" -h|--help Print this help\n");
779 prdata("Value Parameters:\n");
781 prdata(" -s|--rawset OFF,VAL Set a VALue at a byte-OFFset\n");
782 prdata(" -g|--rawget OFF Get a value at a byte-OFFset\n");
784 prdata("Predefined values (for displaying (GET) or modification):\n");
785 prdata(" --subp [0xFFFF] Subsytem product ID for PCI\n");
786 prdata(" --subv [0xFFFF] Subsystem vendor ID for PCI\n");
787 prdata(" --ppid [0xFFFF] Product ID for PCI\n");
788 prdata(" --bflhi [0xFFFF] High 16 bits of boardflags (only if spromversion > 1)\n");
789 prdata(" --bfl [0xFFFF] Low 16 bits of boardflags\n");
790 prdata(" --bgmac [MAC-ADDR] MAC address for 802.11b/g\n");
791 prdata(" --etmac [MAC-ADDR] MAC address for ethernet, see b44 driver\n");
792 prdata(" --amac [MAC-ADDR] Mac address for 802.11a\n");
793 prdata(" --et0phy [0xFF]\n");
794 prdata(" --et1phy [0xFF]\n");
795 prdata(" --et0mdc [BOOL]\n");
796 prdata(" --et1mdc [BOOL]\n");
797 prdata(" --brev [0xFF] Board revision\n");
798 prdata(" --loc [0xF] Country code\n");
799 prdata(" --anta0 [BOOL] Antenna 0 available for A PHY\n");
800 prdata(" --anta1 [BOOL] Antenna 1 available for A PHY\n");
801 prdata(" --antbg0 [BOOL] Antenna 0 available for B/G PHY\n");
802 prdata(" --antbg1 [BOOL] Antenna 1 available for B/G PHY\n");
803 prdata(" --antga [0xFF] Antenna gain for A PHY\n");
804 prdata(" --antgbg [0xFF] Antenna gain for B/G PHY\n");
805 prdata(" --pa0b0 [0xFFFF]\n");
806 prdata(" --pa0b1 [0xFFFF]\n");
807 prdata(" --pa0b2 [0xFFFF]\n");
808 prdata(" --pa1b0 [0xFFFF]\n");
809 prdata(" --pa1b1 [0xFFFF]\n");
810 prdata(" --pa1b2 [0xFFFF]\n");
811 prdata(" --wl0gpio0 [0xFF] LED 0 behaviour\n");
812 prdata(" --wl0gpio1 [0xFF] LED 1 behaviour\n");
813 prdata(" --wl0gpio2 [0xFF] LED 2 behaviour\n");
814 prdata(" --wl0gpio3 [0xFF] LED 3 behaviour\n");
815 prdata(" --maxpa [0xFF] A PHY max power\n");
816 prdata(" --maxpbg [0xFF] B/G PHY max power\n");
817 prdata(" --itssia [0xFF] Idle tssi target for A PHY\n");
818 prdata(" --itssibg [0xFF] Idle tssi target for B/G PHY\n");
819 prdata(" --sver [0xFF] SPROM-version\n");
821 prdata(" -P|--print-all Display all values\n");
823 prdata(" BOOL is a boolean value. Either 0 or 1\n");
824 prdata(" 0xF.. is a hexadecimal value\n");
825 prdata(" MAC-ADDR is a MAC address in the format 00:00:00:00:00:00\n");
826 prdata(" If the value parameter is \"GET\", the value will be printed;\n");
827 prdata(" otherwise it is modified.\n");
831 #define ARG_NOMATCH 1
834 static int do_cmp_arg(char **argv, int *pos,
835 const char *template,
841 size_t arg_len, template_len;
844 next_arg = argv[*pos + 1];
845 arg_len = strlen(arg);
846 template_len = strlen(template);
849 /* Maybe we have a merged parameter here.
850 * A merged parameter is "-pfoobar" for example.
852 if (allow_merged && arg_len > template_len) {
853 if (memcmp(arg, template, template_len) == 0) {
854 *param = arg + template_len;
858 } else if (arg_len != template_len)
862 if (strcmp(arg, template) == 0) {
864 /* Skip the parameter on the next iteration. */
867 prerror("%s needs a parameter\n", arg);
877 /* Simple and lean command line argument parsing. */
878 static int cmp_arg(char **argv, int *pos,
879 const char *long_template,
880 const char *short_template,
886 err = do_cmp_arg(argv, pos, long_template, 0, param);
887 if (err == ARG_MATCH || err == ARG_ERROR)
892 err = do_cmp_arg(argv, pos, short_template, 1, param);
896 static int parse_err;
898 static int arg_match(char **argv, int *i,
899 const char *long_template,
900 const char *short_template,
905 res = cmp_arg(argv, i, long_template,
906 short_template, param);
907 if (res == ARG_ERROR) {
911 return (res == ARG_MATCH);
914 static int parse_value(const char *str,
915 struct cmdline_vparm *vparm,
921 vparm->bits = value_length_map[vparm->type];
923 if (strcmp(str, "GET") == 0 || strcmp(str, "get") == 0) {
927 if (vparm->bits == 1) {
928 /* This is a boolean value. */
929 if (strcmp(str, "0") == 0)
931 else if (strcmp(str, "1") == 0)
938 if (strncmp(str, "0x", 2) != 0)
941 for (i = 0; i < vparm->bits / 4; i++) {
948 v = strtoul(str, NULL, 16);
956 prerror("%s value parsing error. Format: 0x", param);
957 for (i = 0; i < vparm->bits / 4; i++)
965 prerror("%s value parsing error. Format: 0 or 1 (boolean)\n", param);
969 static int parse_mac(const char *str,
970 struct cmdline_vparm *vparm,
975 const char *in = str;
976 uint8_t *out = vparm->u.mac;
980 if (strcmp(str, "GET") == 0 || strcmp(str, "get") == 0) {
987 out[i] = strtoul(in, NULL, 16);
991 if (in[1] != '\0' && in[2] != '\0')
995 delim = strchr(in, ':');
1003 prerror("%s MAC parsing error. Format: 00:00:00:00:00:00\n", param);
1007 static int parse_rawset(const char *str,
1008 struct cmdline_vparm *vparm)
1015 vparm->type = VALUE_RAW;
1017 delim = strchr(str, ',');
1021 err = parse_value(str, vparm, NULL);
1024 offset = vparm->u.value;
1025 if (offset >= SPROM_SIZE) {
1026 prerror("--rawset offset too big (>= 0x%02X)\n",
1030 err = parse_value(delim + 1, vparm, NULL);
1033 value = vparm->u.value;
1035 vparm->u.raw.value = value;
1036 vparm->u.raw.offset = offset;
1041 prerror("--rawset value parsing error. Format: 0xFF,0xFF "
1042 "(first Offset, second Value)\n");
1046 static int parse_rawget(const char *str,
1047 struct cmdline_vparm *vparm)
1052 vparm->type = VALUE_RAW;
1054 err = parse_value(str, vparm, "--rawget");
1057 offset = vparm->u.value;
1058 if (offset >= SPROM_SIZE) {
1059 prerror("--rawget offset too big (>= 0x%02X)\n",
1064 vparm->u.raw.offset = offset;
1065 vparm->type = VALUE_RAW;
1071 static int generate_printall(void)
1073 struct cmdline_vparm *vparm;
1075 enum valuetype vt = VALUE_FIRST;
1077 count = VALUE_LAST - VALUE_FIRST + 1;
1078 for (i = 0; i < count; i++, vt++) {
1079 if (cmdargs.nr_vparm == MAX_VPARM) {
1080 prerror("Too many value parameters.\n");
1084 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1087 vparm->bits = value_length_map[vt];
1093 static int parse_args(int argc, char *argv[])
1095 struct cmdline_vparm *vparm;
1100 for (i = 1; i < argc; i++) {
1101 if (cmdargs.nr_vparm == MAX_VPARM) {
1102 prerror("Too many value parameters.\n");
1106 if (arg_match(argv, &i, "--version", "-v", 0)) {
1109 } else if (arg_match(argv, &i, "--help", "-h", 0)) {
1111 } else if (arg_match(argv, &i, "--input", "-i", ¶m)) {
1112 cmdargs.infile = param;
1113 } else if (arg_match(argv, &i, "--output", "-o", ¶m)) {
1114 cmdargs.outfile = param;
1115 } else if (arg_match(argv, &i, "--verbose", "-V", 0)) {
1116 cmdargs.verbose = 1;
1117 } else if (arg_match(argv, &i, "--force", "-n", 0)) {
1119 } else if (arg_match(argv, &i, "--binmode", "-b", 0)) {
1120 cmdargs.bin_mode = 1;
1123 } else if (arg_match(argv, &i, "--rawset", "-s", ¶m)) {
1124 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1125 err = parse_rawset(param, vparm);
1128 } else if (arg_match(argv, &i, "--rawget", "-g", ¶m)) {
1129 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1130 err = parse_rawget(param, vparm);
1135 } else if (arg_match(argv, &i, "--subp", 0, ¶m)) {
1136 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1137 vparm->type = VALUE_SUBP;
1138 err = parse_value(param, vparm, "--subp");
1141 } else if (arg_match(argv, &i, "--subv", 0, ¶m)) {
1142 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1143 vparm->type = VALUE_SUBV;
1144 err = parse_value(param, vparm, "--subv");
1147 } else if (arg_match(argv, &i, "--ppid", 0, ¶m)) {
1148 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1149 vparm->type = VALUE_PPID;
1150 err = parse_value(param, vparm, "--ppid");
1153 } else if (arg_match(argv, &i, "--bflhi", 0, ¶m)) {
1154 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1155 vparm->type = VALUE_BFLHI;
1156 err = parse_value(param, vparm, "--bflhi");
1159 } else if (arg_match(argv, &i, "--bfl", 0, ¶m)) {
1160 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1161 vparm->type = VALUE_BFL;
1162 err = parse_value(param, vparm, "--bfl");
1165 } else if (arg_match(argv, &i, "--bgmac", 0, ¶m)) {
1166 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1167 vparm->type = VALUE_BGMAC;
1168 err = parse_mac(param, vparm, "--bgmac");
1171 } else if (arg_match(argv, &i, "--etmac", 0, ¶m)) {
1172 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1173 vparm->type = VALUE_ETMAC;
1174 err = parse_mac(param, vparm, "--etmac");
1177 } else if (arg_match(argv, &i, "--amac", 0, ¶m)) {
1178 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1179 vparm->type = VALUE_AMAC;
1180 err = parse_mac(param, vparm, "--amac");
1183 } else if (arg_match(argv, &i, "--et0phy", 0, ¶m)) {
1184 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1185 vparm->type = VALUE_ET0PHY;
1186 err = parse_value(param, vparm, "--et0phy");
1189 } else if (arg_match(argv, &i, "--et1phy", 0, ¶m)) {
1190 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1191 vparm->type = VALUE_ET1PHY;
1192 err = parse_value(param, vparm, "--et1phy");
1195 } else if (arg_match(argv, &i, "--et0mdc", 0, ¶m)) {
1196 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1197 vparm->type = VALUE_ET0MDC;
1198 err = parse_value(param, vparm, "--et0mdc");
1201 } else if (arg_match(argv, &i, "--et1mdc", 0, ¶m)) {
1202 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1203 vparm->type = VALUE_ET1MDC;
1204 err = parse_value(param, vparm, "--et1mdc");
1207 } else if (arg_match(argv, &i, "--brev", 0, ¶m)) {
1208 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1209 vparm->type = VALUE_BREV;
1210 err = parse_value(param, vparm, "--brev");
1213 } else if (arg_match(argv, &i, "--loc", 0, ¶m)) {
1214 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1215 vparm->type = VALUE_LOC;
1216 err = parse_value(param, vparm, "--loc");
1219 } else if (arg_match(argv, &i, "--anta0", 0, ¶m)) {
1220 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1221 vparm->type = VALUE_ANTA0;
1222 err = parse_value(param, vparm, "--anta0");
1225 } else if (arg_match(argv, &i, "--anta1", 0, ¶m)) {
1226 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1227 vparm->type = VALUE_ANTA1;
1228 err = parse_value(param, vparm, "--anta1");
1231 } else if (arg_match(argv, &i, "--antbg0", 0, ¶m)) {
1232 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1233 vparm->type = VALUE_ANTBG0;
1234 err = parse_value(param, vparm, "--antbg0");
1237 } else if (arg_match(argv, &i, "--antbg1", 0, ¶m)) {
1238 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1239 vparm->type = VALUE_ANTBG1;
1240 err = parse_value(param, vparm, "--antbg1");
1243 } else if (arg_match(argv, &i, "--antga", 0, ¶m)) {
1244 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1245 vparm->type = VALUE_ANTGA;
1246 err = parse_value(param, vparm, "--antga");
1249 } else if (arg_match(argv, &i, "--antgbg", 0, ¶m)) {
1250 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1251 vparm->type = VALUE_ANTGBG;
1252 err = parse_value(param, vparm, "--antgbg");
1255 } else if (arg_match(argv, &i, "--pa0b0", 0, ¶m)) {
1256 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1257 vparm->type = VALUE_PA0B0;
1258 err = parse_value(param, vparm, "--pa0b0");
1261 } else if (arg_match(argv, &i, "--pa0b1", 0, ¶m)) {
1262 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1263 vparm->type = VALUE_PA0B1;
1264 err = parse_value(param, vparm, "--pa0b1");
1267 } else if (arg_match(argv, &i, "--pa0b2", 0, ¶m)) {
1268 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1269 vparm->type = VALUE_PA0B2;
1270 err = parse_value(param, vparm, "--pa0b2");
1273 } else if (arg_match(argv, &i, "--pa1b0", 0, ¶m)) {
1274 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1275 vparm->type = VALUE_PA1B0;
1276 err = parse_value(param, vparm, "--pa1b0");
1279 } else if (arg_match(argv, &i, "--pa1b1", 0, ¶m)) {
1280 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1281 vparm->type = VALUE_PA1B1;
1282 err = parse_value(param, vparm, "--pa1b1");
1285 } else if (arg_match(argv, &i, "--pa1b2", 0, ¶m)) {
1286 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1287 vparm->type = VALUE_PA1B2;
1288 err = parse_value(param, vparm, "--pa1b2");
1291 } else if (arg_match(argv, &i, "--wl0gpio0", 0, ¶m)) {
1292 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1293 vparm->type = VALUE_WL0GPIO0;
1294 err = parse_value(param, vparm, "--wl0gpio0");
1297 } else if (arg_match(argv, &i, "--wl0gpio1", 0, ¶m)) {
1298 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1299 vparm->type = VALUE_WL0GPIO1;
1300 err = parse_value(param, vparm, "--wl0gpio1");
1303 } else if (arg_match(argv, &i, "--wl0gpio2", 0, ¶m)) {
1304 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1305 vparm->type = VALUE_WL0GPIO2;
1306 err = parse_value(param, vparm, "--wl0gpio2");
1309 } else if (arg_match(argv, &i, "--wl0gpio3", 0, ¶m)) {
1310 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1311 vparm->type = VALUE_WL0GPIO3;
1312 err = parse_value(param, vparm, "--wl0gpio3");
1315 } else if (arg_match(argv, &i, "--maxpa", 0, ¶m)) {
1316 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1317 vparm->type = VALUE_MAXPA;
1318 err = parse_value(param, vparm, "--maxpa");
1321 } else if (arg_match(argv, &i, "--maxpbg", 0, ¶m)) {
1322 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1323 vparm->type = VALUE_MAXPBG;
1324 err = parse_value(param, vparm, "--maxpbg");
1327 } else if (arg_match(argv, &i, "--itssia", 0, ¶m)) {
1328 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1329 vparm->type = VALUE_ITSSIA;
1330 err = parse_value(param, vparm, "--itssia");
1333 } else if (arg_match(argv, &i, "--itssibg", 0, ¶m)) {
1334 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1335 vparm->type = VALUE_ITSSIBG;
1336 err = parse_value(param, vparm, "--itssibg");
1339 } else if (arg_match(argv, &i, "--sver", 0, ¶m)) {
1340 vparm = &(cmdargs.vparm[cmdargs.nr_vparm++]);
1341 vparm->type = VALUE_SVER;
1342 err = parse_value(param, vparm, "--sver");
1345 } else if (arg_match(argv, &i, "--print-all", "-P", 0)) {
1346 err = generate_printall();
1350 prerror("Unrecognized argument: %s\n", argv[i]);
1356 if (cmdargs.nr_vparm == 0) {
1357 prerror("No Value parameter given. See --help.\n");
1363 print_usage(argc, argv);
1369 int main(int argc, char **argv)
1373 uint8_t sprom[SPROM_SIZE];
1374 char *buffer = NULL;
1375 size_t buffer_size = 0;
1377 err = parse_args(argc, argv);
1384 prinfo("\nReading input from \"%s\"...\n",
1385 cmdargs.infile ? cmdargs.infile : "stdin");
1387 err = open_infile(&fd);
1390 err = read_infile(fd, &buffer, &buffer_size);
1394 err = parse_input(sprom, buffer, buffer_size);
1398 err = validate_input(sprom);
1402 err = display_sprom(sprom);
1405 err = modify_sprom(sprom);
1409 err = open_outfile(&fd);
1412 err = write_output(fd, sprom);
1416 prinfo("SPROM modified.\n");