Merge branch 'for-davem' of ssh://master.kernel.org/pub/scm/linux/kernel/git/linville...
[linux-2.6.git] / drivers / net / bnx2x / bnx2x_init.h
1 /* bnx2x_init.h: Broadcom Everest network driver.
2  *               Structures and macroes needed during the initialization.
3  *
4  * Copyright (c) 2007-2009 Broadcom Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation.
9  *
10  * Maintained by: Eilon Greenstein <eilong@broadcom.com>
11  * Written by: Eliezer Tamir
12  * Modified by: Vladislav Zolotarov <vladz@broadcom.com>
13  */
14
15 #ifndef BNX2X_INIT_H
16 #define BNX2X_INIT_H
17
18 /* RAM0 size in bytes */
19 #define STORM_INTMEM_SIZE_E1            0x5800
20 #define STORM_INTMEM_SIZE_E1H           0x10000
21 #define STORM_INTMEM_SIZE(bp) ((CHIP_IS_E1(bp) ? STORM_INTMEM_SIZE_E1 : \
22                                                     STORM_INTMEM_SIZE_E1H) / 4)
23
24
25 /* Init operation types and structures */
26 /* Common for both E1 and E1H */
27 #define OP_RD                   0x1 /* read single register */
28 #define OP_WR                   0x2 /* write single register */
29 #define OP_IW                   0x3 /* write single register using mailbox */
30 #define OP_SW                   0x4 /* copy a string to the device */
31 #define OP_SI                   0x5 /* copy a string using mailbox */
32 #define OP_ZR                   0x6 /* clear memory */
33 #define OP_ZP                   0x7 /* unzip then copy with DMAE */
34 #define OP_WR_64                0x8 /* write 64 bit pattern */
35 #define OP_WB                   0x9 /* copy a string using DMAE */
36
37 /* FPGA and EMUL specific operations */
38 #define OP_WR_EMUL              0xa /* write single register on Emulation */
39 #define OP_WR_FPGA              0xb /* write single register on FPGA */
40 #define OP_WR_ASIC              0xc /* write single register on ASIC */
41
42 /* Init stages */
43 /* Never reorder stages !!! */
44 #define COMMON_STAGE            0
45 #define PORT0_STAGE             1
46 #define PORT1_STAGE             2
47 #define FUNC0_STAGE             3
48 #define FUNC1_STAGE             4
49 #define FUNC2_STAGE             5
50 #define FUNC3_STAGE             6
51 #define FUNC4_STAGE             7
52 #define FUNC5_STAGE             8
53 #define FUNC6_STAGE             9
54 #define FUNC7_STAGE             10
55 #define STAGE_IDX_MAX           11
56
57 #define STAGE_START             0
58 #define STAGE_END               1
59
60
61 /* Indices of blocks */
62 #define PRS_BLOCK               0
63 #define SRCH_BLOCK              1
64 #define TSDM_BLOCK              2
65 #define TCM_BLOCK               3
66 #define BRB1_BLOCK              4
67 #define TSEM_BLOCK              5
68 #define PXPCS_BLOCK             6
69 #define EMAC0_BLOCK             7
70 #define EMAC1_BLOCK             8
71 #define DBU_BLOCK               9
72 #define MISC_BLOCK              10
73 #define DBG_BLOCK               11
74 #define NIG_BLOCK               12
75 #define MCP_BLOCK               13
76 #define UPB_BLOCK               14
77 #define CSDM_BLOCK              15
78 #define USDM_BLOCK              16
79 #define CCM_BLOCK               17
80 #define UCM_BLOCK               18
81 #define USEM_BLOCK              19
82 #define CSEM_BLOCK              20
83 #define XPB_BLOCK               21
84 #define DQ_BLOCK                22
85 #define TIMERS_BLOCK            23
86 #define XSDM_BLOCK              24
87 #define QM_BLOCK                25
88 #define PBF_BLOCK               26
89 #define XCM_BLOCK               27
90 #define XSEM_BLOCK              28
91 #define CDU_BLOCK               29
92 #define DMAE_BLOCK              30
93 #define PXP_BLOCK               31
94 #define CFC_BLOCK               32
95 #define HC_BLOCK                33
96 #define PXP2_BLOCK              34
97 #define MISC_AEU_BLOCK          35
98 #define PGLUE_B_BLOCK           36
99 #define IGU_BLOCK               37
100 #define ATC_BLOCK               38
101 #define QM_4PORT_BLOCK          39
102 #define XSEM_4PORT_BLOCK                40
103
104
105 /* Returns the index of start or end of a specific block stage in ops array*/
106 #define BLOCK_OPS_IDX(block, stage, end) \
107                         (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
108
109
110 struct raw_op {
111         u32 op:8;
112         u32 offset:24;
113         u32 raw_data;
114 };
115
116 struct op_read {
117         u32 op:8;
118         u32 offset:24;
119         u32 pad;
120 };
121
122 struct op_write {
123         u32 op:8;
124         u32 offset:24;
125         u32 val;
126 };
127
128 struct op_string_write {
129         u32 op:8;
130         u32 offset:24;
131 #ifdef __LITTLE_ENDIAN
132         u16 data_off;
133         u16 data_len;
134 #else /* __BIG_ENDIAN */
135         u16 data_len;
136         u16 data_off;
137 #endif
138 };
139
140 struct op_zero {
141         u32 op:8;
142         u32 offset:24;
143         u32 len;
144 };
145
146 union init_op {
147         struct op_read          read;
148         struct op_write         write;
149         struct op_string_write  str_wr;
150         struct op_zero          zero;
151         struct raw_op           raw;
152 };
153
154 #define INITOP_SET              0       /* set the HW directly */
155 #define INITOP_CLEAR            1       /* clear the HW directly */
156 #define INITOP_INIT             2       /* set the init-value array */
157
158 /****************************************************************************
159 * ILT management
160 ****************************************************************************/
161 struct ilt_line {
162         dma_addr_t page_mapping;
163         void *page;
164         u32 size;
165 };
166
167 struct ilt_client_info {
168         u32 page_size;
169         u16 start;
170         u16 end;
171         u16 client_num;
172         u16 flags;
173 #define ILT_CLIENT_SKIP_INIT    0x1
174 #define ILT_CLIENT_SKIP_MEM     0x2
175 };
176
177 struct bnx2x_ilt {
178         u32 start_line;
179         struct ilt_line         *lines;
180         struct ilt_client_info  clients[4];
181 #define ILT_CLIENT_CDU  0
182 #define ILT_CLIENT_QM   1
183 #define ILT_CLIENT_SRC  2
184 #define ILT_CLIENT_TM   3
185 };
186
187 /****************************************************************************
188 * SRC configuration
189 ****************************************************************************/
190 struct src_ent {
191         u8 opaque[56];
192         u64 next;
193 };
194
195 /****************************************************************************
196 * Parity configuration
197 ****************************************************************************/
198 #define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2) \
199 { \
200         block##_REG_##block##_PRTY_MASK, \
201         block##_REG_##block##_PRTY_STS_CLR, \
202         en_mask, {m1, m1h, m2}, #block \
203 }
204
205 #define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2) \
206 { \
207         block##_REG_##block##_PRTY_MASK_0, \
208         block##_REG_##block##_PRTY_STS_CLR_0, \
209         en_mask, {m1, m1h, m2}, #block"_0" \
210 }
211
212 #define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2) \
213 { \
214         block##_REG_##block##_PRTY_MASK_1, \
215         block##_REG_##block##_PRTY_STS_CLR_1, \
216         en_mask, {m1, m1h, m2}, #block"_1" \
217 }
218
219 static const struct {
220         u32 mask_addr;
221         u32 sts_clr_addr;
222         u32 en_mask;            /* Mask to enable parity attentions */
223         struct {
224                 u32 e1;         /* 57710 */
225                 u32 e1h;        /* 57711 */
226                 u32 e2;         /* 57712 */
227         } reg_mask;             /* Register mask (all valid bits) */
228         char name[7];           /* Block's longest name is 6 characters long
229                                  * (name + suffix)
230                                  */
231 } bnx2x_blocks_parity_data[] = {
232         /* bit 19 masked */
233         /* REG_WR(bp, PXP_REG_PXP_PRTY_MASK, 0x80000); */
234         /* bit 5,18,20-31 */
235         /* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */
236         /* bit 5 */
237         /* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_1, 0x20); */
238         /* REG_WR(bp, HC_REG_HC_PRTY_MASK, 0x0); */
239         /* REG_WR(bp, MISC_REG_MISC_PRTY_MASK, 0x0); */
240
241         /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't
242          * want to handle "system kill" flow at the moment.
243          */
244         BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff),
245         BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff),
246         BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff),
247         BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0),
248         BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff),
249         BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1),
250         BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff),
251         BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3),
252         {GRCBASE_UPB + PB_REG_PB_PRTY_MASK,
253                 GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0,
254                 {0xf, 0xf, 0xf}, "UPB"},
255         {GRCBASE_XPB + PB_REG_PB_PRTY_MASK,
256                 GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0,
257                 {0xf, 0xf, 0xf}, "XPB"},
258         BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7),
259         BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f),
260         BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf),
261         BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1),
262         BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf),
263         BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf),
264         BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff),
265         BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff),
266         BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff),
267         BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff),
268         BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff),
269         BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
270         BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f),
271         BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
272         BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f),
273         BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
274         BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f),
275         BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
276         BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f),
277 };
278
279
280 /* [28] MCP Latched rom_parity
281  * [29] MCP Latched ump_rx_parity
282  * [30] MCP Latched ump_tx_parity
283  * [31] MCP Latched scpad_parity
284  */
285 #define MISC_AEU_ENABLE_MCP_PRTY_BITS   \
286         (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
287          AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
288          AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \
289          AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
290
291 /* Below registers control the MCP parity attention output. When
292  * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are
293  * enabled, when cleared - disabled.
294  */
295 static const u32 mcp_attn_ctl_regs[] = {
296         MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
297         MISC_REG_AEU_ENABLE4_NIG_0,
298         MISC_REG_AEU_ENABLE4_PXP_0,
299         MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
300         MISC_REG_AEU_ENABLE4_NIG_1,
301         MISC_REG_AEU_ENABLE4_PXP_1
302 };
303
304 static inline void bnx2x_set_mcp_parity(struct bnx2x *bp, u8 enable)
305 {
306         int i;
307         u32 reg_val;
308
309         for (i = 0; i < ARRAY_SIZE(mcp_attn_ctl_regs); i++) {
310                 reg_val = REG_RD(bp, mcp_attn_ctl_regs[i]);
311
312                 if (enable)
313                         reg_val |= MISC_AEU_ENABLE_MCP_PRTY_BITS;
314                 else
315                         reg_val &= ~MISC_AEU_ENABLE_MCP_PRTY_BITS;
316
317                 REG_WR(bp, mcp_attn_ctl_regs[i], reg_val);
318         }
319 }
320
321 static inline u32 bnx2x_parity_reg_mask(struct bnx2x *bp, int idx)
322 {
323         if (CHIP_IS_E1(bp))
324                 return bnx2x_blocks_parity_data[idx].reg_mask.e1;
325         else if (CHIP_IS_E1H(bp))
326                 return bnx2x_blocks_parity_data[idx].reg_mask.e1h;
327         else
328                 return bnx2x_blocks_parity_data[idx].reg_mask.e2;
329 }
330
331 static inline void bnx2x_disable_blocks_parity(struct bnx2x *bp)
332 {
333         int i;
334
335         for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
336                 u32 dis_mask = bnx2x_parity_reg_mask(bp, i);
337
338                 if (dis_mask) {
339                         REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr,
340                                dis_mask);
341                         DP(NETIF_MSG_HW, "Setting parity mask "
342                                                  "for %s to\t\t0x%x\n",
343                                     bnx2x_blocks_parity_data[i].name, dis_mask);
344                 }
345         }
346
347         /* Disable MCP parity attentions */
348         bnx2x_set_mcp_parity(bp, false);
349 }
350
351 /**
352  * Clear the parity error status registers.
353  */
354 static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp)
355 {
356         int i;
357         u32 reg_val, mcp_aeu_bits =
358                 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY |
359                 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY |
360                 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY |
361                 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY;
362
363         /* Clear SEM_FAST parities */
364         REG_WR(bp, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
365         REG_WR(bp, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
366         REG_WR(bp, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
367         REG_WR(bp, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
368
369         for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
370                 u32 reg_mask = bnx2x_parity_reg_mask(bp, i);
371
372                 if (reg_mask) {
373                         reg_val = REG_RD(bp, bnx2x_blocks_parity_data[i].
374                                          sts_clr_addr);
375                         if (reg_val & reg_mask)
376                                 DP(NETIF_MSG_HW,
377                                             "Parity errors in %s: 0x%x\n",
378                                             bnx2x_blocks_parity_data[i].name,
379                                             reg_val & reg_mask);
380                 }
381         }
382
383         /* Check if there were parity attentions in MCP */
384         reg_val = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_MCP);
385         if (reg_val & mcp_aeu_bits)
386                 DP(NETIF_MSG_HW, "Parity error in MCP: 0x%x\n",
387                    reg_val & mcp_aeu_bits);
388
389         /* Clear parity attentions in MCP:
390          * [7]  clears Latched rom_parity
391          * [8]  clears Latched ump_rx_parity
392          * [9]  clears Latched ump_tx_parity
393          * [10] clears Latched scpad_parity (both ports)
394          */
395         REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780);
396 }
397
398 static inline void bnx2x_enable_blocks_parity(struct bnx2x *bp)
399 {
400         int i;
401
402         for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
403                 u32 reg_mask = bnx2x_parity_reg_mask(bp, i);
404
405                 if (reg_mask)
406                         REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr,
407                                 bnx2x_blocks_parity_data[i].en_mask & reg_mask);
408         }
409
410         /* Enable MCP parity attentions */
411         bnx2x_set_mcp_parity(bp, true);
412 }
413
414
415 #endif /* BNX2X_INIT_H */
416