aboutsummaryrefslogtreecommitdiff
path: root/gen_fw.c
diff options
context:
space:
mode:
Diffstat (limited to 'gen_fw.c')
-rw-r--r--gen_fw.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/gen_fw.c b/gen_fw.c
new file mode 100644
index 0000000..e068c2c
--- /dev/null
+++ b/gen_fw.c
@@ -0,0 +1,164 @@
+/* $Id: gen_fw.c,v 1.2 2003/12/25 22:40:27 jal2 Exp $ */
+
+/* This file includes the old style firmwares and outputs new, binary files. */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "fw-rfmd-1.101.0-84.h"
+#include "fw-rfmd-acc-1.101.0-84.h"
+#include "fw-i3861.h"
+#include "fw-i3863.h"
+#include "fw-r505.h"
+#include "fw-505rfmd2958-1.101.0-86.h"
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+/* The struct of the firmware header: */
+typedef struct {
+ u32 crc; // CRC32 of the whole image (seed ~0, no post-process)
+ u32 board_id; // BOARDTYPE_xxx
+ u32 version; // firmware version code
+ u32 str_offset; // printable string offset (copyright)
+ u32 internal_offset; // internal firmware image offset
+ u32 internal_len; // internal firmawre image len
+ u32 external_offset; // external firmware image offset
+ u32 external_len; // external firmware image len
+} at76c50x_fw_t __attribute__((packed));
+
+#define cpu_to_le32(x) (x)
+// round to next multiple of four
+#define QUAD(x) ((x) % 4 ? (x) + (4 - ((x)%4)) : (x))
+
+u8 intfw_503rfmd[] = FW_503RFMD_INTERNAL;
+u8 extfw_503rfmd[] = FW_503RFMD_EXTERNAL;
+u8 intfw_503rfmd_acc[] = FW_503RFMD_ACC_INTERNAL;
+u8 extfw_503rfmd_acc[] = FW_503RFMD_ACC_EXTERNAL;
+u8 intfw_i3861[] = FW_I3861_INTERNAL;
+u8 extfw_i3861[] = FW_I3861_EXTERNAL;
+u8 intfw_i3863[] = FW_I3863_INTERNAL;
+u8 extfw_i3863[] = FW_I3863_EXTERNAL;
+u8 intfw_505rfmd[] = FW_505RFMD_INTERNAL;
+u8 extfw_505rfmd[] = FW_505RFMD_EXTERNAL;
+u8 intfw_505rfmd2958[] = FW_505RFMD2958_INTERNAL;
+u8 extfw_505rfmd2958[] = FW_505RFMD2958_EXTERNAL;
+
+struct fw {
+ const char *filename;
+ u32 board_id;
+ u32 version;
+ const char *str_id;
+ u8 *intfw;
+ u32 intfw_sz;
+ u8 *extfw;
+ u32 extfw_sz;
+} fws[] = {
+ { "at76c503-rfmd-fw", 1, 0x01650054, "1.101.0-84 503 RFMD "
+ "Copyright (c) 1999-2000 by Atmel Corporation",
+ intfw_503rfmd, sizeof(intfw_503rfmd), extfw_503rfmd, sizeof(extfw_503rfmd)},
+
+ { "at76c503-rfmd-acc-fw", 3, 0x01650054, "1.101.0-84 503 RFMD Accton design "
+ "Copyright (c) 1999-2000 by Atmel Corporation",
+ intfw_503rfmd_acc, sizeof(intfw_503rfmd_acc), extfw_503rfmd_acc, sizeof(extfw_503rfmd_acc)},
+
+ { "at76c503-i3861-fw", 0, 0x005a002c, "0.90.0-44 Intersil 3861 "
+ "Copyright (c) 1999-2000 by Atmel Corporation",
+ intfw_i3861, sizeof(intfw_i3861), extfw_i3861, sizeof(extfw_i3861)},
+
+ { "at76c503-i3863-fw", 0, 0x005a002c, "0.90.0-44 Intersil 3863 "
+ "Copyright (c) 1999-2000 by Atmel Corporation",
+ intfw_i3863, sizeof(intfw_i3863), extfw_i3863, sizeof(extfw_i3863)},
+
+ { "at76c505-rfmd-fw", 2, 0x005b0004, "0.91.0-4 505 RFMD "
+ "Copyright (c) 1999-2000 by Atmel Corporation",
+ intfw_505rfmd, sizeof(intfw_505rfmd), extfw_505rfmd, sizeof(extfw_505rfmd)},
+
+ { "at76c505-rfmd2958-fw", 2, 0x01650056, "1.101.0-86 505 RFMD2958 "
+ "Copyright (c) 1999-2000 by Atmel Corporation",
+ intfw_505rfmd2958, sizeof(intfw_505rfmd2958), extfw_505rfmd2958, sizeof(extfw_505rfmd2958)},
+
+};
+
+int nr_fws = sizeof(fws) / sizeof(struct fw);
+const u8 zeros[] = {0,0,0};
+
+#define _CRCPOLY_LE 0xedb88320
+static u32 crc32 (u32 crc, u8 const *p, size_t len)
+{
+ int i;
+ while (len--) {
+ crc ^= *p++;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? _CRCPOLY_LE : 0);
+ }
+ return crc;
+}
+
+int main(void)
+{
+ int i;
+ u32 val, offs;
+ FILE *f;
+ struct fw *fw;
+ at76c50x_fw_t hd;
+
+ for(i=0,fw=fws; i < nr_fws; fw++,i++) {
+ if ((f=fopen(fw->filename, "w")) == NULL) {
+ fprintf(stderr,"#ERR cannot open %s for writing (errno %m)\n",
+ fw->filename);
+ continue;
+ }
+
+ hd.crc = ~0; /* the initial seed */
+ hd.board_id = cpu_to_le32(fw->board_id);
+ hd.version = cpu_to_le32(fw->version);
+ // string area starts after header
+ hd.str_offset = cpu_to_le32(sizeof(at76c50x_fw_t));
+ hd.internal_offset = hd.str_offset + strlen(fw->str_id) + 1;
+ hd.internal_offset = QUAD(hd.internal_offset);
+ hd.internal_len = fw->intfw_sz;
+ hd.external_offset = hd.internal_offset + hd.internal_len;
+ hd.external_offset = QUAD(hd.external_offset);
+ hd.external_len = fw->extfw_sz;
+
+ /* calc crc */
+ /* the header */
+ hd.crc = crc32(hd.crc, (u8 *)&hd.board_id, 0x20-0x4);
+ /* the string */
+ hd.crc = crc32(hd.crc, fw->str_id, strlen(fw->str_id) +1);
+ /* zeros in gap */
+ hd.crc = crc32(hd.crc, zeros, hd.internal_offset -
+ (hd.str_offset + strlen(fw->str_id) + 1));
+ /* internal fw */
+ hd.crc = crc32(hd.crc, fw->intfw, fw->intfw_sz);
+ /* zeros in gap */
+ hd.crc = crc32(hd.crc, zeros, hd.external_offset -
+ (hd.internal_offset + fw->intfw_sz));
+ /* external fw */
+ hd.crc = crc32(hd.crc, fw->extfw, fw->extfw_sz);
+
+#define FWRITE(ptr,len,fp) \
+ if (len > 0) {\
+ if (fwrite(ptr,len,1,fp) < 1) {\
+ fprintf(stderr,"#ERR failed to write %d bytes, errno %m\n", len);\
+ fclose(fp);\
+ continue;\
+ }\
+ }
+
+ FWRITE((u8 *)&hd, sizeof(hd),f);
+ FWRITE(fw->str_id, strlen(fw->str_id)+1, f);
+ FWRITE(zeros, hd.internal_offset -
+ (hd.str_offset + strlen(fw->str_id) + 1), f);
+ FWRITE(fw->intfw, fw->intfw_sz, f);
+ FWRITE(zeros, hd.external_offset -
+ (hd.internal_offset + fw->intfw_sz), f);
+ FWRITE(fw->extfw, fw->extfw_sz, f);
+
+ fclose(f);
+ }
+
+ return 0;
+}
+