diff options
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_init.h')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_init.h | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index a9d54874a559..5a268e9a0895 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h | |||
@@ -192,5 +192,225 @@ struct src_ent { | |||
192 | u64 next; | 192 | u64 next; |
193 | }; | 193 | }; |
194 | 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, 0x3ffffff, 0x3ffffff, 0x3ffffff, 0x3ffffff), | ||
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 | |||
195 | #endif /* BNX2X_INIT_H */ | 415 | #endif /* BNX2X_INIT_H */ |
196 | 416 | ||