Commit 674c18b2ed65f9db04e5c2e9c9e4af8fa2af0f1b
Committed by
Jeff Kirsher
1 parent
9c432adaa8
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
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>
Showing 1 changed file with 21 additions and 24 deletions Side-by-side Diff
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
... | ... | @@ -2506,42 +2506,39 @@ |
2506 | 2506 | **/ |
2507 | 2507 | s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) |
2508 | 2508 | { |
2509 | - u32 gssr; | |
2509 | + u32 gssr = 0; | |
2510 | 2510 | u32 swmask = mask; |
2511 | 2511 | u32 fwmask = mask << 5; |
2512 | - s32 timeout = 200; | |
2512 | + u32 timeout = 200; | |
2513 | + u32 i; | |
2513 | 2514 | |
2514 | - while (timeout) { | |
2515 | + for (i = 0; i < timeout; i++) { | |
2515 | 2516 | /* |
2516 | - * SW EEPROM semaphore bit is used for access to all | |
2517 | - * SW_FW_SYNC/GSSR bits (not just EEPROM) | |
2517 | + * SW NVM semaphore bit is used for access to all | |
2518 | + * SW_FW_SYNC bits (not just NVM) | |
2518 | 2519 | */ |
2519 | 2520 | if (ixgbe_get_eeprom_semaphore(hw)) |
2520 | 2521 | return IXGBE_ERR_SWFW_SYNC; |
2521 | 2522 | |
2522 | 2523 | gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); |
2523 | - if (!(gssr & (fwmask | swmask))) | |
2524 | - break; | |
2525 | - | |
2526 | - /* | |
2527 | - * Firmware currently using resource (fwmask) or other software | |
2528 | - * thread currently using resource (swmask) | |
2529 | - */ | |
2530 | - ixgbe_release_eeprom_semaphore(hw); | |
2531 | - usleep_range(5000, 10000); | |
2532 | - timeout--; | |
2524 | + if (!(gssr & (fwmask | swmask))) { | |
2525 | + gssr |= swmask; | |
2526 | + IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); | |
2527 | + ixgbe_release_eeprom_semaphore(hw); | |
2528 | + return 0; | |
2529 | + } else { | |
2530 | + /* Resource is currently in use by FW or SW */ | |
2531 | + ixgbe_release_eeprom_semaphore(hw); | |
2532 | + usleep_range(5000, 10000); | |
2533 | + } | |
2533 | 2534 | } |
2534 | 2535 | |
2535 | - if (!timeout) { | |
2536 | - hw_dbg(hw, "Driver can't access resource, SW_FW_SYNC timeout.\n"); | |
2537 | - return IXGBE_ERR_SWFW_SYNC; | |
2538 | - } | |
2536 | + /* If time expired clear the bits holding the lock and retry */ | |
2537 | + if (gssr & (fwmask | swmask)) | |
2538 | + ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask)); | |
2539 | 2539 | |
2540 | - gssr |= swmask; | |
2541 | - IXGBE_WRITE_REG(hw, IXGBE_GSSR, gssr); | |
2542 | - | |
2543 | - ixgbe_release_eeprom_semaphore(hw); | |
2544 | - return 0; | |
2540 | + usleep_range(5000, 10000); | |
2541 | + return IXGBE_ERR_SWFW_SYNC; | |
2545 | 2542 | } |
2546 | 2543 | |
2547 | 2544 | /** |