]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/bnx2x/bnx2x_init.h
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / net / bnx2x / bnx2x_init.h
index a9d54874a55997f26d8808cd42d143204e4462d8..fa6dbe3f2058d799e664d47f9515b5826b55719c 100644 (file)
@@ -192,5 +192,225 @@ struct src_ent {
        u64 next;
 };
 
+/****************************************************************************
+* Parity configuration
+****************************************************************************/
+#define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2) \
+{ \
+       block##_REG_##block##_PRTY_MASK, \
+       block##_REG_##block##_PRTY_STS_CLR, \
+       en_mask, {m1, m1h, m2}, #block \
+}
+
+#define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2) \
+{ \
+       block##_REG_##block##_PRTY_MASK_0, \
+       block##_REG_##block##_PRTY_STS_CLR_0, \
+       en_mask, {m1, m1h, m2}, #block"_0" \
+}
+
+#define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2) \
+{ \
+       block##_REG_##block##_PRTY_MASK_1, \
+       block##_REG_##block##_PRTY_STS_CLR_1, \
+       en_mask, {m1, m1h, m2}, #block"_1" \
+}
+
+static const struct {
+       u32 mask_addr;
+       u32 sts_clr_addr;
+       u32 en_mask;            /* Mask to enable parity attentions */
+       struct {
+               u32 e1;         /* 57710 */
+               u32 e1h;        /* 57711 */
+               u32 e2;         /* 57712 */
+       } reg_mask;             /* Register mask (all valid bits) */
+       char name[7];           /* Block's longest name is 6 characters long
+                                * (name + suffix)
+                                */
+} bnx2x_blocks_parity_data[] = {
+       /* bit 19 masked */
+       /* REG_WR(bp, PXP_REG_PXP_PRTY_MASK, 0x80000); */
+       /* bit 5,18,20-31 */
+       /* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */
+       /* bit 5 */
+       /* REG_WR(bp, PXP2_REG_PXP2_PRTY_MASK_1, 0x20); */
+       /* REG_WR(bp, HC_REG_HC_PRTY_MASK, 0x0); */
+       /* REG_WR(bp, MISC_REG_MISC_PRTY_MASK, 0x0); */
+
+       /* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't
+        * want to handle "system kill" flow at the moment.
+        */
+       BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff),
+       BLOCK_PRTY_INFO_0(PXP2, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff),
+       BLOCK_PRTY_INFO_1(PXP2, 0x7ff, 0x7f, 0x7f, 0x7ff),
+       BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0),
+       BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff),
+       BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1),
+       BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff),
+       BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3),
+       {GRCBASE_UPB + PB_REG_PB_PRTY_MASK,
+               GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0,
+               {0xf, 0xf, 0xf}, "UPB"},
+       {GRCBASE_XPB + PB_REG_PB_PRTY_MASK,
+               GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0,
+               {0xf, 0xf, 0xf}, "XPB"},
+       BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7),
+       BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f),
+       BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf),
+       BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1),
+       BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf),
+       BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf),
+       BLOCK_PRTY_INFO(PRS, (1<<6), 0xff, 0xff, 0xff),
+       BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff),
+       BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff),
+       BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff),
+       BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff),
+       BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
+       BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f),
+       BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
+       BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f),
+       BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
+       BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f),
+       BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff),
+       BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f),
+};
+
+
+/* [28] MCP Latched rom_parity
+ * [29] MCP Latched ump_rx_parity
+ * [30] MCP Latched ump_tx_parity
+ * [31] MCP Latched scpad_parity
+ */
+#define MISC_AEU_ENABLE_MCP_PRTY_BITS  \
+       (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
+        AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
+        AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \
+        AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
+
+/* Below registers control the MCP parity attention output. When
+ * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are
+ * enabled, when cleared - disabled.
+ */
+static const u32 mcp_attn_ctl_regs[] = {
+       MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
+       MISC_REG_AEU_ENABLE4_NIG_0,
+       MISC_REG_AEU_ENABLE4_PXP_0,
+       MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
+       MISC_REG_AEU_ENABLE4_NIG_1,
+       MISC_REG_AEU_ENABLE4_PXP_1
+};
+
+static inline void bnx2x_set_mcp_parity(struct bnx2x *bp, u8 enable)
+{
+       int i;
+       u32 reg_val;
+
+       for (i = 0; i < ARRAY_SIZE(mcp_attn_ctl_regs); i++) {
+               reg_val = REG_RD(bp, mcp_attn_ctl_regs[i]);
+
+               if (enable)
+                       reg_val |= MISC_AEU_ENABLE_MCP_PRTY_BITS;
+               else
+                       reg_val &= ~MISC_AEU_ENABLE_MCP_PRTY_BITS;
+
+               REG_WR(bp, mcp_attn_ctl_regs[i], reg_val);
+       }
+}
+
+static inline u32 bnx2x_parity_reg_mask(struct bnx2x *bp, int idx)
+{
+       if (CHIP_IS_E1(bp))
+               return bnx2x_blocks_parity_data[idx].reg_mask.e1;
+       else if (CHIP_IS_E1H(bp))
+               return bnx2x_blocks_parity_data[idx].reg_mask.e1h;
+       else
+               return bnx2x_blocks_parity_data[idx].reg_mask.e2;
+}
+
+static inline void bnx2x_disable_blocks_parity(struct bnx2x *bp)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
+               u32 dis_mask = bnx2x_parity_reg_mask(bp, i);
+
+               if (dis_mask) {
+                       REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr,
+                              dis_mask);
+                       DP(NETIF_MSG_HW, "Setting parity mask "
+                                                "for %s to\t\t0x%x\n",
+                                   bnx2x_blocks_parity_data[i].name, dis_mask);
+               }
+       }
+
+       /* Disable MCP parity attentions */
+       bnx2x_set_mcp_parity(bp, false);
+}
+
+/**
+ * Clear the parity error status registers.
+ */
+static inline void bnx2x_clear_blocks_parity(struct bnx2x *bp)
+{
+       int i;
+       u32 reg_val, mcp_aeu_bits =
+               AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY |
+               AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY |
+               AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY |
+               AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY;
+
+       /* Clear SEM_FAST parities */
+       REG_WR(bp, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
+       REG_WR(bp, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
+       REG_WR(bp, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
+       REG_WR(bp, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
+
+       for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
+               u32 reg_mask = bnx2x_parity_reg_mask(bp, i);
+
+               if (reg_mask) {
+                       reg_val = REG_RD(bp, bnx2x_blocks_parity_data[i].
+                                        sts_clr_addr);
+                       if (reg_val & reg_mask)
+                               DP(NETIF_MSG_HW,
+                                           "Parity errors in %s: 0x%x\n",
+                                           bnx2x_blocks_parity_data[i].name,
+                                           reg_val & reg_mask);
+               }
+       }
+
+       /* Check if there were parity attentions in MCP */
+       reg_val = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_MCP);
+       if (reg_val & mcp_aeu_bits)
+               DP(NETIF_MSG_HW, "Parity error in MCP: 0x%x\n",
+                  reg_val & mcp_aeu_bits);
+
+       /* Clear parity attentions in MCP:
+        * [7]  clears Latched rom_parity
+        * [8]  clears Latched ump_rx_parity
+        * [9]  clears Latched ump_tx_parity
+        * [10] clears Latched scpad_parity (both ports)
+        */
+       REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780);
+}
+
+static inline void bnx2x_enable_blocks_parity(struct bnx2x *bp)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(bnx2x_blocks_parity_data); i++) {
+               u32 reg_mask = bnx2x_parity_reg_mask(bp, i);
+
+               if (reg_mask)
+                       REG_WR(bp, bnx2x_blocks_parity_data[i].mask_addr,
+                               bnx2x_blocks_parity_data[i].en_mask & reg_mask);
+       }
+
+       /* Enable MCP parity attentions */
+       bnx2x_set_mcp_parity(bp, true);
+}
+
+
 #endif /* BNX2X_INIT_H */