Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 27577
b: refs/heads/master
c: fba9fe9
h: refs/heads/master
i:
  27575: 7d99234
v: v3
  • Loading branch information
Michael Chan authored and David S. Miller committed Jun 18, 2006
1 parent 558b47a commit 54b5849
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 160882722cb21cbe5cead55cf38a5e70fc3af63e
refs/heads/master: fba9fe911bb4213c3de1d142fe0ee127cd361a78
2 changes: 2 additions & 0 deletions trunk/drivers/net/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2163,6 +2163,8 @@ config TIGON3
config BNX2
tristate "Broadcom NetXtremeII support"
depends on PCI
select CRC32
select ZLIB_INFLATE
help
This driver supports Broadcom NetXtremeII gigabit Ethernet cards.

Expand Down
159 changes: 147 additions & 12 deletions trunk/drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <linux/crc32.h>
#include <linux/prefetch.h>
#include <linux/cache.h>
#include <linux/zlib.h>

#include "bnx2.h"
#include "bnx2_fw.h"
Expand Down Expand Up @@ -2083,6 +2084,92 @@ bnx2_set_rx_mode(struct net_device *dev)
spin_unlock_bh(&bp->phy_lock);
}

#define FW_BUF_SIZE 0x8000

static int
bnx2_gunzip_init(struct bnx2 *bp)
{
if ((bp->gunzip_buf = vmalloc(FW_BUF_SIZE)) == NULL)
goto gunzip_nomem1;

if ((bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL)) == NULL)
goto gunzip_nomem2;

bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
if (bp->strm->workspace == NULL)
goto gunzip_nomem3;

return 0;

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

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;
}

static void
load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len,
u32 rv2p_proc)
Expand All @@ -2092,9 +2179,9 @@ load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len,


for (i = 0; i < rv2p_code_len; i += 8) {
REG_WR(bp, BNX2_RV2P_INSTR_HIGH, *rv2p_code);
REG_WR(bp, BNX2_RV2P_INSTR_HIGH, cpu_to_le32(*rv2p_code));
rv2p_code++;
REG_WR(bp, BNX2_RV2P_INSTR_LOW, *rv2p_code);
REG_WR(bp, BNX2_RV2P_INSTR_LOW, cpu_to_le32(*rv2p_code));
rv2p_code++;

if (rv2p_proc == RV2P_PROC1) {
Expand Down Expand Up @@ -2134,7 +2221,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
int j;

for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
REG_WR_IND(bp, offset, fw->text[j]);
REG_WR_IND(bp, offset, cpu_to_le32(fw->text[j]));
}
}

Expand Down Expand Up @@ -2190,15 +2277,32 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw)
REG_WR_IND(bp, cpu_reg->mode, val);
}

static void
static int
bnx2_init_cpus(struct bnx2 *bp)
{
struct cpu_reg cpu_reg;
struct fw_info fw;
int rc = 0;
void *text;
u32 text_len;

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

/* Initialize the RV2P processor. */
load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1);
load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2);
rc = bnx2_gunzip(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), &text,
&text_len);
if (rc)
goto init_cpu_err;

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)
goto init_cpu_err;

load_rv2p_fw(bp, text, text_len, RV2P_PROC2);

/* Initialize the RX Processor. */
cpu_reg.mode = BNX2_RXP_CPU_MODE;
Expand All @@ -2222,7 +2326,13 @@ bnx2_init_cpus(struct bnx2 *bp)
fw.text_addr = bnx2_RXP_b06FwTextAddr;
fw.text_len = bnx2_RXP_b06FwTextLen;
fw.text_index = 0;
fw.text = bnx2_RXP_b06FwText;

rc = bnx2_gunzip(bp, bnx2_RXP_b06FwText, sizeof(bnx2_RXP_b06FwText),
&text, &text_len);
if (rc)
goto init_cpu_err;

fw.text = text;

fw.data_addr = bnx2_RXP_b06FwDataAddr;
fw.data_len = bnx2_RXP_b06FwDataLen;
Expand Down Expand Up @@ -2268,7 +2378,13 @@ bnx2_init_cpus(struct bnx2 *bp)
fw.text_addr = bnx2_TXP_b06FwTextAddr;
fw.text_len = bnx2_TXP_b06FwTextLen;
fw.text_index = 0;
fw.text = bnx2_TXP_b06FwText;

rc = bnx2_gunzip(bp, bnx2_TXP_b06FwText, sizeof(bnx2_TXP_b06FwText),
&text, &text_len);
if (rc)
goto init_cpu_err;

fw.text = text;

fw.data_addr = bnx2_TXP_b06FwDataAddr;
fw.data_len = bnx2_TXP_b06FwDataLen;
Expand Down Expand Up @@ -2314,7 +2430,13 @@ bnx2_init_cpus(struct bnx2 *bp)
fw.text_addr = bnx2_TPAT_b06FwTextAddr;
fw.text_len = bnx2_TPAT_b06FwTextLen;
fw.text_index = 0;
fw.text = bnx2_TPAT_b06FwText;

rc = bnx2_gunzip(bp, bnx2_TPAT_b06FwText, sizeof(bnx2_TPAT_b06FwText),
&text, &text_len);
if (rc)
goto init_cpu_err;

fw.text = text;

fw.data_addr = bnx2_TPAT_b06FwDataAddr;
fw.data_len = bnx2_TPAT_b06FwDataLen;
Expand Down Expand Up @@ -2360,7 +2482,13 @@ bnx2_init_cpus(struct bnx2 *bp)
fw.text_addr = bnx2_COM_b06FwTextAddr;
fw.text_len = bnx2_COM_b06FwTextLen;
fw.text_index = 0;
fw.text = bnx2_COM_b06FwText;

rc = bnx2_gunzip(bp, bnx2_COM_b06FwText, sizeof(bnx2_COM_b06FwText),
&text, &text_len);
if (rc)
goto init_cpu_err;

fw.text = text;

fw.data_addr = bnx2_COM_b06FwDataAddr;
fw.data_len = bnx2_COM_b06FwDataLen;
Expand All @@ -2384,6 +2512,9 @@ bnx2_init_cpus(struct bnx2 *bp)

load_cpu_fw(bp, &cpu_reg, &fw);

init_cpu_err:
bnx2_gunzip_end(bp);
return rc;
}

static int
Expand Down Expand Up @@ -3256,7 +3387,9 @@ bnx2_init_chip(struct bnx2 *bp)
* context block must have already been enabled. */
bnx2_init_context(bp);

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

bnx2_init_nvram(bp);

bnx2_set_mac_addr(bp);
Expand Down Expand Up @@ -3556,7 +3689,9 @@ bnx2_reset_nic(struct bnx2 *bp, u32 reset_code)
if (rc)
return rc;

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

bnx2_init_tx_ring(bp);
bnx2_init_rx_ring(bp);
return 0;
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/net/bnx2.h
Original file line number Diff line number Diff line change
Expand Up @@ -4051,6 +4051,9 @@ 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

0 comments on commit 54b5849

Please sign in to comment.