diff options
author | Vladislav Zolotarov <vladz@broadcom.com> | 2011-07-21 03:58:36 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-21 15:33:56 -0400 |
commit | 8736c82650500222c031dd7f59f0126e59808e36 (patch) | |
tree | 408084aee5546fbb65e3343fbb2ab146dbc50315 /drivers/net/bnx2x/bnx2x_main.c | |
parent | c03bd39c564f4b5d7683514e9249986e1404940d (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.c | 119 |
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 | ||
3944 | static 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 | |||
3936 | static inline bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, | 3971 | static 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 | */ |
3974 | bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print) | 4017 | bool 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) | |||
7932 | static void bnx2x_process_kill_chip_reset(struct bnx2x *bp, bool global) | 7979 | static 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 | } |