ixgbe/base: rework protected access to autoc register
authorJijiang Liu <jijiang.liu@intel.com>
Wed, 18 Jun 2014 17:40:32 +0000 (19:40 +0200)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 18 Jun 2014 21:31:46 +0000 (23:31 +0200)
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
[Thomas: split code drop]

lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_82599.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h

index 6a1b263..fc5f7d7 100644 (file)
@@ -165,7 +165,6 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 {
        s32 ret_val = IXGBE_SUCCESS;
        u16 list_offset, data_offset, data_value;
-       bool got_lock = false;
 
        DEBUGFUNC("ixgbe_setup_sfp_modules_82599");
 
@@ -187,44 +186,26 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
                        goto setup_sfp_out;
                }
 
-               hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+               if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
+                       goto setup_sfp_err;
                while (data_value != 0xffff) {
                        IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
                        IXGBE_WRITE_FLUSH(hw);
-                       hw->eeprom.ops.read(hw, ++data_offset, &data_value);
+                       if (hw->eeprom.ops.read(hw, ++data_offset, &data_value))
+                               goto setup_sfp_err;
                }
 
                /* Release the semaphore */
                hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
-               /* Delay obtaining semaphore again to allow FW access */
-               msec_delay(hw->eeprom.semaphore_delay);
-
-               /* Need SW/FW semaphore around AUTOC writes if LESM on,
-                * likewise reset_pipeline requires lock as it also writes
-                * AUTOC.
+               /* Delay obtaining semaphore again to allow FW access
+                * prot_autoc_write uses the semaphore too.
                 */
-               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 != IXGBE_SUCCESS) {
-                               ret_val = IXGBE_ERR_SWFW_SYNC;
-                               goto setup_sfp_out;
-                       }
-
-                       got_lock = true;
-               }
+               msec_delay(hw->eeprom.semaphore_delay);
 
                /* 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;
-               }
+               ret_val = hw->mac.ops.prot_autoc_write(hw,
+                       hw->mac.orig_autoc | IXGBE_AUTOC_LMS_10G_SERIAL,
+                       false);
 
                if (ret_val) {
                        DEBUGOUT("sfp module setup not complete\n");
@@ -236,6 +217,88 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 
 setup_sfp_out:
        return ret_val;
+
+setup_sfp_err:
+       /* Release the semaphore */
+       hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+       /* Delay obtaining semaphore again to allow FW access */
+       msec_delay(hw->eeprom.semaphore_delay);
+       ERROR_REPORT2(IXGBE_ERROR_INVALID_STATE,
+                     "eeprom read at offset %d failed", data_offset);
+       return IXGBE_ERR_PHY;
+}
+
+/**
+ *  prot_autoc_read_82599 - Hides MAC differences needed for AUTOC read
+ *  @hw: pointer to hardware structure
+ *  @locked: Return the if we locked for this read.
+ *  @reg_val: Value we read from AUTOC
+ *
+ *  For this part (82599) we need to wrap read-modify-writes with a possible
+ *  FW/SW lock.  It is assumed this lock will be freed with the next
+ *  prot_autoc_write_82599().
+ */
+s32 prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, u32 *reg_val)
+{
+       s32 ret_val;
+
+       *locked = false;
+        /* If LESM is on then we need to hold the SW/FW semaphore. */
+       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 != IXGBE_SUCCESS)
+                       return IXGBE_ERR_SWFW_SYNC;
+
+               *locked = true;
+       }
+
+       *reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       return IXGBE_SUCCESS;
+}
+
+/**
+ * prot_autoc_write_82599 - Hides MAC differences needed for AUTOC write
+ * @hw: pointer to hardware structure
+ * @reg_val: value to write to AUTOC
+ * @locked: bool to indicate whether the SW/FW lock was already taken by
+ *           previous proc_autoc_read_82599.
+ *
+ * This part (82599) may need to hold a the SW/FW lock around all writes to
+ * AUTOC. Likewise after a write we need to do a pipeline reset.
+ */
+s32 prot_autoc_write_82599(struct ixgbe_hw *hw, u32 autoc, bool locked)
+{
+       s32 ret_val = IXGBE_SUCCESS;
+
+       /* Blocked by MNG FW so bail */
+       if (ixgbe_check_reset_blocked(hw))
+               goto out;
+
+       /* We only need to get the lock if:
+        *  - We didn't do it already (in the read part of a read-modify-write)
+        *  - LESM is enabled.
+        */
+       if (!locked && ixgbe_verify_lesm_fw_enabled_82599(hw)) {
+               ret_val = hw->mac.ops.acquire_swfw_sync(hw,
+                                       IXGBE_GSSR_MAC_CSR_SM);
+               if (ret_val != IXGBE_SUCCESS)
+                       return IXGBE_ERR_SWFW_SYNC;
+
+               locked = true;
+       }
+
+       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
+       ret_val = ixgbe_reset_pipeline_82599(hw);
+
+out:
+       /* Free the SW/FW semaphore as we either grabbed it here or
+        * already had it when this function was called.
+        */
+       if (locked)
+               hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+
+       return ret_val;
 }
 
 /**
@@ -279,6 +342,8 @@ s32 ixgbe_init_ops_82599(struct ixgbe_hw *hw)
        mac->ops.get_device_caps = &ixgbe_get_device_caps_generic;
        mac->ops.get_wwn_prefix = &ixgbe_get_wwn_prefix_generic;
        mac->ops.get_fcoe_boot_status = &ixgbe_get_fcoe_boot_status_generic;
+       mac->ops.prot_autoc_read = &prot_autoc_read_82599;
+       mac->ops.prot_autoc_write = &prot_autoc_write_82599;
 
        /* RAR, Multicast, VLAN */
        mac->ops.set_vmdq = &ixgbe_set_vmdq_generic;
@@ -943,17 +1008,15 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
 {
        bool autoneg = false;
        s32 status = IXGBE_SUCCESS;
-       u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 pma_pmd_1g, link_mode;
+       u32 current_autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC); /* holds the value of AUTOC register at this current point in time */
+       u32 orig_autoc = 0; /* holds the cached value of AUTOC register */
+       u32 autoc = current_autoc; /* Temporary variable used for comparison purposes */
        u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
-       u32 start_autoc = autoc;
-       u32 orig_autoc = 0;
-       u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
-       u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
        u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
        u32 links_reg;
        u32 i;
        ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
-       bool got_lock = false;
 
        DEBUGFUNC("ixgbe_setup_mac_link_82599");
 
@@ -975,6 +1038,9 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
        else
                orig_autoc = autoc;
 
+       link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
+       pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+
        if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
            link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
            link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
@@ -1011,31 +1077,11 @@ 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 != IXGBE_SUCCESS) {
-                               status = IXGBE_ERR_SWFW_SYNC;
-                               goto out;
-                       }
-
-                       got_lock = true;
-               }
-
+       if (autoc != current_autoc) {
                /* Restart link */
-               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);
-                       got_lock = false;
-               }
+               status = hw->mac.ops.prot_autoc_write(hw, autoc, false);
+               if (status != IXGBE_SUCCESS)
+                       goto out;
 
                /* Only poll for autoneg to complete if specified to do so */
                if (autoneg_wait_to_complete) {
@@ -1103,7 +1149,9 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
 {
        ixgbe_link_speed link_speed;
        s32 status;
-       u32 ctrl, i, autoc, autoc2;
+       u32 ctrl = 0;
+       u32 i, autoc, autoc2;
+       u32 curr_lms;
        bool link_up = false;
 
        DEBUGFUNC("ixgbe_reset_hw_82599");
@@ -1137,6 +1185,9 @@ 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 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.
@@ -1200,29 +1251,25 @@ mac_reset_top:
                hw->mac.orig_autoc2 = autoc2;
                hw->mac.orig_link_settings_stored = true;
        } else {
-               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 != IXGBE_SUCCESS) {
-                                       status = IXGBE_ERR_SWFW_SYNC;
-                                       goto reset_hw_out;
-                               }
-
-                               got_lock = true;
-                       }
 
-                       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
-                       ixgbe_reset_pipeline_82599(hw);
+               /* 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.
+                * Likewise if we support WoL we don't want change the
+                * LMS state.
+                */
+               if ((hw->phy.multispeed_fiber && ixgbe_mng_enabled(hw)) ||
+                   hw->wol_enabled)
+                       hw->mac.orig_autoc =
+                               (hw->mac.orig_autoc & ~IXGBE_AUTOC_LMS_MASK) |
+                               curr_lms;
 
-                       if (got_lock)
-                               hw->mac.ops.release_swfw_sync(hw,
-                                                     IXGBE_GSSR_MAC_CSR_SM);
+               if (autoc != hw->mac.orig_autoc) {
+                       status = hw->mac.ops.prot_autoc_write(hw,
+                                                       hw->mac.orig_autoc,
+                                                       false);
+                       if (status != IXGBE_SUCCESS)
+                               goto reset_hw_out;
                }
 
                if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
@@ -2430,12 +2477,13 @@ STATIC s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
  *  @hw: pointer to hardware structure
  *
  * Reset pipeline by asserting Restart_AN together with LMS change to ensure
- * full pipeline reset
+ * full pipeline reset.  This function assumes the SW/FW lock is held.
  **/
 s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
 {
-       s32 i, autoc_reg, autoc2_reg, ret_val;
-       s32 anlp1_reg = 0;
+       s32 ret_val;
+       u32 anlp1_reg = 0;
+       u32 i, autoc_reg, autoc2_reg;
 
        /* Enable link if disabled in NVM */
        autoc2_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
@@ -2448,7 +2496,8 @@ s32 ixgbe_reset_pipeline_82599(struct ixgbe_hw *hw)
        autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
        autoc_reg |= IXGBE_AUTOC_AN_RESTART;
        /* Write AUTOC register with toggled LMS[2] bit and Restart_AN */
-       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg ^ IXGBE_AUTOC_LMS_1G_AN);
+       IXGBE_WRITE_REG(hw, IXGBE_AUTOC,
+                       autoc_reg ^ (0x4 << IXGBE_AUTOC_LMS_SHIFT));
        /* Wait for AN to leave state 0 */
        for (i = 0; i < 10; i++) {
                msec_delay(4);
index d30eb6d..05223ee 100644 (file)
@@ -61,4 +61,6 @@ s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
 s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw);
 u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
 s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval);
+s32 prot_autoc_read_82599(struct ixgbe_hw *hw, bool *locked, u32 *reg_val);
+s32 prot_autoc_write_82599(struct ixgbe_hw *hw, u32 reg_val, bool locked);
 #endif /* _IXGBE_82599_H_ */
index eb3bba7..f3968c6 100644 (file)
@@ -106,6 +106,8 @@ s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw)
        mac->ops.set_lan_id = &ixgbe_set_lan_id_multi_port_pcie;
        mac->ops.acquire_swfw_sync = &ixgbe_acquire_swfw_sync;
        mac->ops.release_swfw_sync = &ixgbe_release_swfw_sync;
+       mac->ops.prot_autoc_read = &prot_autoc_read_generic;
+       mac->ops.prot_autoc_write = &prot_autoc_write_generic;
 
        /* LEDs */
        mac->ops.led_on = &ixgbe_led_on_generic;
@@ -204,7 +206,7 @@ STATIC s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
        s32 ret_val = IXGBE_SUCCESS;
        u32 reg = 0, reg_bp = 0;
        u16 reg_cu = 0;
-       bool got_lock = false;
+       bool locked = false;
 
        DEBUGFUNC("ixgbe_setup_fc");
 
@@ -232,10 +234,16 @@ STATIC s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
         * 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:
+               /* some MAC's need RMW protection on AUTOC */
+               ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &reg_bp);
+               if (ret_val != IXGBE_SUCCESS)
+                       goto out;
+
+               /* only backplane uses autoc so fall though */
+       case ixgbe_media_type_fiber:
                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, IXGBE_MDIO_AUTO_NEG_ADVT,
@@ -330,30 +338,11 @@ STATIC s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
         */
        if (hw->phy.media_type == ixgbe_media_type_backplane) {
                reg_bp |= IXGBE_AUTOC_AN_RESTART;
-               /* Need the SW/FW semaphore around AUTOC writes if 82599 and
-                * LESM is on, likewise reset_pipeline requries the lock as
-                * it also writes AUTOC.
-                */
-               if ((hw->mac.type == ixgbe_mac_82599EB) &&
-                   ixgbe_verify_lesm_fw_enabled_82599(hw)) {
-                       ret_val = hw->mac.ops.acquire_swfw_sync(hw,
-                                                       IXGBE_GSSR_MAC_CSR_SM);
-                       if (ret_val != IXGBE_SUCCESS) {
-                               ret_val = IXGBE_ERR_SWFW_SYNC;
-                               goto out;
-                       }
-                       got_lock = true;
-               }
-
-               IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
-               if (hw->mac.type == ixgbe_mac_82599EB)
-                       ixgbe_reset_pipeline_82599(hw);
-
-               if (got_lock)
-                       hw->mac.ops.release_swfw_sync(hw,
-                                                     IXGBE_GSSR_MAC_CSR_SM);
+               ret_val = hw->mac.ops.prot_autoc_write(hw, reg_bp, locked);
+               if (ret_val)
+                       goto out;
        } else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
-                   (ixgbe_device_supports_autoneg_fc(hw) == IXGBE_SUCCESS)) {
+                   (ixgbe_device_supports_autoneg_fc(hw))) {
                hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_ADVT,
                                      IXGBE_MDIO_AUTO_NEG_DEV_TYPE, reg_cu);
        }
@@ -3258,6 +3247,37 @@ s32 ixgbe_disable_sec_rx_path_generic(struct ixgbe_hw *hw)
        return IXGBE_SUCCESS;
 }
 
+/**
+ *  prot_autoc_read_generic - Hides MAC differences needed for AUTOC read
+ *  @hw: pointer to hardware structure
+ *  @reg_val: Value we read from AUTOC
+ *
+ *  The default case requires no protection so just to the register read.
+ */
+s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *locked, u32 *reg_val)
+{
+       *locked = false;
+       *reg_val = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       return IXGBE_SUCCESS;
+}
+
+/**
+ * prot_autoc_write_generic - Hides MAC differences needed for AUTOC write
+ * @hw: pointer to hardware structure
+ * @reg_val: value to write to AUTOC
+ * @locked: bool to indicate whether the SW/FW lock was already taken by
+ *           previous read.
+ *
+ * The default case requires no protection so just to the register write.
+ */
+s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked)
+{
+       UNREFERENCED_1PARAMETER(locked);
+
+       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_val);
+       return IXGBE_SUCCESS;
+}
+
 /**
  *  ixgbe_enable_sec_rx_path_generic - Enables the receive data path
  *  @hw: pointer to hardware structure
@@ -3306,9 +3326,10 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
 {
        ixgbe_link_speed speed = 0;
        bool link_up = 0;
-       u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 autoc_reg = 0;
        u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
        s32 ret_val = IXGBE_SUCCESS;
+       bool locked = false;
 
        DEBUGFUNC("ixgbe_blink_led_start_generic");
 
@@ -3319,29 +3340,18 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
        hw->mac.ops.check_link(hw, &speed, &link_up, false);
 
        if (!link_up) {
-               /* Need the SW/FW semaphore around AUTOC writes if 82599 and
-                * LESM is on.
-                */
-               bool got_lock = false;
-               if ((hw->mac.type == ixgbe_mac_82599EB) &&
-                   ixgbe_verify_lesm_fw_enabled_82599(hw)) {
-                       ret_val = hw->mac.ops.acquire_swfw_sync(hw,
-                                                       IXGBE_GSSR_MAC_CSR_SM);
-                       if (ret_val != IXGBE_SUCCESS) {
-                               ret_val = IXGBE_ERR_SWFW_SYNC;
-                               goto out;
-                       }
-                       got_lock = true;
-               }
+               ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
+               if (ret_val != IXGBE_SUCCESS)
+                       goto out;
 
                autoc_reg |= IXGBE_AUTOC_AN_RESTART;
                autoc_reg |= IXGBE_AUTOC_FLU;
-               IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-               IXGBE_WRITE_FLUSH(hw);
 
-               if (got_lock)
-                       hw->mac.ops.release_swfw_sync(hw,
-                                                     IXGBE_GSSR_MAC_CSR_SM);
+               ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
+               if (ret_val != IXGBE_SUCCESS)
+                       goto out;
+
+               IXGBE_WRITE_FLUSH(hw);
                msec_delay(10);
        }
 
@@ -3361,36 +3371,23 @@ out:
  **/
 s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
 {
-       u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 autoc_reg = 0;
        u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
        s32 ret_val = IXGBE_SUCCESS;
-       bool got_lock = false;
+       bool locked = false;
 
        DEBUGFUNC("ixgbe_blink_led_stop_generic");
-       /* Need the SW/FW semaphore around AUTOC writes if 82599 and
-        * LESM is on.
-        */
-       if ((hw->mac.type == ixgbe_mac_82599EB) &&
-           ixgbe_verify_lesm_fw_enabled_82599(hw)) {
-               ret_val = hw->mac.ops.acquire_swfw_sync(hw,
-                                               IXGBE_GSSR_MAC_CSR_SM);
-               if (ret_val != IXGBE_SUCCESS) {
-                       ret_val = IXGBE_ERR_SWFW_SYNC;
-                       goto out;
-               }
-               got_lock = true;
-       }
 
+       ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
+       if (ret_val != IXGBE_SUCCESS)
+               goto out;
 
        autoc_reg &= ~IXGBE_AUTOC_FLU;
        autoc_reg |= IXGBE_AUTOC_AN_RESTART;
-       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
 
-       if (hw->mac.type == ixgbe_mac_82599EB)
-               ixgbe_reset_pipeline_82599(hw);
-
-       if (got_lock)
-               hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+       ret_val = hw->mac.ops.prot_autoc_write(hw, autoc_reg, locked);
+       if (ret_val != IXGBE_SUCCESS)
+               goto out;
 
        led_reg &= ~IXGBE_LED_MODE_MASK(index);
        led_reg &= ~IXGBE_LED_BLINK(index);
index 0413f19..75a6ef7 100644 (file)
@@ -120,6 +120,9 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
 void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask);
 s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
 
+s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *, u32 *reg_val);
+s32 prot_autoc_write_generic(struct ixgbe_hw *hw, u32 reg_val, bool locked);
+
 s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index);
 s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
 
index 991bc61..11fa5c9 100644 (file)
@@ -3047,6 +3047,8 @@ struct ixgbe_mac_operations {
        s32 (*enable_sec_rx_path)(struct ixgbe_hw *);
        s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u16);
        void (*release_swfw_sync)(struct ixgbe_hw *, u16);
+       s32 (*prot_autoc_read)(struct ixgbe_hw *, bool *, u32 *);
+       s32 (*prot_autoc_write)(struct ixgbe_hw *, u32, bool);
 
        /* Link */
        void (*disable_tx_laser)(struct ixgbe_hw *);