Skip to content

Commit

Permalink
ixgbe: Fix 82599 adapter link flickering issues
Browse files Browse the repository at this point in the history
Fix autoneg restart issues in flow control path which might create
endless link flickering due to known timing issues with 82599
adapters.

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakakla@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Mallikarjuna R Chilakala authored and David S. Miller committed Jun 7, 2009
1 parent 50ac58b commit 620fa03
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 227 deletions.
115 changes: 31 additions & 84 deletions drivers/net/ixgbe/ixgbe_82598.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,17 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
u32 rmcs_reg;
u32 reg;

#ifdef CONFIG_DCB
if (hw->fc.requested_mode == ixgbe_fc_pfc)
goto out;

#endif /* CONFIG_DCB */
/* Negotiate the fc mode to use */
ret_val = ixgbe_fc_autoneg(hw);
if (ret_val)
goto out;

/* Disable any previous flow control settings */
fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);

Expand All @@ -304,14 +315,20 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
* 0: Flow control is completely disabled
* 1: Rx flow control is enabled (we can receive pause frames,
* but not send pause frames).
* 2: Tx flow control is enabled (we can send pause frames but
* 2: Tx flow control is enabled (we can send pause frames but
* we do not support receiving pause frames).
* 3: Both Rx and Tx flow control (symmetric) are enabled.
* other: Invalid.
#ifdef CONFIG_DCB
* 4: Priority Flow Control is enabled.
#endif
*/
switch (hw->fc.current_mode) {
case ixgbe_fc_none:
/* Flow control completely disabled by software override. */
/*
* Flow control is disabled by software override or autoneg.
* The code below will actually disable it in the HW.
*/
break;
case ixgbe_fc_rx_pause:
/*
Expand All @@ -336,14 +353,19 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
fctrl_reg |= IXGBE_FCTRL_RFCE;
rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
break;
#ifdef CONFIG_DCB
case ixgbe_fc_pfc:
goto out;
break;
#endif /* CONFIG_DCB */
default:
hw_dbg(hw, "Flow control param set incorrectly\n");
ret_val = -IXGBE_ERR_CONFIG;
goto out;
break;
}

/* Enable 802.3x based flow control settings. */
/* Set 802.3x based flow control settings. */
fctrl_reg |= IXGBE_FCTRL_DPF;
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
Expand Down Expand Up @@ -376,79 +398,6 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
return ret_val;
}

/**
* ixgbe_setup_fc_82598 - Configure flow control settings
* @hw: pointer to hardware structure
* @packetbuf_num: packet buffer number (0-7)
*
* Configures the flow control settings based on SW configuration. This
* function is used for 802.3x flow control configuration only.
**/
static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
{
s32 ret_val = 0;
ixgbe_link_speed speed;
bool link_up;

/* Validate the packetbuf configuration */
if (packetbuf_num < 0 || packetbuf_num > 7) {
hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
" 0-7\n", packetbuf_num);
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
goto out;
}

/*
* Validate the water mark configuration. Zero water marks are invalid
* because it causes the controller to just blast out fc packets.
*/
if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
if (hw->fc.requested_mode != ixgbe_fc_none) {
hw_dbg(hw, "Invalid water mark configuration\n");
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
goto out;
}
}

/*
* Validate the requested mode. Strict IEEE mode does not allow
* ixgbe_fc_rx_pause because it will cause testing anomalies.
*/
if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
goto out;
}

/*
* 10gig parts do not have a word in the EEPROM to determine the
* default flow control setting, so we explicitly set it to full.
*/
if (hw->fc.requested_mode == ixgbe_fc_default)
hw->fc.requested_mode = ixgbe_fc_full;

/*
* Save off the requested flow control mode for use later. Depending
* on the link partner's capabilities, we may or may not use this mode.
*/

hw->fc.current_mode = hw->fc.requested_mode;

/* Decide whether to use autoneg or not. */
hw->mac.ops.check_link(hw, &speed, &link_up, false);
if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
(speed == IXGBE_LINK_SPEED_1GB_FULL))
ret_val = ixgbe_fc_autoneg(hw);

if (ret_val)
goto out;

ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num);

out:
return ret_val;
}

/**
* ixgbe_setup_mac_link_82598 - Configures MAC link settings
* @hw: pointer to hardware structure
Expand Down Expand Up @@ -488,13 +437,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
}
}

/*
* We want to save off the original Flow Control configuration just in
* case we get disconnected and then reconnected into a different hub
* or switch with different Flow Control capabilities.
*/
ixgbe_setup_fc_82598(hw, 0);

/* Add delay to filter out noises during initial link setup */
msleep(50);

Expand Down Expand Up @@ -581,6 +523,11 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
else
*speed = IXGBE_LINK_SPEED_1GB_FULL;

/* if link is down, zero out the current_mode */
if (*link_up == false) {
hw->fc.current_mode = ixgbe_fc_none;
hw->fc.fc_was_autonegged = false;
}
out:
return 0;
}
Expand Down Expand Up @@ -1168,7 +1115,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.disable_mc = &ixgbe_disable_mc_generic,
.clear_vfta = &ixgbe_clear_vfta_82598,
.set_vfta = &ixgbe_set_vfta_82598,
.setup_fc = &ixgbe_setup_fc_82598,
.fc_enable = &ixgbe_fc_enable_82598,
};

static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
Expand Down
13 changes: 6 additions & 7 deletions drivers/net/ixgbe/ixgbe_82599.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,9 +413,6 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
}
}

/* Set up flow control */
status = ixgbe_setup_fc_generic(hw, 0);

/* Add delay to filter out noises during initial link setup */
msleep(50);

Expand Down Expand Up @@ -641,6 +638,11 @@ s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
else
*speed = IXGBE_LINK_SPEED_100_FULL;

/* if link is down, zero out the current_mode */
if (*link_up == false) {
hw->fc.current_mode = ixgbe_fc_none;
hw->fc.fc_was_autonegged = false;
}

return 0;
}
Expand Down Expand Up @@ -747,9 +749,6 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
}
}

/* Set up flow control */
status = ixgbe_setup_fc_generic(hw, 0);

/* Add delay to filter out noises during initial link setup */
msleep(50);
}
Expand Down Expand Up @@ -1509,7 +1508,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.disable_mc = &ixgbe_disable_mc_generic,
.clear_vfta = &ixgbe_clear_vfta_82599,
.set_vfta = &ixgbe_set_vfta_82599,
.setup_fc = &ixgbe_setup_fc_generic,
.fc_enable = &ixgbe_fc_enable_generic,
.init_uta_tables = &ixgbe_init_uta_tables_82599,
.setup_sfp = &ixgbe_setup_sfp_modules_82599,
};
Expand Down
Loading

0 comments on commit 620fa03

Please sign in to comment.