From patchwork Thu Oct 27 15:09:46 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yaniv Rosner X-Patchwork-Id: 122150 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9043C100AB7 for ; Fri, 28 Oct 2011 00:10:19 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752969Ab1J0NKI (ORCPT ); Thu, 27 Oct 2011 09:10:08 -0400 Received: from mms3.broadcom.com ([216.31.210.19]:3254 "EHLO MMS3.broadcom.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752822Ab1J0NKF (ORCPT ); Thu, 27 Oct 2011 09:10:05 -0400 Received: from [10.9.200.131] by MMS3.broadcom.com with ESMTP (Broadcom SMTP Relay (Email Firewall v6.3.2)); Thu, 27 Oct 2011 06:16:30 -0700 X-Server-Uuid: B55A25B1-5D7D-41F8-BC53-C57E7AD3C201 Received: from mail-irva-13.broadcom.com (10.11.16.103) by IRVEXCHHUB01.corp.ad.broadcom.com (10.9.200.131) with Microsoft SMTP Server id 8.2.247.2; Thu, 27 Oct 2011 06:09:55 -0700 Received: from lb-tlvb-yanivr.il.broadcom.com ( lb-tlvb-yanivr.il.broadcom.com [10.185.7.25]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id ECCE7BC394; Thu, 27 Oct 2011 06:09:53 -0700 (PDT) From: "Yaniv Rosner" To: "David Miller" cc: netdev , "Yaniv Rosner" , "Eilon Greenstein" Subject: [net v2 2/7] bnx2x: Add link retry to 578xx-KR Date: Thu, 27 Oct 2011 17:09:46 +0200 Message-ID: <1319728191-24938-3-git-send-email-yanivr@broadcom.com> X-Mailer: git-send-email 1.7.7.1 In-Reply-To: <1319728191-24938-1-git-send-email-yanivr@broadcom.com> References: <1319728191-24938-1-git-send-email-yanivr@broadcom.com> MIME-Version: 1.0 X-WSS-ID: 62B786240EG5295624-01-01 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This fix solves a problem of no link on 578xx-KR by retrying to link up to four timer using the periodic function. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 117 +++++++++++++++++++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | 3 + 2 files changed, 104 insertions(+), 16 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index edc9259..a47db9d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -261,6 +261,7 @@ #define MAX_PACKET_SIZE (9700) #define WC_UC_TIMEOUT 100 +#define MAX_KR_LINK_RETRY 4 /**********************************************************/ /* INTERFACE */ @@ -3578,6 +3579,11 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, u16 val16 = 0, lane, bam37 = 0; struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n"); + + /* Disable Autoneg: re-enable it after adv is done. */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0); + /* Check adding advertisement for 1G KX */ if (((vars->line_speed == SPEED_AUTO_NEG) && (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || @@ -3619,9 +3625,6 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL, 0x03f0); - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, - 0x383f); /* Advertised speeds */ bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, @@ -3648,19 +3651,22 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy, /* Advertise pause */ bnx2x_ext_phy_set_pause(params, phy, vars); - /* Enable Autoneg */ - bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, - MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000); - - /* Over 1G - AN local device user page 1 */ - bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, - MDIO_WC_REG_DIGITAL3_UP1, 0x1f); + vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY; bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, &val16); bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100); + + /* Over 1G - AN local device user page 1 */ + bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD, + MDIO_WC_REG_DIGITAL3_UP1, 0x1f); + + /* Enable Autoneg */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000); + } static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy, @@ -4129,6 +4135,85 @@ static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy, else return 0; } +static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy, + struct link_params *params) +{ + u16 gp2_status_reg0, lane; + struct bnx2x *bp = params->bp; + + lane = bnx2x_get_warpcore_lane(phy, params); + + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0, + &gp2_status_reg0); + + return (gp2_status_reg0 >> (8+lane)) & 0x1; +} + +static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u32 serdes_net_if; + u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0; + u16 lane = bnx2x_get_warpcore_lane(phy, params); + + vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1; + + if (!vars->turn_to_run_wc_rt) + return; + + /* return if there is no link partner */ + if (!(bnx2x_warpcore_get_sigdet(phy, params))) { + DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n"); + return; + } + + if (vars->rx_tx_asic_rst) { + serdes_net_if = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].default_cfg)) & + PORT_HW_CFG_NET_SERDES_IF_MASK); + + switch (serdes_net_if) { + case PORT_HW_CFG_NET_SERDES_IF_KR: + /* Do we get link yet? */ + bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1, + &gp_status1); + lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */ + /*10G KR*/ + lnkup_kr = (gp_status1 >> (12+lane)) & 0x1; + + DP(NETIF_MSG_LINK, + "gp_status1 0x%x\n", gp_status1); + + if (lnkup_kr || lnkup) { + vars->rx_tx_asic_rst = 0; + DP(NETIF_MSG_LINK, + "link up, rx_tx_asic_rst 0x%x\n", + vars->rx_tx_asic_rst); + } else { + /*reset the lane to see if link comes up.*/ + bnx2x_warpcore_reset_lane(bp, phy, 1); + bnx2x_warpcore_reset_lane(bp, phy, 0); + + /* restart Autoneg */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, + MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200); + + vars->rx_tx_asic_rst--; + DP(NETIF_MSG_LINK, "0x%x retry left\n", + vars->rx_tx_asic_rst); + } + break; + + default: + break; + } + + } /*params->rx_tx_asic_rst*/ + +} static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy, struct link_params *params, @@ -12339,11 +12424,6 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 phy_idx; - if (!params) { - DP(NETIF_MSG_LINK, "Uninitialized params !\n"); - return; - } - for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) { bnx2x_set_aer_mmd(params, ¶ms->phy[phy_idx]); @@ -12352,8 +12432,13 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars) } } - if (CHIP_IS_E3(bp)) + if (CHIP_IS_E3(bp)) { + struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; + bnx2x_set_aer_mmd(params, phy); bnx2x_check_over_curr(params, vars); + bnx2x_warpcore_config_runtime(phy, params, vars); + } + } u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index c12db6d..2a46e63 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -303,6 +303,9 @@ struct link_vars { #define PERIODIC_FLAGS_LINK_EVENT 0x0001 u32 aeu_int_mask; + u8 rx_tx_asic_rst; + u8 turn_to_run_wc_rt; + u16 rsrv2; }; /***********************************************************/