From a4c1aaf3c644783fb51154e1c7992642986adaff Mon Sep 17 00:00:00 2001 From: Wenzhuo Lu Date: Fri, 5 Jun 2015 13:21:55 +0800 Subject: [PATCH] ixgbe/base: add X550em link check This patch adds ixgbe_check_link_t_X550em for checking x550em PHY link. We check that both the MAC and external x550em PHY have link. This is to avoid a false link up between the internal and external PHY when the external PHY doesn't have link. Signed-off-by: Wenzhuo Lu Acked-by: Helin Zhang --- drivers/net/ixgbe/base/ixgbe_x550.c | 50 +++++++++++++++++++++++++++++ drivers/net/ixgbe/base/ixgbe_x550.h | 2 ++ 2 files changed, 52 insertions(+) diff --git a/drivers/net/ixgbe/base/ixgbe_x550.c b/drivers/net/ixgbe/base/ixgbe_x550.c index adc77fb486..a1bc579b71 100644 --- a/drivers/net/ixgbe/base/ixgbe_x550.c +++ b/drivers/net/ixgbe/base/ixgbe_x550.c @@ -1070,6 +1070,7 @@ void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) break; case ixgbe_media_type_copper: mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; + mac->ops.check_link = ixgbe_check_link_t_X550em; break; default: break; @@ -2838,3 +2839,52 @@ s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, return hw->phy.ops.setup_link_speed(hw, speed, autoneg_wait_to_complete); } + +/** + * ixgbe_check_link_t_X550em - Determine link and speed status + * @hw: pointer to hardware structure + * @speed: pointer to link speed + * @link_up: true when link is up + * @link_up_wait_to_complete: bool used to wait for link up or not + * + * Check that both the MAC and X557 external PHY have link. + **/ +s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete) +{ + u32 status; + u16 autoneg_status; + + if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) + return IXGBE_ERR_CONFIG; + + status = ixgbe_check_mac_link_generic(hw, speed, link_up, + link_up_wait_to_complete); + + /* If check link fails or MAC link is not up, then return */ + if (status != IXGBE_SUCCESS || !(*link_up)) + return status; + + /* MAC link is up, so check external PHY link. + * 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 (status != IXGBE_SUCCESS) + return status; + + /* If external PHY link is not up, then indicate link not up */ + if (!(autoneg_status & IXGBE_MDIO_AUTO_NEG_LINK_STATUS)) + *link_up = false; + + return IXGBE_SUCCESS; +} diff --git a/drivers/net/ixgbe/base/ixgbe_x550.h b/drivers/net/ixgbe/base/ixgbe_x550.h index ee23c7603b..ead9e7954b 100644 --- a/drivers/net/ixgbe/base/ixgbe_x550.h +++ b/drivers/net/ixgbe/base/ixgbe_x550.h @@ -99,5 +99,7 @@ s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw); s32 ixgbe_setup_mac_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg_wait_to_complete); +s32 ixgbe_check_link_t_X550em(struct ixgbe_hw *hw, ixgbe_link_speed *speed, + bool *link_up, bool link_up_wait_to_complete); #endif /* _IXGBE_X550_H_ */ -- 2.20.1