Commit cd7e1f0b authored by Don Skidmore's avatar Don Skidmore Committed by David S. Miller

ixgbe: Fix KR to KX fail over for Mezzanine cards

This patch allows the recently added backplane device IDs that support KR
to fail over to KX during link setup.  This is accomplished by the new MAC
link setup function ixgbe_setup_mac_link_smartspeed().  Comments were also
updated to better document the reason for the delays chosen for KX, KX4, BX,
BX4 and KR connections.
Signed-off-by: default avatarDon Skidmore <don.c.skidmore@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 38ad1c8e
...@@ -42,6 +42,10 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, ...@@ -42,6 +42,10 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
ixgbe_link_speed speed, ixgbe_link_speed speed,
bool autoneg, bool autoneg,
bool autoneg_wait_to_complete); bool autoneg_wait_to_complete);
static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
ixgbe_link_speed speed,
bool autoneg,
bool autoneg_wait_to_complete);
s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
bool autoneg_wait_to_complete); bool autoneg_wait_to_complete);
s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
...@@ -64,7 +68,13 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) ...@@ -64,7 +68,13 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
/* Set up dual speed SFP+ support */ /* Set up dual speed SFP+ support */
mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber; mac->ops.setup_link = &ixgbe_setup_mac_link_multispeed_fiber;
} else { } else {
mac->ops.setup_link = &ixgbe_setup_mac_link_82599; if ((mac->ops.get_media_type(hw) ==
ixgbe_media_type_backplane) &&
(hw->phy.smart_speed == ixgbe_smart_speed_auto ||
hw->phy.smart_speed == ixgbe_smart_speed_on))
mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed;
else
mac->ops.setup_link = &ixgbe_setup_mac_link_82599;
} }
} }
...@@ -480,7 +490,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, ...@@ -480,7 +490,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
hw->mac.autotry_restart = false; hw->mac.autotry_restart = false;
} }
/* The controller may take up to 500ms at 10g to acquire link */ /*
* Wait for the controller to acquire link. Per IEEE 802.3ap,
* Section 73.10.2, we may have to wait up to 500ms if KR is
* attempted. 82599 uses the same timing for 10g SFI.
*/
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
/* Wait for the link partner to also set speed */ /* Wait for the link partner to also set speed */
msleep(100); msleep(100);
...@@ -567,6 +582,111 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, ...@@ -567,6 +582,111 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
return status; return status;
} }
/**
* ixgbe_setup_mac_link_smartspeed - Set MAC link speed using SmartSpeed
* @hw: pointer to hardware structure
* @speed: new link speed
* @autoneg: true if autonegotiation enabled
* @autoneg_wait_to_complete: true when waiting for completion is needed
*
* Implements the Intel SmartSpeed algorithm.
**/
static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
ixgbe_link_speed speed, bool autoneg,
bool autoneg_wait_to_complete)
{
s32 status = 0;
ixgbe_link_speed link_speed;
s32 i, j;
bool link_up = false;
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
hw_dbg(hw, "ixgbe_setup_mac_link_smartspeed.\n");
/* Set autoneg_advertised value based on input link speed */
hw->phy.autoneg_advertised = 0;
if (speed & IXGBE_LINK_SPEED_10GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
if (speed & IXGBE_LINK_SPEED_1GB_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
if (speed & IXGBE_LINK_SPEED_100_FULL)
hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_100_FULL;
/*
* Implement Intel SmartSpeed algorithm. SmartSpeed will reduce the
* autoneg advertisement if link is unable to be established at the
* highest negotiated rate. This can sometimes happen due to integrity
* issues with the physical media connection.
*/
/* First, try to get link with full advertisement */
hw->phy.smart_speed_active = false;
for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
autoneg_wait_to_complete);
if (status)
goto out;
/*
* Wait for the controller to acquire link. Per IEEE 802.3ap,
* Section 73.10.2, we may have to wait up to 500ms if KR is
* attempted, or 200ms if KX/KX4/BX/BX4 is attempted, per
* Table 9 in the AN MAS.
*/
for (i = 0; i < 5; i++) {
mdelay(100);
/* If we have link, just jump out */
hw->mac.ops.check_link(hw, &link_speed,
&link_up, false);
if (link_up)
goto out;
}
}
/*
* We didn't get link. If we advertised KR plus one of KX4/KX
* (or BX4/BX), then disable KR and try again.
*/
if (((autoc_reg & IXGBE_AUTOC_KR_SUPP) == 0) ||
((autoc_reg & IXGBE_AUTOC_KX4_KX_SUPP_MASK) == 0))
goto out;
/* Turn SmartSpeed on to disable KR support */
hw->phy.smart_speed_active = true;
status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
autoneg_wait_to_complete);
if (status)
goto out;
/*
* Wait for the controller to acquire link. 600ms will allow for
* the AN link_fail_inhibit_timer as well for multiple cycles of
* parallel detect, both 10g and 1g. This allows for the maximum
* connect attempts as defined in the AN MAS table 73-7.
*/
for (i = 0; i < 6; i++) {
mdelay(100);
/* If we have link, just jump out */
hw->mac.ops.check_link(hw, &link_speed,
&link_up, false);
if (link_up)
goto out;
}
/* We didn't get link. Turn SmartSpeed back off. */
hw->phy.smart_speed_active = false;
status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
autoneg_wait_to_complete);
out:
return status;
}
/** /**
* ixgbe_check_mac_link_82599 - Determine link and speed status * ixgbe_check_mac_link_82599 - Determine link and speed status
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -670,7 +790,8 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ...@@ -670,7 +790,8 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
if (speed & IXGBE_LINK_SPEED_10GB_FULL) if (speed & IXGBE_LINK_SPEED_10GB_FULL)
if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
autoc |= IXGBE_AUTOC_KX4_SUPP; autoc |= IXGBE_AUTOC_KX4_SUPP;
if (orig_autoc & IXGBE_AUTOC_KR_SUPP) if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) &&
(hw->phy.smart_speed_active == false))
autoc |= IXGBE_AUTOC_KR_SUPP; autoc |= IXGBE_AUTOC_KR_SUPP;
if (speed & IXGBE_LINK_SPEED_1GB_FULL) if (speed & IXGBE_LINK_SPEED_1GB_FULL)
autoc |= IXGBE_AUTOC_KX_SUPP; autoc |= IXGBE_AUTOC_KX_SUPP;
......
...@@ -2172,6 +2172,14 @@ enum ixgbe_fc_mode { ...@@ -2172,6 +2172,14 @@ enum ixgbe_fc_mode {
ixgbe_fc_default ixgbe_fc_default
}; };
/* Smart Speed Settings */
#define IXGBE_SMARTSPEED_MAX_RETRIES 3
enum ixgbe_smart_speed {
ixgbe_smart_speed_auto = 0,
ixgbe_smart_speed_on,
ixgbe_smart_speed_off
};
/* PCI bus types */ /* PCI bus types */
enum ixgbe_bus_type { enum ixgbe_bus_type {
ixgbe_bus_type_unknown = 0, ixgbe_bus_type_unknown = 0,
...@@ -2432,6 +2440,8 @@ struct ixgbe_phy_info { ...@@ -2432,6 +2440,8 @@ struct ixgbe_phy_info {
enum ixgbe_media_type media_type; enum ixgbe_media_type media_type;
bool reset_disable; bool reset_disable;
ixgbe_autoneg_advertised autoneg_advertised; ixgbe_autoneg_advertised autoneg_advertised;
enum ixgbe_smart_speed smart_speed;
bool smart_speed_active;
bool multispeed_fiber; bool multispeed_fiber;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment