igb: cleanup flow control configuration to make requested/current more clear
This patch cleans up the flow control configuration for igb to make it a bit more readable in regards to what the requested and current modes are. This should help with the maintainability of the current igb driver in regards to flow control. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2d94d8ab76
commit
0cce119aa9
5 changed files with 55 additions and 45 deletions
|
@ -137,7 +137,7 @@ enum e1000_rev_polarity {
|
||||||
e1000_rev_polarity_undefined = 0xFF
|
e1000_rev_polarity_undefined = 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
enum e1000_fc_type {
|
enum e1000_fc_mode {
|
||||||
e1000_fc_none = 0,
|
e1000_fc_none = 0,
|
||||||
e1000_fc_rx_pause,
|
e1000_fc_rx_pause,
|
||||||
e1000_fc_tx_pause,
|
e1000_fc_tx_pause,
|
||||||
|
@ -429,8 +429,8 @@ struct e1000_fc_info {
|
||||||
u16 pause_time; /* Flow control pause timer */
|
u16 pause_time; /* Flow control pause timer */
|
||||||
bool send_xon; /* Flow control send XON */
|
bool send_xon; /* Flow control send XON */
|
||||||
bool strict_ieee; /* Strict IEEE mode */
|
bool strict_ieee; /* Strict IEEE mode */
|
||||||
enum e1000_fc_type type; /* Type of flow control */
|
enum e1000_fc_mode current_mode; /* Type of flow control */
|
||||||
enum e1000_fc_type original_type;
|
enum e1000_fc_mode requested_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct e1000_mbx_operations {
|
struct e1000_mbx_operations {
|
||||||
|
|
|
@ -536,18 +536,24 @@ s32 igb_setup_link(struct e1000_hw *hw)
|
||||||
if (igb_check_reset_block(hw))
|
if (igb_check_reset_block(hw))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret_val = igb_set_default_fc(hw);
|
/*
|
||||||
if (ret_val)
|
* If requested flow control is set to default, set flow control
|
||||||
goto out;
|
* based on the EEPROM flow control settings.
|
||||||
|
*/
|
||||||
|
if (hw->fc.requested_mode == e1000_fc_default) {
|
||||||
|
ret_val = igb_set_default_fc(hw);
|
||||||
|
if (ret_val)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We want to save off the original Flow Control configuration just
|
* We want to save off the original Flow Control configuration just
|
||||||
* in case we get disconnected and then reconnected into a different
|
* in case we get disconnected and then reconnected into a different
|
||||||
* hub or switch with different Flow Control capabilities.
|
* hub or switch with different Flow Control capabilities.
|
||||||
*/
|
*/
|
||||||
hw->fc.original_type = hw->fc.type;
|
hw->fc.current_mode = hw->fc.requested_mode;
|
||||||
|
|
||||||
hw_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.type);
|
hw_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode);
|
||||||
|
|
||||||
/* Call the necessary media_type subroutine to configure the link. */
|
/* Call the necessary media_type subroutine to configure the link. */
|
||||||
ret_val = hw->mac.ops.setup_physical_interface(hw);
|
ret_val = hw->mac.ops.setup_physical_interface(hw);
|
||||||
|
@ -614,7 +620,7 @@ static s32 igb_set_fc_watermarks(struct e1000_hw *hw)
|
||||||
* ability to transmit pause frames is not enabled, then these
|
* ability to transmit pause frames is not enabled, then these
|
||||||
* registers will be set to 0.
|
* registers will be set to 0.
|
||||||
*/
|
*/
|
||||||
if (hw->fc.type & e1000_fc_tx_pause) {
|
if (hw->fc.current_mode & e1000_fc_tx_pause) {
|
||||||
/*
|
/*
|
||||||
* We need to set up the Receive Threshold high and low water
|
* We need to set up the Receive Threshold high and low water
|
||||||
* marks as well as (optionally) enabling the transmission of
|
* marks as well as (optionally) enabling the transmission of
|
||||||
|
@ -661,12 +667,12 @@ static s32 igb_set_default_fc(struct e1000_hw *hw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
|
if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
|
||||||
hw->fc.type = e1000_fc_none;
|
hw->fc.requested_mode = e1000_fc_none;
|
||||||
else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
|
else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
|
||||||
NVM_WORD0F_ASM_DIR)
|
NVM_WORD0F_ASM_DIR)
|
||||||
hw->fc.type = e1000_fc_tx_pause;
|
hw->fc.requested_mode = e1000_fc_tx_pause;
|
||||||
else
|
else
|
||||||
hw->fc.type = e1000_fc_full;
|
hw->fc.requested_mode = e1000_fc_full;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
@ -696,7 +702,7 @@ s32 igb_force_mac_fc(struct e1000_hw *hw)
|
||||||
* receive flow control.
|
* receive flow control.
|
||||||
*
|
*
|
||||||
* The "Case" statement below enables/disable flow control
|
* The "Case" statement below enables/disable flow control
|
||||||
* according to the "hw->fc.type" parameter.
|
* according to the "hw->fc.current_mode" parameter.
|
||||||
*
|
*
|
||||||
* The possible values of the "fc" parameter are:
|
* The possible values of the "fc" parameter are:
|
||||||
* 0: Flow control is completely disabled
|
* 0: Flow control is completely disabled
|
||||||
|
@ -707,9 +713,9 @@ s32 igb_force_mac_fc(struct e1000_hw *hw)
|
||||||
* 3: Both Rx and TX flow control (symmetric) is enabled.
|
* 3: Both Rx and TX flow control (symmetric) is enabled.
|
||||||
* other: No other values should be possible at this point.
|
* other: No other values should be possible at this point.
|
||||||
*/
|
*/
|
||||||
hw_dbg("hw->fc.type = %u\n", hw->fc.type);
|
hw_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode);
|
||||||
|
|
||||||
switch (hw->fc.type) {
|
switch (hw->fc.current_mode) {
|
||||||
case e1000_fc_none:
|
case e1000_fc_none:
|
||||||
ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
|
ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
|
||||||
break;
|
break;
|
||||||
|
@ -857,11 +863,11 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
||||||
* ONLY. Hence, we must now check to see if we need to
|
* ONLY. Hence, we must now check to see if we need to
|
||||||
* turn OFF the TRANSMISSION of PAUSE frames.
|
* turn OFF the TRANSMISSION of PAUSE frames.
|
||||||
*/
|
*/
|
||||||
if (hw->fc.original_type == e1000_fc_full) {
|
if (hw->fc.requested_mode == e1000_fc_full) {
|
||||||
hw->fc.type = e1000_fc_full;
|
hw->fc.current_mode = e1000_fc_full;
|
||||||
hw_dbg("Flow Control = FULL.\r\n");
|
hw_dbg("Flow Control = FULL.\r\n");
|
||||||
} else {
|
} else {
|
||||||
hw->fc.type = e1000_fc_rx_pause;
|
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||||
hw_dbg("Flow Control = "
|
hw_dbg("Flow Control = "
|
||||||
"RX PAUSE frames only.\r\n");
|
"RX PAUSE frames only.\r\n");
|
||||||
}
|
}
|
||||||
|
@ -878,7 +884,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
||||||
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
|
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
|
||||||
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
|
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
|
||||||
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
|
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
|
||||||
hw->fc.type = e1000_fc_tx_pause;
|
hw->fc.current_mode = e1000_fc_tx_pause;
|
||||||
hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
|
hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -893,7 +899,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
||||||
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
|
(mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
|
||||||
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
|
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
|
||||||
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
|
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
|
||||||
hw->fc.type = e1000_fc_rx_pause;
|
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||||
hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
|
hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -917,13 +923,13 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
||||||
* be asked to delay transmission of packets than asking
|
* be asked to delay transmission of packets than asking
|
||||||
* our link partner to pause transmission of frames.
|
* our link partner to pause transmission of frames.
|
||||||
*/
|
*/
|
||||||
else if ((hw->fc.original_type == e1000_fc_none ||
|
else if ((hw->fc.requested_mode == e1000_fc_none ||
|
||||||
hw->fc.original_type == e1000_fc_tx_pause) ||
|
hw->fc.requested_mode == e1000_fc_tx_pause) ||
|
||||||
hw->fc.strict_ieee) {
|
hw->fc.strict_ieee) {
|
||||||
hw->fc.type = e1000_fc_none;
|
hw->fc.current_mode = e1000_fc_none;
|
||||||
hw_dbg("Flow Control = NONE.\r\n");
|
hw_dbg("Flow Control = NONE.\r\n");
|
||||||
} else {
|
} else {
|
||||||
hw->fc.type = e1000_fc_rx_pause;
|
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||||
hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
|
hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,7 +945,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (duplex == HALF_DUPLEX)
|
if (duplex == HALF_DUPLEX)
|
||||||
hw->fc.type = e1000_fc_none;
|
hw->fc.current_mode = e1000_fc_none;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we call a subroutine to actually force the MAC
|
* Now we call a subroutine to actually force the MAC
|
||||||
|
|
|
@ -735,7 +735,7 @@ static s32 igb_phy_setup_autoneg(struct e1000_hw *hw)
|
||||||
* other: No software override. The flow control configuration
|
* other: No software override. The flow control configuration
|
||||||
* in the EEPROM is used.
|
* in the EEPROM is used.
|
||||||
*/
|
*/
|
||||||
switch (hw->fc.type) {
|
switch (hw->fc.current_mode) {
|
||||||
case e1000_fc_none:
|
case e1000_fc_none:
|
||||||
/*
|
/*
|
||||||
* Flow control (RX & TX) is completely disabled by a
|
* Flow control (RX & TX) is completely disabled by a
|
||||||
|
@ -992,7 +992,7 @@ static void igb_phy_force_speed_duplex_setup(struct e1000_hw *hw,
|
||||||
u32 ctrl;
|
u32 ctrl;
|
||||||
|
|
||||||
/* Turn off flow control when forcing speed/duplex */
|
/* Turn off flow control when forcing speed/duplex */
|
||||||
hw->fc.type = e1000_fc_none;
|
hw->fc.current_mode = e1000_fc_none;
|
||||||
|
|
||||||
/* Force speed/duplex on the mac */
|
/* Force speed/duplex on the mac */
|
||||||
ctrl = rd32(E1000_CTRL);
|
ctrl = rd32(E1000_CTRL);
|
||||||
|
|
|
@ -194,6 +194,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
|
||||||
ADVERTISED_TP |
|
ADVERTISED_TP |
|
||||||
ADVERTISED_Autoneg;
|
ADVERTISED_Autoneg;
|
||||||
ecmd->advertising = hw->phy.autoneg_advertised;
|
ecmd->advertising = hw->phy.autoneg_advertised;
|
||||||
|
if (adapter->fc_autoneg)
|
||||||
|
hw->fc.requested_mode = e1000_fc_default;
|
||||||
} else {
|
} else {
|
||||||
if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
|
if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
|
||||||
clear_bit(__IGB_RESETTING, &adapter->state);
|
clear_bit(__IGB_RESETTING, &adapter->state);
|
||||||
|
@ -221,11 +223,11 @@ static void igb_get_pauseparam(struct net_device *netdev,
|
||||||
pause->autoneg =
|
pause->autoneg =
|
||||||
(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
|
(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
|
||||||
|
|
||||||
if (hw->fc.type == e1000_fc_rx_pause)
|
if (hw->fc.current_mode == e1000_fc_rx_pause)
|
||||||
pause->rx_pause = 1;
|
pause->rx_pause = 1;
|
||||||
else if (hw->fc.type == e1000_fc_tx_pause)
|
else if (hw->fc.current_mode == e1000_fc_tx_pause)
|
||||||
pause->tx_pause = 1;
|
pause->tx_pause = 1;
|
||||||
else if (hw->fc.type == e1000_fc_full) {
|
else if (hw->fc.current_mode == e1000_fc_full) {
|
||||||
pause->rx_pause = 1;
|
pause->rx_pause = 1;
|
||||||
pause->tx_pause = 1;
|
pause->tx_pause = 1;
|
||||||
}
|
}
|
||||||
|
@ -243,26 +245,28 @@ static int igb_set_pauseparam(struct net_device *netdev,
|
||||||
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
|
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
|
||||||
msleep(1);
|
msleep(1);
|
||||||
|
|
||||||
if (pause->rx_pause && pause->tx_pause)
|
|
||||||
hw->fc.type = e1000_fc_full;
|
|
||||||
else if (pause->rx_pause && !pause->tx_pause)
|
|
||||||
hw->fc.type = e1000_fc_rx_pause;
|
|
||||||
else if (!pause->rx_pause && pause->tx_pause)
|
|
||||||
hw->fc.type = e1000_fc_tx_pause;
|
|
||||||
else if (!pause->rx_pause && !pause->tx_pause)
|
|
||||||
hw->fc.type = e1000_fc_none;
|
|
||||||
|
|
||||||
hw->fc.original_type = hw->fc.type;
|
|
||||||
|
|
||||||
if (adapter->fc_autoneg == AUTONEG_ENABLE) {
|
if (adapter->fc_autoneg == AUTONEG_ENABLE) {
|
||||||
|
hw->fc.requested_mode = e1000_fc_default;
|
||||||
if (netif_running(adapter->netdev)) {
|
if (netif_running(adapter->netdev)) {
|
||||||
igb_down(adapter);
|
igb_down(adapter);
|
||||||
igb_up(adapter);
|
igb_up(adapter);
|
||||||
} else
|
} else
|
||||||
igb_reset(adapter);
|
igb_reset(adapter);
|
||||||
} else
|
} else {
|
||||||
|
if (pause->rx_pause && pause->tx_pause)
|
||||||
|
hw->fc.requested_mode = e1000_fc_full;
|
||||||
|
else if (pause->rx_pause && !pause->tx_pause)
|
||||||
|
hw->fc.requested_mode = e1000_fc_rx_pause;
|
||||||
|
else if (!pause->rx_pause && pause->tx_pause)
|
||||||
|
hw->fc.requested_mode = e1000_fc_tx_pause;
|
||||||
|
else if (!pause->rx_pause && !pause->tx_pause)
|
||||||
|
hw->fc.requested_mode = e1000_fc_none;
|
||||||
|
|
||||||
|
hw->fc.current_mode = hw->fc.requested_mode;
|
||||||
|
|
||||||
retval = ((hw->phy.media_type == e1000_media_type_copper) ?
|
retval = ((hw->phy.media_type == e1000_media_type_copper) ?
|
||||||
igb_force_mac_fc(hw) : igb_setup_link(hw));
|
igb_force_mac_fc(hw) : igb_setup_link(hw));
|
||||||
|
}
|
||||||
|
|
||||||
clear_bit(__IGB_RESETTING, &adapter->state);
|
clear_bit(__IGB_RESETTING, &adapter->state);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -1130,7 +1130,7 @@ void igb_reset(struct igb_adapter *adapter)
|
||||||
}
|
}
|
||||||
fc->pause_time = 0xFFFF;
|
fc->pause_time = 0xFFFF;
|
||||||
fc->send_xon = 1;
|
fc->send_xon = 1;
|
||||||
fc->type = fc->original_type;
|
fc->current_mode = fc->requested_mode;
|
||||||
|
|
||||||
/* disable receive for all VFs and wait one second */
|
/* disable receive for all VFs and wait one second */
|
||||||
if (adapter->vfs_allocated_count) {
|
if (adapter->vfs_allocated_count) {
|
||||||
|
@ -1427,8 +1427,8 @@ static int __devinit igb_probe(struct pci_dev *pdev,
|
||||||
hw->mac.autoneg = true;
|
hw->mac.autoneg = true;
|
||||||
hw->phy.autoneg_advertised = 0x2f;
|
hw->phy.autoneg_advertised = 0x2f;
|
||||||
|
|
||||||
hw->fc.original_type = e1000_fc_default;
|
hw->fc.requested_mode = e1000_fc_default;
|
||||||
hw->fc.type = e1000_fc_default;
|
hw->fc.current_mode = e1000_fc_default;
|
||||||
|
|
||||||
adapter->itr_setting = IGB_DEFAULT_ITR;
|
adapter->itr_setting = IGB_DEFAULT_ITR;
|
||||||
adapter->itr = IGB_START_ITR;
|
adapter->itr = IGB_START_ITR;
|
||||||
|
|
Reference in a new issue