|
@@ -2506,42 +2506,39 @@ out:
|
|
|
**/
|
|
|
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 (!timeout) {
|
|
|
- hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n");
|
|
|
- return IXGBE_ERR_SWFW_SYNC;
|
|
|
+ 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);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- gssr |= swmask;
|
|
|
- IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr);
|
|
|
+ /* If time expired clear the bits holding the lock and retry */
|
|
|
+ if (gssr & (fwmask | swmask))
|
|
|
+ ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask));
|
|
|
|
|
|
- ixgbe_release_eeprom_semaphore(hw);
|
|
|
- return 0;
|
|
|
+ usleep_range(5000, 10000);
|
|
|
+ return IXGBE_ERR_SWFW_SYNC;
|
|
|
}
|
|
|
|
|
|
/**
|