aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-08-12 04:24:14 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-13 02:02:59 -0400
commit573f203574581faaf80ca4fc079d33452327fc3b (patch)
tree1bd1cce6b130dc6a30fced46665d3a112a168bfb /drivers/net
parente4ed7113372a04df9b7aa985ce3860207dbb1141 (diff)
bnx2x: Re-factor the initialization code
Moving the code to a more logical place and beautifying it. No real change in behavior. 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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/bnx2x.h28
-rw-r--r--drivers/net/bnx2x_init.h320
-rw-r--r--drivers/net/bnx2x_init_ops.h419
-rw-r--r--drivers/net/bnx2x_main.c79
-rw-r--r--drivers/net/bnx2x_reg.h113
5 files changed, 495 insertions, 464 deletions
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h
index a231780061c0..97bc5e046f47 100644
--- a/drivers/net/bnx2x.h
+++ b/drivers/net/bnx2x.h
@@ -116,16 +116,22 @@
116#define REG_RD_DMAE(bp, offset, valp, len32) \ 116#define REG_RD_DMAE(bp, offset, valp, len32) \
117 do { \ 117 do { \
118 bnx2x_read_dmae(bp, offset, len32);\ 118 bnx2x_read_dmae(bp, offset, len32);\
119 memcpy(valp, bnx2x_sp(bp, wb_data[0]), len32 * 4); \ 119 memcpy(valp, bnx2x_sp(bp, wb_data[0]), (len32) * 4); \
120 } while (0) 120 } while (0)
121 121
122#define REG_WR_DMAE(bp, offset, valp, len32) \ 122#define REG_WR_DMAE(bp, offset, valp, len32) \
123 do { \ 123 do { \
124 memcpy(bnx2x_sp(bp, wb_data[0]), valp, len32 * 4); \ 124 memcpy(bnx2x_sp(bp, wb_data[0]), valp, (len32) * 4); \
125 bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), \ 125 bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), \
126 offset, len32); \ 126 offset, len32); \
127 } while (0) 127 } while (0)
128 128
129#define VIRT_WR_DMAE_LEN(bp, data, addr, len32) \
130 do { \
131 memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \
132 bnx2x_write_big_buf_wb(bp, addr, len32); \
133 } while (0)
134
129#define SHMEM_ADDR(bp, field) (bp->common.shmem_base + \ 135#define SHMEM_ADDR(bp, field) (bp->common.shmem_base + \
130 offsetof(struct shmem_region, field)) 136 offsetof(struct shmem_region, field))
131#define SHMEM_RD(bp, field) REG_RD(bp, SHMEM_ADDR(bp, field)) 137#define SHMEM_RD(bp, field) REG_RD(bp, SHMEM_ADDR(bp, field))
@@ -988,6 +994,9 @@ struct bnx2x {
988 dma_addr_t gunzip_mapping; 994 dma_addr_t gunzip_mapping;
989 int gunzip_outlen; 995 int gunzip_outlen;
990#define FW_BUF_SIZE 0x8000 996#define FW_BUF_SIZE 0x8000
997#define GUNZIP_BUF(bp) (bp->gunzip_buf)
998#define GUNZIP_PHYS(bp) (bp->gunzip_mapping)
999#define GUNZIP_OUTLEN(bp) (bp->gunzip_outlen)
991 1000
992 struct raw_op *init_ops; 1001 struct raw_op *init_ops;
993 /* Init blocks offsets inside init_ops */ 1002 /* Init blocks offsets inside init_ops */
@@ -1003,6 +1012,18 @@ struct bnx2x {
1003 const u8 *xsem_pram_data; 1012 const u8 *xsem_pram_data;
1004 const u8 *csem_int_table_data; 1013 const u8 *csem_int_table_data;
1005 const u8 *csem_pram_data; 1014 const u8 *csem_pram_data;
1015#define INIT_OPS(bp) (bp->init_ops)
1016#define INIT_OPS_OFFSETS(bp) (bp->init_ops_offsets)
1017#define INIT_DATA(bp) (bp->init_data)
1018#define INIT_TSEM_INT_TABLE_DATA(bp) (bp->tsem_int_table_data)
1019#define INIT_TSEM_PRAM_DATA(bp) (bp->tsem_pram_data)
1020#define INIT_USEM_INT_TABLE_DATA(bp) (bp->usem_int_table_data)
1021#define INIT_USEM_PRAM_DATA(bp) (bp->usem_pram_data)
1022#define INIT_XSEM_INT_TABLE_DATA(bp) (bp->xsem_int_table_data)
1023#define INIT_XSEM_PRAM_DATA(bp) (bp->xsem_pram_data)
1024#define INIT_CSEM_INT_TABLE_DATA(bp) (bp->csem_int_table_data)
1025#define INIT_CSEM_PRAM_DATA(bp) (bp->csem_pram_data)
1026
1006 const struct firmware *firmware; 1027 const struct firmware *firmware;
1007}; 1028};
1008 1029
@@ -1030,6 +1051,9 @@ int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port);
1030int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); 1051int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
1031int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); 1052int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port);
1032u32 bnx2x_fw_command(struct bnx2x *bp, u32 command); 1053u32 bnx2x_fw_command(struct bnx2x *bp, u32 command);
1054void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
1055void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
1056 u32 addr, u32 len);
1033 1057
1034static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, 1058static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
1035 int wait) 1059 int wait)
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
index 3ba4d888068f..65b26cbfe3e7 100644
--- a/drivers/net/bnx2x_init.h
+++ b/drivers/net/bnx2x_init.h
@@ -15,24 +15,11 @@
15#ifndef BNX2X_INIT_H 15#ifndef BNX2X_INIT_H
16#define BNX2X_INIT_H 16#define BNX2X_INIT_H
17 17
18#define COMMON 0x1
19#define PORT0 0x2
20#define PORT1 0x4
21
22#define INIT_EMULATION 0x1
23#define INIT_FPGA 0x2
24#define INIT_ASIC 0x4
25#define INIT_HARDWARE 0x7
26
27#define TSTORM_INTMEM_ADDR TSEM_REG_FAST_MEMORY
28#define CSTORM_INTMEM_ADDR CSEM_REG_FAST_MEMORY
29#define XSTORM_INTMEM_ADDR XSEM_REG_FAST_MEMORY
30#define USTORM_INTMEM_ADDR USEM_REG_FAST_MEMORY
31/* RAM0 size in bytes */ 18/* RAM0 size in bytes */
32#define STORM_INTMEM_SIZE_E1 0x5800 19#define STORM_INTMEM_SIZE_E1 0x5800
33#define STORM_INTMEM_SIZE_E1H 0x10000 20#define STORM_INTMEM_SIZE_E1H 0x10000
34#define STORM_INTMEM_SIZE(bp) ((CHIP_IS_E1H(bp) ? STORM_INTMEM_SIZE_E1H : \ 21#define STORM_INTMEM_SIZE(bp) ((CHIP_IS_E1(bp) ? STORM_INTMEM_SIZE_E1 : \
35 STORM_INTMEM_SIZE_E1) / 4) 22 STORM_INTMEM_SIZE_E1H) / 4)
36 23
37 24
38/* Init operation types and structures */ 25/* Init operation types and structures */
@@ -53,65 +40,68 @@
53#define OP_WR_ASIC 0xc /* write single register on ASIC */ 40#define OP_WR_ASIC 0xc /* write single register on ASIC */
54 41
55/* Init stages */ 42/* Init stages */
56#define COMMON_STAGE 0 43/* Never reorder stages !!! */
57#define PORT0_STAGE 1 44#define COMMON_STAGE 0
58#define PORT1_STAGE 2 45#define PORT0_STAGE 1
59/* Never reorder FUNCx stages !!! */ 46#define PORT1_STAGE 2
60#define FUNC0_STAGE 3 47#define FUNC0_STAGE 3
61#define FUNC1_STAGE 4 48#define FUNC1_STAGE 4
62#define FUNC2_STAGE 5 49#define FUNC2_STAGE 5
63#define FUNC3_STAGE 6 50#define FUNC3_STAGE 6
64#define FUNC4_STAGE 7 51#define FUNC4_STAGE 7
65#define FUNC5_STAGE 8 52#define FUNC5_STAGE 8
66#define FUNC6_STAGE 9 53#define FUNC6_STAGE 9
67#define FUNC7_STAGE 10 54#define FUNC7_STAGE 10
68#define STAGE_IDX_MAX 11 55#define STAGE_IDX_MAX 11
69 56
70#define STAGE_START 0 57#define STAGE_START 0
71#define STAGE_END 1 58#define STAGE_END 1
72 59
73 60
74/* Indices of blocks */ 61/* Indices of blocks */
75#define PRS_BLOCK 0 62#define PRS_BLOCK 0
76#define SRCH_BLOCK 1 63#define SRCH_BLOCK 1
77#define TSDM_BLOCK 2 64#define TSDM_BLOCK 2
78#define TCM_BLOCK 3 65#define TCM_BLOCK 3
79#define BRB1_BLOCK 4 66#define BRB1_BLOCK 4
80#define TSEM_BLOCK 5 67#define TSEM_BLOCK 5
81#define PXPCS_BLOCK 6 68#define PXPCS_BLOCK 6
82#define EMAC0_BLOCK 7 69#define EMAC0_BLOCK 7
83#define EMAC1_BLOCK 8 70#define EMAC1_BLOCK 8
84#define DBU_BLOCK 9 71#define DBU_BLOCK 9
85#define MISC_BLOCK 10 72#define MISC_BLOCK 10
86#define DBG_BLOCK 11 73#define DBG_BLOCK 11
87#define NIG_BLOCK 12 74#define NIG_BLOCK 12
88#define MCP_BLOCK 13 75#define MCP_BLOCK 13
89#define UPB_BLOCK 14 76#define UPB_BLOCK 14
90#define CSDM_BLOCK 15 77#define CSDM_BLOCK 15
91#define USDM_BLOCK 16 78#define USDM_BLOCK 16
92#define CCM_BLOCK 17 79#define CCM_BLOCK 17
93#define UCM_BLOCK 18 80#define UCM_BLOCK 18
94#define USEM_BLOCK 19 81#define USEM_BLOCK 19
95#define CSEM_BLOCK 20 82#define CSEM_BLOCK 20
96#define XPB_BLOCK 21 83#define XPB_BLOCK 21
97#define DQ_BLOCK 22 84#define DQ_BLOCK 22
98#define TIMERS_BLOCK 23 85#define TIMERS_BLOCK 23
99#define XSDM_BLOCK 24 86#define XSDM_BLOCK 24
100#define QM_BLOCK 25 87#define QM_BLOCK 25
101#define PBF_BLOCK 26 88#define PBF_BLOCK 26
102#define XCM_BLOCK 27 89#define XCM_BLOCK 27
103#define XSEM_BLOCK 28 90#define XSEM_BLOCK 28
104#define CDU_BLOCK 29 91#define CDU_BLOCK 29
105#define DMAE_BLOCK 30 92#define DMAE_BLOCK 30
106#define PXP_BLOCK 31 93#define PXP_BLOCK 31
107#define CFC_BLOCK 32 94#define CFC_BLOCK 32
108#define HC_BLOCK 33 95#define HC_BLOCK 33
109#define PXP2_BLOCK 34 96#define PXP2_BLOCK 34
110#define MISC_AEU_BLOCK 35 97#define MISC_AEU_BLOCK 35
98#define PGLUE_B_BLOCK 36
99#define IGU_BLOCK 37
100
111 101
112/* Returns the index of start or end of a specific block stage in ops array*/ 102/* Returns the index of start or end of a specific block stage in ops array*/
113#define BLOCK_OPS_IDX(block, stage, end) \ 103#define BLOCK_OPS_IDX(block, stage, end) \
114 (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end)) 104 (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
115 105
116 106
117struct raw_op { 107struct raw_op {
@@ -158,199 +148,5 @@ union init_op {
158 struct raw_op raw; 148 struct raw_op raw;
159}; 149};
160 150
161/****************************************************************************
162* PXP
163****************************************************************************/
164/*
165 * This code configures the PCI read/write arbiter
166 * which implements a weighted round robin
167 * between the virtual queues in the chip.
168 *
169 * The values were derived for each PCI max payload and max request size.
170 * since max payload and max request size are only known at run time,
171 * this is done as a separate init stage.
172 */
173
174#define NUM_WR_Q 13
175#define NUM_RD_Q 29
176#define MAX_RD_ORD 3
177#define MAX_WR_ORD 2
178
179/* configuration for one arbiter queue */
180struct arb_line {
181 int l;
182 int add;
183 int ubound;
184};
185
186/* derived configuration for each read queue for each max request size */
187static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
188/* 1 */ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
189 { {4, 8, 4}, {4, 8, 4}, {4, 8, 4}, {4, 8, 4} },
190 { {4, 3, 3}, {4, 3, 3}, {4, 3, 3}, {4, 3, 3} },
191 { {8, 3, 6}, {16, 3, 11}, {16, 3, 11}, {16, 3, 11} },
192 { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
193 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
194 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
195 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
196 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
197/* 10 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
198 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
199 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
200 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
201 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
202 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
203 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
204 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
205 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
206 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
207/* 20 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
208 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
209 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
210 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
211 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
212 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
213 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
214 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
215 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
216 { {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
217};
218
219/* derived configuration for each write queue for each max request size */
220static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
221/* 1 */ { {4, 6, 3}, {4, 6, 3}, {4, 6, 3} },
222 { {4, 2, 3}, {4, 2, 3}, {4, 2, 3} },
223 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
224 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
225 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
226 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
227 { {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
228 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
229 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
230/* 10 */{ {8, 9, 6}, {16, 9, 11}, {32, 9, 21} },
231 { {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
232 { {8, 9, 6}, {16, 9, 11}, {16, 9, 11} },
233 { {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
234};
235
236/* register addresses for read queues */
237static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
238/* 1 */ {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
239 PXP2_REG_RQ_BW_RD_UBOUND0},
240 {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
241 PXP2_REG_PSWRQ_BW_UB1},
242 {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
243 PXP2_REG_PSWRQ_BW_UB2},
244 {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
245 PXP2_REG_PSWRQ_BW_UB3},
246 {PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
247 PXP2_REG_RQ_BW_RD_UBOUND4},
248 {PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
249 PXP2_REG_RQ_BW_RD_UBOUND5},
250 {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
251 PXP2_REG_PSWRQ_BW_UB6},
252 {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
253 PXP2_REG_PSWRQ_BW_UB7},
254 {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
255 PXP2_REG_PSWRQ_BW_UB8},
256/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
257 PXP2_REG_PSWRQ_BW_UB9},
258 {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
259 PXP2_REG_PSWRQ_BW_UB10},
260 {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
261 PXP2_REG_PSWRQ_BW_UB11},
262 {PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
263 PXP2_REG_RQ_BW_RD_UBOUND12},
264 {PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
265 PXP2_REG_RQ_BW_RD_UBOUND13},
266 {PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
267 PXP2_REG_RQ_BW_RD_UBOUND14},
268 {PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
269 PXP2_REG_RQ_BW_RD_UBOUND15},
270 {PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
271 PXP2_REG_RQ_BW_RD_UBOUND16},
272 {PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
273 PXP2_REG_RQ_BW_RD_UBOUND17},
274 {PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
275 PXP2_REG_RQ_BW_RD_UBOUND18},
276/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
277 PXP2_REG_RQ_BW_RD_UBOUND19},
278 {PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
279 PXP2_REG_RQ_BW_RD_UBOUND20},
280 {PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
281 PXP2_REG_RQ_BW_RD_UBOUND22},
282 {PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
283 PXP2_REG_RQ_BW_RD_UBOUND23},
284 {PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
285 PXP2_REG_RQ_BW_RD_UBOUND24},
286 {PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
287 PXP2_REG_RQ_BW_RD_UBOUND25},
288 {PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
289 PXP2_REG_RQ_BW_RD_UBOUND26},
290 {PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
291 PXP2_REG_RQ_BW_RD_UBOUND27},
292 {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
293 PXP2_REG_PSWRQ_BW_UB28}
294};
295
296/* register addresses for write queues */
297static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
298/* 1 */ {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
299 PXP2_REG_PSWRQ_BW_UB1},
300 {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
301 PXP2_REG_PSWRQ_BW_UB2},
302 {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
303 PXP2_REG_PSWRQ_BW_UB3},
304 {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
305 PXP2_REG_PSWRQ_BW_UB6},
306 {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
307 PXP2_REG_PSWRQ_BW_UB7},
308 {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
309 PXP2_REG_PSWRQ_BW_UB8},
310 {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
311 PXP2_REG_PSWRQ_BW_UB9},
312 {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
313 PXP2_REG_PSWRQ_BW_UB10},
314 {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
315 PXP2_REG_PSWRQ_BW_UB11},
316/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
317 PXP2_REG_PSWRQ_BW_UB28},
318 {PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
319 PXP2_REG_RQ_BW_WR_UBOUND29},
320 {PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
321 PXP2_REG_RQ_BW_WR_UBOUND30}
322};
323
324
325/****************************************************************************
326* CDU
327****************************************************************************/
328
329#define CDU_REGION_NUMBER_XCM_AG 2
330#define CDU_REGION_NUMBER_UCM_AG 4
331
332/**
333 * String-to-compress [31:8] = CID (all 24 bits)
334 * String-to-compress [7:4] = Region
335 * String-to-compress [3:0] = Type
336 */
337#define CDU_VALID_DATA(_cid, _region, _type) \
338 (((_cid) << 8) | (((_region) & 0xf) << 4) | (((_type) & 0xf)))
339#define CDU_CRC8(_cid, _region, _type) \
340 calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff)
341#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type) \
342 (0x80 | (CDU_CRC8(_cid, _region, _type) & 0x7f))
343#define CDU_RSRVD_VALUE_TYPE_B(_crc, _type) \
344 (0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
345#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
346
347
348/* registers addresses are not in order
349 so these arrays help simplify the code */
350static const int cm_blocks[9] = {
351 MISC_BLOCK, TCM_BLOCK, UCM_BLOCK, CCM_BLOCK, XCM_BLOCK,
352 TSEM_BLOCK, USEM_BLOCK, CSEM_BLOCK, XSEM_BLOCK
353};
354
355#endif /* BNX2X_INIT_H */ 151#endif /* BNX2X_INIT_H */
356 152
diff --git a/drivers/net/bnx2x_init_ops.h b/drivers/net/bnx2x_init_ops.h
index 32552b9366cb..38b970a14fd7 100644
--- a/drivers/net/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x_init_ops.h
@@ -11,85 +11,68 @@
11 * Maintained by: Eilon Greenstein <eilong@broadcom.com> 11 * Maintained by: Eilon Greenstein <eilong@broadcom.com>
12 * Written by: Vladislav Zolotarov <vladz@broadcom.com> 12 * Written by: Vladislav Zolotarov <vladz@broadcom.com>
13 */ 13 */
14
14#ifndef BNX2X_INIT_OPS_H 15#ifndef BNX2X_INIT_OPS_H
15#define BNX2X_INIT_OPS_H 16#define BNX2X_INIT_OPS_H
16 17
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); 18static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
19 19
20
20static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, 21static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
21 u32 len) 22 u32 len)
22{ 23{
23 int i; 24 u32 i;
24 25
25 for (i = 0; i < len; i++) { 26 for (i = 0; i < len; i++)
26 REG_WR(bp, addr + i*4, data[i]); 27 REG_WR(bp, addr + i*4, data[i]);
27 if (!(i % 10000)) {
28 touch_softlockup_watchdog();
29 cpu_relax();
30 }
31 }
32} 28}
33 29
34static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, 30static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
35 u16 len) 31 u32 len)
36{ 32{
37 int i; 33 u32 i;
38 34
39 for (i = 0; i < len; i++) { 35 for (i = 0; i < len; i++)
40 REG_WR_IND(bp, addr + i*4, data[i]); 36 REG_WR_IND(bp, addr + i*4, data[i]);
41 if (!(i % 10000)) {
42 touch_softlockup_watchdog();
43 cpu_relax();
44 }
45 }
46} 37}
47 38
48static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) 39static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
49{ 40{
50 int offset = 0; 41 if (bp->dmae_ready)
51 42 bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
52 if (bp->dmae_ready) { 43 else
53 while (len > DMAE_LEN32_WR_MAX) { 44 bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
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} 45}
64 46
65static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) 47static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
66{ 48{
67 u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4)); 49 u32 buf_len = (((len*4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len*4));
68 u32 buf_len32 = buf_len / 4; 50 u32 buf_len32 = buf_len/4;
69 int i; 51 u32 i;
70 52
71 memset(bp->gunzip_buf, fill, buf_len); 53 memset(GUNZIP_BUF(bp), (u8)fill, buf_len);
72 54
73 for (i = 0; i < len; i += buf_len32) { 55 for (i = 0; i < len; i += buf_len32) {
74 u32 cur_len = min(buf_len32, len - i); 56 u32 cur_len = min(buf_len32, len - i);
75 57
76 bnx2x_write_big_buf(bp, addr + i * 4, cur_len); 58 bnx2x_write_big_buf(bp, addr + i*4, cur_len);
77 } 59 }
78} 60}
79 61
80static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, 62static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
81 u32 len64) 63 u32 len64)
82{ 64{
83 u32 buf_len32 = FW_BUF_SIZE / 4; 65 u32 buf_len32 = FW_BUF_SIZE/4;
84 u32 len = len64 * 2; 66 u32 len = len64*2;
85 u64 data64 = 0; 67 u64 data64 = 0;
86 int i; 68 u32 i;
87 69
88 /* 64 bit value is in a blob: first low DWORD, then high DWORD */ 70 /* 64 bit value is in a blob: first low DWORD, then high DWORD */
89 data64 = HILO_U64((*(data + 1)), (*data)); 71 data64 = HILO_U64((*(data + 1)), (*data));
72
90 len64 = min((u32)(FW_BUF_SIZE/8), len64); 73 len64 = min((u32)(FW_BUF_SIZE/8), len64);
91 for (i = 0; i < len64; i++) { 74 for (i = 0; i < len64; i++) {
92 u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i; 75 u64 *pdata = ((u64 *)(GUNZIP_BUF(bp))) + i;
93 76
94 *pdata = data64; 77 *pdata = data64;
95 } 78 }
@@ -97,7 +80,7 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
97 for (i = 0; i < len; i += buf_len32) { 80 for (i = 0; i < len; i += buf_len32) {
98 u32 cur_len = min(buf_len32, len - i); 81 u32 cur_len = min(buf_len32, len - i);
99 82
100 bnx2x_write_big_buf(bp, addr + i * 4, cur_len); 83 bnx2x_write_big_buf(bp, addr + i*4, cur_len);
101 } 84 }
102} 85}
103 86
@@ -118,97 +101,81 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
118static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data) 101static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data)
119{ 102{
120 IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr) 103 IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
121 data = bp->tsem_int_table_data; 104 data = INIT_TSEM_INT_TABLE_DATA(bp);
122 else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr) 105 else
123 data = bp->csem_int_table_data; 106 IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
124 else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr) 107 data = INIT_CSEM_INT_TABLE_DATA(bp);
125 data = bp->usem_int_table_data; 108 else
126 else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr) 109 IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
127 data = bp->xsem_int_table_data; 110 data = INIT_USEM_INT_TABLE_DATA(bp);
128 else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr) 111 else
129 data = bp->tsem_pram_data; 112 IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
130 else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr) 113 data = INIT_XSEM_INT_TABLE_DATA(bp);
131 data = bp->csem_pram_data; 114 else
132 else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr) 115 IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
133 data = bp->usem_pram_data; 116 data = INIT_TSEM_PRAM_DATA(bp);
134 else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr) 117 else
135 data = bp->xsem_pram_data; 118 IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
119 data = INIT_CSEM_PRAM_DATA(bp);
120 else
121 IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
122 data = INIT_USEM_PRAM_DATA(bp);
123 else
124 IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
125 data = INIT_XSEM_PRAM_DATA(bp);
136 126
137 return data; 127 return data;
138} 128}
139 129
140static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) 130static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
141{ 131{
142 int offset = 0; 132 if (bp->dmae_ready)
143 133 bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
144 if (bp->dmae_ready) { 134 else
145 while (len > DMAE_LEN32_WR_MAX) { 135 bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
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} 136}
156 137
157static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, 138static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
158 u32 len) 139 u32 len)
159{ 140{
160 /* This is needed for NO_ZIP mode, currently supported 141 data = (const u32 *)bnx2x_sel_blob(bp, addr, (const u8 *)data);
161 in little endian mode only */
162 data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data);
163 142
164 if ((len * 4) > FW_BUF_SIZE) { 143 if (bp->dmae_ready)
165 BNX2X_ERR("LARGE DMAE OPERATION ! " 144 VIRT_WR_DMAE_LEN(bp, data, addr, len);
166 "addr 0x%x len 0x%x\n", addr, len*4); 145 else
167 return; 146 bnx2x_init_ind_wr(bp, addr, data, len);
168 }
169 memcpy(bp->gunzip_buf, data, len * 4);
170
171 bnx2x_write_big_buf_wb(bp, addr, len);
172} 147}
173 148
174static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, 149static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off)
175 u32 len, u32 blob_off)
176{ 150{
177 int rc, i; 151 const u8 *data = NULL;
178 const u8 *data = NULL; 152 int rc;
153 u32 i;
179 154
180 data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off; 155 data = bnx2x_sel_blob(bp, addr, data) + blob_off*4;
181
182 if (data == NULL) {
183 panic("Blob not found for addr 0x%x\n", addr);
184 return;
185 }
186 156
187 rc = bnx2x_gunzip(bp, data, len); 157 rc = bnx2x_gunzip(bp, data, len);
188 if (rc) { 158 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; 159 return;
192 }
193 160
194 /* gunzip_outlen is in dwords */ 161 /* gunzip_outlen is in dwords */
195 len = bp->gunzip_outlen; 162 len = GUNZIP_OUTLEN(bp);
196 for (i = 0; i < len; i++) 163 for (i = 0; i < len; i++)
197 ((u32 *)bp->gunzip_buf)[i] = 164 ((u32 *)GUNZIP_BUF(bp))[i] =
198 cpu_to_le32(((u32 *)bp->gunzip_buf)[i]); 165 cpu_to_le32(((u32 *)GUNZIP_BUF(bp))[i]);
199 166
200 bnx2x_write_big_buf_wb(bp, addr, len); 167 bnx2x_write_big_buf_wb(bp, addr, len);
201} 168}
202 169
203static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage) 170static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
204{ 171{
205 int hw_wr, i;
206 u16 op_start = 172 u16 op_start =
207 bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)]; 173 INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_START)];
208 u16 op_end = 174 u16 op_end =
209 bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)]; 175 INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_END)];
210 union init_op *op; 176 union init_op *op;
211 u32 op_type, addr, len; 177 int hw_wr;
178 u32 i, op_type, addr, len;
212 const u32 *data, *data_base; 179 const u32 *data, *data_base;
213 180
214 /* If empty block */ 181 /* If empty block */
@@ -222,11 +189,11 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
222 else 189 else
223 hw_wr = OP_WR_ASIC; 190 hw_wr = OP_WR_ASIC;
224 191
225 data_base = bp->init_data; 192 data_base = INIT_DATA(bp);
226 193
227 for (i = op_start; i < op_end; i++) { 194 for (i = op_start; i < op_end; i++) {
228 195
229 op = (union init_op *)&(bp->init_ops[i]); 196 op = (union init_op *)&(INIT_OPS(bp)[i]);
230 197
231 op_type = op->str_wr.op; 198 op_type = op->str_wr.op;
232 addr = op->str_wr.offset; 199 addr = op->str_wr.offset;
@@ -234,7 +201,7 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
234 data = data_base + op->str_wr.data_off; 201 data = data_base + op->str_wr.data_off;
235 202
236 /* HW/EMUL specific */ 203 /* HW/EMUL specific */
237 if (unlikely((op_type > OP_WB) && (op_type == hw_wr))) 204 if ((op_type > OP_WB) && (op_type == hw_wr))
238 op_type = OP_WR; 205 op_type = OP_WR;
239 206
240 switch (op_type) { 207 switch (op_type) {
@@ -265,35 +232,179 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
265 break; 232 break;
266 default: 233 default:
267 /* happens whenever an op is of a diff HW */ 234 /* 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; 235 break;
275 } 236 }
276 } 237 }
277} 238}
278 239
279/* PXP */ 240
280static void bnx2x_init_pxp(struct bnx2x *bp) 241/****************************************************************************
242* PXP Arbiter
243****************************************************************************/
244/*
245 * This code configures the PCI read/write arbiter
246 * which implements a weighted round robin
247 * between the virtual queues in the chip.
248 *
249 * The values were derived for each PCI max payload and max request size.
250 * since max payload and max request size are only known at run time,
251 * this is done as a separate init stage.
252 */
253
254#define NUM_WR_Q 13
255#define NUM_RD_Q 29
256#define MAX_RD_ORD 3
257#define MAX_WR_ORD 2
258
259/* configuration for one arbiter queue */
260struct arb_line {
261 int l;
262 int add;
263 int ubound;
264};
265
266/* derived configuration for each read queue for each max request size */
267static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
268/* 1 */ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
269 { {4, 8, 4}, {4, 8, 4}, {4, 8, 4}, {4, 8, 4} },
270 { {4, 3, 3}, {4, 3, 3}, {4, 3, 3}, {4, 3, 3} },
271 { {8, 3, 6}, {16, 3, 11}, {16, 3, 11}, {16, 3, 11} },
272 { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
273 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
274 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
275 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
276 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
277/* 10 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
278 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
279 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
280 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
281 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
282 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
283 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
284 { {8, 64, 6}, {16, 64, 11}, {32, 64, 21}, {32, 64, 21} },
285 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
286 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
287/* 20 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
288 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
289 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
290 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
291 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
292 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
293 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
294 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
295 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
296 { {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
297};
298
299/* derived configuration for each write queue for each max request size */
300static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
301/* 1 */ { {4, 6, 3}, {4, 6, 3}, {4, 6, 3} },
302 { {4, 2, 3}, {4, 2, 3}, {4, 2, 3} },
303 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
304 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
305 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
306 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
307 { {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
308 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
309 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
310/* 10 */{ {8, 9, 6}, {16, 9, 11}, {32, 9, 21} },
311 { {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
312 { {8, 9, 6}, {16, 9, 11}, {16, 9, 11} },
313 { {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
314};
315
316/* register addresses for read queues */
317static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
318/* 1 */ {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
319 PXP2_REG_RQ_BW_RD_UBOUND0},
320 {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
321 PXP2_REG_PSWRQ_BW_UB1},
322 {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
323 PXP2_REG_PSWRQ_BW_UB2},
324 {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
325 PXP2_REG_PSWRQ_BW_UB3},
326 {PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
327 PXP2_REG_RQ_BW_RD_UBOUND4},
328 {PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
329 PXP2_REG_RQ_BW_RD_UBOUND5},
330 {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
331 PXP2_REG_PSWRQ_BW_UB6},
332 {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
333 PXP2_REG_PSWRQ_BW_UB7},
334 {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
335 PXP2_REG_PSWRQ_BW_UB8},
336/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
337 PXP2_REG_PSWRQ_BW_UB9},
338 {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
339 PXP2_REG_PSWRQ_BW_UB10},
340 {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
341 PXP2_REG_PSWRQ_BW_UB11},
342 {PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
343 PXP2_REG_RQ_BW_RD_UBOUND12},
344 {PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
345 PXP2_REG_RQ_BW_RD_UBOUND13},
346 {PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
347 PXP2_REG_RQ_BW_RD_UBOUND14},
348 {PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
349 PXP2_REG_RQ_BW_RD_UBOUND15},
350 {PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
351 PXP2_REG_RQ_BW_RD_UBOUND16},
352 {PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
353 PXP2_REG_RQ_BW_RD_UBOUND17},
354 {PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
355 PXP2_REG_RQ_BW_RD_UBOUND18},
356/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
357 PXP2_REG_RQ_BW_RD_UBOUND19},
358 {PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
359 PXP2_REG_RQ_BW_RD_UBOUND20},
360 {PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
361 PXP2_REG_RQ_BW_RD_UBOUND22},
362 {PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
363 PXP2_REG_RQ_BW_RD_UBOUND23},
364 {PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
365 PXP2_REG_RQ_BW_RD_UBOUND24},
366 {PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
367 PXP2_REG_RQ_BW_RD_UBOUND25},
368 {PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
369 PXP2_REG_RQ_BW_RD_UBOUND26},
370 {PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
371 PXP2_REG_RQ_BW_RD_UBOUND27},
372 {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
373 PXP2_REG_PSWRQ_BW_UB28}
374};
375
376/* register addresses for write queues */
377static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
378/* 1 */ {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
379 PXP2_REG_PSWRQ_BW_UB1},
380 {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
381 PXP2_REG_PSWRQ_BW_UB2},
382 {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
383 PXP2_REG_PSWRQ_BW_UB3},
384 {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
385 PXP2_REG_PSWRQ_BW_UB6},
386 {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
387 PXP2_REG_PSWRQ_BW_UB7},
388 {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
389 PXP2_REG_PSWRQ_BW_UB8},
390 {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
391 PXP2_REG_PSWRQ_BW_UB9},
392 {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
393 PXP2_REG_PSWRQ_BW_UB10},
394 {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
395 PXP2_REG_PSWRQ_BW_UB11},
396/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
397 PXP2_REG_PSWRQ_BW_UB28},
398 {PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
399 PXP2_REG_RQ_BW_WR_UBOUND29},
400 {PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
401 PXP2_REG_RQ_BW_WR_UBOUND30}
402};
403
404static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order)
281{ 405{
282 u16 devctl;
283 int r_order, w_order;
284 u32 val, i; 406 u32 val, i;
285 407
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) { 408 if (r_order > MAX_RD_ORD) {
298 DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n", 409 DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
299 r_order, MAX_RD_ORD); 410 r_order, MAX_RD_ORD);
@@ -367,6 +478,11 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
367 REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); 478 REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
368 479
369 if (CHIP_IS_E1H(bp)) { 480 if (CHIP_IS_E1H(bp)) {
481 /* MPS w_order optimal TH presently TH
482 * 128 0 0 2
483 * 256 1 1 3
484 * >=512 2 2 3
485 */
370 val = ((w_order == 0) ? 2 : 3); 486 val = ((w_order == 0) ? 2 : 3);
371 REG_WR(bp, PXP2_REG_WR_HC_MPS, val); 487 REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
372 REG_WR(bp, PXP2_REG_WR_USDM_MPS, val); 488 REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
@@ -382,61 +498,4 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
382 } 498 }
383} 499}
384 500
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 */ 501#endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index b084e8b531af..8b6bb999d8e0 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -153,7 +153,7 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl);
153/* used only at init 153/* used only at init
154 * locking is done by mcp 154 * locking is done by mcp
155 */ 155 */
156static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val) 156void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
157{ 157{
158 pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr); 158 pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr);
159 pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val); 159 pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val);
@@ -346,6 +346,21 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
346 mutex_unlock(&bp->dmae_mutex); 346 mutex_unlock(&bp->dmae_mutex);
347} 347}
348 348
349void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr,
350 u32 addr, u32 len)
351{
352 int offset = 0;
353
354 while (len > DMAE_LEN32_WR_MAX) {
355 bnx2x_write_dmae(bp, phys_addr + offset,
356 addr + offset, DMAE_LEN32_WR_MAX);
357 offset += DMAE_LEN32_WR_MAX * 4;
358 len -= DMAE_LEN32_WR_MAX;
359 }
360
361 bnx2x_write_dmae(bp, phys_addr + offset, addr + offset, len);
362}
363
349/* used only for slowpath so not inlined */ 364/* used only for slowpath so not inlined */
350static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo) 365static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo)
351{ 366{
@@ -5917,6 +5932,24 @@ static void bnx2x_reset_common(struct bnx2x *bp)
5917 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403); 5932 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 0x1403);
5918} 5933}
5919 5934
5935static void bnx2x_init_pxp(struct bnx2x *bp)
5936{
5937 u16 devctl;
5938 int r_order, w_order;
5939
5940 pci_read_config_word(bp->pdev,
5941 bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
5942 DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
5943 w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
5944 if (bp->mrrs == -1)
5945 r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
5946 else {
5947 DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
5948 r_order = bp->mrrs;
5949 }
5950
5951 bnx2x_init_pxp_arb(bp, r_order, w_order);
5952}
5920 5953
5921static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) 5954static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp)
5922{ 5955{
@@ -6479,9 +6512,15 @@ static int bnx2x_init_func(struct bnx2x *bp)
6479 6512
6480 6513
6481 if (CHIP_IS_E1H(bp)) { 6514 if (CHIP_IS_E1H(bp)) {
6482 for (i = 0; i < 9; i++) 6515 bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func);
6483 bnx2x_init_block(bp, 6516 bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func);
6484 cm_blocks[i], FUNC0_STAGE + func); 6517 bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func);
6518 bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func);
6519 bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func);
6520 bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func);
6521 bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func);
6522 bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func);
6523 bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func);
6485 6524
6486 REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); 6525 REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
6487 REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); 6526 REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
@@ -11834,22 +11873,22 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
11834 BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n); 11873 BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n);
11835 11874
11836 /* STORMs firmware */ 11875 /* STORMs firmware */
11837 bp->tsem_int_table_data = bp->firmware->data + 11876 INIT_TSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
11838 be32_to_cpu(fw_hdr->tsem_int_table_data.offset); 11877 be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
11839 bp->tsem_pram_data = bp->firmware->data + 11878 INIT_TSEM_PRAM_DATA(bp) = bp->firmware->data +
11840 be32_to_cpu(fw_hdr->tsem_pram_data.offset); 11879 be32_to_cpu(fw_hdr->tsem_pram_data.offset);
11841 bp->usem_int_table_data = bp->firmware->data + 11880 INIT_USEM_INT_TABLE_DATA(bp) = bp->firmware->data +
11842 be32_to_cpu(fw_hdr->usem_int_table_data.offset); 11881 be32_to_cpu(fw_hdr->usem_int_table_data.offset);
11843 bp->usem_pram_data = bp->firmware->data + 11882 INIT_USEM_PRAM_DATA(bp) = bp->firmware->data +
11844 be32_to_cpu(fw_hdr->usem_pram_data.offset); 11883 be32_to_cpu(fw_hdr->usem_pram_data.offset);
11845 bp->xsem_int_table_data = bp->firmware->data + 11884 INIT_XSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
11846 be32_to_cpu(fw_hdr->xsem_int_table_data.offset); 11885 be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
11847 bp->xsem_pram_data = bp->firmware->data + 11886 INIT_XSEM_PRAM_DATA(bp) = bp->firmware->data +
11848 be32_to_cpu(fw_hdr->xsem_pram_data.offset); 11887 be32_to_cpu(fw_hdr->xsem_pram_data.offset);
11849 bp->csem_int_table_data = bp->firmware->data + 11888 INIT_CSEM_INT_TABLE_DATA(bp) = bp->firmware->data +
11850 be32_to_cpu(fw_hdr->csem_int_table_data.offset); 11889 be32_to_cpu(fw_hdr->csem_int_table_data.offset);
11851 bp->csem_pram_data = bp->firmware->data + 11890 INIT_CSEM_PRAM_DATA(bp) = bp->firmware->data +
11852 be32_to_cpu(fw_hdr->csem_pram_data.offset); 11891 be32_to_cpu(fw_hdr->csem_pram_data.offset);
11853 11892
11854 return 0; 11893 return 0;
11855init_offsets_alloc_err: 11894init_offsets_alloc_err:
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index 999838629be3..1e6f5aa4eb5a 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -6019,3 +6019,116 @@ Theotherbitsarereservedandshouldbezero*/
6019#define COMMAND_REG_SIMD_NOMASK 0x1c 6019#define COMMAND_REG_SIMD_NOMASK 0x1c
6020 6020
6021 6021
6022#define IGU_MEM_BASE 0x0000
6023
6024#define IGU_MEM_MSIX_BASE 0x0000
6025#define IGU_MEM_MSIX_UPPER 0x007f
6026#define IGU_MEM_MSIX_RESERVED_UPPER 0x01ff
6027
6028#define IGU_MEM_PBA_MSIX_BASE 0x0200
6029#define IGU_MEM_PBA_MSIX_UPPER 0x0200
6030
6031#define IGU_CMD_BACKWARD_COMP_PROD_UPD 0x0201
6032#define IGU_MEM_PBA_MSIX_RESERVED_UPPER 0x03ff
6033
6034#define IGU_CMD_INT_ACK_BASE 0x0400
6035#define IGU_CMD_INT_ACK_UPPER\
6036 (IGU_CMD_INT_ACK_BASE + MAX_SB_PER_PORT * NUM_OF_PORTS_PER_PATH - 1)
6037#define IGU_CMD_INT_ACK_RESERVED_UPPER 0x04ff
6038
6039#define IGU_CMD_E2_PROD_UPD_BASE 0x0500
6040#define IGU_CMD_E2_PROD_UPD_UPPER\
6041 (IGU_CMD_E2_PROD_UPD_BASE + MAX_SB_PER_PORT * NUM_OF_PORTS_PER_PATH - 1)
6042#define IGU_CMD_E2_PROD_UPD_RESERVED_UPPER 0x059f
6043
6044#define IGU_CMD_ATTN_BIT_UPD_UPPER 0x05a0
6045#define IGU_CMD_ATTN_BIT_SET_UPPER 0x05a1
6046#define IGU_CMD_ATTN_BIT_CLR_UPPER 0x05a2
6047
6048#define IGU_REG_SISR_MDPC_WMASK_UPPER 0x05a3
6049#define IGU_REG_SISR_MDPC_WMASK_LSB_UPPER 0x05a4
6050#define IGU_REG_SISR_MDPC_WMASK_MSB_UPPER 0x05a5
6051#define IGU_REG_SISR_MDPC_WOMASK_UPPER 0x05a6
6052
6053#define IGU_REG_RESERVED_UPPER 0x05ff
6054
6055
6056#define CDU_REGION_NUMBER_XCM_AG 2
6057#define CDU_REGION_NUMBER_UCM_AG 4
6058
6059
6060/**
6061 * String-to-compress [31:8] = CID (all 24 bits)
6062 * String-to-compress [7:4] = Region
6063 * String-to-compress [3:0] = Type
6064 */
6065#define CDU_VALID_DATA(_cid, _region, _type)\
6066 (((_cid) << 8) | (((_region)&0xf)<<4) | (((_type)&0xf)))
6067#define CDU_CRC8(_cid, _region, _type)\
6068 (calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff))
6069#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type)\
6070 (0x80 | ((CDU_CRC8(_cid, _region, _type)) & 0x7f))
6071#define CDU_RSRVD_VALUE_TYPE_B(_crc, _type)\
6072 (0x80 | ((_type)&0xf << 3) | ((CDU_CRC8(_cid, _region, _type)) & 0x7))
6073#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80)
6074
6075/******************************************************************************
6076 * Description:
6077 * Calculates crc 8 on a word value: polynomial 0-1-2-8
6078 * Code was translated from Verilog.
6079 * Return:
6080 *****************************************************************************/
6081static inline u8 calc_crc8(u32 data, u8 crc)
6082{
6083 u8 D[32];
6084 u8 NewCRC[8];
6085 u8 C[8];
6086 u8 crc_res;
6087 u8 i;
6088
6089 /* split the data into 31 bits */
6090 for (i = 0; i < 32; i++) {
6091 D[i] = (u8)(data & 1);
6092 data = data >> 1;
6093 }
6094
6095 /* split the crc into 8 bits */
6096 for (i = 0; i < 8; i++) {
6097 C[i] = crc & 1;
6098 crc = crc >> 1;
6099 }
6100
6101 NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
6102 D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
6103 C[6] ^ C[7];
6104 NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
6105 D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
6106 D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^
6107 C[6];
6108 NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
6109 D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
6110 C[0] ^ C[1] ^ C[4] ^ C[5];
6111 NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
6112 D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
6113 C[1] ^ C[2] ^ C[5] ^ C[6];
6114 NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
6115 D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
6116 C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
6117 NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
6118 D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
6119 C[3] ^ C[4] ^ C[7];
6120 NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
6121 D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
6122 C[5];
6123 NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
6124 D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
6125 C[6];
6126
6127 crc_res = 0;
6128 for (i = 0; i < 8; i++)
6129 crc_res |= (NewCRC[i] << i);
6130
6131 return crc_res;
6132}
6133
6134