From 4e7466cccde83505d5a6261675f3fe161117b444 Mon Sep 17 00:00:00 2001 From: Wenzhuo Lu Date: Fri, 20 Nov 2015 15:17:43 +0800 Subject: [PATCH] ixgbe/base: avoid needless copper PHY access Avoid a needless PHY access on copper phys to save the 10ms wait time for each PHY access. A helper function is introduced to actually do the register access and process the contents. Signed-off-by: Wenzhuo Lu --- drivers/net/ixgbe/base/ixgbe_phy.c | 72 ++++++++++++++++++----------- drivers/net/ixgbe/base/ixgbe_type.h | 1 + 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/net/ixgbe/base/ixgbe_phy.c b/drivers/net/ixgbe/base/ixgbe_phy.c index 51f32c654e..1a83758334 100644 --- a/drivers/net/ixgbe/base/ixgbe_phy.c +++ b/drivers/net/ixgbe/base/ixgbe_phy.c @@ -956,49 +956,65 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, return IXGBE_SUCCESS; } +/** + * ixgbe_get_copper_speeds_supported - Get copper link speeds from phy + * @hw: pointer to hardware structure + * + * Determines the supported link capabilities by reading the PHY auto + * negotiation register. + **/ +static s32 ixgbe_get_copper_speeds_supported(struct ixgbe_hw *hw) +{ + s32 status; + u16 speed_ability; + + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &speed_ability); + if (status) + return status; + + if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_10GB_FULL; + if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_1GB_FULL; + if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M) + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_100_FULL; + + switch (hw->mac.type) { + case ixgbe_mac_X550: + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_2_5GB_FULL; + hw->phy.speeds_supported |= IXGBE_LINK_SPEED_5GB_FULL; + break; + case ixgbe_mac_X550EM_x: + hw->phy.speeds_supported &= ~IXGBE_LINK_SPEED_100_FULL; + break; + default: + break; + } + + return status; +} + /** * ixgbe_get_copper_link_capabilities_generic - Determines link capabilities * @hw: pointer to hardware structure * @speed: pointer to link speed * @autoneg: boolean auto-negotiation value - * - * Determines the supported link capabilities by reading the PHY auto - * negotiation register. **/ s32 ixgbe_get_copper_link_capabilities_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, bool *autoneg) { - s32 status; - u16 speed_ability; + s32 status = IXGBE_SUCCESS; DEBUGFUNC("ixgbe_get_copper_link_capabilities_generic"); - *speed = 0; *autoneg = true; + if (!hw->phy.speeds_supported) + status = ixgbe_get_copper_speeds_supported(hw); - status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, - &speed_ability); - - if (status == IXGBE_SUCCESS) { - if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) - *speed |= IXGBE_LINK_SPEED_10GB_FULL; - if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) - *speed |= IXGBE_LINK_SPEED_1GB_FULL; - if (speed_ability & IXGBE_MDIO_PHY_SPEED_100M) - *speed |= IXGBE_LINK_SPEED_100_FULL; - } - - /* Internal PHY does not support 100 Mbps */ - if (hw->mac.type == ixgbe_mac_X550EM_x) - *speed &= ~IXGBE_LINK_SPEED_100_FULL; - - if (hw->mac.type == ixgbe_mac_X550) { - *speed |= IXGBE_LINK_SPEED_2_5GB_FULL; - *speed |= IXGBE_LINK_SPEED_5GB_FULL; - } - + *speed = hw->phy.speeds_supported; return status; } diff --git a/drivers/net/ixgbe/base/ixgbe_type.h b/drivers/net/ixgbe/base/ixgbe_type.h index 4ef1a81487..d6a30678a2 100644 --- a/drivers/net/ixgbe/base/ixgbe_type.h +++ b/drivers/net/ixgbe/base/ixgbe_type.h @@ -3849,6 +3849,7 @@ struct ixgbe_phy_info { u32 phy_semaphore_mask; bool reset_disable; ixgbe_autoneg_advertised autoneg_advertised; + ixgbe_link_speed speeds_supported; enum ixgbe_smart_speed smart_speed; bool smart_speed_active; bool multispeed_fiber;