aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h15
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c82
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c7
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h2
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
4150static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy, 4177static 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
6762static 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