aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2013-09-22 07:59:22 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-23 02:10:19 -0400
commitb6a9c1ef3d82c1efb66340a27e810bad63e046ed (patch)
tree416f607453080e672d0fad13cf5c2945474db339 /drivers/net/ethernet
parentda7add323d1e00e867e4e8ef51789acdd1d749cd (diff)
bnx2x: Generalize KR work-around
Previously, in case of KR link down, the driver would reset the PHY and restart auto negotiation only when old Warpcore microcode was used (below D108). This patch comes to generalize this by keep trying to restart KR link, regardless of Warpcore microcode, since it was found that it solves another link issue which source is a link-partner. As part of this change, the signal detect is no longer a condition to apply the work-around to cover this new case. Like before, as long as the link is down, AN will be restarted every 2 seconds. Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c32
1 files changed, 8 insertions, 24 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index d60a2ea3da19..12ef8e1a2dad 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -3715,7 +3715,6 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3715 struct link_params *params, 3715 struct link_params *params,
3716 struct link_vars *vars) { 3716 struct link_vars *vars) {
3717 u16 lane, i, cl72_ctrl, an_adv = 0; 3717 u16 lane, i, cl72_ctrl, an_adv = 0;
3718 u16 ucode_ver;
3719 struct bnx2x *bp = params->bp; 3718 struct bnx2x *bp = params->bp;
3720 static struct bnx2x_reg_set reg_set[] = { 3719 static struct bnx2x_reg_set reg_set[] = {
3721 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7}, 3720 {MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
@@ -3806,15 +3805,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3806 3805
3807 /* Advertise pause */ 3806 /* Advertise pause */
3808 bnx2x_ext_phy_set_pause(params, phy, vars); 3807 bnx2x_ext_phy_set_pause(params, phy, vars);
3809 /* Set KR Autoneg Work-Around flag for Warpcore version older than D108 3808 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3810 */
3811 bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3812 MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver);
3813 if (ucode_ver < 0xd108) {
3814 DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n",
3815 ucode_ver);
3816 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3817 }
3818 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, 3809 bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3819 MDIO_WC_REG_DIGITAL5_MISC7, 0x100); 3810 MDIO_WC_REG_DIGITAL5_MISC7, 0x100);
3820 3811
@@ -4347,20 +4338,14 @@ static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4347 struct bnx2x *bp = params->bp; 4338 struct bnx2x *bp = params->bp;
4348 u32 serdes_net_if; 4339 u32 serdes_net_if;
4349 u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0; 4340 u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4350 u16 lane = bnx2x_get_warpcore_lane(phy, params);
4351 4341
4352 vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1; 4342 vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4353 4343
4354 if (!vars->turn_to_run_wc_rt) 4344 if (!vars->turn_to_run_wc_rt)
4355 return; 4345 return;
4356 4346
4357 /* Return if there is no link partner */
4358 if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
4359 DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n");
4360 return;
4361 }
4362
4363 if (vars->rx_tx_asic_rst) { 4347 if (vars->rx_tx_asic_rst) {
4348 u16 lane = bnx2x_get_warpcore_lane(phy, params);
4364 serdes_net_if = (REG_RD(bp, params->shmem_base + 4349 serdes_net_if = (REG_RD(bp, params->shmem_base +
4365 offsetof(struct shmem_region, dev_info. 4350 offsetof(struct shmem_region, dev_info.
4366 port_hw_config[params->port].default_cfg)) & 4351 port_hw_config[params->port].default_cfg)) &
@@ -4375,14 +4360,8 @@ static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4375 /*10G KR*/ 4360 /*10G KR*/
4376 lnkup_kr = (gp_status1 >> (12+lane)) & 0x1; 4361 lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4377 4362
4378 DP(NETIF_MSG_LINK,
4379 "gp_status1 0x%x\n", gp_status1);
4380
4381 if (lnkup_kr || lnkup) { 4363 if (lnkup_kr || lnkup) {
4382 vars->rx_tx_asic_rst = 0; 4364 vars->rx_tx_asic_rst = 0;
4383 DP(NETIF_MSG_LINK,
4384 "link up, rx_tx_asic_rst 0x%x\n",
4385 vars->rx_tx_asic_rst);
4386 } else { 4365 } else {
4387 /* Reset the lane to see if link comes up.*/ 4366 /* Reset the lane to see if link comes up.*/
4388 bnx2x_warpcore_reset_lane(bp, phy, 1); 4367 bnx2x_warpcore_reset_lane(bp, phy, 1);
@@ -5757,6 +5736,11 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
5757 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed, 5736 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
5758 duplex); 5737 duplex);
5759 5738
5739 /* In case of KR link down, start up the recovering procedure */
5740 if ((!link_up) && (phy->media_type == ETH_PHY_KR) &&
5741 (!(phy->flags & FLAGS_WC_DUAL_MODE)))
5742 vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
5743
5760 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", 5744 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
5761 vars->duplex, vars->flow_ctrl, vars->link_status); 5745 vars->duplex, vars->flow_ctrl, vars->link_status);
5762 return rc; 5746 return rc;