mirror of
https://github.com/torvalds/linux.git
synced 2026-04-23 17:15:46 -04:00
ixgbe: add support for devlink reload
The E610 adapters contain an embedded chip with firmware which can be updated using devlink flash. The firmware which runs on this chip is referred to as the Embedded Management Processor firmware (EMP firmware). Activating the new firmware image currently requires that the system be rebooted. This is not ideal as rebooting the system can cause unwanted downtime. The EMP firmware itself can be reloaded by issuing a special update to the device called an Embedded Management Processor reset (EMP reset). This reset causes the device to reset and reload the EMP firmware. Implement support for devlink reload with the "fw_activate" flag. This allows user space to request the firmware be activated immediately. Reviewed-by: Mateusz Polchlopek <mateusz.polchlopek@intel.com> Tested-by: Bharath R <bharath.r@intel.com> Co-developed-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com> Co-developed-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com> Signed-off-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com> Co-developed-by: Stefan Wegrzyn <stefan.wegrzyn@intel.com> Signed-off-by: Stefan Wegrzyn <stefan.wegrzyn@intel.com> Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
committed by
Tony Nguyen
parent
a0f45672d5
commit
c9e563cae1
@@ -322,6 +322,9 @@ static int ixgbe_devlink_info_get(struct devlink *devlink,
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
if (hw->mac.type == ixgbe_mac_e610)
|
||||
ixgbe_refresh_fw_version(adapter);
|
||||
|
||||
ixgbe_info_get_dsn(adapter, ctx);
|
||||
err = devlink_info_serial_number_put(req, ctx->buf);
|
||||
if (err)
|
||||
@@ -365,11 +368,120 @@ free_ctx:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_devlink_reload_empr_start - Start EMP reset to activate new firmware
|
||||
* @devlink: pointer to the devlink instance to reload
|
||||
* @netns_change: if true, the network namespace is changing
|
||||
* @action: the action to perform. Must be DEVLINK_RELOAD_ACTION_FW_ACTIVATE
|
||||
* @limit: limits on what reload should do, such as not resetting
|
||||
* @extack: netlink extended ACK structure
|
||||
*
|
||||
* Allow user to activate new Embedded Management Processor firmware by
|
||||
* issuing device specific EMP reset. Called in response to
|
||||
* a DEVLINK_CMD_RELOAD with the DEVLINK_RELOAD_ACTION_FW_ACTIVATE.
|
||||
*
|
||||
* Note that teardown and rebuild of the driver state happens automatically as
|
||||
* part of an interrupt and watchdog task. This is because all physical
|
||||
* functions on the device must be able to reset when an EMP reset occurs from
|
||||
* any source.
|
||||
*
|
||||
* Return: the exit code of the operation.
|
||||
*/
|
||||
static int ixgbe_devlink_reload_empr_start(struct devlink *devlink,
|
||||
bool netns_change,
|
||||
enum devlink_reload_action action,
|
||||
enum devlink_reload_limit limit,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = devlink_priv(devlink);
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u8 pending;
|
||||
int err;
|
||||
|
||||
if (hw->mac.type != ixgbe_mac_e610)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = ixgbe_get_pending_updates(adapter, &pending, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Pending is a bitmask of which flash banks have a pending update,
|
||||
* including the main NVM bank, the Option ROM bank, and the netlist
|
||||
* bank. If any of these bits are set, then there is a pending update
|
||||
* waiting to be activated.
|
||||
*/
|
||||
if (!pending) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "No pending firmware update");
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
if (adapter->fw_emp_reset_disabled) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"EMP reset is not available. To activate firmware, a reboot or power cycle is needed");
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
err = ixgbe_aci_nvm_update_empr(hw);
|
||||
if (err)
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Failed to trigger EMP device reset to reload firmware");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*Wait for 10 sec with 0.5 sec tic. EMPR takes no less than half of a sec */
|
||||
#define IXGBE_DEVLINK_RELOAD_TIMEOUT_SEC 20
|
||||
|
||||
/**
|
||||
* ixgbe_devlink_reload_empr_finish - finishes EMP reset
|
||||
* @devlink: pointer to the devlink instance
|
||||
* @action: the action to perform.
|
||||
* @limit: limits on what reload should do
|
||||
* @actions_performed: actions performed
|
||||
* @extack: netlink extended ACK structure
|
||||
*
|
||||
* Wait for new NVM to be loaded during EMP reset.
|
||||
*
|
||||
* Return: -ETIME when timer is exceeded, 0 on success.
|
||||
*/
|
||||
static int ixgbe_devlink_reload_empr_finish(struct devlink *devlink,
|
||||
enum devlink_reload_action action,
|
||||
enum devlink_reload_limit limit,
|
||||
u32 *actions_performed,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = devlink_priv(devlink);
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
int i = 0;
|
||||
u32 fwsm;
|
||||
|
||||
do {
|
||||
/* Just right away after triggering EMP reset the FWSM register
|
||||
* may be not cleared yet, so begin the loop with the delay
|
||||
* in order to not check the not updated register.
|
||||
*/
|
||||
mdelay(500);
|
||||
|
||||
fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM(hw));
|
||||
|
||||
if (i++ >= IXGBE_DEVLINK_RELOAD_TIMEOUT_SEC)
|
||||
return -ETIME;
|
||||
|
||||
} while (!(fwsm & IXGBE_FWSM_FW_VAL_BIT));
|
||||
|
||||
*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct devlink_ops ixgbe_devlink_ops = {
|
||||
.info_get = ixgbe_devlink_info_get,
|
||||
.supported_flash_update_params =
|
||||
DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
|
||||
.flash_update = ixgbe_flash_pldm_image,
|
||||
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
|
||||
.reload_down = ixgbe_devlink_reload_empr_start,
|
||||
.reload_up = ixgbe_devlink_reload_empr_finish,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user