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: Emil Tantilov <emil.s.tantilov@intel.com> Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
9c432adaa8
commit
674c18b2ed
1 changed files with 21 additions and 24 deletions
|
@ -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)
|
||||
{
|
||||
u32 gssr;
|
||||
u32 gssr = 0;
|
||||
u32 swmask = mask;
|
||||
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_FW_SYNC/GSSR bits (not just EEPROM)
|
||||
* SW NVM semaphore bit is used for access to all
|
||||
* SW_FW_SYNC bits (not just NVM)
|
||||
*/
|
||||
if (ixgbe_get_eeprom_semaphore(hw))
|
||||
return IXGBE_ERR_SWFW_SYNC;
|
||||
|
||||
gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
|
||||
if (!(gssr & (fwmask | swmask)))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Firmware currently using resource (fwmask) or other software
|
||||
* thread currently using resource (swmask)
|
||||
*/
|
||||
ixgbe_release_eeprom_semaphore(hw);
|
||||
usleep_range(5000, 10000);
|
||||
timeout--;
|
||||
if (!(gssr & (fwmask | swmask))) {
|
||||
gssr |= swmask;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
|
||||
ixgbe_release_eeprom_semaphore(hw);
|
||||
return 0;
|
||||
} else {
|
||||
/* Resource is currently in use by FW or SW */
|
||||
ixgbe_release_eeprom_semaphore(hw);
|
||||
usleep_range(5000, 10000);
|
||||
}
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n");
|
||||
return IXGBE_ERR_SWFW_SYNC;
|
||||
}
|
||||
/* If time expired clear the bits holding the lock and retry */
|
||||
if (gssr & (fwmask | swmask))
|
||||
ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask));
|
||||
|
||||
gssr |= swmask;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
|
||||
|
||||
ixgbe_release_eeprom_semaphore(hw);
|
||||
return 0;
|
||||
usleep_range(5000, 10000);
|
||||
return IXGBE_ERR_SWFW_SYNC;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue