From patchwork Wed Jun 24 03:26:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenzhuo Lu X-Patchwork-Id: 5734 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id AA57BC9A2; Wed, 24 Jun 2015 05:27:23 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 95B2BC626 for ; Wed, 24 Jun 2015 05:27:19 +0200 (CEST) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 23 Jun 2015 20:27:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,669,1427785200"; d="scan'208";a="733464628" Received: from shvmail01.sh.intel.com ([10.239.29.42]) by fmsmga001.fm.intel.com with ESMTP; 23 Jun 2015 20:27:18 -0700 Received: from shecgisg004.sh.intel.com (shecgisg004.sh.intel.com [10.239.29.89]) by shvmail01.sh.intel.com with ESMTP id t5O3RH2Z020561; Wed, 24 Jun 2015 11:27:17 +0800 Received: from shecgisg004.sh.intel.com (localhost [127.0.0.1]) by shecgisg004.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id t5O3RDPq012188; Wed, 24 Jun 2015 11:27:15 +0800 Received: (from wenzhuol@localhost) by shecgisg004.sh.intel.com (8.13.6/8.13.6/Submit) id t5O3RDSg012184; Wed, 24 Jun 2015 11:27:13 +0800 From: Wenzhuo Lu To: dev@dpdk.org Date: Wed, 24 Jun 2015 11:26:09 +0800 Message-Id: <1435116386-12010-21-git-send-email-wenzhuo.lu@intel.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1435116386-12010-1-git-send-email-wenzhuo.lu@intel.com> References: <1435116386-12010-1-git-send-email-wenzhuo.lu@intel.com> Subject: [dpdk-dev] [PATCH 20/37] ixgbe/base: check link again after getting speed X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Ensure link is still up after getting the speed, to ensure that the speed read is valid. Signed-off-by: Wenzhuo Lu --- drivers/net/ixgbe/base/ixgbe_x550.c | 79 ++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/drivers/net/ixgbe/base/ixgbe_x550.c b/drivers/net/ixgbe/base/ixgbe_x550.c index 2a7046c..a7e95d9 100644 --- a/drivers/net/ixgbe/base/ixgbe_x550.c +++ b/drivers/net/ixgbe/base/ixgbe_x550.c @@ -1860,6 +1860,38 @@ STATIC s32 ixgbe_setup_ixfi_x550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed) } /** + * ixgbe_ext_phy_t_x550em_get_link - Get ext phy link status + * @hw: address of hardware structure + * @link_up: address of boolean to indicate link status + * + * Returns error code if unable to get link status. + */ +STATIC s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up) +{ + u32 ret; + u16 autoneg_status; + + *link_up = false; + + /* read this twice back to back to indicate current status */ + ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_status); + if (ret != IXGBE_SUCCESS) + return ret; + + ret = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_status); + if (ret != IXGBE_SUCCESS) + return ret; + + *link_up = !!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS); + + return IXGBE_SUCCESS; +} + +/** * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP * @hw: pointer to hardware structure * @@ -1936,33 +1968,34 @@ s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, */ s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw) { - u32 status; - u16 autoneg_status, speed; ixgbe_link_speed force_speed; + bool link_up; + u32 status; + u16 speed; if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) return IXGBE_ERR_CONFIG; - /* read this twice back to back to indicate current status */ - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_status); - if (status != IXGBE_SUCCESS) - return status; - - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_status); + /* If link is not up, then there is no setup necessary so return */ + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); if (status != IXGBE_SUCCESS) return status; - /* If link is not up, then there is no setup necessary so return */ - if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS)) + if (!link_up) return IXGBE_SUCCESS; status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_STAT, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &speed); + if (status != IXGBE_SUCCESS) + return status; + + /* If link is not still up, then no setup is necessary so return */ + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); + if (status != IXGBE_SUCCESS) + return status; + if (!link_up) + return IXGBE_SUCCESS; /* clear everything but the speed and duplex bits */ speed &= IXGBE_MDIO_AUTO_NEG_VENDOR_STATUS_MASK; @@ -2687,19 +2720,17 @@ void ixgbe_disable_rx_x550(struct ixgbe_hw *hw) **/ s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) { - u16 autoneg_status, an_10g_cntl_reg, autoneg_reg, speed; + u16 an_10g_cntl_reg, autoneg_reg, speed; s32 status; ixgbe_link_speed lcd_speed; u32 save_autoneg; + bool link_up; /* If blocked by MNG FW, then don't restart AN */ if (ixgbe_check_reset_blocked(hw)) return IXGBE_SUCCESS; - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_status); - + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); if (status != IXGBE_SUCCESS) return status; @@ -2711,8 +2742,7 @@ s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) /* If link is down, LPLU disabled in NVM, WoL disabled, or manageability * disabled, then force link down by entering low power mode. */ - if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS) || - !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) || + if (!link_up || !(hw->eeprom.ctrl_word_3 & NVM_INIT_CTRL_3_LPLU) || !(hw->wol_enabled || ixgbe_mng_present(hw))) return ixgbe_set_copper_phy_power(hw, FALSE); @@ -2733,6 +2763,11 @@ s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) if (status != IXGBE_SUCCESS) return status; + /* If no link now, speed is invalid so take link down */ + status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); + if (status != IXGBE_SUCCESS) + return ixgbe_set_copper_phy_power(hw, false); + /* clear everything but the speed bits */ speed &= IXGBE_MDIO_AUTO_NEG_VEN_STAT_SPEED_MASK; @@ -2746,7 +2781,7 @@ s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw) /* Clear AN completed indication */ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_VENDOR_TX_ALARM, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_status); + &autoneg_reg); if (status != IXGBE_SUCCESS) return status;