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 
bnx2x_set_mcp_parity(struct bnx2x * bp,u8 enable)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 
bnx2x_parity_reg_mask(struct bnx2x * bp,int idx)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 
bnx2x_disable_blocks_parity(struct bnx2x * bp)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  */
bnx2x_clear_blocks_parity(struct bnx2x * bp)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 
bnx2x_enable_blocks_parity(struct bnx2x * bp)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 
417