netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2.6.18 4/6] bnx2: Add firmware decompression
@ 2006-06-13  0:17 Michael Chan
  2006-06-13  0:38 ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Michael Chan @ 2006-06-13  0:17 UTC (permalink / raw)
  To: davem; +Cc: netdev

Add functions to decompress firmware before loading to the internal
CPUs. Compressing the firmware reduces the driver size significantly.

Signed-off-by: Michael Chan <mchan@broadcom.com>


diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index bdaaad8..1fb0a19 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -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.
 
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 7a3d888..3b1fe1e 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -50,6 +50,7 @@
 #include <linux/crc32.h>
 #include <linux/prefetch.h>
 #include <linux/cache.h>
+#include <linux/zlib.h>
 
 #include "bnx2.h"
 #include "bnx2_fw.h"
@@ -2084,6 +2085,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);
+
+	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)
@@ -2093,9 +2180,9 @@ load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_
 
 
 	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) {
@@ -2135,7 +2222,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_
 		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]));
 	        }
 	}
 
@@ -2191,15 +2278,32 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_
 	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;
@@ -2223,7 +2327,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;
@@ -2269,7 +2379,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;
@@ -2315,7 +2431,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;
@@ -2361,7 +2483,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;
@@ -2385,6 +2513,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
@@ -3257,7 +3388,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);
@@ -3557,7 +3690,9 @@ bnx2_reset_nic(struct bnx2 *bp, u32 rese
 	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;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index de2b58c..768abca 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -4048,6 +4048,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);



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 2.6.18 4/6] bnx2: Add firmware decompression
  2006-06-13  0:17 [PATCH 2.6.18 4/6] bnx2: Add firmware decompression Michael Chan
@ 2006-06-13  0:38 ` David Miller
  2006-06-13  1:42   ` [PATCH 2.6.18 4/6 revised] " Michael Chan
  0 siblings, 1 reply; 4+ messages in thread
From: David Miller @ 2006-06-13  0:38 UTC (permalink / raw)
  To: mchan; +Cc: netdev

From: "Michael Chan" <mchan@broadcom.com>
Date: Mon, 12 Jun 2006 17:17:18 -0700

> Add functions to decompress firmware before loading to the internal
> CPUs. Compressing the firmware reduces the driver size significantly.
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>
 ...
> +#define FNAME	0x8
> +	if (zbuf[3] & FNAME)
> +		while (zbuf[n++] != 0);

This can potentially loop past the end of zbuf[], so maybe
put a sanity check against 'len' and return non-zero if we
traverse past the end?



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2.6.18 4/6 revised] bnx2: Add firmware decompression
  2006-06-13  0:38 ` David Miller
@ 2006-06-13  1:42   ` Michael Chan
  2006-06-13  5:21     ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Michael Chan @ 2006-06-13  1:42 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

On Mon, 2006-06-12 at 17:38 -0700, David Miller wrote:
> From: "Michael Chan" <mchan@broadcom.com>
> Date: Mon, 12 Jun 2006 17:17:18 -0700
> 
> > Add functions to decompress firmware before loading to the internal
> > CPUs. Compressing the firmware reduces the driver size significantly.
> > 
> > Signed-off-by: Michael Chan <mchan@broadcom.com>
>  ...
> > +#define FNAME	0x8
> > +	if (zbuf[3] & FNAME)
> > +		while (zbuf[n++] != 0);
> 
> This can potentially loop past the end of zbuf[], so maybe
> put a sanity check against 'len' and return non-zero if we
> traverse past the end?

Add functions to decompress firmware before loading to the internal
CPUs. Compressing the firmware reduces the driver size significantly.

Added file name length sanity check in the gzip header to prevent
going past the end of buffer [suggested by DaveM].

Signed-off-by: Michael Chan <mchan@broadcom.com>


diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index bdaaad8..1fb0a19 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -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.
 
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 7a3d888..8ed190f 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -50,6 +50,7 @@
 #include <linux/crc32.h>
 #include <linux/prefetch.h>
 #include <linux/cache.h>
+#include <linux/zlib.h>
 
 #include "bnx2.h"
 #include "bnx2_fw.h"
@@ -2084,6 +2085,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)
@@ -2093,9 +2180,9 @@ load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_
 
 
 	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) {
@@ -2135,7 +2222,7 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_
 		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]));
 	        }
 	}
 
@@ -2191,15 +2278,32 @@ load_cpu_fw(struct bnx2 *bp, struct cpu_
 	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;
@@ -2223,7 +2327,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;
@@ -2269,7 +2379,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;
@@ -2315,7 +2431,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;
@@ -2361,7 +2483,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;
@@ -2385,6 +2513,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
@@ -3257,7 +3388,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);
@@ -3557,7 +3690,9 @@ bnx2_reset_nic(struct bnx2 *bp, u32 rese
 	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;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index de2b58c..768abca 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -4048,6 +4048,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);



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 2.6.18 4/6 revised] bnx2: Add firmware decompression
  2006-06-13  1:42   ` [PATCH 2.6.18 4/6 revised] " Michael Chan
@ 2006-06-13  5:21     ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2006-06-13  5:21 UTC (permalink / raw)
  To: mchan; +Cc: netdev

From: "Michael Chan" <mchan@broadcom.com>
Date: Mon, 12 Jun 2006 18:42:29 -0700

> On Mon, 2006-06-12 at 17:38 -0700, David Miller wrote:
> > From: "Michael Chan" <mchan@broadcom.com>
> > Date: Mon, 12 Jun 2006 17:17:18 -0700
> > 
> > > Add functions to decompress firmware before loading to the internal
> > > CPUs. Compressing the firmware reduces the driver size significantly.
> > > 
> > > Signed-off-by: Michael Chan <mchan@broadcom.com>
> >  ...
> > > +#define FNAME	0x8
> > > +	if (zbuf[3] & FNAME)
> > > +		while (zbuf[n++] != 0);
> > 
> > This can potentially loop past the end of zbuf[], so maybe
> > put a sanity check against 'len' and return non-zero if we
> > traverse past the end?
> 
> Add functions to decompress firmware before loading to the internal
> CPUs. Compressing the firmware reduces the driver size significantly.
> 
> Added file name length sanity check in the gzip header to prevent
> going past the end of buffer [suggested by DaveM].
> 
> Signed-off-by: Michael Chan <mchan@broadcom.com>

This looks great, applied.

Thanks a lot.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-06-13  5:21 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-13  0:17 [PATCH 2.6.18 4/6] bnx2: Add firmware decompression Michael Chan
2006-06-13  0:38 ` David Miller
2006-06-13  1:42   ` [PATCH 2.6.18 4/6 revised] " Michael Chan
2006-06-13  5:21     ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).