Skip to content

Commit

Permalink
[BNX2]: factor out gzip unpacker
Browse files Browse the repository at this point in the history
This patch modifies gzip unpacking code in bnx2 driver so that
it does not depend on bnx2 internals. I will move this code
out of the driver and into zlib in follow-on patch.

It can be useful in other drivers which need to store firmwares
or any other relatively big binary blobs - fonts, cursor bitmaps,
whatever.

Patch is run tested by Michael Chan (driver author).

Signed-off-by: Denys Vlasenko <[email protected]>
Acked-by: Michael Chan <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Denys Vlasenko authored and David S. Miller committed Oct 10, 2007
1 parent 89e536a commit b3448b0
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 122 deletions.
160 changes: 58 additions & 102 deletions drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
#include "bnx2_fw.h"
#include "bnx2_fw2.h"

#define FW_BUF_SIZE 0x8000

#define DRV_MODULE_NAME "bnx2"
#define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.6.5"
Expand Down Expand Up @@ -2759,89 +2761,45 @@ bnx2_set_rx_mode(struct net_device *dev)
spin_unlock_bh(&bp->phy_lock);
}

#define FW_BUF_SIZE 0x8000

/* To be moved to generic lib/ */
static int
bnx2_gunzip_init(struct bnx2 *bp)
bnx2_gunzip(void *gunzip_buf, unsigned sz, u8 *zbuf, int len)
{
if ((bp->gunzip_buf = vmalloc(FW_BUF_SIZE)) == NULL)
goto gunzip_nomem1;
struct z_stream_s *strm;
int rc;

if ((bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL)) == NULL)
goto gunzip_nomem2;
/* gzip header (1f,8b,08... 10 bytes total + possible asciz filename)
* is stripped */

bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
if (bp->strm->workspace == NULL)
rc = -ENOMEM;
strm = kmalloc(sizeof(*strm), GFP_KERNEL);
if (strm == NULL)
goto gunzip_nomem2;
strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
if (strm->workspace == NULL)
goto gunzip_nomem3;

return 0;
strm->next_in = zbuf;
strm->avail_in = len;
strm->next_out = gunzip_buf;
strm->avail_out = sz;

rc = zlib_inflateInit2(strm, -MAX_WBITS);
if (rc == Z_OK) {
rc = zlib_inflate(strm, Z_FINISH);
/* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
if (rc == Z_STREAM_END)
rc = sz - strm->avail_out;
else
rc = -EINVAL;
zlib_inflateEnd(strm);
} else
rc = -EINVAL;

kfree(strm->workspace);
gunzip_nomem3:
kfree(bp->strm);
bp->strm = NULL;

kfree(strm);
gunzip_nomem2:
vfree(bp->gunzip_buf);
bp->gunzip_buf = NULL;

gunzip_nomem1:
printk(KERN_ERR PFX "%s: Cannot allocate firmware buffer for "
"uncompression.\n", bp->dev->name);
return -ENOMEM;
}

static void
bnx2_gunzip_end(struct bnx2 *bp)
{
kfree(bp->strm->workspace);

kfree(bp->strm);
bp->strm = NULL;

if (bp->gunzip_buf) {
vfree(bp->gunzip_buf);
bp->gunzip_buf = NULL;
}
}

static int
bnx2_gunzip(struct bnx2 *bp, u8 *zbuf, int len, void **outbuf, int *outlen)
{
int n, rc;

/* check gzip header */
if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
return -EINVAL;

n = 10;

#define FNAME 0x8
if (zbuf[3] & FNAME)
while ((zbuf[n++] != 0) && (n < len));

bp->strm->next_in = zbuf + n;
bp->strm->avail_in = len - n;
bp->strm->next_out = bp->gunzip_buf;
bp->strm->avail_out = FW_BUF_SIZE;

rc = zlib_inflateInit2(bp->strm, -MAX_WBITS);
if (rc != Z_OK)
return rc;

rc = zlib_inflate(bp->strm, Z_FINISH);

*outlen = FW_BUF_SIZE - bp->strm->avail_out;
*outbuf = bp->gunzip_buf;

if ((rc != Z_OK) && (rc != Z_STREAM_END))
printk(KERN_ERR PFX "%s: Firmware decompression error: %s\n",
bp->dev->name, bp->strm->msg);

zlib_inflateEnd(bp->strm);

if (rc == Z_STREAM_END)
return 0;

return rc;
}

Expand Down Expand Up @@ -2894,22 +2852,21 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
/* Load the Text area. */
offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
if (fw->gz_text) {
u32 text_len;
void *text;

rc = bnx2_gunzip(bp, fw->gz_text, fw->gz_text_len, &text,
&text_len);
if (rc)
return rc;

fw->text = text;
}
if (fw->gz_text) {
u32 *text;
int j;

text = vmalloc(FW_BUF_SIZE);
if (!text)
return -ENOMEM;
rc = bnx2_gunzip(text, FW_BUF_SIZE, fw->gz_text, fw->gz_text_len);
if (rc < 0) {
vfree(text);
return rc;
}
for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
REG_WR_IND(bp, offset, cpu_to_le32(fw->text[j]));
REG_WR_IND(bp, offset, cpu_to_le32(text[j]));
}
vfree(text);
}

/* Load the Data area. */
Expand Down Expand Up @@ -2971,27 +2928,27 @@ bnx2_init_cpus(struct bnx2 *bp)
{
struct cpu_reg cpu_reg;
struct fw_info *fw;
int rc = 0;
int rc;
void *text;
u32 text_len;

if ((rc = bnx2_gunzip_init(bp)) != 0)
return rc;

/* Initialize the RV2P processor. */
rc = bnx2_gunzip(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), &text,
&text_len);
if (rc)
text = vmalloc(FW_BUF_SIZE);
if (!text)
return -ENOMEM;
rc = bnx2_gunzip(text, FW_BUF_SIZE, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1));
if (rc < 0) {
vfree(text);
goto init_cpu_err;
}
load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC1);

load_rv2p_fw(bp, text, text_len, RV2P_PROC1);

rc = bnx2_gunzip(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), &text,
&text_len);
if (rc)
rc = bnx2_gunzip(text, FW_BUF_SIZE, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2));
if (rc < 0) {
vfree(text);
goto init_cpu_err;

load_rv2p_fw(bp, text, text_len, RV2P_PROC2);
}
load_rv2p_fw(bp, text, rc /* == len */, RV2P_PROC2);
vfree(text);

/* Initialize the RX Processor. */
cpu_reg.mode = BNX2_RXP_CPU_MODE;
Expand Down Expand Up @@ -3107,7 +3064,6 @@ bnx2_init_cpus(struct bnx2 *bp)
goto init_cpu_err;
}
init_cpu_err:
bnx2_gunzip_end(bp);
return rc;
}

Expand Down
5 changes: 1 addition & 4 deletions drivers/net/bnx2.h
Original file line number Diff line number Diff line change
Expand Up @@ -6681,9 +6681,6 @@ struct bnx2 {
u32 flash_size;

int status_stats_size;

struct z_stream_s *strm;
void *gunzip_buf;
};

static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset);
Expand Down Expand Up @@ -6741,7 +6738,7 @@ struct fw_info {
const u32 text_addr;
const u32 text_len;
const u32 text_index;
u32 *text;
/* u32 *text;*/
u8 *gz_text;
const u32 gz_text_len;

Expand Down
28 changes: 17 additions & 11 deletions drivers/net/bnx2_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/

static u8 bnx2_COM_b06FwText[] = {
0x1f, 0x8b, 0x08, 0x00, 0x45, 0x30, 0xe7, 0x45, 0x00, 0x03, 0xdc, 0x5a,
/* 0x1f, 0x8b, 0x08, 0x00, 0x45, 0x30, 0xe7, 0x45, 0x00, 0x03, */
0xdc, 0x5a,
0x6b, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x4b, 0xae, 0xc8, 0x15,
0x35, 0xa2, 0xc6, 0xf4, 0x5a, 0xa2, 0xed, 0x5d, 0x72, 0x28, 0x12, 0x96,
0xec, 0x6e, 0x68, 0xda, 0x62, 0x8c, 0x8d, 0xb4, 0xd9, 0xa5, 0x0c, 0xa1,
Expand Down Expand Up @@ -1085,8 +1086,9 @@ static struct fw_info bnx2_com_fw_06 = {
};

static u8 bnx2_RXP_b06FwText[] = {
0x1f, 0x8b, 0x08, 0x08, 0xcb, 0xa3, 0x46, 0x45, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xec, 0x5c, 0x6f, 0x6c,
/* 0x1f, 0x8b, 0x08, 0x08, 0xcb, 0xa3, 0x46, 0x45, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
0xec, 0x5c, 0x6f, 0x6c,
0x1c, 0xc7, 0x75, 0x7f, 0x3b, 0xbb, 0xa4, 0x4e, 0xd4, 0x91, 0x5c, 0x1e,
0x4f, 0xf4, 0x49, 0x66, 0x94, 0x5d, 0x71, 0x25, 0x5e, 0x2d, 0xc6, 0x5d,
0x31, 0x57, 0x9b, 0x08, 0xce, 0xf1, 0x79, 0xef, 0x64, 0xb1, 0x86, 0x0a,
Expand Down Expand Up @@ -1798,8 +1800,9 @@ static struct fw_info bnx2_rxp_fw_06 = {
};

static u8 bnx2_rv2p_proc1[] = {
0x1f, 0x8b, 0x08, 0x08, 0x5e, 0xd0, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xc5, 0x56, 0xcf, 0x6b,
/* 0x1f, 0x8b, 0x08, 0x08, 0x5e, 0xd0, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
0xc5, 0x56, 0xcf, 0x6b,
0x13, 0x51, 0x10, 0x9e, 0xec, 0x6e, 0xb2, 0xdb, 0x74, 0xbb, 0x1b, 0x2b,
0xda, 0xa0, 0xb1, 0x8d, 0x51, 0x6a, 0x7f, 0xa4, 0xb4, 0x11, 0x0f, 0x82,
0x42, 0x25, 0x3d, 0x04, 0x54, 0x44, 0x7a, 0x28, 0x22, 0x82, 0x36, 0x8a,
Expand Down Expand Up @@ -1877,8 +1880,9 @@ static u8 bnx2_rv2p_proc1[] = {
0x12, 0x3d, 0x80, 0x0b, 0x00, 0x00, 0x00 };

static u8 bnx2_rv2p_proc2[] = {
0x1f, 0x8b, 0x08, 0x08, 0x7e, 0xd1, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xcd, 0x58, 0x5b, 0x6c,
/* 0x1f, 0x8b, 0x08, 0x08, 0x7e, 0xd1, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
0xcd, 0x58, 0x5b, 0x6c,
0x54, 0x55, 0x14, 0x3d, 0xf3, 0xe8, 0xcc, 0x9d, 0xe9, 0xed, 0x9d, 0xf2,
0xb2, 0x03, 0xad, 0x08, 0xe5, 0xd1, 0x56, 0x29, 0xe8, 0x54, 0xab, 0x18,
0x15, 0x2c, 0x5a, 0x8c, 0x26, 0x68, 0xf0, 0xf9, 0x63, 0x14, 0x04, 0xda,
Expand Down Expand Up @@ -2057,8 +2061,9 @@ static u8 bnx2_rv2p_proc2[] = {
0x17, 0x00, 0x00, 0x00 };

static u8 bnx2_TPAT_b06FwText[] = {
0x1f, 0x8b, 0x08, 0x08, 0x47, 0xd2, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xc5, 0x57, 0x4d, 0x68,
/* 0x1f, 0x8b, 0x08, 0x08, 0x47, 0xd2, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
0xc5, 0x57, 0x4d, 0x68,
0x1c, 0xe7, 0x19, 0x7e, 0xe7, 0x77, 0x47, 0x62, 0x25, 0x8d, 0x93, 0x3d,
0xac, 0x5d, 0xa5, 0x99, 0x91, 0x46, 0x3f, 0x54, 0x26, 0x9e, 0x84, 0xa5,
0x56, 0x61, 0x20, 0xe3, 0x99, 0x95, 0x2c, 0x0c, 0x05, 0x07, 0x42, 0x08,
Expand Down Expand Up @@ -2290,8 +2295,9 @@ static struct fw_info bnx2_tpat_fw_06 = {
};

static u8 bnx2_TXP_b06FwText[] = {
0x1f, 0x8b, 0x08, 0x08, 0x21, 0xd3, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xed, 0x5c, 0x6d, 0x6c,
/* 0x1f, 0x8b, 0x08, 0x08, 0x21, 0xd3, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65,
0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, */
0xed, 0x5c, 0x6d, 0x6c,
0x1b, 0xf7, 0x79, 0x7f, 0xee, 0x85, 0xd2, 0x51, 0x96, 0xe9, 0x93, 0xc2,
0x78, 0x6c, 0xc0, 0xa6, 0x77, 0xd6, 0x51, 0x66, 0x20, 0xb5, 0xa0, 0x05,
0x36, 0x55, 0x87, 0x43, 0x73, 0x3e, 0x52, 0x2f, 0x4e, 0x5c, 0x57, 0x71,
Expand Down
15 changes: 10 additions & 5 deletions drivers/net/bnx2_fw2.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
*/

static u8 bnx2_COM_b09FwText[] = {
0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xdc, 0x5b,
/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
0xdc, 0x5b,
0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xef, 0xd9, 0xbb, 0xf2, 0x5a, 0x92,
0xe5, 0x6b, 0x79, 0x23, 0x16, 0x4b, 0xc0, 0xae, 0x75, 0x6d, 0x69, 0xb0,
0x43, 0x16, 0xa1, 0x80, 0x9a, 0xd9, 0xc0, 0xb2, 0x2b, 0x33, 0x9e, 0x0c,
Expand Down Expand Up @@ -1083,7 +1084,8 @@ static struct fw_info bnx2_com_fw_09 = {
};

static u8 bnx2_CP_b09FwText[] = {
0x1f, 0x8b, 0x08, 0x00, 0x0f, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xbd, 0x7d,
/* 0x1f, 0x8b, 0x08, 0x00, 0x0f, 0x34, 0xe7, 0x45, 0x00, 0x03, */
0xbd, 0x7d,
0x0d, 0x74, 0x5c, 0x57, 0x7d, 0xe7, 0xff, 0xdd, 0x19, 0x49, 0x63, 0x59,
0x96, 0x9f, 0xe5, 0x89, 0x32, 0x51, 0x84, 0x3d, 0x23, 0x3d, 0xd9, 0x22,
0x12, 0xe1, 0xc5, 0x11, 0xac, 0xda, 0x2a, 0xe9, 0x30, 0x92, 0x3f, 0x12,
Expand Down Expand Up @@ -2279,7 +2281,8 @@ static struct fw_info bnx2_cp_fw_09 = {
};

static u8 bnx2_RXP_b09FwText[] = {
0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xec, 0x5c,
/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
0xec, 0x5c,
0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x43, 0x6a, 0x49, 0xf1, 0x67,
0xb8, 0x5c, 0xb1, 0x2b, 0x99, 0x96, 0x77, 0xc9, 0x91, 0xc8, 0x58, 0x8a,
0x31, 0xa2, 0x09, 0x5b, 0x48, 0x17, 0xf6, 0x76, 0x76, 0x25, 0xb1, 0xb1,
Expand Down Expand Up @@ -2988,7 +2991,8 @@ static struct fw_info bnx2_rxp_fw_09 = {
};

static u8 bnx2_TPAT_b09FwText[] = {
0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xcd, 0x58,
/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
0xcd, 0x58,
0x5d, 0x68, 0x1c, 0xd7, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0x52, 0x24, 0xeb,
0x5a, 0xd9, 0xa6, 0xeb, 0xa0, 0x34, 0x33, 0xda, 0x91, 0xac, 0x22, 0x13,
0x4f, 0x9d, 0x25, 0x16, 0x65, 0x21, 0x93, 0xd9, 0x91, 0xac, 0x98, 0x3c,
Expand Down Expand Up @@ -3279,7 +3283,8 @@ static struct fw_info bnx2_tpat_fw_09 = {
};

static u8 bnx2_TXP_b09FwText[] = {
0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xcd, 0x7c,
/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */
0xcd, 0x7c,
0x6f, 0x70, 0x5b, 0xd7, 0x95, 0xdf, 0x79, 0xef, 0x81, 0x24, 0x48, 0xd1,
0xd4, 0x13, 0x17, 0x56, 0x60, 0x87, 0x71, 0x00, 0xf1, 0x81, 0x66, 0x42,
0xae, 0x04, 0x2b, 0x4c, 0xc2, 0x6d, 0xd1, 0xf8, 0x05, 0x00, 0x29, 0x48,
Expand Down

0 comments on commit b3448b0

Please sign in to comment.