net/ixgbe/base: add function to reset swfw semaphore

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>
This commit is contained in:
Beilei Xing 2016-06-23 15:22:25 +08:00 committed by Bruce Richardson
parent f2a5f0b8ee
commit 6e42840a4d
6 changed files with 38 additions and 0 deletions

View 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)
{

View 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);

View 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);

View 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);

View 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

View 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);