bnx2x: prevent false parity error in MSI-X memory of HC block
authorVladislav Zolotarov <vladz@broadcom.com>
Tue, 19 Oct 2010 05:13:09 +0000 (05:13 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 19 Oct 2010 15:37:37 +0000 (08:37 -0700)
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
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>
drivers/net/bnx2x/bnx2x_main.c
drivers/net/bnx2x/bnx2x_reg.h

index 3f49b551ff05b2cf14fcdc20bb0ef5714ab12223..f22e283cabef848a163dab1e43defe571178fa72 100644 (file)
@@ -5457,7 +5457,8 @@ static int bnx2x_init_hw_func(struct bnx2x *bp)
        struct bnx2x_ilt *ilt = BP_ILT(bp);
        u16 cdu_ilt_start;
        u32 addr, val;
-       int i;
+       u32 main_mem_base, main_mem_size, main_mem_prty_clr;
+       int i, main_mem_width;
 
        DP(BNX2X_MSG_MCP, "starting func init  func %d\n", func);
 
@@ -5706,6 +5707,31 @@ static int bnx2x_init_hw_func(struct bnx2x *bp)
        bnx2x_init_block(bp, MCP_BLOCK, FUNC0_STAGE + func);
        bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func);
 
+       if (CHIP_IS_E1x(bp)) {
+               main_mem_size = HC_REG_MAIN_MEMORY_SIZE / 2; /*dwords*/
+               main_mem_base = HC_REG_MAIN_MEMORY +
+                               BP_PORT(bp) * (main_mem_size * 4);
+               main_mem_prty_clr = HC_REG_HC_PRTY_STS_CLR;
+               main_mem_width = 8;
+
+               val = REG_RD(bp, main_mem_prty_clr);
+               if (val)
+                       DP(BNX2X_MSG_MCP, "Hmmm... Parity errors in HC "
+                                         "block during "
+                                         "function init (0x%x)!\n", val);
+
+               /* Clear "false" parity errors in MSI-X table */
+               for (i = main_mem_base;
+                    i < main_mem_base + main_mem_size * 4;
+                    i += main_mem_width) {
+                       bnx2x_read_dmae(bp, i, main_mem_width / 4);
+                       bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data),
+                                        i, main_mem_width / 4);
+               }
+               /* Clear HC parity attention */
+               REG_RD(bp, main_mem_prty_clr);
+       }
+
        bnx2x_phy_probe(&bp->link_params);
 
        return 0;
index 18a86284ebcc4b4b32ceb0f275c5b2792e51152d..1cefe489a9553b62ff6b8b2618efebf9b440ba4e 100644 (file)
 #define HC_REG_HC_PRTY_MASK                                     0x1080a0
 /* [R 3] Parity register #0 read */
 #define HC_REG_HC_PRTY_STS                                      0x108094
-#define HC_REG_INT_MASK                                         0x108108
+/* [RC 3] Parity register #0 read clear */
+#define HC_REG_HC_PRTY_STS_CLR                                  0x108098
+#define HC_REG_INT_MASK                                                 0x108108
 #define HC_REG_LEADING_EDGE_0                                   0x108040
 #define HC_REG_LEADING_EDGE_1                                   0x108048
+#define HC_REG_MAIN_MEMORY                                      0x108800
+#define HC_REG_MAIN_MEMORY_SIZE                                         152
 #define HC_REG_P0_PROD_CONS                                     0x108200
 #define HC_REG_P1_PROD_CONS                                     0x108400
 #define HC_REG_PBA_COMMAND                                      0x108140