Commit 674c18b2 authored by Emil Tantilov's avatar Emil Tantilov Committed by Jeff Kirsher

ixgbe: clear semaphore bits on timeouts

This patch changes the error code path in ixgbe_acquire_swfw_sync() to deal
with cases where acquiring SW semaphore times out.

In cases where the SW/FW semaphore bits were set (i.e. due to a crash) the
driver will hang on load. With this patch the driver will clear
the stuck bits if the semaphore was not acquired in the allotted time.
Signed-off-by: default avatarEmil Tantilov <emil.s.tantilov@intel.com>
Tested-by: default avatarPhil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 9c432ada
...@@ -2506,42 +2506,39 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) ...@@ -2506,42 +2506,39 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
**/ **/
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
{ {
u32 gssr; u32 gssr = 0;
u32 swmask = mask; u32 swmask = mask;
u32 fwmask = mask << 5; u32 fwmask = mask << 5;
s32 timeout = 200; u32 timeout = 200;
u32 i;
while (timeout) { for (i = 0; i < timeout; i++) {
/* /*
* SW EEPROM semaphore bit is used for access to all * SW NVM semaphore bit is used for access to all
* SW_FW_SYNC/GSSR bits (not just EEPROM) * SW_FW_SYNC bits (not just NVM)
*/ */
if (ixgbe_get_eeprom_semaphore(hw)) if (ixgbe_get_eeprom_semaphore(hw))
return IXGBE_ERR_SWFW_SYNC; return IXGBE_ERR_SWFW_SYNC;
gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
if (!(gssr & (fwmask | swmask))) if (!(gssr & (fwmask | swmask))) {
break; gssr |= swmask;
IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
/* ixgbe_release_eeprom_semaphore(hw);
* Firmware currently using resource (fwmask) or other software return 0;
* thread currently using resource (swmask) } else {
*/ /* Resource is currently in use by FW or SW */
ixgbe_release_eeprom_semaphore(hw); ixgbe_release_eeprom_semaphore(hw);
usleep_range(5000, 10000); usleep_range(5000, 10000);
timeout--;
} }
if (!timeout) {
hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n");
return IXGBE_ERR_SWFW_SYNC;
} }
gssr |= swmask; /* If time expired clear the bits holding the lock and retry */
IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); if (gssr & (fwmask | swmask))
ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask));
ixgbe_release_eeprom_semaphore(hw); usleep_range(5000, 10000);
return 0; return IXGBE_ERR_SWFW_SYNC;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment