On Thu, Feb 07, 2008 at 04:10:56PM +0100, Bastian Blank wrote: > This is the first version of the bnx2 request_firmware patch. It works > with the 4.0.5 firmware from the bnx2 version in 2.6.25. Second version, it fixes the problems and changes the firmware names a little bit. I also attached the updated firmware extractor. Bastian -- Our missions are peaceful -- not for conquest. When we do battle, it is only because we have no choice. -- Kirk, "The Squire of Gothos", stardate 2124.5
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 8b552c6..ec72b56 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -46,11 +46,10 @@ #include <linux/crc32.h> #include <linux/prefetch.h> #include <linux/cache.h> -#include <linux/zlib.h> +#include <linux/firmware.h> #include "bnx2.h" -#include "bnx2_fw.h" -#include "bnx2_fw2.h" +#include "bnx2_fw_file.h" #define FW_BUF_SIZE 0x10000 @@ -58,12 +57,20 @@ #define PFX DRV_MODULE_NAME ": " #define DRV_MODULE_VERSION "1.7.3" #define DRV_MODULE_RELDATE "January 29, 2008" +#define FW_FILE_06 "bnx2-06-4.0.5.fw" +#define FW_FILE_09 "bnx2-09-4.0.5.fw" #define RUN_AT(x) (jiffies + (x)) /* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (5*HZ) +#ifdef DEBUG +# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) +#else +# define DPRINTK(fmt, args...) +#endif + static const char version[] __devinitdata = "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -71,6 +78,8 @@ MODULE_AUTHOR("Michael Chan <mchan@broadcom.com>"); MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708 Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); +MODULE_FIRMWARE(FW_FILE_06); +MODULE_FIRMWARE(FW_FILE_09); static int disable_msi = 0; @@ -3161,26 +3170,32 @@ bnx2_set_rx_mode(struct net_device *dev) spin_unlock_bh(&bp->phy_lock); } -static void -load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len, - u32 rv2p_proc) +static int +load_rv2p_fw(struct bnx2 *bp, u32 rv2p_proc, const struct bnx2_fw_file_section *fw_section) { - int i; + int i, len, offset; + u32 *data; u32 val; + len = be32_to_cpu(fw_section->len); + offset = be32_to_cpu(fw_section->offset); + + if (!len || !offset || len + offset > bp->firmware->size) + return -EINVAL; + DPRINTK("load rv2p firmware with length %u from file offset %u\n", len, offset); + + data = (u32 *)(bp->firmware->data + offset); - for (i = 0; i < rv2p_code_len; i += 8) { - REG_WR(bp, BNX2_RV2P_INSTR_HIGH, le32_to_cpu(*rv2p_code)); - rv2p_code++; - REG_WR(bp, BNX2_RV2P_INSTR_LOW, le32_to_cpu(*rv2p_code)); - rv2p_code++; + for (i = 0; i < (len / 4); i += 2) { + REG_WR(bp, BNX2_RV2P_INSTR_HIGH, be32_to_cpu(data[i])); + REG_WR(bp, BNX2_RV2P_INSTR_LOW, be32_to_cpu(data[i+1])); if (rv2p_proc == RV2P_PROC1) { - val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR; + val = (i / 2) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR; REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val); } else { - val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR; + val = (i / 2) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR; REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val); } } @@ -3192,14 +3207,18 @@ load_rv2p_fw(struct bnx2 *bp, __le32 *rv2p_code, u32 rv2p_code_len, else { REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET); } + + return 0; } static int -load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) +load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, + const struct bnx2_fw_file_entry *fw_entry) { + u32 addr, len, file_offset; u32 offset; u32 val; - int rc; + u32 *data; /* Halt the CPU. */ val = bnx2_reg_rd_ind(bp, cpu_reg->mode); @@ -3208,64 +3227,87 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) bnx2_reg_wr_ind(bp, cpu_reg->state, cpu_reg->state_value_clear); /* Load the Text area. */ - offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base); - if (fw->gz_text) { + addr = be32_to_cpu(fw_entry->text.addr); + len = be32_to_cpu(fw_entry->text.len); + file_offset = be32_to_cpu(fw_entry->text.offset); + data = (u32 *)(bp->firmware->data + file_offset); + DPRINTK("load text section to %x with length %u from file offset %x\n", addr, len, file_offset); + + offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base); + if (len) { int j; - rc = zlib_inflate_blob(fw->text, FW_BUF_SIZE, fw->gz_text, - fw->gz_text_len); - if (rc < 0) - return rc; - - for (j = 0; j < (fw->text_len / 4); j++, offset += 4) { - bnx2_reg_wr_ind(bp, offset, le32_to_cpu(fw->text[j])); + for (j = 0; j < (len / 4); j++, offset += 4) { + bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j])); } } /* Load the Data area. */ - offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base); - if (fw->data) { + addr = be32_to_cpu(fw_entry->data.addr); + len = be32_to_cpu(fw_entry->data.len); + file_offset = be32_to_cpu(fw_entry->data.offset); + data = (u32 *)(bp->firmware->data + file_offset); + DPRINTK("load data section to %x with length %u from file offset %x\n", addr, len, file_offset); + + offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base); + if (len) { int j; - for (j = 0; j < (fw->data_len / 4); j++, offset += 4) { - bnx2_reg_wr_ind(bp, offset, fw->data[j]); + for (j = 0; j < (len / 4); j++, offset += 4) { + bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j])); } } /* Load the SBSS area. */ - offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base); - if (fw->sbss_len) { + addr = be32_to_cpu(fw_entry->sbss.addr); + len = be32_to_cpu(fw_entry->sbss.len); + DPRINTK("init sbss section on %x with length %u\n", addr, len); + + offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base); + if (len) { int j; - for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) { + for (j = 0; j < (len / 4); j++, offset += 4) { bnx2_reg_wr_ind(bp, offset, 0); } } /* Load the BSS area. */ - offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base); - if (fw->bss_len) { + addr = be32_to_cpu(fw_entry->bss.addr); + len = be32_to_cpu(fw_entry->bss.len); + DPRINTK("init bss section on %x with length %u\n", addr, len); + + offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base); + if (len) { int j; - for (j = 0; j < (fw->bss_len/4); j++, offset += 4) { + for (j = 0; j < (len / 4); j++, offset += 4) { bnx2_reg_wr_ind(bp, offset, 0); } } /* Load the Read-Only area. */ - offset = cpu_reg->spad_base + - (fw->rodata_addr - cpu_reg->mips_view_base); - if (fw->rodata) { + addr = be32_to_cpu(fw_entry->rodata.addr); + len = be32_to_cpu(fw_entry->rodata.len); + file_offset = be32_to_cpu(fw_entry->rodata.offset); + data = (u32 *)(bp->firmware->data + file_offset); + DPRINTK("load rodata section to %x with length %u from file offset %x\n", addr, len, file_offset); + + offset = cpu_reg->spad_base + (addr - cpu_reg->mips_view_base); + if (len) { int j; - for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) { - bnx2_reg_wr_ind(bp, offset, fw->rodata[j]); + for (j = 0; j < (len / 4); j++, offset += 4) { + bnx2_reg_wr_ind(bp, offset, be32_to_cpu(data[j])); } } /* Clear the pre-fetch instruction. */ bnx2_reg_wr_ind(bp, cpu_reg->inst, 0); - bnx2_reg_wr_ind(bp, cpu_reg->pc, fw->start_addr); + + val = be32_to_cpu(fw_entry->start_addr); + DPRINTK("starting cpu on %x\n", val); + bnx2_reg_wr_ind(bp, cpu_reg->pc, val); /* Start the CPU. */ val = bnx2_reg_rd_ind(bp, cpu_reg->mode); @@ -3280,39 +3322,14 @@ static int bnx2_init_cpus(struct bnx2 *bp) { struct cpu_reg cpu_reg; - struct fw_info *fw; - int rc, rv2p_len; - void *text, *rv2p; - - /* Initialize the RV2P processor. */ - text = vmalloc(FW_BUF_SIZE); - if (!text) - return -ENOMEM; - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - rv2p = bnx2_xi_rv2p_proc1; - rv2p_len = sizeof(bnx2_xi_rv2p_proc1); - } else { - rv2p = bnx2_rv2p_proc1; - rv2p_len = sizeof(bnx2_rv2p_proc1); - } - rc = zlib_inflate_blob(text, FW_BUF_SIZE, rv2p, rv2p_len); - if (rc < 0) - goto init_cpu_err; + const struct bnx2_fw_file *fw = NULL; + int rc; - load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC1); + fw = (struct bnx2_fw_file *)bp->firmware->data; - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - rv2p = bnx2_xi_rv2p_proc2; - rv2p_len = sizeof(bnx2_xi_rv2p_proc2); - } else { - rv2p = bnx2_rv2p_proc2; - rv2p_len = sizeof(bnx2_rv2p_proc2); - } - rc = zlib_inflate_blob(text, FW_BUF_SIZE, rv2p, rv2p_len); - if (rc < 0) - goto init_cpu_err; - - load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC2); + /* Initialize the RV2P processor. */ + load_rv2p_fw(bp, RV2P_PROC1, &fw->rv2p_proc1); + load_rv2p_fw(bp, RV2P_PROC2, &fw->rv2p_proc2); /* Initialize the RX Processor. */ cpu_reg.mode = BNX2_RXP_CPU_MODE; @@ -3328,15 +3345,9 @@ bnx2_init_cpus(struct bnx2 *bp) cpu_reg.spad_base = BNX2_RXP_SCRATCH; cpu_reg.mips_view_base = 0x8000000; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - fw = &bnx2_rxp_fw_09; - else - fw = &bnx2_rxp_fw_06; - - fw->text = text; - rc = load_cpu_fw(bp, &cpu_reg, fw); + rc = load_cpu_fw(bp, &cpu_reg, &fw->rxp); if (rc) - goto init_cpu_err; + return rc; /* Initialize the TX Processor. */ cpu_reg.mode = BNX2_TXP_CPU_MODE; @@ -3352,15 +3363,9 @@ bnx2_init_cpus(struct bnx2 *bp) cpu_reg.spad_base = BNX2_TXP_SCRATCH; cpu_reg.mips_view_base = 0x8000000; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - fw = &bnx2_txp_fw_09; - else - fw = &bnx2_txp_fw_06; - - fw->text = text; - rc = load_cpu_fw(bp, &cpu_reg, fw); + rc = load_cpu_fw(bp, &cpu_reg, &fw->txp); if (rc) - goto init_cpu_err; + return rc; /* Initialize the TX Patch-up Processor. */ cpu_reg.mode = BNX2_TPAT_CPU_MODE; @@ -3376,15 +3381,9 @@ bnx2_init_cpus(struct bnx2 *bp) cpu_reg.spad_base = BNX2_TPAT_SCRATCH; cpu_reg.mips_view_base = 0x8000000; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - fw = &bnx2_tpat_fw_09; - else - fw = &bnx2_tpat_fw_06; - - fw->text = text; - rc = load_cpu_fw(bp, &cpu_reg, fw); + rc = load_cpu_fw(bp, &cpu_reg, &fw->tpat); if (rc) - goto init_cpu_err; + return rc; /* Initialize the Completion Processor. */ cpu_reg.mode = BNX2_COM_CPU_MODE; @@ -3400,15 +3399,9 @@ bnx2_init_cpus(struct bnx2 *bp) cpu_reg.spad_base = BNX2_COM_SCRATCH; cpu_reg.mips_view_base = 0x8000000; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - fw = &bnx2_com_fw_09; - else - fw = &bnx2_com_fw_06; - - fw->text = text; - rc = load_cpu_fw(bp, &cpu_reg, fw); + rc = load_cpu_fw(bp, &cpu_reg, &fw->com); if (rc) - goto init_cpu_err; + return rc; /* Initialize the Command Processor. */ cpu_reg.mode = BNX2_CP_CPU_MODE; @@ -3424,17 +3417,7 @@ bnx2_init_cpus(struct bnx2 *bp) cpu_reg.spad_base = BNX2_CP_SCRATCH; cpu_reg.mips_view_base = 0x8000000; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - fw = &bnx2_cp_fw_09; - else - fw = &bnx2_cp_fw_06; - - fw->text = text; - rc = load_cpu_fw(bp, &cpu_reg, fw); - -init_cpu_err: - vfree(text); - return rc; + return load_cpu_fw(bp, &cpu_reg, &fw->cp); } static int @@ -7456,6 +7439,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct bnx2 *bp; int rc; char str[40]; + const char *fw_file; DECLARE_MAC_BUF(mac); if (version_printed++ == 0) @@ -7497,6 +7481,23 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); + if (CHIP_NUM(bp) == CHIP_NUM_5709) + fw_file = FW_FILE_09; + else + fw_file = FW_FILE_06; + + rc = request_firmware(&bp->firmware, fw_file, &pdev->dev); + if (rc) { + printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file); + goto error; + } + + if (bp->firmware->size < sizeof(struct bnx2_fw_file)) { + printk(KERN_ERR PFX "Firmware file too small\n"); + rc = -EINVAL; + goto error; + } + memcpy(dev->dev_addr, bp->mac_addr, 6); memcpy(dev->perm_addr, bp->mac_addr, 6); bp->name = board_info[ent->driver_data].name; @@ -7514,13 +7515,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if ((rc = register_netdev(dev))) { dev_err(&pdev->dev, "Cannot register net device\n"); - if (bp->regview) - iounmap(bp->regview); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - free_netdev(dev); - return rc; + goto error; } printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, " @@ -7534,6 +7529,15 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) bp->pdev->irq, print_mac(mac, dev->dev_addr)); return 0; + +error: + if (bp->regview) + iounmap(bp->regview); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + free_netdev(dev); + return rc; } static void __devexit @@ -7549,6 +7553,8 @@ bnx2_remove_one(struct pci_dev *pdev) if (bp->regview) iounmap(bp->regview); + release_firmware(bp->firmware); + free_netdev(dev); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 3aa0364..b9a052f 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6812,6 +6812,8 @@ struct bnx2 { struct bnx2_irq irq_tbl[BNX2_MAX_MSIX_VEC]; int irq_nvecs; + + const struct firmware *firmware; }; #define REG_RD(bp, offset) \ @@ -6842,44 +6844,6 @@ struct cpu_reg { u32 mips_view_base; }; -struct fw_info { - const u32 ver_major; - const u32 ver_minor; - const u32 ver_fix; - - const u32 start_addr; - - /* Text section. */ - const u32 text_addr; - const u32 text_len; - const u32 text_index; - __le32 *text; - u8 *gz_text; - const u32 gz_text_len; - - /* Data section. */ - const u32 data_addr; - const u32 data_len; - const u32 data_index; - const u32 *data; - - /* SBSS section. */ - const u32 sbss_addr; - const u32 sbss_len; - const u32 sbss_index; - - /* BSS section. */ - const u32 bss_addr; - const u32 bss_len; - const u32 bss_index; - - /* Read-only section. */ - const u32 rodata_addr; - const u32 rodata_len; - const u32 rodata_index; - const u32 *rodata; -}; - #define RV2P_PROC1 0 #define RV2P_PROC2 1 diff --git a/drivers/net/bnx2_fw_file.h b/drivers/net/bnx2_fw_file.h new file mode 100644 index 0000000..06c003c --- /dev/null +++ b/drivers/net/bnx2_fw_file.h @@ -0,0 +1,25 @@ +struct bnx2_fw_file_section { + uint32_t addr; + uint32_t len; + uint32_t offset; +}; + +struct bnx2_fw_file_entry { + uint32_t start_addr; + struct bnx2_fw_file_section text; + struct bnx2_fw_file_section data; + struct bnx2_fw_file_section sbss; + struct bnx2_fw_file_section bss; + struct bnx2_fw_file_section rodata; +}; + +struct bnx2_fw_file { + struct bnx2_fw_file_entry com; + struct bnx2_fw_file_entry cp; + struct bnx2_fw_file_entry rxp; + struct bnx2_fw_file_entry tpat; + struct bnx2_fw_file_entry txp; + struct bnx2_fw_file_section rv2p_proc1; + struct bnx2_fw_file_section rv2p_proc2; +}; +
#include <assert.h> #include <byteswap.h> #include <endian.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <zlib.h> #include "bnx2_fw_file.h" struct fw_info { const uint32_t ver_major; const uint32_t ver_minor; const uint32_t ver_fix; const uint32_t start_addr; /* Text section. */ const uint32_t text_addr; const uint32_t text_len; const uint32_t text_index; void *text; const void *gz_text; const uint32_t gz_text_len; /* Data section. */ const uint32_t data_addr; const uint32_t data_len; const uint32_t data_index; const uint32_t *data; /* SBSS section. */ const uint32_t sbss_addr; const uint32_t sbss_len; const uint32_t sbss_index; /* BSS section. */ const uint32_t bss_addr; const uint32_t bss_len; const uint32_t bss_index; /* Read-only section. */ const uint32_t rodata_addr; const uint32_t rodata_len; const uint32_t rodata_index; const uint32_t *rodata; }; typedef uint8_t u8; typedef uint32_t u32; #include "bnx2_fw.h" #include "bnx2_fw2.h" #if __BYTE_ORDER == __LITTLE_ENDIAN #define cpu_to_be32(x) bswap_32(x) #elif __BYTE_ORDER == __BIG_ENDIAN #define cpu_to_be32(x) (x) #endif #define le32_to_be32(x) bswap_32(x) void set_firmware_image_part(struct bnx2_fw_file_section *s, uint32_t addr, uint32_t len) { s->addr = cpu_to_be32(addr); s->len = cpu_to_be32(len); } void write_firmware_flat(int fd, struct bnx2_fw_file_section *out, void *data, int len) { off_t offset = lseek(fd, 0, SEEK_CUR); uint32_t buf[0x10000]; struct z_stream_s strm; memset(&strm, 0, sizeof strm); strm.next_in = (void *)data; strm.avail_in = len; strm.next_out = (void *)buf; strm.avail_out = sizeof buf; int ret = inflateInit2(&strm, -MAX_WBITS); assert(ret == Z_OK); ret = inflate(&strm, Z_FINISH); assert(ret == Z_STREAM_END); unsigned int l = strm.total_out; out->len = cpu_to_be32(l); out->offset = cpu_to_be32(offset); inflateEnd(&strm); for (unsigned int j = 0; j < (l / 4); j++) buf[j] = le32_to_be32(buf[j]); write(fd, buf, l); } void write_firmware_image(int fd, struct bnx2_fw_file_entry *out, struct fw_info *fw) { off_t offset = lseek(fd, 0, SEEK_CUR); out->start_addr = cpu_to_be32(fw->start_addr); set_firmware_image_part(&out->text, fw->text_addr, fw->text_len); out->text.offset = cpu_to_be32(offset); uint32_t buf[0x10000]; struct z_stream_s strm; memset(&strm, 0, sizeof strm); strm.next_in = (void *)fw->gz_text; strm.avail_in = fw->gz_text_len; strm.next_out = (void *)buf; strm.avail_out = sizeof buf; int ret = inflateInit2(&strm, -MAX_WBITS); assert(ret == Z_OK); ret = inflate(&strm, Z_FINISH); assert(ret == Z_STREAM_END); inflateEnd(&strm); for (unsigned int j = 0; j < (fw->text_len / 4); j++) buf[j] = le32_to_be32(buf[j]); offset += write(fd, buf, fw->text_len); if (fw->data_addr) { set_firmware_image_part(&out->data, fw->data_addr, fw->data_len); out->data.offset = cpu_to_be32(offset); for (unsigned int j = 0; j < (fw->data_len / 4); j++) buf[j] = cpu_to_be32(fw->data[j]); offset += write(fd, buf, fw->data_len); } if (fw->sbss_len) set_firmware_image_part(&out->sbss, fw->sbss_addr, fw->sbss_len); if (fw->bss_len) set_firmware_image_part(&out->bss, fw->bss_addr, fw->bss_len); if (fw->rodata_addr) { set_firmware_image_part(&out->rodata, fw->rodata_addr, fw->rodata_len); out->rodata.offset = cpu_to_be32(offset); for (unsigned int j = 0; j < (fw->rodata_len / 4); j++) buf[j] = cpu_to_be32(fw->rodata[j]); offset += write(fd, buf, fw->rodata_len); } } void write_firmware(const char *filename_base, struct fw_info *com_fw, struct fw_info *cp_fw, struct fw_info *rxp_fw, struct fw_info *tpat_fw, struct fw_info *txp_fw, void *rv2p_proc1, int rv2p_proc1_len, void *rv2p_proc2, int rv2p_proc2_len) { struct bnx2_fw_file out; memset(&out, 0, sizeof out); char filename[64]; snprintf(filename, sizeof filename, "%s-%d.%d.%d.fw", filename_base, com_fw->ver_major, com_fw->ver_minor, com_fw->ver_fix); int fd = open(filename, O_WRONLY | O_CREAT, 0666); lseek(fd, sizeof out, SEEK_SET); write_firmware_image(fd, &out.com, com_fw); write_firmware_image(fd, &out.cp, cp_fw); write_firmware_image(fd, &out.rxp, rxp_fw); write_firmware_image(fd, &out.tpat, tpat_fw); write_firmware_image(fd, &out.txp, txp_fw); write_firmware_flat(fd, &out.rv2p_proc1, rv2p_proc1, rv2p_proc1_len); write_firmware_flat(fd, &out.rv2p_proc2, rv2p_proc2, rv2p_proc2_len); lseek(fd, 0, SEEK_SET); write(fd, &out, sizeof out); close(fd); } int main() { write_firmware("bnx2-06", &bnx2_com_fw_06, &bnx2_cp_fw_06, &bnx2_rxp_fw_06, &bnx2_tpat_fw_06, &bnx2_txp_fw_06, bnx2_rv2p_proc1, sizeof bnx2_rv2p_proc1, bnx2_rv2p_proc2, sizeof bnx2_rv2p_proc2); write_firmware("bnx2-09", &bnx2_com_fw_09, &bnx2_cp_fw_09, &bnx2_rxp_fw_09, &bnx2_tpat_fw_09, &bnx2_txp_fw_09, bnx2_xi_rv2p_proc1, sizeof bnx2_xi_rv2p_proc2, bnx2_xi_rv2p_proc2, sizeof bnx2_xi_rv2p_proc2); return EXIT_SUCCESS; }
Attachment:
signature.asc
Description: Digital signature