|
@@ -59,12 +59,34 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
|
|
|
bool autoneg_wait_to_complete);
|
|
|
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
|
|
|
|
|
|
+static bool ixgbe_mng_enabled(struct ixgbe_hw *hw)
|
|
|
+{
|
|
|
+ u32 fwsm, manc, factps;
|
|
|
+
|
|
|
+ fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM);
|
|
|
+ if ((fwsm & IXGBE_FWSM_MODE_MASK) != IXGBE_FWSM_FW_MODE_PT)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ manc = IXGBE_READ_REG(hw, IXGBE_MANC);
|
|
|
+ if (!(manc & IXGBE_MANC_RCV_TCO_EN))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ factps = IXGBE_READ_REG(hw, IXGBE_FACTPS);
|
|
|
+ if (factps & IXGBE_FACTPS_MNGCG)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
struct ixgbe_mac_info *mac = &hw->mac;
|
|
|
|
|
|
- /* enable the laser control functions for SFP+ fiber */
|
|
|
- if (mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) {
|
|
|
+ /* enable the laser control functions for SFP+ fiber
|
|
|
+ * and MNG not enabled
|
|
|
+ */
|
|
|
+ if ((mac->ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
|
|
|
+ !hw->mng_fw_enabled) {
|
|
|
mac->ops.disable_tx_laser =
|
|
|
&ixgbe_disable_tx_laser_multispeed_fiber;
|
|
|
mac->ops.enable_tx_laser =
|
|
@@ -563,7 +585,8 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
|
|
return status;
|
|
|
|
|
|
/* Flap the tx laser if it has not already been done */
|
|
|
- hw->mac.ops.flap_tx_laser(hw);
|
|
|
+ if (hw->mac.ops.flap_tx_laser)
|
|
|
+ hw->mac.ops.flap_tx_laser(hw);
|
|
|
|
|
|
/*
|
|
|
* Wait for the controller to acquire link. Per IEEE 802.3ap,
|
|
@@ -615,7 +638,8 @@ static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
|
|
return status;
|
|
|
|
|
|
/* Flap the tx laser if it has not already been done */
|
|
|
- hw->mac.ops.flap_tx_laser(hw);
|
|
|
+ if (hw->mac.ops.flap_tx_laser)
|
|
|
+ hw->mac.ops.flap_tx_laser(hw);
|
|
|
|
|
|
/* Wait for the link partner to also set speed */
|
|
|
msleep(100);
|
|
@@ -933,6 +957,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
|
|
|
ixgbe_link_speed link_speed;
|
|
|
s32 status;
|
|
|
u32 ctrl, i, autoc, autoc2;
|
|
|
+ u32 curr_lms;
|
|
|
bool link_up = false;
|
|
|
|
|
|
/* Call adapter stop to disable tx/rx and clear interrupts */
|
|
@@ -964,6 +989,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
|
|
|
if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
|
|
|
hw->phy.ops.reset(hw);
|
|
|
|
|
|
+ /* remember AUTOC LMS from before we reset */
|
|
|
+ curr_lms = IXGBE_READ_REG(hw, IXGBE_AUTOC) & IXGBE_AUTOC_LMS_MASK;
|
|
|
+
|
|
|
mac_reset_top:
|
|
|
/*
|
|
|
* Issue global reset to the MAC. Needs to be SW reset if link is up.
|
|
@@ -1019,6 +1047,16 @@ mac_reset_top:
|
|
|
hw->mac.orig_autoc2 = autoc2;
|
|
|
hw->mac.orig_link_settings_stored = true;
|
|
|
} else {
|
|
|
+
|
|
|
+ /* If MNG FW is running on a multi-speed device that
|
|
|
+ * doesn't autoneg with out driver support we need to
|
|
|
+ * leave LMS in the state it was before we MAC reset.
|
|
|
+ */
|
|
|
+ if (hw->phy.multispeed_fiber && hw->mng_fw_enabled)
|
|
|
+ hw->mac.orig_autoc =
|
|
|
+ (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) |
|
|
|
+ curr_lms;
|
|
|
+
|
|
|
if (autoc != hw->mac.orig_autoc) {
|
|
|
/* Need SW/FW semaphore around AUTOC writes if LESM is
|
|
|
* on, likewise reset_pipeline requires us to hold
|
|
@@ -2216,7 +2254,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
|
|
|
.release_swfw_sync = &ixgbe_release_swfw_sync,
|
|
|
.get_thermal_sensor_data = &ixgbe_get_thermal_sensor_data_generic,
|
|
|
.init_thermal_sensor_thresh = &ixgbe_init_thermal_sensor_thresh_generic,
|
|
|
-
|
|
|
+ .mng_fw_enabled = &ixgbe_mng_enabled,
|
|
|
};
|
|
|
|
|
|
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
|