diff options
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 82 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 7 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 2 |
4 files changed, 89 insertions, 17 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 583591d52497..058bc7328220 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | |||
@@ -521,6 +521,17 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ | |||
521 | */ | 521 | */ |
522 | #define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000 | 522 | #define PORT_HW_CFG_TX_DRV_BROADCAST_MASK 0x000F0000 |
523 | #define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16 | 523 | #define PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT 16 |
524 | /* Set non-default values for TXFIR in SFP mode. */ | ||
525 | #define PORT_HW_CFG_TX_DRV_IFIR_MASK 0x00F00000 | ||
526 | #define PORT_HW_CFG_TX_DRV_IFIR_SHIFT 20 | ||
527 | |||
528 | /* Set non-default values for IPREDRIVER in SFP mode. */ | ||
529 | #define PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK 0x0F000000 | ||
530 | #define PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT 24 | ||
531 | |||
532 | /* Set non-default values for POST2 in SFP mode. */ | ||
533 | #define PORT_HW_CFG_TX_DRV_POST2_MASK 0xF0000000 | ||
534 | #define PORT_HW_CFG_TX_DRV_POST2_SHIFT 28 | ||
524 | 535 | ||
525 | u32 reserved0[5]; /* 0x17c */ | 536 | u32 reserved0[5]; /* 0x17c */ |
526 | 537 | ||
@@ -2247,8 +2258,8 @@ struct shmem2_region { | |||
2247 | #define LINK_SFP_EEPROM_COMP_CODE_LRM 0x00004000 | 2258 | #define LINK_SFP_EEPROM_COMP_CODE_LRM 0x00004000 |
2248 | 2259 | ||
2249 | u32 reserved5[2]; | 2260 | u32 reserved5[2]; |
2250 | u32 reserved6[PORT_MAX]; | 2261 | u32 link_change_count[PORT_MAX]; /* Offset 0x160-0x164 */ |
2251 | 2262 | #define LINK_CHANGE_COUNT_MASK 0xff /* Offset 0x168 */ | |
2252 | /* driver version for each personality */ | 2263 | /* driver version for each personality */ |
2253 | struct os_drv_ver func_os_drv_ver[E2_FUNC_MAX]; /* Offset 0x16c */ | 2264 | struct os_drv_ver func_os_drv_ver[E2_FUNC_MAX]; /* Offset 0x16c */ |
2254 | 2265 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index b7c77b26a8a4..21a0d6afca4a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -195,6 +195,10 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy, | |||
195 | 195 | ||
196 | #define MAX_PACKET_SIZE (9700) | 196 | #define MAX_PACKET_SIZE (9700) |
197 | #define MAX_KR_LINK_RETRY 4 | 197 | #define MAX_KR_LINK_RETRY 4 |
198 | #define DEFAULT_TX_DRV_BRDCT 2 | ||
199 | #define DEFAULT_TX_DRV_IFIR 0 | ||
200 | #define DEFAULT_TX_DRV_POST2 3 | ||
201 | #define DEFAULT_TX_DRV_IPRE_DRIVER 6 | ||
198 | 202 | ||
199 | /**********************************************************/ | 203 | /**********************************************************/ |
200 | /* INTERFACE */ | 204 | /* INTERFACE */ |
@@ -3595,10 +3599,11 @@ static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, | |||
3595 | * init configuration, and set/clear SGMII flag. Internal | 3599 | * init configuration, and set/clear SGMII flag. Internal |
3596 | * phy init is done purely in phy_init stage. | 3600 | * phy init is done purely in phy_init stage. |
3597 | */ | 3601 | */ |
3598 | #define WC_TX_DRIVER(post2, idriver, ipre) \ | 3602 | #define WC_TX_DRIVER(post2, idriver, ipre, ifir) \ |
3599 | ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \ | 3603 | ((post2 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) | \ |
3600 | (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \ | 3604 | (idriver << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) | \ |
3601 | (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)) | 3605 | (ipre << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET) | \ |
3606 | (ifir << MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET)) | ||
3602 | 3607 | ||
3603 | #define WC_TX_FIR(post, main, pre) \ | 3608 | #define WC_TX_FIR(post, main, pre) \ |
3604 | ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \ | 3609 | ((post << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) | \ |
@@ -3765,12 +3770,12 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, | |||
3765 | lane = bnx2x_get_warpcore_lane(phy, params); | 3770 | lane = bnx2x_get_warpcore_lane(phy, params); |
3766 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 3771 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
3767 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, | 3772 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, |
3768 | WC_TX_DRIVER(0x02, 0x06, 0x09)); | 3773 | WC_TX_DRIVER(0x02, 0x06, 0x09, 0)); |
3769 | /* Configure the next lane if dual mode */ | 3774 | /* Configure the next lane if dual mode */ |
3770 | if (phy->flags & FLAGS_WC_DUAL_MODE) | 3775 | if (phy->flags & FLAGS_WC_DUAL_MODE) |
3771 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 3776 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
3772 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1), | 3777 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*(lane+1), |
3773 | WC_TX_DRIVER(0x02, 0x06, 0x09)); | 3778 | WC_TX_DRIVER(0x02, 0x06, 0x09, 0)); |
3774 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 3779 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
3775 | MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, | 3780 | MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL, |
3776 | 0x03f0); | 3781 | 0x03f0); |
@@ -3933,6 +3938,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, | |||
3933 | struct bnx2x *bp = params->bp; | 3938 | struct bnx2x *bp = params->bp; |
3934 | u16 misc1_val, tap_val, tx_driver_val, lane, val; | 3939 | u16 misc1_val, tap_val, tx_driver_val, lane, val; |
3935 | u32 cfg_tap_val, tx_drv_brdct, tx_equal; | 3940 | u32 cfg_tap_val, tx_drv_brdct, tx_equal; |
3941 | u32 ifir_val, ipost2_val, ipre_driver_val; | ||
3936 | 3942 | ||
3937 | /* Hold rxSeqStart */ | 3943 | /* Hold rxSeqStart */ |
3938 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, | 3944 | bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, |
@@ -3978,7 +3984,7 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, | |||
3978 | if (is_xfi) { | 3984 | if (is_xfi) { |
3979 | misc1_val |= 0x5; | 3985 | misc1_val |= 0x5; |
3980 | tap_val = WC_TX_FIR(0x08, 0x37, 0x00); | 3986 | tap_val = WC_TX_FIR(0x08, 0x37, 0x00); |
3981 | tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03); | 3987 | tx_driver_val = WC_TX_DRIVER(0x00, 0x02, 0x03, 0); |
3982 | } else { | 3988 | } else { |
3983 | cfg_tap_val = REG_RD(bp, params->shmem_base + | 3989 | cfg_tap_val = REG_RD(bp, params->shmem_base + |
3984 | offsetof(struct shmem_region, dev_info. | 3990 | offsetof(struct shmem_region, dev_info. |
@@ -3987,10 +3993,6 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, | |||
3987 | 3993 | ||
3988 | tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK; | 3994 | tx_equal = cfg_tap_val & PORT_HW_CFG_TX_EQUALIZATION_MASK; |
3989 | 3995 | ||
3990 | tx_drv_brdct = (cfg_tap_val & | ||
3991 | PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >> | ||
3992 | PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT; | ||
3993 | |||
3994 | misc1_val |= 0x9; | 3996 | misc1_val |= 0x9; |
3995 | 3997 | ||
3996 | /* TAP values are controlled by nvram, if value there isn't 0 */ | 3998 | /* TAP values are controlled by nvram, if value there isn't 0 */ |
@@ -3999,11 +4001,36 @@ static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy, | |||
3999 | else | 4001 | else |
4000 | tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02); | 4002 | tap_val = WC_TX_FIR(0x0f, 0x2b, 0x02); |
4001 | 4003 | ||
4002 | if (tx_drv_brdct) | 4004 | ifir_val = DEFAULT_TX_DRV_IFIR; |
4003 | tx_driver_val = WC_TX_DRIVER(0x03, (u16)tx_drv_brdct, | 4005 | ipost2_val = DEFAULT_TX_DRV_POST2; |
4004 | 0x06); | 4006 | ipre_driver_val = DEFAULT_TX_DRV_IPRE_DRIVER; |
4005 | else | 4007 | tx_drv_brdct = DEFAULT_TX_DRV_BRDCT; |
4006 | tx_driver_val = WC_TX_DRIVER(0x03, 0x02, 0x06); | 4008 | |
4009 | /* If any of the IFIR/IPRE_DRIVER/POST@ is set, apply all | ||
4010 | * configuration. | ||
4011 | */ | ||
4012 | if (cfg_tap_val & (PORT_HW_CFG_TX_DRV_IFIR_MASK | | ||
4013 | PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK | | ||
4014 | PORT_HW_CFG_TX_DRV_POST2_MASK)) { | ||
4015 | ifir_val = (cfg_tap_val & | ||
4016 | PORT_HW_CFG_TX_DRV_IFIR_MASK) >> | ||
4017 | PORT_HW_CFG_TX_DRV_IFIR_SHIFT; | ||
4018 | ipre_driver_val = (cfg_tap_val & | ||
4019 | PORT_HW_CFG_TX_DRV_IPREDRIVER_MASK) | ||
4020 | >> PORT_HW_CFG_TX_DRV_IPREDRIVER_SHIFT; | ||
4021 | ipost2_val = (cfg_tap_val & | ||
4022 | PORT_HW_CFG_TX_DRV_POST2_MASK) >> | ||
4023 | PORT_HW_CFG_TX_DRV_POST2_SHIFT; | ||
4024 | } | ||
4025 | |||
4026 | if (cfg_tap_val & PORT_HW_CFG_TX_DRV_BROADCAST_MASK) { | ||
4027 | tx_drv_brdct = (cfg_tap_val & | ||
4028 | PORT_HW_CFG_TX_DRV_BROADCAST_MASK) >> | ||
4029 | PORT_HW_CFG_TX_DRV_BROADCAST_SHIFT; | ||
4030 | } | ||
4031 | |||
4032 | tx_driver_val = WC_TX_DRIVER(ipost2_val, tx_drv_brdct, | ||
4033 | ipre_driver_val, ifir_val); | ||
4007 | } | 4034 | } |
4008 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 4035 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
4009 | MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); | 4036 | MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val); |
@@ -4144,7 +4171,7 @@ static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp, | |||
4144 | MDIO_WC_REG_TX_FIR_TAP_ENABLE)); | 4171 | MDIO_WC_REG_TX_FIR_TAP_ENABLE)); |
4145 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, | 4172 | bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, |
4146 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, | 4173 | MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, |
4147 | WC_TX_DRIVER(0x02, 0x02, 0x02)); | 4174 | WC_TX_DRIVER(0x02, 0x02, 0x02, 0)); |
4148 | } | 4175 | } |
4149 | 4176 | ||
4150 | static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, | 4177 | static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, |
@@ -6731,6 +6758,25 @@ static int bnx2x_update_link_up(struct link_params *params, | |||
6731 | msleep(20); | 6758 | msleep(20); |
6732 | return rc; | 6759 | return rc; |
6733 | } | 6760 | } |
6761 | |||
6762 | static void bnx2x_chng_link_count(struct link_params *params, bool clear) | ||
6763 | { | ||
6764 | struct bnx2x *bp = params->bp; | ||
6765 | u32 addr, val; | ||
6766 | |||
6767 | /* Verify the link_change_count is supported by the MFW */ | ||
6768 | if (!(SHMEM2_HAS(bp, link_change_count))) | ||
6769 | return; | ||
6770 | |||
6771 | addr = params->shmem2_base + | ||
6772 | offsetof(struct shmem2_region, link_change_count[params->port]); | ||
6773 | if (clear) | ||
6774 | val = 0; | ||
6775 | else | ||
6776 | val = REG_RD(bp, addr) + 1; | ||
6777 | REG_WR(bp, addr, val); | ||
6778 | } | ||
6779 | |||
6734 | /* The bnx2x_link_update function should be called upon link | 6780 | /* The bnx2x_link_update function should be called upon link |
6735 | * interrupt. | 6781 | * interrupt. |
6736 | * Link is considered up as follows: | 6782 | * Link is considered up as follows: |
@@ -6749,6 +6795,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
6749 | struct link_vars phy_vars[MAX_PHYS]; | 6795 | struct link_vars phy_vars[MAX_PHYS]; |
6750 | u8 port = params->port; | 6796 | u8 port = params->port; |
6751 | u8 link_10g_plus, phy_index; | 6797 | u8 link_10g_plus, phy_index; |
6798 | u32 prev_link_status = vars->link_status; | ||
6752 | u8 ext_phy_link_up = 0, cur_link_up; | 6799 | u8 ext_phy_link_up = 0, cur_link_up; |
6753 | int rc = 0; | 6800 | int rc = 0; |
6754 | u8 is_mi_int = 0; | 6801 | u8 is_mi_int = 0; |
@@ -6988,6 +7035,9 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
6988 | else | 7035 | else |
6989 | rc = bnx2x_update_link_down(params, vars); | 7036 | rc = bnx2x_update_link_down(params, vars); |
6990 | 7037 | ||
7038 | if ((prev_link_status ^ vars->link_status) & LINK_STATUS_LINK_UP) | ||
7039 | bnx2x_chng_link_count(params, false); | ||
7040 | |||
6991 | /* Update MCP link status was changed */ | 7041 | /* Update MCP link status was changed */ |
6992 | if (params->feature_config_flags & FEATURE_CONFIG_BC_SUPPORTS_AFEX) | 7042 | if (params->feature_config_flags & FEATURE_CONFIG_BC_SUPPORTS_AFEX) |
6993 | bnx2x_fw_command(bp, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0); | 7043 | bnx2x_fw_command(bp, DRV_MSG_CODE_LINK_STATUS_CHANGED, 0); |
@@ -12631,6 +12681,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) | |||
12631 | params->link_flags = PHY_INITIALIZED; | 12681 | params->link_flags = PHY_INITIALIZED; |
12632 | /* Driver opens NIG-BRB filters */ | 12682 | /* Driver opens NIG-BRB filters */ |
12633 | bnx2x_set_rx_filter(params, 1); | 12683 | bnx2x_set_rx_filter(params, 1); |
12684 | bnx2x_chng_link_count(params, true); | ||
12634 | /* Check if link flap can be avoided */ | 12685 | /* Check if link flap can be avoided */ |
12635 | lfa_status = bnx2x_check_lfa(params); | 12686 | lfa_status = bnx2x_check_lfa(params); |
12636 | 12687 | ||
@@ -12705,6 +12756,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
12705 | DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); | 12756 | DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); |
12706 | /* Disable attentions */ | 12757 | /* Disable attentions */ |
12707 | vars->link_status = 0; | 12758 | vars->link_status = 0; |
12759 | bnx2x_chng_link_count(params, true); | ||
12708 | bnx2x_update_mng(params, vars->link_status); | 12760 | bnx2x_update_mng(params, vars->link_status); |
12709 | vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | | 12761 | vars->eee_status &= ~(SHMEM_EEE_LP_ADV_STATUS_MASK | |
12710 | SHMEM_EEE_ACTIVE_BIT); | 12762 | SHMEM_EEE_ACTIVE_BIT); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 8120d266e068..768dfb16bc80 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -11650,6 +11650,13 @@ static int bnx2x_get_hwinfo(struct bnx2x *bp) | |||
11650 | u32 val = 0, val2 = 0; | 11650 | u32 val = 0, val2 = 0; |
11651 | int rc = 0; | 11651 | int rc = 0; |
11652 | 11652 | ||
11653 | /* Validate that chip access is feasible */ | ||
11654 | if (REG_RD(bp, MISC_REG_CHIP_NUM) == 0xffffffff) { | ||
11655 | dev_err(&bp->pdev->dev, | ||
11656 | "Chip read returns all Fs. Preventing probe from continuing\n"); | ||
11657 | return -EINVAL; | ||
11658 | } | ||
11659 | |||
11653 | bnx2x_get_common_hwinfo(bp); | 11660 | bnx2x_get_common_hwinfo(bp); |
11654 | 11661 | ||
11655 | /* | 11662 | /* |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 0770e4bff89b..49d511092c82 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | |||
@@ -7341,6 +7341,8 @@ Theotherbitsarereservedandshouldbezero*/ | |||
7341 | #define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081 | 7341 | #define MDIO_WC_REG_TX2_ANA_CTRL0 0x8081 |
7342 | #define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091 | 7342 | #define MDIO_WC_REG_TX3_ANA_CTRL0 0x8091 |
7343 | #define MDIO_WC_REG_TX0_TX_DRIVER 0x8067 | 7343 | #define MDIO_WC_REG_TX0_TX_DRIVER 0x8067 |
7344 | #define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_OFFSET 0x01 | ||
7345 | #define MDIO_WC_REG_TX0_TX_DRIVER_IFIR_MASK 0x000e | ||
7344 | #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04 | 7346 | #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET 0x04 |
7345 | #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0 | 7347 | #define MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_MASK 0x00f0 |
7346 | #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08 | 7348 | #define MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET 0x08 |