|
@@ -62,7 +62,6 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
|
|
|
bool autoneg,
|
|
|
bool autoneg_wait_to_complete);
|
|
|
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
|
|
|
-static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
|
|
|
|
|
|
static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
|
|
|
{
|
|
@@ -99,9 +98,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
|
|
|
static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
s32 ret_val = 0;
|
|
|
- u32 reg_anlp1 = 0;
|
|
|
- u32 i = 0;
|
|
|
u16 list_offset, data_offset, data_value;
|
|
|
+ bool got_lock = false;
|
|
|
|
|
|
if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
|
|
|
ixgbe_init_mac_link_ops_82599(hw);
|
|
@@ -137,28 +135,36 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
|
|
|
usleep_range(hw->eeprom.semaphore_delay * 1000,
|
|
|
hw->eeprom.semaphore_delay * 2000);
|
|
|
|
|
|
- /* Now restart DSP by setting Restart_AN and clearing LMS */
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
|
|
|
- IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) |
|
|
|
- IXGBE_AUTOC_AN_RESTART));
|
|
|
-
|
|
|
- /* Wait for AN to leave state 0 */
|
|
|
- for (i = 0; i < 10; i++) {
|
|
|
- usleep_range(4000, 8000);
|
|
|
- reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
|
|
|
- if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
|
|
|
- break;
|
|
|
+ /* Need SW/FW semaphore around AUTOC writes if LESM on,
|
|
|
+ * likewise reset_pipeline requires lock as it also writes
|
|
|
+ * AUTOC.
|
|
|
+ */
|
|
|
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
|
|
|
+ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
|
|
|
+ IXGBE_GSSR_MAC_CSR_SM);
|
|
|
+ if (ret_val)
|
|
|
+ goto setup_sfp_out;
|
|
|
+
|
|
|
+ got_lock = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Restart DSP and set SFI mode */
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
|
|
|
+ IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL));
|
|
|
+
|
|
|
+ ret_val = ixgbe_reset_pipeline_82599(hw);
|
|
|
+
|
|
|
+ if (got_lock) {
|
|
|
+ hw->mac.ops.release_swfw_sync(hw,
|
|
|
+ IXGBE_GSSR_MAC_CSR_SM);
|
|
|
+ got_lock = false;
|
|
|
}
|
|
|
- if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
|
|
|
- hw_dbg(hw, "sfp module setup not complete\n");
|
|
|
+
|
|
|
+ if (ret_val) {
|
|
|
+ hw_dbg(hw, " sfp module setup not complete\n");
|
|
|
ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
|
|
|
goto setup_sfp_out;
|
|
|
}
|
|
|
-
|
|
|
- /* Restart DSP by setting Restart_AN and return to SFI mode */
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
|
|
|
- IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
|
|
|
- IXGBE_AUTOC_AN_RESTART));
|
|
|
}
|
|
|
|
|
|
setup_sfp_out:
|
|
@@ -394,14 +400,26 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
|
|
|
u32 links_reg;
|
|
|
u32 i;
|
|
|
s32 status = 0;
|
|
|
+ bool got_lock = false;
|
|
|
+
|
|
|
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
|
|
|
+ status = hw->mac.ops.acquire_swfw_sync(hw,
|
|
|
+ IXGBE_GSSR_MAC_CSR_SM);
|
|
|
+ if (status)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ got_lock = true;
|
|
|
+ }
|
|
|
|
|
|
/* Restart link */
|
|
|
- autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
|
|
- autoc_reg |= IXGBE_AUTOC_AN_RESTART;
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
|
|
|
+ ixgbe_reset_pipeline_82599(hw);
|
|
|
+
|
|
|
+ if (got_lock)
|
|
|
+ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
|
|
|
|
|
|
/* Only poll for autoneg to complete if specified to do so */
|
|
|
if (autoneg_wait_to_complete) {
|
|
|
+ autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
|
|
if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
|
|
|
IXGBE_AUTOC_LMS_KX4_KX_KR ||
|
|
|
(autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
|
|
@@ -425,6 +443,7 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
|
|
|
/* Add delay to filter out noises during initial link setup */
|
|
|
msleep(50);
|
|
|
|
|
|
+out:
|
|
|
return status;
|
|
|
}
|
|
|
|
|
@@ -779,6 +798,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
|
|
|
u32 links_reg;
|
|
|
u32 i;
|
|
|
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
|
|
|
+ bool got_lock = false;
|
|
|
|
|
|
/* Check to see if speed passed in is supported. */
|
|
|
status = hw->mac.ops.get_link_capabilities(hw, &link_capabilities,
|
|
@@ -836,9 +856,26 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
|
|
|
}
|
|
|
|
|
|
if (autoc != start_autoc) {
|
|
|
+ /* Need SW/FW semaphore around AUTOC writes if LESM is on,
|
|
|
+ * likewise reset_pipeline requires us to hold this lock as
|
|
|
+ * it also writes to AUTOC.
|
|
|
+ */
|
|
|
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
|
|
|
+ status = hw->mac.ops.acquire_swfw_sync(hw,
|
|
|
+ IXGBE_GSSR_MAC_CSR_SM);
|
|
|
+ if (status != 0)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ got_lock = true;
|
|
|
+ }
|
|
|
+
|
|
|
/* Restart link */
|
|
|
- autoc |= IXGBE_AUTOC_AN_RESTART;
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
|
|
|
+ ixgbe_reset_pipeline_82599(hw);
|
|
|
+
|
|
|
+ if (got_lock)
|
|
|
+ hw->mac.ops.release_swfw_sync(hw,
|
|
|
+ IXGBE_GSSR_MAC_CSR_SM);
|
|
|
|
|
|
/* Only poll for autoneg to complete if specified to do so */
|
|
|
if (autoneg_wait_to_complete) {
|
|
@@ -994,9 +1031,28 @@ mac_reset_top:
|
|
|
hw->mac.orig_autoc2 = autoc2;
|
|
|
hw->mac.orig_link_settings_stored = true;
|
|
|
} else {
|
|
|
- if (autoc != hw->mac.orig_autoc)
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
|
|
|
- IXGBE_AUTOC_AN_RESTART));
|
|
|
+ if (autoc != hw->mac.orig_autoc) {
|
|
|
+ /* Need SW/FW semaphore around AUTOC writes if LESM is
|
|
|
+ * on, likewise reset_pipeline requires us to hold
|
|
|
+ * this lock as it also writes to AUTOC.
|
|
|
+ */
|
|
|
+ bool got_lock = false;
|
|
|
+ if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
|
|
|
+ status = hw->mac.ops.acquire_swfw_sync(hw,
|
|
|
+ IXGBE_GSSR_MAC_CSR_SM);
|
|
|
+ if (status)
|
|
|
+ goto reset_hw_out;
|
|
|
+
|
|
|
+ got_lock = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
|
|
|
+ ixgbe_reset_pipeline_82599(hw);
|
|
|
+
|
|
|
+ if (got_lock)
|
|
|
+ hw->mac.ops.release_swfw_sync(hw,
|
|
|
+ IXGBE_GSSR_MAC_CSR_SM);
|
|
|
+ }
|
|
|
|
|
|
if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
|
|
|
(hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
|
|
@@ -1983,7 +2039,7 @@ fw_version_out:
|
|
|
* Returns true if the LESM FW module is present and enabled. Otherwise
|
|
|
* returns false. Smart Speed must be disabled if LESM FW module is enabled.
|
|
|
**/
|
|
|
-static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
|
|
|
+bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
bool lesm_enabled = false;
|
|
|
u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
|