Commit 73c4b7cd authored by Alexander Duyck's avatar Alexander Duyck Committed by Jeff Kirsher

ixgbe: cleanup race conditions in link setup

This change makes it so that we perform link setup with interrupts
disabled. If the SFP has not been detected previously we will schedule the
SFP detection task to run in order to detect link.  By doing this we avoid
the possibility of interrupts firing in the middle of our link setup during
ixgbe_up_complete.

In addition this change makes it so that the multi-speed fiber setup and SFP
setup are not mutually exclusive.  The addresses issues seen in which a
link would only come up at 1G on some multi-speed fiber modules.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Tested-by: default avatarRoss Brattain <ross.b.brattain@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 7d637bcc
......@@ -1712,17 +1712,18 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
{
struct ixgbe_hw *hw = &adapter->hw;
if (eicr & IXGBE_EICR_GPI_SDP2) {
/* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
schedule_work(&adapter->sfp_config_module_task);
}
if (eicr & IXGBE_EICR_GPI_SDP1) {
/* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
schedule_work(&adapter->multispeed_fiber_task);
} else if (eicr & IXGBE_EICR_GPI_SDP2) {
/* Clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
schedule_work(&adapter->sfp_config_module_task);
} else {
/* Interrupt isn't for us... */
return;
if (!test_bit(__IXGBE_DOWN, &adapter->state))
schedule_work(&adapter->multispeed_fiber_task);
}
}
......@@ -3587,6 +3588,14 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
clear_bit(__IXGBE_DOWN, &adapter->state);
ixgbe_napi_enable_all(adapter);
if (ixgbe_is_sfp(hw)) {
ixgbe_sfp_link_config(adapter);
} else {
err = ixgbe_non_sfp_link_config(hw);
if (err)
e_err(probe, "link_config FAILED %d\n", err);
}
/* clear any pending interrupts, may auto mask */
IXGBE_READ_REG(hw, IXGBE_EICR);
ixgbe_irq_enable(adapter, true, true);
......@@ -3609,26 +3618,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
* If we're not hot-pluggable SFP+, we just need to configure link
* and bring it up.
*/
if (hw->phy.type == ixgbe_phy_unknown) {
err = hw->phy.ops.identify(hw);
if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
/*
* Take the device down and schedule the sfp tasklet
* which will unregister_netdev and log it.
*/
ixgbe_down(adapter);
schedule_work(&adapter->sfp_config_module_task);
return err;
}
}
if (ixgbe_is_sfp(hw)) {
ixgbe_sfp_link_config(adapter);
} else {
err = ixgbe_non_sfp_link_config(hw);
if (err)
e_err(probe, "link_config FAILED %d\n", err);
}
if (hw->phy.type == ixgbe_phy_unknown)
schedule_work(&adapter->sfp_config_module_task);
/* enable transmits */
netif_tx_start_all_queues(adapter->netdev);
......
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