Commit 4811b0c2 authored by Andrii Staikov's avatar Andrii Staikov Committed by Tony Nguyen
Browse files

ixgbe: add support for FW rollback mode



The driver should detect whether the device entered FW rollback
mode and then notify user with the dedicated message including
FW and NVM versions.

Even if the driver detected rollback mode, this should not result
in an probe error and the normal flow proceeds.

FW tries to rollback to "old" operational FW located in the
inactive NVM bank in cases when newly loaded FW exhibits faulty
behavior. If something goes wrong during boot the FW may switch
into rollback mode in an attempt to avoid recovery mode and stay
operational. After rollback is successful, the banks are swapped,
and the "rollback" bank becomes the active bank for the next reset.

Reviewed-by: default avatarMateusz Polchlopek <mateusz.polchlopek@intel.com>
Signed-off-by: default avatarAndrii Staikov <andrii.staikov@intel.com>
Signed-off-by: default avatarJedrzej Jagielski <jedrzej.jagielski@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 29cb3b8d
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -471,7 +471,8 @@ static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink,

	*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);

	adapter->flags2 &= ~IXGBE_FLAG2_API_MISMATCH;
	adapter->flags2 &= ~(IXGBE_FLAG2_API_MISMATCH |
			     IXGBE_FLAG2_FW_ROLLBACK);

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -672,6 +672,7 @@ struct ixgbe_adapter {
#define IXGBE_FLAG2_NO_MEDIA			BIT(21)
#define IXGBE_FLAG2_MOD_POWER_UNSUPPORTED	BIT(22)
#define IXGBE_FLAG2_API_MISMATCH		BIT(23)
#define IXGBE_FLAG2_FW_ROLLBACK			BIT(24)

	/* Tx fast path data */
	int num_tx_queues;
+34 −0
Original line number Diff line number Diff line
@@ -1832,6 +1832,22 @@ static bool ixgbe_fw_recovery_mode_e610(struct ixgbe_hw *hw)
	return !!(fwsm & IXGBE_GL_MNG_FWSM_RECOVERY_M);
}

/**
 * ixgbe_fw_rollback_mode_e610 - Check FW NVM rollback mode
 * @hw: pointer to hardware structure
 *
 * Check FW NVM rollback mode by reading the value of
 * the dedicated register.
 *
 * Return: true if FW is in rollback mode, otherwise false.
 */
static bool ixgbe_fw_rollback_mode_e610(struct ixgbe_hw *hw)
{
	u32 fwsm = IXGBE_READ_REG(hw, IXGBE_GL_MNG_FWSM);

	return !!(fwsm & IXGBE_GL_MNG_FWSM_ROLLBACK_M);
}

/**
 * ixgbe_init_phy_ops_e610 - PHY specific init
 * @hw: pointer to hardware structure
@@ -3163,6 +3179,22 @@ int ixgbe_get_inactive_nvm_ver(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm)
	return ixgbe_get_nvm_ver_info(hw, IXGBE_INACTIVE_FLASH_BANK, nvm);
}

/**
 * ixgbe_get_active_nvm_ver - Read Option ROM version from the active bank
 * @hw: pointer to the HW structure
 * @nvm: storage for Option ROM version information
 *
 * Reads the NVM EETRACK ID, Map version, and security revision of the
 * active NVM bank.
 *
 * Return: the exit code of the operation.
 */
static int ixgbe_get_active_nvm_ver(struct ixgbe_hw *hw,
				    struct ixgbe_nvm_info *nvm)
{
	return ixgbe_get_nvm_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK, nvm);
}

/**
 * ixgbe_get_netlist_info - Read the netlist version information
 * @hw: pointer to the HW struct
@@ -3893,6 +3925,8 @@ static const struct ixgbe_mac_operations mac_ops_e610 = {
	.get_media_type			= ixgbe_get_media_type_e610,
	.setup_link			= ixgbe_setup_link_e610,
	.fw_recovery_mode		= ixgbe_fw_recovery_mode_e610,
	.fw_rollback_mode		= ixgbe_fw_rollback_mode_e610,
	.get_nvm_ver			= ixgbe_get_active_nvm_ver,
	.get_link_capabilities		= ixgbe_get_link_capabilities_e610,
	.get_bus_info			= ixgbe_get_bus_info_generic,
	.acquire_swfw_sync		= ixgbe_acquire_swfw_sync_X540,
+26 −0
Original line number Diff line number Diff line
@@ -8424,6 +8424,32 @@ static bool ixgbe_check_fw_error(struct ixgbe_adapter *adapter)
			return true;
	}

	/* return here if FW rollback mode has been already detected */
	if (adapter->flags2 & IXGBE_FLAG2_FW_ROLLBACK)
		return false;

	if (hw->mac.ops.fw_rollback_mode && hw->mac.ops.fw_rollback_mode(hw)) {
		struct ixgbe_nvm_info *nvm_info = &adapter->hw.flash.nvm;
		char ver_buff[64] = "";

		if (hw->mac.ops.get_fw_ver && hw->mac.ops.get_fw_ver(hw))
			goto no_version;

		if (hw->mac.ops.get_nvm_ver &&
		    hw->mac.ops.get_nvm_ver(hw, nvm_info))
			goto no_version;

		snprintf(ver_buff, sizeof(ver_buff),
			 "Current version is NVM:%x.%x.%x, FW:%d.%d. ",
			 nvm_info->major, nvm_info->minor, nvm_info->eetrack,
			 hw->fw_maj_ver, hw->fw_maj_ver);
no_version:
		e_dev_warn("Firmware rollback mode detected. %sDevice may exhibit limited functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware rollback mode.",
			   ver_buff);

		adapter->flags2 |= IXGBE_FLAG2_FW_ROLLBACK;
	}

	return false;
}

+2 −0
Original line number Diff line number Diff line
@@ -3525,6 +3525,8 @@ struct ixgbe_mac_operations {
	int (*get_thermal_sensor_data)(struct ixgbe_hw *);
	int (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw);
	bool (*fw_recovery_mode)(struct ixgbe_hw *hw);
	bool (*fw_rollback_mode)(struct ixgbe_hw *hw);
	int (*get_nvm_ver)(struct ixgbe_hw *hw, struct ixgbe_nvm_info *nvm);
	void (*disable_rx)(struct ixgbe_hw *hw);
	void (*enable_rx)(struct ixgbe_hw *hw);
	void (*set_source_address_pruning)(struct ixgbe_hw *, bool,
Loading