aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_main.c
diff options
context:
space:
mode:
authorVladislav Zolotarov <vladz@broadcom.com>2011-07-21 03:58:36 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-21 15:33:56 -0400
commit8736c82650500222c031dd7f59f0126e59808e36 (patch)
tree408084aee5546fbb65e3343fbb2ab146dbc50315 /drivers/net/bnx2x/bnx2x_main.c
parentc03bd39c564f4b5d7683514e9249986e1404940d (diff)
bnx2x: Parity errors recovery for 578xx
Fix the parity errors recovery flow for 578xx: - Add a separate column for the 578xx in the parity mask registers DB. - Fix the bnx2x_process_kill_chip_reset() to handle the blocks newly introduced in the 578xx. Cover ATC and PGLUE_B blocks for 57712 and 578xx. 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>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c119
1 files changed, 94 insertions, 25 deletions
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 6ee9fc8d8e77..e1ec1a302474 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -3817,6 +3817,10 @@ static inline int bnx2x_check_blocks_with_parity1(u32 sig, int par_num,
3817 if (print) 3817 if (print)
3818 _print_next_block(par_num++, "USDM"); 3818 _print_next_block(par_num++, "USDM");
3819 break; 3819 break;
3820 case AEU_INPUTS_ATTN_BITS_UCM_PARITY_ERROR:
3821 if (print)
3822 _print_next_block(par_num++, "UCM");
3823 break;
3820 case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR: 3824 case AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR:
3821 if (print) 3825 if (print)
3822 _print_next_block(par_num++, "USEMI"); 3826 _print_next_block(par_num++, "USEMI");
@@ -3829,6 +3833,10 @@ static inline int bnx2x_check_blocks_with_parity1(u32 sig, int par_num,
3829 if (print) 3833 if (print)
3830 _print_next_block(par_num++, "CSDM"); 3834 _print_next_block(par_num++, "CSDM");
3831 break; 3835 break;
3836 case AEU_INPUTS_ATTN_BITS_CCM_PARITY_ERROR:
3837 if (print)
3838 _print_next_block(par_num++, "CCM");
3839 break;
3832 } 3840 }
3833 3841
3834 /* Clear the bit */ 3842 /* Clear the bit */
@@ -3933,32 +3941,67 @@ static inline int bnx2x_check_blocks_with_parity3(u32 sig, int par_num,
3933 return par_num; 3941 return par_num;
3934} 3942}
3935 3943
3944static inline int bnx2x_check_blocks_with_parity4(u32 sig, int par_num,
3945 bool print)
3946{
3947 int i = 0;
3948 u32 cur_bit = 0;
3949 for (i = 0; sig; i++) {
3950 cur_bit = ((u32)0x1 << i);
3951 if (sig & cur_bit) {
3952 switch (cur_bit) {
3953 case AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR:
3954 if (print)
3955 _print_next_block(par_num++, "PGLUE_B");
3956 break;
3957 case AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR:
3958 if (print)
3959 _print_next_block(par_num++, "ATC");
3960 break;
3961 }
3962
3963 /* Clear the bit */
3964 sig &= ~cur_bit;
3965 }
3966 }
3967
3968 return par_num;
3969}
3970
3936static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, 3971static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
3937 u32 sig0, u32 sig1, u32 sig2, u32 sig3) 3972 u32 *sig)
3938{ 3973{
3939 if ((sig0 & HW_PRTY_ASSERT_SET_0) || (sig1 & HW_PRTY_ASSERT_SET_1) || 3974 if ((sig[0] & HW_PRTY_ASSERT_SET_0) ||
3940 (sig2 & HW_PRTY_ASSERT_SET_2) || (sig3 & HW_PRTY_ASSERT_SET_3)) { 3975 (sig[1] & HW_PRTY_ASSERT_SET_1) ||
3976 (sig[2] & HW_PRTY_ASSERT_SET_2) ||
3977 (sig[3] & HW_PRTY_ASSERT_SET_3) ||
3978 (sig[4] & HW_PRTY_ASSERT_SET_4)) {
3941 int par_num = 0; 3979 int par_num = 0;
3942 DP(NETIF_MSG_HW, "Was parity error: HW block parity attention: " 3980 DP(NETIF_MSG_HW, "Was parity error: HW block parity attention: "
3943 "[0]:0x%08x [1]:0x%08x " 3981 "[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x "
3944 "[2]:0x%08x [3]:0x%08x\n", 3982 "[4]:0x%08x\n",
3945 sig0 & HW_PRTY_ASSERT_SET_0, 3983 sig[0] & HW_PRTY_ASSERT_SET_0,
3946 sig1 & HW_PRTY_ASSERT_SET_1, 3984 sig[1] & HW_PRTY_ASSERT_SET_1,
3947 sig2 & HW_PRTY_ASSERT_SET_2, 3985 sig[2] & HW_PRTY_ASSERT_SET_2,
3948 sig3 & HW_PRTY_ASSERT_SET_3); 3986 sig[3] & HW_PRTY_ASSERT_SET_3,
3987 sig[4] & HW_PRTY_ASSERT_SET_4);
3949 if (print) 3988 if (print)
3950 netdev_err(bp->dev, 3989 netdev_err(bp->dev,
3951 "Parity errors detected in blocks: "); 3990 "Parity errors detected in blocks: ");
3952 par_num = bnx2x_check_blocks_with_parity0( 3991 par_num = bnx2x_check_blocks_with_parity0(
3953 sig0 & HW_PRTY_ASSERT_SET_0, par_num, print); 3992 sig[0] & HW_PRTY_ASSERT_SET_0, par_num, print);
3954 par_num = bnx2x_check_blocks_with_parity1( 3993 par_num = bnx2x_check_blocks_with_parity1(
3955 sig1 & HW_PRTY_ASSERT_SET_1, par_num, global, print); 3994 sig[1] & HW_PRTY_ASSERT_SET_1, par_num, global, print);
3956 par_num = bnx2x_check_blocks_with_parity2( 3995 par_num = bnx2x_check_blocks_with_parity2(
3957 sig2 & HW_PRTY_ASSERT_SET_2, par_num, print); 3996 sig[2] & HW_PRTY_ASSERT_SET_2, par_num, print);
3958 par_num = bnx2x_check_blocks_with_parity3( 3997 par_num = bnx2x_check_blocks_with_parity3(
3959 sig3 & HW_PRTY_ASSERT_SET_3, par_num, global, print); 3998 sig[3] & HW_PRTY_ASSERT_SET_3, par_num, global, print);
3999 par_num = bnx2x_check_blocks_with_parity4(
4000 sig[4] & HW_PRTY_ASSERT_SET_4, par_num, print);
4001
3960 if (print) 4002 if (print)
3961 pr_cont("\n"); 4003 pr_cont("\n");
4004
3962 return true; 4005 return true;
3963 } else 4006 } else
3964 return false; 4007 return false;
@@ -3973,7 +4016,7 @@ static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print,
3973 */ 4016 */
3974bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print) 4017bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print)
3975{ 4018{
3976 struct attn_route attn; 4019 struct attn_route attn = { {0} };
3977 int port = BP_PORT(bp); 4020 int port = BP_PORT(bp);
3978 4021
3979 attn.sig[0] = REG_RD(bp, 4022 attn.sig[0] = REG_RD(bp,
@@ -3989,8 +4032,12 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print)
3989 MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + 4032 MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 +
3990 port*4); 4033 port*4);
3991 4034
3992 return bnx2x_parity_attn(bp, global, print, attn.sig[0], attn.sig[1], 4035 if (!CHIP_IS_E1x(bp))
3993 attn.sig[2], attn.sig[3]); 4036 attn.sig[4] = REG_RD(bp,
4037 MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 +
4038 port*4);
4039
4040 return bnx2x_parity_attn(bp, global, print, attn.sig);
3994} 4041}
3995 4042
3996 4043
@@ -7932,7 +7979,7 @@ static void bnx2x_pxp_prep(struct bnx2x *bp)
7932static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) 7979static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global)
7933{ 7980{
7934 u32 not_reset_mask1, reset_mask1, not_reset_mask2, reset_mask2; 7981 u32 not_reset_mask1, reset_mask1, not_reset_mask2, reset_mask2;
7935 u32 global_bits2; 7982 u32 global_bits2, stay_reset2;
7936 7983
7937 /* 7984 /*
7938 * Bits that have to be set in reset_mask2 if we want to reset 'global' 7985 * Bits that have to be set in reset_mask2 if we want to reset 'global'
@@ -7942,6 +7989,7 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global)
7942 MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CPU | 7989 MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CPU |
7943 MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CORE; 7990 MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_CMN_CORE;
7944 7991
7992 /* Don't reset the following blocks */
7945 not_reset_mask1 = 7993 not_reset_mask1 =
7946 MISC_REGISTERS_RESET_REG_1_RST_HC | 7994 MISC_REGISTERS_RESET_REG_1_RST_HC |
7947 MISC_REGISTERS_RESET_REG_1_RST_PXPV | 7995 MISC_REGISTERS_RESET_REG_1_RST_PXPV |
@@ -7955,19 +8003,35 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global)
7955 MISC_REGISTERS_RESET_REG_2_RST_RBCN | 8003 MISC_REGISTERS_RESET_REG_2_RST_RBCN |
7956 MISC_REGISTERS_RESET_REG_2_RST_GRC | 8004 MISC_REGISTERS_RESET_REG_2_RST_GRC |
7957 MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE | 8005 MISC_REGISTERS_RESET_REG_2_RST_MCP_N_RESET_REG_HARD_CORE |
7958 MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B; 8006 MISC_REGISTERS_RESET_REG_2_RST_MCP_N_HARD_CORE_RST_B |
8007 MISC_REGISTERS_RESET_REG_2_RST_ATC |
8008 MISC_REGISTERS_RESET_REG_2_PGLC;
7959 8009
8010 /*
8011 * Keep the following blocks in reset:
8012 * - all xxMACs are handled by the bnx2x_link code.
8013 */
8014 stay_reset2 =
8015 MISC_REGISTERS_RESET_REG_2_RST_BMAC0 |
8016 MISC_REGISTERS_RESET_REG_2_RST_BMAC1 |
8017 MISC_REGISTERS_RESET_REG_2_RST_EMAC0 |
8018 MISC_REGISTERS_RESET_REG_2_RST_EMAC1 |
8019 MISC_REGISTERS_RESET_REG_2_UMAC0 |
8020 MISC_REGISTERS_RESET_REG_2_UMAC1 |
8021 MISC_REGISTERS_RESET_REG_2_XMAC |
8022 MISC_REGISTERS_RESET_REG_2_XMAC_SOFT;
8023
8024 /* Full reset masks according to the chip */
7960 reset_mask1 = 0xffffffff; 8025 reset_mask1 = 0xffffffff;
7961 8026
7962 if (CHIP_IS_E1(bp)) 8027 if (CHIP_IS_E1(bp))
7963 reset_mask2 = 0xffff; 8028 reset_mask2 = 0xffff;
7964 else 8029 else if (CHIP_IS_E1H(bp))
7965 reset_mask2 = 0x1ffff; 8030 reset_mask2 = 0x1ffff;
7966 8031 else if (CHIP_IS_E2(bp))
7967 if (CHIP_IS_E3(bp)) { 8032 reset_mask2 = 0xfffff;
7968 reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT0; 8033 else /* CHIP_IS_E3 */
7969 reset_mask2 |= MISC_REGISTERS_RESET_REG_2_MSTAT1; 8034 reset_mask2 = 0x3ffffff;
7970 }
7971 8035
7972 /* Don't reset global blocks unless we need to */ 8036 /* Don't reset global blocks unless we need to */
7973 if (!global) 8037 if (!global)
@@ -7996,7 +8060,12 @@ static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global)
7996 barrier(); 8060 barrier();
7997 mmiowb(); 8061 mmiowb();
7998 8062
7999 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, reset_mask2); 8063 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
8064 reset_mask2 & (~stay_reset2));
8065
8066 barrier();
8067 mmiowb();
8068
8000 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1); 8069 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, reset_mask1);
8001 mmiowb(); 8070 mmiowb();
8002} 8071}