Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+21 −24
Original line number Original line Diff line number Diff line
@@ -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;
}
}


/**
/**