net/ixgbe/base: add function to reset swfw semaphore
authorBeilei Xing <beilei.xing@intel.com>
Thu, 23 Jun 2016 07:22:25 +0000 (15:22 +0800)
committerBruce Richardson <bruce.richardson@intel.com>
Mon, 27 Jun 2016 14:17:53 +0000 (16:17 +0200)
For X540 onwards it is possible if a system reset occurs at the
right time to leave the SWFW semaphore high. This new function will
attempt to grab and release the semaphore. If the grab times out it
will still release the semaphore placing it in a known good state.
The idea is to call this when you know no one should be holding the
semaphore (i.e. probe time)

Signed-off-by: Beilei Xing <beilei.xing@intel.com>
drivers/net/ixgbe/base/ixgbe_api.c
drivers/net/ixgbe/base/ixgbe_api.h
drivers/net/ixgbe/base/ixgbe_common.c
drivers/net/ixgbe/base/ixgbe_type.h
drivers/net/ixgbe/base/ixgbe_x540.c
drivers/net/ixgbe/base/ixgbe_x540.h

index 19e52c9..e117b86 100644 (file)
@@ -1639,6 +1639,20 @@ void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u32 mask)
                hw->mac.ops.release_swfw_sync(hw, mask);
 }
 
+/**
+ *  ixgbe_init_swfw_semaphore - Clean up SWFW semaphore
+ *  @hw: pointer to hardware structure
+ *
+ *  Attempts to acquire the SWFW semaphore through SW_FW_SYNC register.
+ *  Regardless of whether is succeeds or not it then release the semaphore.
+ *  This is function is called to recover from catastrophic failures that
+ *  may have left the semaphore locked.
+ **/
+void ixgbe_init_swfw_semaphore(struct ixgbe_hw *hw)
+{
+       if (hw->mac.ops.init_swfw_sync)
+               hw->mac.ops.init_swfw_sync(hw);
+}
 
 void ixgbe_disable_rx(struct ixgbe_hw *hw)
 {
index ae26a6a..f5970a8 100644 (file)
@@ -191,6 +191,7 @@ s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr);
 s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps);
 s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u32 mask);
 void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u32 mask);
+void ixgbe_init_swfw_semaphore(struct ixgbe_hw *hw);
 s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix,
                         u16 *wwpn_prefix);
 s32 ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs);
index d211303..0a74714 100644 (file)
@@ -4390,6 +4390,7 @@ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
                DEBUGOUT1("Buffer length failure buffersize=%d.\n", length);
                return IXGBE_ERR_HOST_INTERFACE_COMMAND;
        }
+
        /* Set bit 9 of FWSTS clearing FW reset indication */
        fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS);
        IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI);
index 6a837f1..f40580d 100644 (file)
@@ -3785,6 +3785,7 @@ struct ixgbe_mac_operations {
        s32 (*enable_sec_rx_path)(struct ixgbe_hw *);
        s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u32);
        void (*release_swfw_sync)(struct ixgbe_hw *, u32);
+       void (*init_swfw_sync)(struct ixgbe_hw *);
        s32 (*prot_autoc_read)(struct ixgbe_hw *, bool *, u32 *);
        s32 (*prot_autoc_write)(struct ixgbe_hw *, u32, bool);
 
index 0678913..31dead0 100644 (file)
@@ -99,6 +99,7 @@ s32 ixgbe_init_ops_X540(struct ixgbe_hw *hw)
        mac->ops.get_fcoe_boot_status = ixgbe_get_fcoe_boot_status_generic;
        mac->ops.acquire_swfw_sync = ixgbe_acquire_swfw_sync_X540;
        mac->ops.release_swfw_sync = ixgbe_release_swfw_sync_X540;
+       mac->ops.init_swfw_sync = ixgbe_init_swfw_sync_X540;
        mac->ops.disable_sec_rx_path = ixgbe_disable_sec_rx_path_generic;
        mac->ops.enable_sec_rx_path = ixgbe_enable_sec_rx_path_generic;
 
@@ -945,6 +946,25 @@ STATIC void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
        IXGBE_WRITE_FLUSH(hw);
 }
 
+/**
+ *  ixgbe_init_swfw_sync_X540 - Release hardware semaphore
+ *  @hw: pointer to hardware structure
+ *
+ *  This function reset hardware semaphore bits for a semaphore that may
+ *  have be left locked due to a catastrophic failure.
+ **/
+void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw)
+{
+       /* First try to grab the semaphore but we don't need to bother
+        * looking to see whether we got the lock or  not since we do
+        * the same thing regardless of whether we got the lock or not.
+        * We got the lock - we release it.
+        * We timeout trying to get the lock - we force its release.
+        */
+       ixgbe_get_swfw_sync_semaphore(hw);
+       ixgbe_release_swfw_sync_semaphore(hw);
+}
+
 /**
  * ixgbe_blink_led_start_X540 - Blink LED based on index.
  * @hw: pointer to hardware structure
index 42c08a8..e4baf6f 100644 (file)
@@ -59,6 +59,7 @@ s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw);
 
 s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask);
 void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask);
+void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw);
 
 s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index);
 s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index);