aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladislav Zolotarov <vladz@broadcom.com>2009-04-27 06:27:43 -0400
committerDavid S. Miller <davem@davemloft.net>2009-04-27 06:27:43 -0400
commit94a78b79cb5f14c09a42522738d6694c6a1cdd20 (patch)
tree17bb6b92c16c91db0398baafa04996c958a8d494
parentec9323f417e803f07a99a15a9cfb207662ad2c55 (diff)
bnx2x: Separated FW from the source.
>From now on FW will be downloaded from the binary file using request_firmware. There will be different files for every supported chip. Currently 57710 (e1) and 57711 (e1h). File names have the following format: bnx2x-<chip version>-<FW version>.fw. ihex versions of current FW files are submitted in the next patch. Each binary file has a header in the following format: struct bnx2x_fw_file_section { __be32 len; __be32 offset; } struct bnx2x_fw_file_hdr { struct bnx2x_fw_file_section init_ops; struct bnx2x_fw_file_section init_ops_offsets; struct bnx2x_fw_file_section init_data; struct bnx2x_fw_file_section tsem_int_table_data; struct bnx2x_fw_file_section tsem_pram_data; struct bnx2x_fw_file_section usem_int_table_data; struct bnx2x_fw_file_section usem_pram_data; struct bnx2x_fw_file_section csem_int_table_data; struct bnx2x_fw_file_section csem_pram_data; struct bnx2x_fw_file_section xsem_int_table_data; struct bnx2x_fw_file_section xsem_pram_data; struct bnx2x_fw_file_section fw_version; } Each bnx2x_fw_file_section contains the length and the offset of the appropriate section in the binary file. Values are stored in the big endian format. Data types of arrays: init_data __be32 init_ops_offsets __be16 XXsem_pram_data u8 XXsem_int_table_data u8 init_ops struct raw_op { u8 op; __be24 offset; __be32 data; } fw_version u8 >From now boundaries of a specific initialization stage are stored in init_ops_offsets array instead of being defined by separate macroes. The index in init_ops_offsets is calculated by BLOCK_OPS_IDX macro: #define BLOCK_OPS_IDX(block, stage, end) \ (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end)) Security: In addition to sanity check of array boundaries bnx2x will check a FW version. Additional checks might be added in the future. Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/Kconfig1
-rw-r--r--drivers/net/bnx2x.h15
-rw-r--r--drivers/net/bnx2x_fw_file_hdr.h37
-rw-r--r--drivers/net/bnx2x_init.h605
-rw-r--r--drivers/net/bnx2x_init_ops.h442
-rw-r--r--drivers/net/bnx2x_main.c343
-rw-r--r--firmware/Makefile1
-rw-r--r--firmware/WHENCE20
8 files changed, 866 insertions, 598 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3320e7761576..bc7eef12d955 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2676,6 +2676,7 @@ config TEHUTI
2676config BNX2X 2676config BNX2X
2677 tristate "Broadcom NetXtremeII 10Gb support" 2677 tristate "Broadcom NetXtremeII 10Gb support"
2678 depends on PCI 2678 depends on PCI
2679 select FW_LOADER
2679 select ZLIB_INFLATE 2680 select ZLIB_INFLATE
2680 select LIBCRC32C 2681 select LIBCRC32C
2681 help 2682 help
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index a329bee25550..8678457849f9 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -965,6 +965,21 @@ struct bnx2x {
965 int gunzip_outlen; 965 int gunzip_outlen;
966#define FW_BUF_SIZE 0x8000 966#define FW_BUF_SIZE 0x8000
967 967
968 struct raw_op *init_ops;
969 /* Init blocks offsets inside init_ops */
970 u16 *init_ops_offsets;
971 /* Data blob - has 32 bit granularity */
972 u32 *init_data;
973 /* Zipped PRAM blobs - raw data */
974 const u8 *tsem_int_table_data;
975 const u8 *tsem_pram_data;
976 const u8 *usem_int_table_data;
977 const u8 *usem_pram_data;
978 const u8 *xsem_int_table_data;
979 const u8 *xsem_pram_data;
980 const u8 *csem_int_table_data;
981 const u8 *csem_pram_data;
982 const struct firmware *firmware;
968}; 983};
969 984
970 985
diff --git a/drivers/net/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x_fw_file_hdr.h
new file mode 100644
index 000000000000..3f5ee5d7cc2a
--- /dev/null
+++ b/drivers/net/bnx2x_fw_file_hdr.h
@@ -0,0 +1,37 @@
1/* bnx2x_fw_file_hdr.h: FW binary file header structure.
2 *
3 * Copyright (c) 2007-2009 Broadcom Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation.
8 *
9 * Maintained by: Eilon Greenstein <eilong@broadcom.com>
10 * Written by: Vladislav Zolotarov <vladz@broadcom.com>
11 * Based on the original idea of John Wright <john.wright@hp.com>.
12 */
13
14#ifndef BNX2X_INIT_FILE_HDR_H
15#define BNX2X_INIT_FILE_HDR_H
16
17struct bnx2x_fw_file_section {
18 __be32 len;
19 __be32 offset;
20};
21
22struct bnx2x_fw_file_hdr {
23 struct bnx2x_fw_file_section init_ops;
24 struct bnx2x_fw_file_section init_ops_offsets;
25 struct bnx2x_fw_file_section init_data;
26 struct bnx2x_fw_file_section tsem_int_table_data;
27 struct bnx2x_fw_file_section tsem_pram_data;
28 struct bnx2x_fw_file_section usem_int_table_data;
29 struct bnx2x_fw_file_section usem_pram_data;
30 struct bnx2x_fw_file_section csem_int_table_data;
31 struct bnx2x_fw_file_section csem_pram_data;
32 struct bnx2x_fw_file_section xsem_int_table_data;
33 struct bnx2x_fw_file_section xsem_pram_data;
34 struct bnx2x_fw_file_section fw_version;
35};
36
37#endif /* BNX2X_INIT_FILE_HDR_H */
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 39ba2936c0c2..3ba4d888068f 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -1,4 +1,5 @@
1/* bnx2x_init.h: Broadcom Everest network driver. 1/* bnx2x_init.h: Broadcom Everest network driver.
2 * Structures and macroes needed during the initialization.
2 * 3 *
3 * Copyright (c) 2007-2009 Broadcom Corporation 4 * Copyright (c) 2007-2009 Broadcom Corporation
4 * 5 *
@@ -8,6 +9,7 @@
8 * 9 *
9 * Maintained by: Eilon Greenstein <eilong@broadcom.com> 10 * Maintained by: Eilon Greenstein <eilong@broadcom.com>
10 * Written by: Eliezer Tamir 11 * Written by: Eliezer Tamir
12 * Modified by: Vladislav Zolotarov <vladz@broadcom.com>
11 */ 13 */
12 14
13#ifndef BNX2X_INIT_H 15#ifndef BNX2X_INIT_H
@@ -45,33 +47,71 @@
45#define OP_WR_64 0x8 /* write 64 bit pattern */ 47#define OP_WR_64 0x8 /* write 64 bit pattern */
46#define OP_WB 0x9 /* copy a string using DMAE */ 48#define OP_WB 0x9 /* copy a string using DMAE */
47 49
48/* Operation specific for E1 */
49#define OP_RD_E1 0xa /* read single register */
50#define OP_WR_E1 0xb /* write single register */
51#define OP_IW_E1 0xc /* write single register using mailbox */
52#define OP_SW_E1 0xd /* copy a string to the device */
53#define OP_SI_E1 0xe /* copy a string using mailbox */
54#define OP_ZR_E1 0xf /* clear memory */
55#define OP_ZP_E1 0x10 /* unzip then copy with DMAE */
56#define OP_WR_64_E1 0x11 /* write 64 bit pattern on E1 */
57#define OP_WB_E1 0x12 /* copy a string using DMAE */
58
59/* Operation specific for E1H */
60#define OP_RD_E1H 0x13 /* read single register */
61#define OP_WR_E1H 0x14 /* write single register */
62#define OP_IW_E1H 0x15 /* write single register using mailbox */
63#define OP_SW_E1H 0x16 /* copy a string to the device */
64#define OP_SI_E1H 0x17 /* copy a string using mailbox */
65#define OP_ZR_E1H 0x18 /* clear memory */
66#define OP_ZP_E1H 0x19 /* unzip then copy with DMAE */
67#define OP_WR_64_E1H 0x1a /* write 64 bit pattern on E1H */
68#define OP_WB_E1H 0x1b /* copy a string using DMAE */
69
70/* FPGA and EMUL specific operations */ 50/* FPGA and EMUL specific operations */
71#define OP_WR_EMUL_E1H 0x1c /* write single register on E1H Emul */ 51#define OP_WR_EMUL 0xa /* write single register on Emulation */
72#define OP_WR_EMUL 0x1d /* write single register on Emulation */ 52#define OP_WR_FPGA 0xb /* write single register on FPGA */
73#define OP_WR_FPGA 0x1e /* write single register on FPGA */ 53#define OP_WR_ASIC 0xc /* write single register on ASIC */
74#define OP_WR_ASIC 0x1f /* write single register on ASIC */ 54
55/* Init stages */
56#define COMMON_STAGE 0
57#define PORT0_STAGE 1
58#define PORT1_STAGE 2
59/* Never reorder FUNCx stages !!! */
60#define FUNC0_STAGE 3
61#define FUNC1_STAGE 4
62#define FUNC2_STAGE 5
63#define FUNC3_STAGE 6
64#define FUNC4_STAGE 7
65#define FUNC5_STAGE 8
66#define FUNC6_STAGE 9
67#define FUNC7_STAGE 10
68#define STAGE_IDX_MAX 11
69
70#define STAGE_START 0
71#define STAGE_END 1
72
73
74/* Indices of blocks */
75#define PRS_BLOCK 0
76#define SRCH_BLOCK 1
77#define TSDM_BLOCK 2
78#define TCM_BLOCK 3
79#define BRB1_BLOCK 4
80#define TSEM_BLOCK 5
81#define PXPCS_BLOCK 6
82#define EMAC0_BLOCK 7
83#define EMAC1_BLOCK 8
84#define DBU_BLOCK 9
85#define MISC_BLOCK 10
86#define DBG_BLOCK 11
87#define NIG_BLOCK 12
88#define MCP_BLOCK 13
89#define UPB_BLOCK 14
90#define CSDM_BLOCK 15
91#define USDM_BLOCK 16
92#define CCM_BLOCK 17
93#define UCM_BLOCK 18
94#define USEM_BLOCK 19
95#define CSEM_BLOCK 20
96#define XPB_BLOCK 21
97#define DQ_BLOCK 22
98#define TIMERS_BLOCK 23
99#define XSDM_BLOCK 24
100#define QM_BLOCK 25
101#define PBF_BLOCK 26
102#define XCM_BLOCK 27
103#define XSEM_BLOCK 28
104#define CDU_BLOCK 29
105#define DMAE_BLOCK 30
106#define PXP_BLOCK 31
107#define CFC_BLOCK 32
108#define HC_BLOCK 33
109#define PXP2_BLOCK 34
110#define MISC_AEU_BLOCK 35
111
112/* Returns the index of start or end of a specific block stage in ops array*/
113#define BLOCK_OPS_IDX(block, stage, end) \
114 (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
75 115
76 116
77struct raw_op { 117struct raw_op {
@@ -118,292 +158,6 @@ union init_op {
118 struct raw_op raw; 158 struct raw_op raw;
119}; 159};
120 160
121#include "bnx2x_init_values.h"
122
123static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
124static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
125
126static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
127 u32 len)
128{
129 int i;
130
131 for (i = 0; i < len; i++) {
132 REG_WR(bp, addr + i*4, data[i]);
133 if (!(i % 10000)) {
134 touch_softlockup_watchdog();
135 cpu_relax();
136 }
137 }
138}
139
140static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
141 u16 len)
142{
143 int i;
144
145 for (i = 0; i < len; i++) {
146 REG_WR_IND(bp, addr + i*4, data[i]);
147 if (!(i % 10000)) {
148 touch_softlockup_watchdog();
149 cpu_relax();
150 }
151 }
152}
153
154static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
155{
156 int offset = 0;
157
158 if (bp->dmae_ready) {
159 while (len > DMAE_LEN32_WR_MAX) {
160 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
161 addr + offset, DMAE_LEN32_WR_MAX);
162 offset += DMAE_LEN32_WR_MAX * 4;
163 len -= DMAE_LEN32_WR_MAX;
164 }
165 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
166 addr + offset, len);
167 } else
168 bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
169}
170
171static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
172{
173 u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
174 u32 buf_len32 = buf_len / 4;
175 int i;
176
177 memset(bp->gunzip_buf, fill, buf_len);
178
179 for (i = 0; i < len; i += buf_len32) {
180 u32 cur_len = min(buf_len32, len - i);
181
182 bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
183 }
184}
185
186static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
187 u32 len64)
188{
189 u32 buf_len32 = FW_BUF_SIZE / 4;
190 u32 len = len64 * 2;
191 u64 data64 = 0;
192 int i;
193
194 /* 64 bit value is in a blob: first low DWORD, then high DWORD */
195 data64 = HILO_U64((*(data + 1)), (*data));
196 len64 = min((u32)(FW_BUF_SIZE/8), len64);
197 for (i = 0; i < len64; i++) {
198 u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
199
200 *pdata = data64;
201 }
202
203 for (i = 0; i < len; i += buf_len32) {
204 u32 cur_len = min(buf_len32, len - i);
205
206 bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
207 }
208}
209
210/*********************************************************
211 There are different blobs for each PRAM section.
212 In addition, each blob write operation is divided into a few operations
213 in order to decrease the amount of phys. contiguous buffer needed.
214 Thus, when we select a blob the address may be with some offset
215 from the beginning of PRAM section.
216 The same holds for the INT_TABLE sections.
217**********************************************************/
218#define IF_IS_INT_TABLE_ADDR(base, addr) \
219 if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
220
221#define IF_IS_PRAM_ADDR(base, addr) \
222 if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
223
224static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1)
225{
226 IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
227 data = is_e1 ? tsem_int_table_data_e1 :
228 tsem_int_table_data_e1h;
229 else
230 IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
231 data = is_e1 ? csem_int_table_data_e1 :
232 csem_int_table_data_e1h;
233 else
234 IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
235 data = is_e1 ? usem_int_table_data_e1 :
236 usem_int_table_data_e1h;
237 else
238 IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
239 data = is_e1 ? xsem_int_table_data_e1 :
240 xsem_int_table_data_e1h;
241 else
242 IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
243 data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h;
244 else
245 IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
246 data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h;
247 else
248 IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
249 data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h;
250 else
251 IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
252 data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h;
253
254 return data;
255}
256
257static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
258 u32 len, int gunzip, int is_e1, u32 blob_off)
259{
260 int offset = 0;
261
262 data = bnx2x_sel_blob(addr, data, is_e1) + blob_off;
263
264 if (gunzip) {
265 int rc;
266#ifdef __BIG_ENDIAN
267 int i, size;
268 u32 *temp;
269
270 temp = kmalloc(len, GFP_KERNEL);
271 size = (len / 4) + ((len % 4) ? 1 : 0);
272 for (i = 0; i < size; i++)
273 temp[i] = swab32(data[i]);
274 data = temp;
275#endif
276 rc = bnx2x_gunzip(bp, (u8 *)data, len);
277 if (rc) {
278 BNX2X_ERR("gunzip failed ! rc %d\n", rc);
279#ifdef __BIG_ENDIAN
280 kfree(temp);
281#endif
282 return;
283 }
284 len = bp->gunzip_outlen;
285#ifdef __BIG_ENDIAN
286 kfree(temp);
287 for (i = 0; i < len; i++)
288 ((u32 *)bp->gunzip_buf)[i] =
289 swab32(((u32 *)bp->gunzip_buf)[i]);
290#endif
291 } else {
292 if ((len * 4) > FW_BUF_SIZE) {
293 BNX2X_ERR("LARGE DMAE OPERATION ! "
294 "addr 0x%x len 0x%x\n", addr, len*4);
295 return;
296 }
297 memcpy(bp->gunzip_buf, data, len * 4);
298 }
299
300 if (bp->dmae_ready) {
301 while (len > DMAE_LEN32_WR_MAX) {
302 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
303 addr + offset, DMAE_LEN32_WR_MAX);
304 offset += DMAE_LEN32_WR_MAX * 4;
305 len -= DMAE_LEN32_WR_MAX;
306 }
307 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
308 addr + offset, len);
309 } else
310 bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
311}
312
313static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
314{
315 int is_e1 = CHIP_IS_E1(bp);
316 int is_e1h = CHIP_IS_E1H(bp);
317 int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h);
318 int hw_wr, i;
319 union init_op *op;
320 u32 op_type, addr, len;
321 const u32 *data, *data_base;
322
323 if (CHIP_REV_IS_FPGA(bp))
324 hw_wr = OP_WR_FPGA;
325 else if (CHIP_REV_IS_EMUL(bp))
326 hw_wr = OP_WR_EMUL;
327 else
328 hw_wr = OP_WR_ASIC;
329
330 if (is_e1)
331 data_base = init_data_e1;
332 else /* CHIP_IS_E1H(bp) */
333 data_base = init_data_e1h;
334
335 for (i = op_start; i < op_end; i++) {
336
337 op = (union init_op *)&(init_ops[i]);
338
339 op_type = op->str_wr.op;
340 addr = op->str_wr.offset;
341 len = op->str_wr.data_len;
342 data = data_base + op->str_wr.data_off;
343
344 /* careful! it must be in order */
345 if (unlikely(op_type > OP_WB)) {
346
347 /* If E1 only */
348 if (op_type <= OP_WB_E1) {
349 if (is_e1)
350 op_type -= (OP_RD_E1 - OP_RD);
351
352 /* If E1H only */
353 } else if (op_type <= OP_WB_E1H) {
354 if (is_e1h)
355 op_type -= (OP_RD_E1H - OP_RD);
356 }
357
358 /* HW/EMUL specific */
359 if (op_type == hw_wr)
360 op_type = OP_WR;
361
362 /* EMUL on E1H is special */
363 if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h)
364 op_type = OP_WR;
365 }
366
367 switch (op_type) {
368 case OP_RD:
369 REG_RD(bp, addr);
370 break;
371 case OP_WR:
372 REG_WR(bp, addr, op->write.val);
373 break;
374 case OP_SW:
375 bnx2x_init_str_wr(bp, addr, data, len);
376 break;
377 case OP_WB:
378 bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0);
379 break;
380 case OP_SI:
381 bnx2x_init_ind_wr(bp, addr, data, len);
382 break;
383 case OP_ZR:
384 bnx2x_init_fill(bp, addr, 0, op->zero.len);
385 break;
386 case OP_ZP:
387 bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1,
388 op->str_wr.data_off);
389 break;
390 case OP_WR_64:
391 bnx2x_init_wr_64(bp, addr, data, len);
392 break;
393 default:
394 /* happens whenever an op is of a diff HW */
395#if 0
396 DP(NETIF_MSG_HW, "skipping init operation "
397 "index %d[%d:%d]: type %d addr 0x%x "
398 "len %d(0x%x)\n",
399 i, op_start, op_end, op_type, addr, len, len);
400#endif
401 break;
402 }
403 }
404}
405
406
407/**************************************************************************** 161/****************************************************************************
408* PXP 162* PXP
409****************************************************************************/ 163****************************************************************************/
@@ -567,111 +321,6 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
567 PXP2_REG_RQ_BW_WR_UBOUND30} 321 PXP2_REG_RQ_BW_WR_UBOUND30}
568}; 322};
569 323
570static void bnx2x_init_pxp(struct bnx2x *bp)
571{
572 u16 devctl;
573 int r_order, w_order;
574 u32 val, i;
575
576 pci_read_config_word(bp->pdev,
577 bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
578 DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
579 w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
580 if (bp->mrrs == -1)
581 r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
582 else {
583 DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
584 r_order = bp->mrrs;
585 }
586
587 if (r_order > MAX_RD_ORD) {
588 DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
589 r_order, MAX_RD_ORD);
590 r_order = MAX_RD_ORD;
591 }
592 if (w_order > MAX_WR_ORD) {
593 DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
594 w_order, MAX_WR_ORD);
595 w_order = MAX_WR_ORD;
596 }
597 if (CHIP_REV_IS_FPGA(bp)) {
598 DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
599 w_order = 0;
600 }
601 DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
602
603 for (i = 0; i < NUM_RD_Q-1; i++) {
604 REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
605 REG_WR(bp, read_arb_addr[i].add,
606 read_arb_data[i][r_order].add);
607 REG_WR(bp, read_arb_addr[i].ubound,
608 read_arb_data[i][r_order].ubound);
609 }
610
611 for (i = 0; i < NUM_WR_Q-1; i++) {
612 if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
613 (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
614
615 REG_WR(bp, write_arb_addr[i].l,
616 write_arb_data[i][w_order].l);
617
618 REG_WR(bp, write_arb_addr[i].add,
619 write_arb_data[i][w_order].add);
620
621 REG_WR(bp, write_arb_addr[i].ubound,
622 write_arb_data[i][w_order].ubound);
623 } else {
624
625 val = REG_RD(bp, write_arb_addr[i].l);
626 REG_WR(bp, write_arb_addr[i].l,
627 val | (write_arb_data[i][w_order].l << 10));
628
629 val = REG_RD(bp, write_arb_addr[i].add);
630 REG_WR(bp, write_arb_addr[i].add,
631 val | (write_arb_data[i][w_order].add << 10));
632
633 val = REG_RD(bp, write_arb_addr[i].ubound);
634 REG_WR(bp, write_arb_addr[i].ubound,
635 val | (write_arb_data[i][w_order].ubound << 7));
636 }
637 }
638
639 val = write_arb_data[NUM_WR_Q-1][w_order].add;
640 val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
641 val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
642 REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
643
644 val = read_arb_data[NUM_RD_Q-1][r_order].add;
645 val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
646 val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
647 REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
648
649 REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
650 REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
651 REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
652 REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
653
654 if (r_order == MAX_RD_ORD)
655 REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
656
657 REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
658
659 if (CHIP_IS_E1H(bp)) {
660 val = ((w_order == 0) ? 2 : 3);
661 REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
662 REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
663 REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
664 REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
665 REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
666 REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
667 REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
668 REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
669 REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
670 REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
671 REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
672 }
673}
674
675 324
676/**************************************************************************** 325/****************************************************************************
677* CDU 326* CDU
@@ -695,128 +344,12 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
695 (0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7)) 344 (0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
696#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80) 345#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
697 346
698/*****************************************************************************
699 * Description:
700 * Calculates crc 8 on a word value: polynomial 0-1-2-8
701 * Code was translated from Verilog.
702 ****************************************************************************/
703static u8 calc_crc8(u32 data, u8 crc)
704{
705 u8 D[32];
706 u8 NewCRC[8];
707 u8 C[8];
708 u8 crc_res;
709 u8 i;
710
711 /* split the data into 31 bits */
712 for (i = 0; i < 32; i++) {
713 D[i] = data & 1;
714 data = data >> 1;
715 }
716
717 /* split the crc into 8 bits */
718 for (i = 0; i < 8; i++) {
719 C[i] = crc & 1;
720 crc = crc >> 1;
721 }
722
723 NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
724 D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
725 C[6] ^ C[7];
726 NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
727 D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
728 D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
729 NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
730 D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
731 C[0] ^ C[1] ^ C[4] ^ C[5];
732 NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
733 D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
734 C[1] ^ C[2] ^ C[5] ^ C[6];
735 NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
736 D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
737 C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
738 NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
739 D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
740 C[3] ^ C[4] ^ C[7];
741 NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
742 D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
743 C[5];
744 NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
745 D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
746 C[6];
747
748 crc_res = 0;
749 for (i = 0; i < 8; i++)
750 crc_res |= (NewCRC[i] << i);
751
752 return crc_res;
753}
754 347
755/* registers addresses are not in order 348/* registers addresses are not in order
756 so these arrays help simplify the code */ 349 so these arrays help simplify the code */
757static const int cm_start[E1H_FUNC_MAX][9] = { 350static const int cm_blocks[9] = {
758 {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START, 351 MISC_BLOCK, TCM_BLOCK, UCM_BLOCK, CCM_BLOCK, XCM_BLOCK,
759 XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START, 352 TSEM_BLOCK, USEM_BLOCK, CSEM_BLOCK, XSEM_BLOCK
760 XSEM_FUNC0_START},
761 {MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START,
762 XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START,
763 XSEM_FUNC1_START},
764 {MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START,
765 XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START,
766 XSEM_FUNC2_START},
767 {MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START,
768 XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START,
769 XSEM_FUNC3_START},
770 {MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START,
771 XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START,
772 XSEM_FUNC4_START},
773 {MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START,
774 XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START,
775 XSEM_FUNC5_START},
776 {MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START,
777 XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START,
778 XSEM_FUNC6_START},
779 {MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START,
780 XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START,
781 XSEM_FUNC7_START}
782};
783
784static const int cm_end[E1H_FUNC_MAX][9] = {
785 {MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END,
786 XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END,
787 XSEM_FUNC0_END},
788 {MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END,
789 XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END,
790 XSEM_FUNC1_END},
791 {MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END,
792 XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END,
793 XSEM_FUNC2_END},
794 {MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END,
795 XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END,
796 XSEM_FUNC3_END},
797 {MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END,
798 XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END,
799 XSEM_FUNC4_END},
800 {MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END,
801 XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END,
802 XSEM_FUNC5_END},
803 {MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END,
804 XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END,
805 XSEM_FUNC6_END},
806 {MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END,
807 XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END,
808 XSEM_FUNC7_END},
809};
810
811static const int hc_limits[E1H_FUNC_MAX][2] = {
812 {HC_FUNC0_START, HC_FUNC0_END},
813 {HC_FUNC1_START, HC_FUNC1_END},
814 {HC_FUNC2_START, HC_FUNC2_END},
815 {HC_FUNC3_START, HC_FUNC3_END},
816 {HC_FUNC4_START, HC_FUNC4_END},
817 {HC_FUNC5_START, HC_FUNC5_END},
818 {HC_FUNC6_START, HC_FUNC6_END},
819 {HC_FUNC7_START, HC_FUNC7_END}
820}; 353};
821 354
822#endif /* BNX2X_INIT_H */ 355#endif /* BNX2X_INIT_H */
diff --git a/drivers/net/bnx2x_init_ops.h b/drivers/net/bnx2x_init_ops.h
new file mode 100644
index 000000000000..32552b9366cb
--- /dev/null
+++ b/drivers/net/bnx2x_init_ops.h
@@ -0,0 +1,442 @@
1/* bnx2x_init_ops.h: Broadcom Everest network driver.
2 * Static functions needed during the initialization.
3 * This file is "included" in bnx2x_main.c.
4 *
5 * Copyright (c) 2007-2009 Broadcom Corporation
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation.
10 *
11 * Maintained by: Eilon Greenstein <eilong@broadcom.com>
12 * Written by: Vladislav Zolotarov <vladz@broadcom.com>
13 */
14#ifndef BNX2X_INIT_OPS_H
15#define BNX2X_INIT_OPS_H
16
17static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
18static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
19
20static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
21 u32 len)
22{
23 int i;
24
25 for (i = 0; i < len; i++) {
26 REG_WR(bp, addr + i*4, data[i]);
27 if (!(i % 10000)) {
28 touch_softlockup_watchdog();
29 cpu_relax();
30 }
31 }
32}
33
34static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
35 u16 len)
36{
37 int i;
38
39 for (i = 0; i < len; i++) {
40 REG_WR_IND(bp, addr + i*4, data[i]);
41 if (!(i % 10000)) {
42 touch_softlockup_watchdog();
43 cpu_relax();
44 }
45 }
46}
47
48static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
49{
50 int offset = 0;
51
52 if (bp->dmae_ready) {
53 while (len > DMAE_LEN32_WR_MAX) {
54 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
55 addr + offset, DMAE_LEN32_WR_MAX);
56 offset += DMAE_LEN32_WR_MAX * 4;
57 len -= DMAE_LEN32_WR_MAX;
58 }
59 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
60 addr + offset, len);
61 } else
62 bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
63}
64
65static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
66{
67 u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
68 u32 buf_len32 = buf_len / 4;
69 int i;
70
71 memset(bp->gunzip_buf, fill, buf_len);
72
73 for (i = 0; i < len; i += buf_len32) {
74 u32 cur_len = min(buf_len32, len - i);
75
76 bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
77 }
78}
79
80static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
81 u32 len64)
82{
83 u32 buf_len32 = FW_BUF_SIZE / 4;
84 u32 len = len64 * 2;
85 u64 data64 = 0;
86 int i;
87
88 /* 64 bit value is in a blob: first low DWORD, then high DWORD */
89 data64 = HILO_U64((*(data + 1)), (*data));
90 len64 = min((u32)(FW_BUF_SIZE/8), len64);
91 for (i = 0; i < len64; i++) {
92 u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
93
94 *pdata = data64;
95 }
96
97 for (i = 0; i < len; i += buf_len32) {
98 u32 cur_len = min(buf_len32, len - i);
99
100 bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
101 }
102}
103
104/*********************************************************
105 There are different blobs for each PRAM section.
106 In addition, each blob write operation is divided into a few operations
107 in order to decrease the amount of phys. contiguous buffer needed.
108 Thus, when we select a blob the address may be with some offset
109 from the beginning of PRAM section.
110 The same holds for the INT_TABLE sections.
111**********************************************************/
112#define IF_IS_INT_TABLE_ADDR(base, addr) \
113 if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
114
115#define IF_IS_PRAM_ADDR(base, addr) \
116 if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
117
118static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data)
119{
120 IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
121 data = bp->tsem_int_table_data;
122 else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
123 data = bp->csem_int_table_data;
124 else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
125 data = bp->usem_int_table_data;
126 else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
127 data = bp->xsem_int_table_data;
128 else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
129 data = bp->tsem_pram_data;
130 else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
131 data = bp->csem_pram_data;
132 else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
133 data = bp->usem_pram_data;
134 else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
135 data = bp->xsem_pram_data;
136
137 return data;
138}
139
140static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
141{
142 int offset = 0;
143
144 if (bp->dmae_ready) {
145 while (len > DMAE_LEN32_WR_MAX) {
146 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
147 addr + offset, DMAE_LEN32_WR_MAX);
148 offset += DMAE_LEN32_WR_MAX * 4;
149 len -= DMAE_LEN32_WR_MAX;
150 }
151 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
152 addr + offset, len);
153 } else
154 bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
155}
156
157static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
158 u32 len)
159{
160 /* This is needed for NO_ZIP mode, currently supported
161 in little endian mode only */
162 data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data);
163
164 if ((len * 4) > FW_BUF_SIZE) {
165 BNX2X_ERR("LARGE DMAE OPERATION ! "
166 "addr 0x%x len 0x%x\n", addr, len*4);
167 return;
168 }
169 memcpy(bp->gunzip_buf, data, len * 4);
170
171 bnx2x_write_big_buf_wb(bp, addr, len);
172}
173
174static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr,
175 u32 len, u32 blob_off)
176{
177 int rc, i;
178 const u8 *data = NULL;
179
180 data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off;
181
182 if (data == NULL) {
183 panic("Blob not found for addr 0x%x\n", addr);
184 return;
185 }
186
187 rc = bnx2x_gunzip(bp, data, len);
188 if (rc) {
189 BNX2X_ERR("gunzip failed ! addr 0x%x rc %d\n", addr, rc);
190 BNX2X_ERR("blob_offset=0x%x\n", blob_off);
191 return;
192 }
193
194 /* gunzip_outlen is in dwords */
195 len = bp->gunzip_outlen;
196 for (i = 0; i < len; i++)
197 ((u32 *)bp->gunzip_buf)[i] =
198 cpu_to_le32(((u32 *)bp->gunzip_buf)[i]);
199
200 bnx2x_write_big_buf_wb(bp, addr, len);
201}
202
203static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
204{
205 int hw_wr, i;
206 u16 op_start =
207 bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)];
208 u16 op_end =
209 bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)];
210 union init_op *op;
211 u32 op_type, addr, len;
212 const u32 *data, *data_base;
213
214 /* If empty block */
215 if (op_start == op_end)
216 return;
217
218 if (CHIP_REV_IS_FPGA(bp))
219 hw_wr = OP_WR_FPGA;
220 else if (CHIP_REV_IS_EMUL(bp))
221 hw_wr = OP_WR_EMUL;
222 else
223 hw_wr = OP_WR_ASIC;
224
225 data_base = bp->init_data;
226
227 for (i = op_start; i < op_end; i++) {
228
229 op = (union init_op *)&(bp->init_ops[i]);
230
231 op_type = op->str_wr.op;
232 addr = op->str_wr.offset;
233 len = op->str_wr.data_len;
234 data = data_base + op->str_wr.data_off;
235
236 /* HW/EMUL specific */
237 if (unlikely((op_type > OP_WB) && (op_type == hw_wr)))
238 op_type = OP_WR;
239
240 switch (op_type) {
241 case OP_RD:
242 REG_RD(bp, addr);
243 break;
244 case OP_WR:
245 REG_WR(bp, addr, op->write.val);
246 break;
247 case OP_SW:
248 bnx2x_init_str_wr(bp, addr, data, len);
249 break;
250 case OP_WB:
251 bnx2x_init_wr_wb(bp, addr, data, len);
252 break;
253 case OP_SI:
254 bnx2x_init_ind_wr(bp, addr, data, len);
255 break;
256 case OP_ZR:
257 bnx2x_init_fill(bp, addr, 0, op->zero.len);
258 break;
259 case OP_ZP:
260 bnx2x_init_wr_zp(bp, addr, len,
261 op->str_wr.data_off);
262 break;
263 case OP_WR_64:
264 bnx2x_init_wr_64(bp, addr, data, len);
265 break;
266 default:
267 /* happens whenever an op is of a diff HW */
268#if 0
269 DP(NETIF_MSG_HW, "skipping init operation "
270 "index %d[%d:%d]: type %d addr 0x%x "
271 "len %d(0x%x)\n",
272 i, op_start, op_end, op_type, addr, len, len);
273#endif
274 break;
275 }
276 }
277}
278
279/* PXP */
280static void bnx2x_init_pxp(struct bnx2x *bp)
281{
282 u16 devctl;
283 int r_order, w_order;
284 u32 val, i;
285
286 pci_read_config_word(bp->pdev,
287 bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
288 DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
289 w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
290 if (bp->mrrs == -1)
291 r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
292 else {
293 DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
294 r_order = bp->mrrs;
295 }
296
297 if (r_order > MAX_RD_ORD) {
298 DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
299 r_order, MAX_RD_ORD);
300 r_order = MAX_RD_ORD;
301 }
302 if (w_order > MAX_WR_ORD) {
303 DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n",
304 w_order, MAX_WR_ORD);
305 w_order = MAX_WR_ORD;
306 }
307 if (CHIP_REV_IS_FPGA(bp)) {
308 DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
309 w_order = 0;
310 }
311 DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order);
312
313 for (i = 0; i < NUM_RD_Q-1; i++) {
314 REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
315 REG_WR(bp, read_arb_addr[i].add,
316 read_arb_data[i][r_order].add);
317 REG_WR(bp, read_arb_addr[i].ubound,
318 read_arb_data[i][r_order].ubound);
319 }
320
321 for (i = 0; i < NUM_WR_Q-1; i++) {
322 if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
323 (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
324
325 REG_WR(bp, write_arb_addr[i].l,
326 write_arb_data[i][w_order].l);
327
328 REG_WR(bp, write_arb_addr[i].add,
329 write_arb_data[i][w_order].add);
330
331 REG_WR(bp, write_arb_addr[i].ubound,
332 write_arb_data[i][w_order].ubound);
333 } else {
334
335 val = REG_RD(bp, write_arb_addr[i].l);
336 REG_WR(bp, write_arb_addr[i].l,
337 val | (write_arb_data[i][w_order].l << 10));
338
339 val = REG_RD(bp, write_arb_addr[i].add);
340 REG_WR(bp, write_arb_addr[i].add,
341 val | (write_arb_data[i][w_order].add << 10));
342
343 val = REG_RD(bp, write_arb_addr[i].ubound);
344 REG_WR(bp, write_arb_addr[i].ubound,
345 val | (write_arb_data[i][w_order].ubound << 7));
346 }
347 }
348
349 val = write_arb_data[NUM_WR_Q-1][w_order].add;
350 val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
351 val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
352 REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
353
354 val = read_arb_data[NUM_RD_Q-1][r_order].add;
355 val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
356 val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
357 REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
358
359 REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
360 REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
361 REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
362 REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
363
364 if (r_order == MAX_RD_ORD)
365 REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
366
367 REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
368
369 if (CHIP_IS_E1H(bp)) {
370 val = ((w_order == 0) ? 2 : 3);
371 REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
372 REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
373 REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
374 REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
375 REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
376 REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
377 REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
378 REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
379 REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
380 REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
381 REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
382 }
383}
384
385/*****************************************************************************
386 * Description:
387 * Calculates crc 8 on a word value: polynomial 0-1-2-8
388 * Code was translated from Verilog.
389 ****************************************************************************/
390static u8 calc_crc8(u32 data, u8 crc)
391{
392 u8 D[32];
393 u8 NewCRC[8];
394 u8 C[8];
395 u8 crc_res;
396 u8 i;
397
398 /* split the data into 31 bits */
399 for (i = 0; i < 32; i++) {
400 D[i] = data & 1;
401 data = data >> 1;
402 }
403
404 /* split the crc into 8 bits */
405 for (i = 0; i < 8; i++) {
406 C[i] = crc & 1;
407 crc = crc >> 1;
408 }
409
410 NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
411 D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
412 C[6] ^ C[7];
413 NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
414 D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
415 D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
416 NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
417 D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
418 C[0] ^ C[1] ^ C[4] ^ C[5];
419 NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
420 D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
421 C[1] ^ C[2] ^ C[5] ^ C[6];
422 NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
423 D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
424 C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
425 NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
426 D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
427 C[3] ^ C[4] ^ C[7];
428 NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
429 D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
430 C[5];
431 NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
432 D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
433 C[6];
434
435 crc_res = 0;
436 for (i = 0; i < 8; i++)
437 crc_res |= (NewCRC[i] << i);
438
439 return crc_res;
440}
441
442#endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index ad5ef25add3e..cdc80e0820cd 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -53,12 +53,19 @@
53 53
54#include "bnx2x.h" 54#include "bnx2x.h"
55#include "bnx2x_init.h" 55#include "bnx2x_init.h"
56#include "bnx2x_init_ops.h"
56#include "bnx2x_dump.h" 57#include "bnx2x_dump.h"
57 58
58#define DRV_MODULE_VERSION "1.48.105" 59#define DRV_MODULE_VERSION "1.48.105"
59#define DRV_MODULE_RELDATE "2009/03/02" 60#define DRV_MODULE_RELDATE "2009/03/02"
60#define BNX2X_BC_VER 0x040200 61#define BNX2X_BC_VER 0x040200
61 62
63#include <linux/firmware.h>
64#include "bnx2x_fw_file_hdr.h"
65/* FW files */
66#define FW_FILE_PREFIX_E1 "bnx2x-e1-"
67#define FW_FILE_PREFIX_E1H "bnx2x-e1h-"
68
62/* Time in jiffies before concluding the transmitter is hung */ 69/* Time in jiffies before concluding the transmitter is hung */
63#define TX_TIMEOUT (5*HZ) 70#define TX_TIMEOUT (5*HZ)
64 71
@@ -5232,13 +5239,15 @@ static void bnx2x_gunzip_end(struct bnx2x *bp)
5232 } 5239 }
5233} 5240}
5234 5241
5235static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len) 5242static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len)
5236{ 5243{
5237 int n, rc; 5244 int n, rc;
5238 5245
5239 /* check gzip header */ 5246 /* check gzip header */
5240 if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) 5247 if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) {
5248 BNX2X_ERR("Bad gzip header\n");
5241 return -EINVAL; 5249 return -EINVAL;
5250 }
5242 5251
5243 n = 10; 5252 n = 10;
5244 5253
@@ -5247,7 +5256,7 @@ static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
5247 if (zbuf[3] & FNAME) 5256 if (zbuf[3] & FNAME)
5248 while ((zbuf[n++] != 0) && (n < len)); 5257 while ((zbuf[n++] != 0) && (n < len));
5249 5258
5250 bp->strm->next_in = zbuf + n; 5259 bp->strm->next_in = (typeof(bp->strm->next_in))zbuf + n;
5251 bp->strm->avail_in = len - n; 5260 bp->strm->avail_in = len - n;
5252 bp->strm->next_out = bp->gunzip_buf; 5261 bp->strm->next_out = bp->gunzip_buf;
5253 bp->strm->avail_out = FW_BUF_SIZE; 5262 bp->strm->avail_out = FW_BUF_SIZE;
@@ -5369,8 +5378,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
5369 msleep(50); 5378 msleep(50);
5370 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); 5379 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
5371 msleep(50); 5380 msleep(50);
5372 bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); 5381 bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
5373 bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); 5382 bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
5374 5383
5375 DP(NETIF_MSG_HW, "part2\n"); 5384 DP(NETIF_MSG_HW, "part2\n");
5376 5385
@@ -5434,8 +5443,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
5434 msleep(50); 5443 msleep(50);
5435 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); 5444 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
5436 msleep(50); 5445 msleep(50);
5437 bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); 5446 bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
5438 bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); 5447 bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
5439#ifndef BCM_ISCSI 5448#ifndef BCM_ISCSI
5440 /* set NIC mode */ 5449 /* set NIC mode */
5441 REG_WR(bp, PRS_REG_NIC_MODE, 1); 5450 REG_WR(bp, PRS_REG_NIC_MODE, 1);
@@ -5510,7 +5519,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
5510 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); 5519 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
5511 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc); 5520 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
5512 5521
5513 bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END); 5522 bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE);
5514 if (CHIP_IS_E1H(bp)) 5523 if (CHIP_IS_E1H(bp))
5515 REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp)); 5524 REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp));
5516 5525
@@ -5518,14 +5527,14 @@ static int bnx2x_init_common(struct bnx2x *bp)
5518 msleep(30); 5527 msleep(30);
5519 REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0); 5528 REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
5520 5529
5521 bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END); 5530 bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE);
5522 if (CHIP_IS_E1(bp)) { 5531 if (CHIP_IS_E1(bp)) {
5523 /* enable HW interrupt from PXP on USDM overflow 5532 /* enable HW interrupt from PXP on USDM overflow
5524 bit 16 on INT_MASK_0 */ 5533 bit 16 on INT_MASK_0 */
5525 REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); 5534 REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
5526 } 5535 }
5527 5536
5528 bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END); 5537 bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE);
5529 bnx2x_init_pxp(bp); 5538 bnx2x_init_pxp(bp);
5530 5539
5531#ifdef __BIG_ENDIAN 5540#ifdef __BIG_ENDIAN
@@ -5571,60 +5580,60 @@ static int bnx2x_init_common(struct bnx2x *bp)
5571 REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); 5580 REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
5572 REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); 5581 REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
5573 5582
5574 bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END); 5583 bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE);
5575 5584
5576 /* clean the DMAE memory */ 5585 /* clean the DMAE memory */
5577 bp->dmae_ready = 1; 5586 bp->dmae_ready = 1;
5578 bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8); 5587 bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8);
5579 5588
5580 bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END); 5589 bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE);
5581 bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END); 5590 bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE);
5582 bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END); 5591 bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE);
5583 bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END); 5592 bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE);
5584 5593
5585 bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3); 5594 bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3);
5586 bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3); 5595 bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3);
5587 bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3); 5596 bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3);
5588 bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3); 5597 bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
5589 5598
5590 bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END); 5599 bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE);
5591 /* soft reset pulse */ 5600 /* soft reset pulse */
5592 REG_WR(bp, QM_REG_SOFT_RESET, 1); 5601 REG_WR(bp, QM_REG_SOFT_RESET, 1);
5593 REG_WR(bp, QM_REG_SOFT_RESET, 0); 5602 REG_WR(bp, QM_REG_SOFT_RESET, 0);
5594 5603
5595#ifdef BCM_ISCSI 5604#ifdef BCM_ISCSI
5596 bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END); 5605 bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE);
5597#endif 5606#endif
5598 5607
5599 bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END); 5608 bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE);
5600 REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT); 5609 REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT);
5601 if (!CHIP_REV_IS_SLOW(bp)) { 5610 if (!CHIP_REV_IS_SLOW(bp)) {
5602 /* enable hw interrupt from doorbell Q */ 5611 /* enable hw interrupt from doorbell Q */
5603 REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); 5612 REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
5604 } 5613 }
5605 5614
5606 bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); 5615 bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
5607 bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); 5616 bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
5608 REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); 5617 REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
5609 /* set NIC mode */ 5618 /* set NIC mode */
5610 REG_WR(bp, PRS_REG_NIC_MODE, 1); 5619 REG_WR(bp, PRS_REG_NIC_MODE, 1);
5611 if (CHIP_IS_E1H(bp)) 5620 if (CHIP_IS_E1H(bp))
5612 REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp)); 5621 REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
5613 5622
5614 bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END); 5623 bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE);
5615 bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END); 5624 bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE);
5616 bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END); 5625 bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE);
5617 bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END); 5626 bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE);
5618 5627
5619 bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp)); 5628 bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
5620 bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp)); 5629 bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
5621 bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp)); 5630 bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
5622 bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp)); 5631 bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
5623 5632
5624 bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END); 5633 bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE);
5625 bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END); 5634 bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE);
5626 bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END); 5635 bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE);
5627 bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END); 5636 bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE);
5628 5637
5629 /* sync semi rtc */ 5638 /* sync semi rtc */
5630 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 5639 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
@@ -5632,16 +5641,16 @@ static int bnx2x_init_common(struct bnx2x *bp)
5632 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 5641 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
5633 0x80000000); 5642 0x80000000);
5634 5643
5635 bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END); 5644 bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE);
5636 bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END); 5645 bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE);
5637 bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END); 5646 bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE);
5638 5647
5639 REG_WR(bp, SRC_REG_SOFT_RST, 1); 5648 REG_WR(bp, SRC_REG_SOFT_RST, 1);
5640 for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) { 5649 for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
5641 REG_WR(bp, i, 0xc0cac01a); 5650 REG_WR(bp, i, 0xc0cac01a);
5642 /* TODO: replace with something meaningful */ 5651 /* TODO: replace with something meaningful */
5643 } 5652 }
5644 bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END); 5653 bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE);
5645 REG_WR(bp, SRC_REG_SOFT_RST, 0); 5654 REG_WR(bp, SRC_REG_SOFT_RST, 0);
5646 5655
5647 if (sizeof(union cdu_context) != 1024) 5656 if (sizeof(union cdu_context) != 1024)
@@ -5649,7 +5658,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
5649 printk(KERN_ALERT PFX "please adjust the size of" 5658 printk(KERN_ALERT PFX "please adjust the size of"
5650 " cdu_context(%ld)\n", (long)sizeof(union cdu_context)); 5659 " cdu_context(%ld)\n", (long)sizeof(union cdu_context));
5651 5660
5652 bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END); 5661 bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE);
5653 val = (4 << 24) + (0 << 12) + 1024; 5662 val = (4 << 24) + (0 << 12) + 1024;
5654 REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val); 5663 REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
5655 if (CHIP_IS_E1(bp)) { 5664 if (CHIP_IS_E1(bp)) {
@@ -5658,7 +5667,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
5658 REG_WR(bp, CDU_REG_CDU_DEBUG, 0); 5667 REG_WR(bp, CDU_REG_CDU_DEBUG, 0);
5659 } 5668 }
5660 5669
5661 bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END); 5670 bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE);
5662 REG_WR(bp, CFC_REG_INIT_REG, 0x7FF); 5671 REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
5663 /* enable context validation interrupt from CFC */ 5672 /* enable context validation interrupt from CFC */
5664 REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); 5673 REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
@@ -5666,20 +5675,25 @@ static int bnx2x_init_common(struct bnx2x *bp)
5666 /* set the thresholds to prevent CFC/CDU race */ 5675 /* set the thresholds to prevent CFC/CDU race */
5667 REG_WR(bp, CFC_REG_DEBUG0, 0x20020000); 5676 REG_WR(bp, CFC_REG_DEBUG0, 0x20020000);
5668 5677
5669 bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END); 5678 bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE);
5670 bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END); 5679 bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE);
5671 5680
5672 /* PXPCS COMMON comes here */ 5681 /* PXPCS COMMON comes here */
5682 bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE);
5673 /* Reset PCIE errors for debug */ 5683 /* Reset PCIE errors for debug */
5674 REG_WR(bp, 0x2814, 0xffffffff); 5684 REG_WR(bp, 0x2814, 0xffffffff);
5675 REG_WR(bp, 0x3820, 0xffffffff); 5685 REG_WR(bp, 0x3820, 0xffffffff);
5676 5686
5677 /* EMAC0 COMMON comes here */ 5687 /* EMAC0 COMMON comes here */
5688 bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE);
5678 /* EMAC1 COMMON comes here */ 5689 /* EMAC1 COMMON comes here */
5690 bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE);
5679 /* DBU COMMON comes here */ 5691 /* DBU COMMON comes here */
5692 bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE);
5680 /* DBG COMMON comes here */ 5693 /* DBG COMMON comes here */
5694 bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE);
5681 5695
5682 bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END); 5696 bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE);
5683 if (CHIP_IS_E1H(bp)) { 5697 if (CHIP_IS_E1H(bp)) {
5684 REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp)); 5698 REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp));
5685 REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp)); 5699 REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp));
@@ -5763,6 +5777,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
5763static int bnx2x_init_port(struct bnx2x *bp) 5777static int bnx2x_init_port(struct bnx2x *bp)
5764{ 5778{
5765 int port = BP_PORT(bp); 5779 int port = BP_PORT(bp);
5780 int init_stage = port ? PORT1_STAGE : PORT0_STAGE;
5766 u32 low, high; 5781 u32 low, high;
5767 u32 val; 5782 u32 val;
5768 5783
@@ -5771,7 +5786,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
5771 REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0); 5786 REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
5772 5787
5773 /* Port PXP comes here */ 5788 /* Port PXP comes here */
5789 bnx2x_init_block(bp, PXP_BLOCK, init_stage);
5774 /* Port PXP2 comes here */ 5790 /* Port PXP2 comes here */
5791 bnx2x_init_block(bp, PXP2_BLOCK, init_stage);
5775#ifdef BCM_ISCSI 5792#ifdef BCM_ISCSI
5776 /* Port0 1 5793 /* Port0 1
5777 * Port1 385 */ 5794 * Port1 385 */
@@ -5798,21 +5815,19 @@ static int bnx2x_init_port(struct bnx2x *bp)
5798 REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i)); 5815 REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
5799#endif 5816#endif
5800 /* Port CMs come here */ 5817 /* Port CMs come here */
5801 bnx2x_init_block(bp, (port ? XCM_PORT1_START : XCM_PORT0_START), 5818 bnx2x_init_block(bp, XCM_BLOCK, init_stage);
5802 (port ? XCM_PORT1_END : XCM_PORT0_END));
5803 5819
5804 /* Port QM comes here */ 5820 /* Port QM comes here */
5805#ifdef BCM_ISCSI 5821#ifdef BCM_ISCSI
5806 REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20); 5822 REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
5807 REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31); 5823 REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
5808 5824
5809 bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START, 5825 bnx2x_init_block(bp, TIMERS_BLOCK, init_stage);
5810 func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
5811#endif 5826#endif
5812 /* Port DQ comes here */ 5827 /* Port DQ comes here */
5828 bnx2x_init_block(bp, DQ_BLOCK, init_stage);
5813 5829
5814 bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START), 5830 bnx2x_init_block(bp, BRB1_BLOCK, init_stage);
5815 (port ? BRB1_PORT1_END : BRB1_PORT0_END));
5816 if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) { 5831 if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
5817 /* no pause for emulation and FPGA */ 5832 /* no pause for emulation and FPGA */
5818 low = 0; 5833 low = 0;
@@ -5837,25 +5852,27 @@ static int bnx2x_init_port(struct bnx2x *bp)
5837 5852
5838 5853
5839 /* Port PRS comes here */ 5854 /* Port PRS comes here */
5855 bnx2x_init_block(bp, PRS_BLOCK, init_stage);
5840 /* Port TSDM comes here */ 5856 /* Port TSDM comes here */
5857 bnx2x_init_block(bp, TSDM_BLOCK, init_stage);
5841 /* Port CSDM comes here */ 5858 /* Port CSDM comes here */
5859 bnx2x_init_block(bp, CSDM_BLOCK, init_stage);
5842 /* Port USDM comes here */ 5860 /* Port USDM comes here */
5861 bnx2x_init_block(bp, USDM_BLOCK, init_stage);
5843 /* Port XSDM comes here */ 5862 /* Port XSDM comes here */
5863 bnx2x_init_block(bp, XSDM_BLOCK, init_stage);
5844 5864
5845 bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START, 5865 bnx2x_init_block(bp, TSEM_BLOCK, init_stage);
5846 port ? TSEM_PORT1_END : TSEM_PORT0_END); 5866 bnx2x_init_block(bp, USEM_BLOCK, init_stage);
5847 bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START, 5867 bnx2x_init_block(bp, CSEM_BLOCK, init_stage);
5848 port ? USEM_PORT1_END : USEM_PORT0_END); 5868 bnx2x_init_block(bp, XSEM_BLOCK, init_stage);
5849 bnx2x_init_block(bp, port ? CSEM_PORT1_START : CSEM_PORT0_START,
5850 port ? CSEM_PORT1_END : CSEM_PORT0_END);
5851 bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
5852 port ? XSEM_PORT1_END : XSEM_PORT0_END);
5853 5869
5854 /* Port UPB comes here */ 5870 /* Port UPB comes here */
5871 bnx2x_init_block(bp, UPB_BLOCK, init_stage);
5855 /* Port XPB comes here */ 5872 /* Port XPB comes here */
5873 bnx2x_init_block(bp, XPB_BLOCK, init_stage);
5856 5874
5857 bnx2x_init_block(bp, port ? PBF_PORT1_START : PBF_PORT0_START, 5875 bnx2x_init_block(bp, PBF_BLOCK, init_stage);
5858 port ? PBF_PORT1_END : PBF_PORT0_END);
5859 5876
5860 /* configure PBF to work without PAUSE mtu 9000 */ 5877 /* configure PBF to work without PAUSE mtu 9000 */
5861 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); 5878 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
@@ -5885,18 +5902,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
5885 /* Port SRCH comes here */ 5902 /* Port SRCH comes here */
5886#endif 5903#endif
5887 /* Port CDU comes here */ 5904 /* Port CDU comes here */
5905 bnx2x_init_block(bp, CDU_BLOCK, init_stage);
5888 /* Port CFC comes here */ 5906 /* Port CFC comes here */
5907 bnx2x_init_block(bp, CFC_BLOCK, init_stage);
5889 5908
5890 if (CHIP_IS_E1(bp)) { 5909 if (CHIP_IS_E1(bp)) {
5891 REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); 5910 REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
5892 REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); 5911 REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
5893 } 5912 }
5894 bnx2x_init_block(bp, port ? HC_PORT1_START : HC_PORT0_START, 5913 bnx2x_init_block(bp, HC_BLOCK, init_stage);
5895 port ? HC_PORT1_END : HC_PORT0_END);
5896 5914
5897 bnx2x_init_block(bp, port ? MISC_AEU_PORT1_START : 5915 bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage);
5898 MISC_AEU_PORT0_START,
5899 port ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
5900 /* init aeu_mask_attn_func_0/1: 5916 /* init aeu_mask_attn_func_0/1:
5901 * - SF mode: bits 3-7 are masked. only bits 0-2 are in use 5917 * - SF mode: bits 3-7 are masked. only bits 0-2 are in use
5902 * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF 5918 * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
@@ -5905,13 +5921,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
5905 (IS_E1HMF(bp) ? 0xF7 : 0x7)); 5921 (IS_E1HMF(bp) ? 0xF7 : 0x7));
5906 5922
5907 /* Port PXPCS comes here */ 5923 /* Port PXPCS comes here */
5924 bnx2x_init_block(bp, PXPCS_BLOCK, init_stage);
5908 /* Port EMAC0 comes here */ 5925 /* Port EMAC0 comes here */
5926 bnx2x_init_block(bp, EMAC0_BLOCK, init_stage);
5909 /* Port EMAC1 comes here */ 5927 /* Port EMAC1 comes here */
5928 bnx2x_init_block(bp, EMAC1_BLOCK, init_stage);
5910 /* Port DBU comes here */ 5929 /* Port DBU comes here */
5930 bnx2x_init_block(bp, DBU_BLOCK, init_stage);
5911 /* Port DBG comes here */ 5931 /* Port DBG comes here */
5932 bnx2x_init_block(bp, DBG_BLOCK, init_stage);
5912 5933
5913 bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START, 5934 bnx2x_init_block(bp, NIG_BLOCK, init_stage);
5914 port ? NIG_PORT1_END : NIG_PORT0_END);
5915 5935
5916 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); 5936 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
5917 5937
@@ -5931,7 +5951,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
5931 } 5951 }
5932 5952
5933 /* Port MCP comes here */ 5953 /* Port MCP comes here */
5954 bnx2x_init_block(bp, MCP_BLOCK, init_stage);
5934 /* Port DMAE comes here */ 5955 /* Port DMAE comes here */
5956 bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
5935 5957
5936 switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { 5958 switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
5937 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 5959 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
@@ -6036,7 +6058,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
6036 if (CHIP_IS_E1H(bp)) { 6058 if (CHIP_IS_E1H(bp)) {
6037 for (i = 0; i < 9; i++) 6059 for (i = 0; i < 9; i++)
6038 bnx2x_init_block(bp, 6060 bnx2x_init_block(bp,
6039 cm_start[func][i], cm_end[func][i]); 6061 cm_blocks[i], FUNC0_STAGE + func);
6040 6062
6041 REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); 6063 REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
6042 REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); 6064 REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
@@ -6049,7 +6071,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
6049 REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); 6071 REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
6050 REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); 6072 REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
6051 } 6073 }
6052 bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]); 6074 bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func);
6053 6075
6054 /* Reset PCIE errors for debug */ 6076 /* Reset PCIE errors for debug */
6055 REG_WR(bp, 0x2114, 0xffffffff); 6077 REG_WR(bp, 0x2114, 0xffffffff);
@@ -11082,6 +11104,190 @@ static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
11082 val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT; 11104 val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
11083 return val; 11105 return val;
11084} 11106}
11107static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
11108{
11109 struct bnx2x_fw_file_hdr *fw_hdr;
11110 struct bnx2x_fw_file_section *sections;
11111 u16 *ops_offsets;
11112 u32 offset, len, num_ops;
11113 int i;
11114 const struct firmware *firmware = bp->firmware;
11115 const u8 * fw_ver;
11116
11117 if (firmware->size < sizeof(struct bnx2x_fw_file_hdr))
11118 return -EINVAL;
11119
11120 fw_hdr = (struct bnx2x_fw_file_hdr *)firmware->data;
11121 sections = (struct bnx2x_fw_file_section *)fw_hdr;
11122
11123 /* Make sure none of the offsets and sizes make us read beyond
11124 * the end of the firmware data */
11125 for (i = 0; i < sizeof(*fw_hdr) / sizeof(*sections); i++) {
11126 offset = be32_to_cpu(sections[i].offset);
11127 len = be32_to_cpu(sections[i].len);
11128 if (offset + len > firmware->size) {
11129 printk(KERN_ERR PFX "Section %d length is out of bounds\n", i);
11130 return -EINVAL;
11131 }
11132 }
11133
11134 /* Likewise for the init_ops offsets */
11135 offset = be32_to_cpu(fw_hdr->init_ops_offsets.offset);
11136 ops_offsets = (u16 *)(firmware->data + offset);
11137 num_ops = be32_to_cpu(fw_hdr->init_ops.len) / sizeof(struct raw_op);
11138
11139 for (i = 0; i < be32_to_cpu(fw_hdr->init_ops_offsets.len) / 2; i++) {
11140 if (be16_to_cpu(ops_offsets[i]) > num_ops) {
11141 printk(KERN_ERR PFX "Section offset %d is out of bounds\n", i);
11142 return -EINVAL;
11143 }
11144 }
11145
11146 /* Check FW version */
11147 offset = be32_to_cpu(fw_hdr->fw_version.offset);
11148 fw_ver = firmware->data + offset;
11149 if ((fw_ver[0] != BCM_5710_FW_MAJOR_VERSION) ||
11150 (fw_ver[1] != BCM_5710_FW_MINOR_VERSION) ||
11151 (fw_ver[2] != BCM_5710_FW_REVISION_VERSION) ||
11152 (fw_ver[3] != BCM_5710_FW_ENGINEERING_VERSION)) {
11153 printk(KERN_ERR PFX "Bad FW version:%d.%d.%d.%d."
11154 " Should be %d.%d.%d.%d\n",
11155 fw_ver[0], fw_ver[1], fw_ver[2],
11156 fw_ver[3], BCM_5710_FW_MAJOR_VERSION,
11157 BCM_5710_FW_MINOR_VERSION,
11158 BCM_5710_FW_REVISION_VERSION,
11159 BCM_5710_FW_ENGINEERING_VERSION);
11160 return -EINVAL;
11161 }
11162
11163 return 0;
11164}
11165
11166static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
11167{
11168 u32 i;
11169 const __be32 *source = (const __be32*)_source;
11170 u32 *target = (u32*)_target;
11171
11172 for (i = 0; i < n/4; i++)
11173 target[i] = be32_to_cpu(source[i]);
11174}
11175
11176/*
11177 Ops array is stored in the following format:
11178 {op(8bit), offset(24bit, big endian), data(32bit, big endian)}
11179 */
11180static void inline bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
11181{
11182 u32 i, j, tmp;
11183 const __be32 *source = (const __be32*)_source;
11184 struct raw_op *target = (struct raw_op*)_target;
11185
11186 for (i = 0, j = 0; i < n/8; i++, j+=2) {
11187 tmp = be32_to_cpu(source[j]);
11188 target[i].op = (tmp >> 24) & 0xff;
11189 target[i].offset = tmp & 0xffffff;
11190 target[i].raw_data = be32_to_cpu(source[j+1]);
11191 }
11192}
11193static void inline be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
11194{
11195 u32 i;
11196 u16 *target = (u16*)_target;
11197 const __be16 *source = (const __be16*)_source;
11198
11199 for (i = 0; i < n/2; i++)
11200 target[i] = be16_to_cpu(source[i]);
11201}
11202
11203#define BNX2X_ALLOC_AND_SET(arr, lbl, func) \
11204 do { \
11205 u32 len = be32_to_cpu(fw_hdr->arr.len); \
11206 bp->arr = kmalloc(len, GFP_KERNEL); \
11207 if (!bp->arr) { \
11208 printk(KERN_ERR PFX "Failed to allocate %d bytes for "#arr"\n", len); \
11209 goto lbl; \
11210 } \
11211 func(bp->firmware->data + \
11212 be32_to_cpu(fw_hdr->arr.offset), \
11213 (u8*)bp->arr, len); \
11214 } while (0)
11215
11216
11217static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
11218{
11219 char fw_file_name[40] = {0};
11220 int rc, offset;
11221 struct bnx2x_fw_file_hdr *fw_hdr;
11222
11223 /* Create a FW file name */
11224 if (CHIP_IS_E1(bp))
11225 offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
11226 else
11227 offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
11228
11229 sprintf(fw_file_name + offset, "%d.%d.%d.%d.fw",
11230 BCM_5710_FW_MAJOR_VERSION,
11231 BCM_5710_FW_MINOR_VERSION,
11232 BCM_5710_FW_REVISION_VERSION,
11233 BCM_5710_FW_ENGINEERING_VERSION);
11234
11235 printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
11236
11237 rc = request_firmware(&bp->firmware, fw_file_name, dev);
11238 if (rc) {
11239 printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file_name);
11240 goto request_firmware_exit;
11241 }
11242
11243 rc = bnx2x_check_firmware(bp);
11244 if (rc) {
11245 printk(KERN_ERR PFX "Corrupt firmware file %s\n", fw_file_name);
11246 goto request_firmware_exit;
11247 }
11248
11249 fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
11250
11251 /* Initialize the pointers to the init arrays */
11252 /* Blob */
11253 BNX2X_ALLOC_AND_SET(init_data, request_firmware_exit, be32_to_cpu_n);
11254
11255 /* Opcodes */
11256 BNX2X_ALLOC_AND_SET(init_ops, init_ops_alloc_err, bnx2x_prep_ops);
11257
11258 /* Offsets */
11259 BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n);
11260
11261 /* STORMs firmware */
11262 bp->tsem_int_table_data = bp->firmware->data +
11263 be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
11264 bp->tsem_pram_data = bp->firmware->data +
11265 be32_to_cpu(fw_hdr->tsem_pram_data.offset);
11266 bp->usem_int_table_data = bp->firmware->data +
11267 be32_to_cpu(fw_hdr->usem_int_table_data.offset);
11268 bp->usem_pram_data = bp->firmware->data +
11269 be32_to_cpu(fw_hdr->usem_pram_data.offset);
11270 bp->xsem_int_table_data = bp->firmware->data +
11271 be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
11272 bp->xsem_pram_data = bp->firmware->data +
11273 be32_to_cpu(fw_hdr->xsem_pram_data.offset);
11274 bp->csem_int_table_data = bp->firmware->data +
11275 be32_to_cpu(fw_hdr->csem_int_table_data.offset);
11276 bp->csem_pram_data = bp->firmware->data +
11277 be32_to_cpu(fw_hdr->csem_pram_data.offset);
11278
11279 return 0;
11280init_offsets_alloc_err:
11281 kfree(bp->init_ops);
11282init_ops_alloc_err:
11283 kfree(bp->init_data);
11284request_firmware_exit:
11285 release_firmware(bp->firmware);
11286
11287 return rc;
11288}
11289
11290
11085 11291
11086static int __devinit bnx2x_init_one(struct pci_dev *pdev, 11292static int __devinit bnx2x_init_one(struct pci_dev *pdev,
11087 const struct pci_device_id *ent) 11293 const struct pci_device_id *ent)
@@ -11116,6 +11322,13 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
11116 if (rc) 11322 if (rc)
11117 goto init_one_exit; 11323 goto init_one_exit;
11118 11324
11325 /* Set init arrays */
11326 rc = bnx2x_init_firmware(bp, &pdev->dev);
11327 if (rc) {
11328 printk(KERN_ERR PFX "Error loading firmware\n");
11329 goto init_one_exit;
11330 }
11331
11119 rc = register_netdev(dev); 11332 rc = register_netdev(dev);
11120 if (rc) { 11333 if (rc) {
11121 dev_err(&pdev->dev, "Cannot register net device\n"); 11334 dev_err(&pdev->dev, "Cannot register net device\n");
@@ -11163,6 +11376,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
11163 11376
11164 unregister_netdev(dev); 11377 unregister_netdev(dev);
11165 11378
11379 kfree(bp->init_ops_offsets);
11380 kfree(bp->init_ops);
11381 kfree(bp->init_data);
11382 release_firmware(bp->firmware);
11383
11166 if (bp->regview) 11384 if (bp->regview)
11167 iounmap(bp->regview); 11385 iounmap(bp->regview);
11168 11386
@@ -11431,3 +11649,4 @@ static void __exit bnx2x_cleanup(void)
11431module_init(bnx2x_init); 11649module_init(bnx2x_init);
11432module_exit(bnx2x_cleanup); 11650module_exit(bnx2x_cleanup);
11433 11651
11652
diff --git a/firmware/Makefile b/firmware/Makefile
index 25200d106ee8..1c670e0c0448 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -32,6 +32,7 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
32 adaptec/starfire_tx.bin 32 adaptec/starfire_tx.bin
33fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin 33fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
34fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw 34fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
35fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-4.8.53.0.fw bnx2x-e1h-4.8.53.0.fw
35fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-4.6.17.fw \ 36fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-4.6.17.fw \
36 bnx2/bnx2-rv2p-09-4.6.15.fw \ 37 bnx2/bnx2-rv2p-09-4.6.15.fw \
37 bnx2/bnx2-mips-06-4.6.16.fw \ 38 bnx2/bnx2-mips-06-4.6.16.fw \
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 4c52984a8319..c1e9c5ab694c 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -618,6 +618,26 @@ Found in hex form in kernel source.
618 618
619-------------------------------------------------------------------------- 619--------------------------------------------------------------------------
620 620
621Driver: bnx2x: Broadcom Everest
622
623File: bnx2x-e1-4.8.53.0.fw.ihex
624File: bnx2x-e1h-4.8.53.0.fw.ihex
625
626License:
627 Copyright (c) 2007-2009 Broadcom Corporation
628
629 This file contains firmware data derived from proprietary unpublished
630 source code, Copyright (c) 2007-2009 Broadcom Corporation.
631
632 Permission is hereby granted for the distribution of this firmware data
633 in hexadecimal or equivalent format, provided this copyright notice is
634 accompanying it.
635
636
637Found in hex form in kernel source.
638
639--------------------------------------------------------------------------
640
621Driver: BNX2 - Broadcom NetXtremeII 641Driver: BNX2 - Broadcom NetXtremeII
622 642
623File: bnx2/bnx2-mips-06-4.6.16.fw 643File: bnx2/bnx2-mips-06-4.6.16.fw