ixgbe: Reorder link flow control functions in ixgbe_common.c

We can avoid many of the forward declarations found in ixgbe_common.c by
just reordering things so this patch does that to help cleanup the code.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Alexander Duyck 2012-04-19 17:49:56 +00:00 committed by Jeff Kirsher
parent dd411ec4a5
commit 67a79df271
1 changed files with 282 additions and 290 deletions

View File

@ -47,13 +47,6 @@ static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw);
static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw);
static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw);
static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
u16 words, u16 *data);
@ -63,6 +56,216 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
u16 offset);
static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
/**
* ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow
* control
* @hw: pointer to hardware structure
*
* There are several phys that do not support autoneg flow control. This
* function check the device id to see if the associated phy supports
* autoneg flow control.
**/
static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
{
switch (hw->device_id) {
case IXGBE_DEV_ID_X540T:
return 0;
case IXGBE_DEV_ID_82599_T3_LOM:
return 0;
default:
return IXGBE_ERR_FC_NOT_SUPPORTED;
}
}
/**
* ixgbe_setup_fc - Set up flow control
* @hw: pointer to hardware structure
*
* Called at init time to set up flow control.
**/
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
{
s32 ret_val = 0;
u32 reg = 0, reg_bp = 0;
u16 reg_cu = 0;
#ifdef CONFIG_DCB
if (hw->fc.requested_mode == ixgbe_fc_pfc) {
hw->fc.current_mode = hw->fc.requested_mode;
goto out;
}
#endif /* CONFIG_DCB */
/* 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[packetbuf_num] ||
!hw->fc.pause_time) {
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 us to fail at UNH.
*/
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;
/*
* Set up the 1G and 10G flow control advertisement registers so the
* HW will be able to do fc autoneg once the cable is plugged in. If
* we link at 10G, the 1G advertisement is harmless and vice versa.
*/
switch (hw->phy.media_type) {
case ixgbe_media_type_fiber:
case ixgbe_media_type_backplane:
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC);
break;
case ixgbe_media_type_copper:
hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
MDIO_MMD_AN, &reg_cu);
break;
default:
;
}
/*
* The possible values of fc.requested_mode are:
* 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
* we do not support receiving pause frames).
* 3: Both Rx and Tx flow control (symmetric) are enabled.
#ifdef CONFIG_DCB
* 4: Priority Flow Control is enabled.
#endif
* other: Invalid.
*/
switch (hw->fc.requested_mode) {
case ixgbe_fc_none:
/* Flow control completely disabled by software override. */
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
if (hw->phy.media_type == ixgbe_media_type_backplane)
reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE |
IXGBE_AUTOC_ASM_PAUSE);
else if (hw->phy.media_type == ixgbe_media_type_copper)
reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
break;
case ixgbe_fc_rx_pause:
/*
* Rx Flow control is enabled and Tx Flow control is
* disabled by software override. Since there really
* isn't a way to advertise that we are capable of RX
* Pause ONLY, we will advertise that we support both
* symmetric and asymmetric Rx PAUSE. Later, we will
* disable the adapter's ability to send PAUSE frames.
*/
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
if (hw->phy.media_type == ixgbe_media_type_backplane)
reg_bp |= (IXGBE_AUTOC_SYM_PAUSE |
IXGBE_AUTOC_ASM_PAUSE);
else if (hw->phy.media_type == ixgbe_media_type_copper)
reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
break;
case ixgbe_fc_tx_pause:
/*
* Tx Flow control is enabled, and Rx Flow control is
* disabled by software override.
*/
reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
if (hw->phy.media_type == ixgbe_media_type_backplane) {
reg_bp |= (IXGBE_AUTOC_ASM_PAUSE);
reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE);
} else if (hw->phy.media_type == ixgbe_media_type_copper) {
reg_cu |= (IXGBE_TAF_ASM_PAUSE);
reg_cu &= ~(IXGBE_TAF_SYM_PAUSE);
}
break;
case ixgbe_fc_full:
/* Flow control (both Rx and Tx) is enabled by SW override. */
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
if (hw->phy.media_type == ixgbe_media_type_backplane)
reg_bp |= (IXGBE_AUTOC_SYM_PAUSE |
IXGBE_AUTOC_ASM_PAUSE);
else if (hw->phy.media_type == ixgbe_media_type_copper)
reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
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;
}
if (hw->mac.type != ixgbe_mac_X540) {
/*
* Enable auto-negotiation between the MAC & PHY;
* the MAC will advertise clause 37 flow control.
*/
IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
/* Disable AN timeout */
if (hw->fc.strict_ieee)
reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
}
/*
* AUTOC restart handles negotiation of 1G and 10G on backplane
* and copper. There is no need to set the PCS1GCTL register.
*
*/
if (hw->phy.media_type == ixgbe_media_type_backplane) {
reg_bp |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
(ixgbe_device_supports_autoneg_fc(hw) == 0)) {
hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
MDIO_MMD_AN, reg_cu);
}
hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
out:
return ret_val;
}
/**
* ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
* @hw: pointer to hardware structure
@ -2043,63 +2246,52 @@ out:
}
/**
* ixgbe_fc_autoneg - Configure flow control
* ixgbe_negotiate_fc - Negotiate flow control
* @hw: pointer to hardware structure
* @adv_reg: flow control advertised settings
* @lp_reg: link partner's flow control settings
* @adv_sym: symmetric pause bit in advertisement
* @adv_asm: asymmetric pause bit in advertisement
* @lp_sym: symmetric pause bit in link partner advertisement
* @lp_asm: asymmetric pause bit in link partner advertisement
*
* Compares our advertised flow control capabilities to those advertised by
* our link partner, and determines the proper flow control mode to use.
* Find the intersection between advertised settings and link partner's
* advertised settings
**/
void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
{
s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
ixgbe_link_speed speed;
bool link_up;
if ((!(adv_reg)) || (!(lp_reg)))
return IXGBE_ERR_FC_NOT_NEGOTIATED;
/*
* AN should have completed when the cable was plugged in.
* Look for reasons to bail out. Bail out if:
* - FC autoneg is disabled, or if
* - link is not up.
*
* Since we're being called from an LSC, link is already known to be up.
* So use link_up_wait_to_complete=false.
*/
if (hw->fc.disable_fc_autoneg)
goto out;
hw->mac.ops.check_link(hw, &speed, &link_up, false);
if (!link_up)
goto out;
switch (hw->phy.media_type) {
/* Autoneg flow control on fiber adapters */
case ixgbe_media_type_fiber:
if (speed == IXGBE_LINK_SPEED_1GB_FULL)
ret_val = ixgbe_fc_autoneg_fiber(hw);
break;
/* Autoneg flow control on backplane adapters */
case ixgbe_media_type_backplane:
ret_val = ixgbe_fc_autoneg_backplane(hw);
break;
/* Autoneg flow control on copper adapters */
case ixgbe_media_type_copper:
if (ixgbe_device_supports_autoneg_fc(hw) == 0)
ret_val = ixgbe_fc_autoneg_copper(hw);
break;
default:
break;
}
out:
if (ret_val == 0) {
hw->fc.fc_was_autonegged = true;
if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
/*
* Now we need to check if the user selected Rx ONLY
* of pause frames. In this case, we had to advertise
* FULL flow control because we could not advertise RX
* ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames.
*/
if (hw->fc.requested_mode == ixgbe_fc_full) {
hw->fc.current_mode = ixgbe_fc_full;
hw_dbg(hw, "Flow Control = FULL.\n");
} else {
hw->fc.current_mode = ixgbe_fc_rx_pause;
hw_dbg(hw, "Flow Control=RX PAUSE frames only\n");
}
} else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
hw->fc.current_mode = ixgbe_fc_tx_pause;
hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
} else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
!(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
hw->fc.current_mode = ixgbe_fc_rx_pause;
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
} else {
hw->fc.fc_was_autonegged = false;
hw->fc.current_mode = hw->fc.requested_mode;
hw->fc.current_mode = ixgbe_fc_none;
hw_dbg(hw, "Flow Control = NONE.\n");
}
return 0;
}
/**
@ -2202,241 +2394,63 @@ static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
}
/**
* ixgbe_negotiate_fc - Negotiate flow control
* @hw: pointer to hardware structure
* @adv_reg: flow control advertised settings
* @lp_reg: link partner's flow control settings
* @adv_sym: symmetric pause bit in advertisement
* @adv_asm: asymmetric pause bit in advertisement
* @lp_sym: symmetric pause bit in link partner advertisement
* @lp_asm: asymmetric pause bit in link partner advertisement
*
* Find the intersection between advertised settings and link partner's
* advertised settings
**/
static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
{
if ((!(adv_reg)) || (!(lp_reg)))
return IXGBE_ERR_FC_NOT_NEGOTIATED;
if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
/*
* Now we need to check if the user selected Rx ONLY
* of pause frames. In this case, we had to advertise
* FULL flow control because we could not advertise RX
* ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames.
*/
if (hw->fc.requested_mode == ixgbe_fc_full) {
hw->fc.current_mode = ixgbe_fc_full;
hw_dbg(hw, "Flow Control = FULL.\n");
} else {
hw->fc.current_mode = ixgbe_fc_rx_pause;
hw_dbg(hw, "Flow Control=RX PAUSE frames only\n");
}
} else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
hw->fc.current_mode = ixgbe_fc_tx_pause;
hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
} else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
!(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
hw->fc.current_mode = ixgbe_fc_rx_pause;
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
} else {
hw->fc.current_mode = ixgbe_fc_none;
hw_dbg(hw, "Flow Control = NONE.\n");
}
return 0;
}
/**
* ixgbe_setup_fc - Set up flow control
* ixgbe_fc_autoneg - Configure flow control
* @hw: pointer to hardware structure
*
* Called at init time to set up flow control.
* Compares our advertised flow control capabilities to those advertised by
* our link partner, and determines the proper flow control mode to use.
**/
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
void ixgbe_fc_autoneg(struct ixgbe_hw *hw)
{
s32 ret_val = 0;
u32 reg = 0, reg_bp = 0;
u16 reg_cu = 0;
#ifdef CONFIG_DCB
if (hw->fc.requested_mode == ixgbe_fc_pfc) {
hw->fc.current_mode = hw->fc.requested_mode;
goto out;
}
#endif /* CONFIG_DCB */
/* 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;
}
s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
ixgbe_link_speed speed;
bool link_up;
/*
* Validate the water mark configuration. Zero water marks are invalid
* because it causes the controller to just blast out fc packets.
* AN should have completed when the cable was plugged in.
* Look for reasons to bail out. Bail out if:
* - FC autoneg is disabled, or if
* - link is not up.
*
* Since we're being called from an LSC, link is already known to be up.
* So use link_up_wait_to_complete=false.
*/
if (!hw->fc.low_water ||
!hw->fc.high_water[packetbuf_num] ||
!hw->fc.pause_time) {
hw_dbg(hw, "Invalid water mark configuration\n");
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
if (hw->fc.disable_fc_autoneg)
goto out;
}
/*
* Validate the requested mode. Strict IEEE mode does not allow
* ixgbe_fc_rx_pause because it will cause us to fail at UNH.
*/
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;
hw->mac.ops.check_link(hw, &speed, &link_up, false);
if (!link_up)
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;
/*
* Set up the 1G and 10G flow control advertisement registers so the
* HW will be able to do fc autoneg once the cable is plugged in. If
* we link at 10G, the 1G advertisement is harmless and vice versa.
*/
switch (hw->phy.media_type) {
/* Autoneg flow control on fiber adapters */
case ixgbe_media_type_fiber:
if (speed == IXGBE_LINK_SPEED_1GB_FULL)
ret_val = ixgbe_fc_autoneg_fiber(hw);
break;
/* Autoneg flow control on backplane adapters */
case ixgbe_media_type_backplane:
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC);
ret_val = ixgbe_fc_autoneg_backplane(hw);
break;
/* Autoneg flow control on copper adapters */
case ixgbe_media_type_copper:
hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
MDIO_MMD_AN, &reg_cu);
if (ixgbe_device_supports_autoneg_fc(hw) == 0)
ret_val = ixgbe_fc_autoneg_copper(hw);
break;
default:
;
}
/*
* The possible values of fc.requested_mode are:
* 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
* we do not support receiving pause frames).
* 3: Both Rx and Tx flow control (symmetric) are enabled.
#ifdef CONFIG_DCB
* 4: Priority Flow Control is enabled.
#endif
* other: Invalid.
*/
switch (hw->fc.requested_mode) {
case ixgbe_fc_none:
/* Flow control completely disabled by software override. */
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
if (hw->phy.media_type == ixgbe_media_type_backplane)
reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE |
IXGBE_AUTOC_ASM_PAUSE);
else if (hw->phy.media_type == ixgbe_media_type_copper)
reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
break;
case ixgbe_fc_rx_pause:
/*
* Rx Flow control is enabled and Tx Flow control is
* disabled by software override. Since there really
* isn't a way to advertise that we are capable of RX
* Pause ONLY, we will advertise that we support both
* symmetric and asymmetric Rx PAUSE. Later, we will
* disable the adapter's ability to send PAUSE frames.
*/
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
if (hw->phy.media_type == ixgbe_media_type_backplane)
reg_bp |= (IXGBE_AUTOC_SYM_PAUSE |
IXGBE_AUTOC_ASM_PAUSE);
else if (hw->phy.media_type == ixgbe_media_type_copper)
reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
break;
case ixgbe_fc_tx_pause:
/*
* Tx Flow control is enabled, and Rx Flow control is
* disabled by software override.
*/
reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
if (hw->phy.media_type == ixgbe_media_type_backplane) {
reg_bp |= (IXGBE_AUTOC_ASM_PAUSE);
reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE);
} else if (hw->phy.media_type == ixgbe_media_type_copper) {
reg_cu |= (IXGBE_TAF_ASM_PAUSE);
reg_cu &= ~(IXGBE_TAF_SYM_PAUSE);
}
break;
case ixgbe_fc_full:
/* Flow control (both Rx and Tx) is enabled by SW override. */
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
if (hw->phy.media_type == ixgbe_media_type_backplane)
reg_bp |= (IXGBE_AUTOC_SYM_PAUSE |
IXGBE_AUTOC_ASM_PAUSE);
else if (hw->phy.media_type == ixgbe_media_type_copper)
reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
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;
}
if (hw->mac.type != ixgbe_mac_X540) {
/*
* Enable auto-negotiation between the MAC & PHY;
* the MAC will advertise clause 37 flow control.
*/
IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
/* Disable AN timeout */
if (hw->fc.strict_ieee)
reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
}
/*
* AUTOC restart handles negotiation of 1G and 10G on backplane
* and copper. There is no need to set the PCS1GCTL register.
*
*/
if (hw->phy.media_type == ixgbe_media_type_backplane) {
reg_bp |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
(ixgbe_device_supports_autoneg_fc(hw) == 0)) {
hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
MDIO_MMD_AN, reg_cu);
}
hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
out:
return ret_val;
if (ret_val == 0) {
hw->fc.fc_was_autonegged = true;
} else {
hw->fc.fc_was_autonegged = false;
hw->fc.current_mode = hw->fc.requested_mode;
}
}
/**
@ -3206,28 +3220,6 @@ wwn_prefix_out:
return 0;
}
/**
* ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow
* control
* @hw: pointer to hardware structure
*
* There are several phys that do not support autoneg flow control. This
* function check the device id to see if the associated phy supports
* autoneg flow control.
**/
static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
{
switch (hw->device_id) {
case IXGBE_DEV_ID_X540T:
return 0;
case IXGBE_DEV_ID_82599_T3_LOM:
return 0;
default:
return IXGBE_ERR_FC_NOT_SUPPORTED;
}
}
/**
* ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
* @hw: pointer to hardware structure