Commit 50db1bca authored by Jacob Keller's avatar Jacob Keller Committed by David S. Miller

ice: add support for flash update overwrite mask

Support the recently added DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK
parameter in the ice flash update handler. Convert the overwrite mask
bitfield into the appropriate preservation level used by the firmware
when updating.

Because there is no equivalent preservation level for overwriting only
identifiers, this combination is rejected by the driver as not supported
with an appropriate extended ACK message.
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Reviewed-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cbb58368
...@@ -81,6 +81,37 @@ The ``ice`` driver reports the following versions ...@@ -81,6 +81,37 @@ The ``ice`` driver reports the following versions
- 0xee16ced7 - 0xee16ced7
- The first 4 bytes of the hash of the netlist module contents. - The first 4 bytes of the hash of the netlist module contents.
Flash Update
============
The ``ice`` driver implements support for flash update using the
``devlink-flash`` interface. It supports updating the device flash using a
combined flash image that contains the ``fw.mgmt``, ``fw.undi``, and
``fw.netlist`` components.
.. list-table:: List of supported overwrite modes
:widths: 5 95
* - Bits
- Behavior
* - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
- Do not preserve settings stored in the flash components being
updated. This includes overwriting the port configuration that
determines the number of physical functions the device will
initialize with.
* - ``DEVLINK_FLASH_OVERWRITE_SETTINGS`` and ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
- Do not preserve either settings or identifiers. Overwrite everything
in the flash with the contents from the provided image, without
performing any preservation. This includes overwriting device
identifying fields such as the MAC address, VPD area, and device
serial number. It is expected that this combination be used with an
image customized for the specific device.
The ice hardware does not support overwriting only identifiers while
preserving settings, and thus ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS`` on its
own will be rejected. If no overwrite mask is provided, the firmware will be
instructed to preserve all settings and identifying fields when updating.
Regions Regions
======= =======
......
...@@ -250,8 +250,24 @@ ice_devlink_flash_update(struct devlink *devlink, ...@@ -250,8 +250,24 @@ ice_devlink_flash_update(struct devlink *devlink,
struct device *dev = &pf->pdev->dev; struct device *dev = &pf->pdev->dev;
struct ice_hw *hw = &pf->hw; struct ice_hw *hw = &pf->hw;
const struct firmware *fw; const struct firmware *fw;
u8 preservation;
int err; int err;
if (!params->overwrite_mask) {
/* preserve all settings and identifiers */
preservation = ICE_AQC_NVM_PRESERVE_ALL;
} else if (params->overwrite_mask == DEVLINK_FLASH_OVERWRITE_SETTINGS) {
/* overwrite settings, but preserve the vital device identifiers */
preservation = ICE_AQC_NVM_PRESERVE_SELECTED;
} else if (params->overwrite_mask == (DEVLINK_FLASH_OVERWRITE_SETTINGS |
DEVLINK_FLASH_OVERWRITE_IDENTIFIERS)) {
/* overwrite both settings and identifiers, preserve nothing */
preservation = ICE_AQC_NVM_NO_PRESERVATION;
} else {
NL_SET_ERR_MSG_MOD(extack, "Requested overwrite mask is not supported");
return -EOPNOTSUPP;
}
if (!hw->dev_caps.common_cap.nvm_unified_update) { if (!hw->dev_caps.common_cap.nvm_unified_update) {
NL_SET_ERR_MSG_MOD(extack, "Current firmware does not support unified update"); NL_SET_ERR_MSG_MOD(extack, "Current firmware does not support unified update");
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -269,7 +285,7 @@ ice_devlink_flash_update(struct devlink *devlink, ...@@ -269,7 +285,7 @@ ice_devlink_flash_update(struct devlink *devlink,
devlink_flash_update_begin_notify(devlink); devlink_flash_update_begin_notify(devlink);
devlink_flash_update_status_notify(devlink, "Preparing to flash", NULL, 0, 0); devlink_flash_update_status_notify(devlink, "Preparing to flash", NULL, 0, 0);
err = ice_flash_pldm_image(pf, fw, extack); err = ice_flash_pldm_image(pf, fw, preservation, extack);
devlink_flash_update_end_notify(devlink); devlink_flash_update_end_notify(devlink);
release_firmware(fw); release_firmware(fw);
...@@ -278,6 +294,7 @@ ice_devlink_flash_update(struct devlink *devlink, ...@@ -278,6 +294,7 @@ ice_devlink_flash_update(struct devlink *devlink,
} }
static const struct devlink_ops ice_devlink_ops = { static const struct devlink_ops ice_devlink_ops = {
.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
.info_get = ice_devlink_info_get, .info_get = ice_devlink_info_get,
.flash_update = ice_devlink_flash_update, .flash_update = ice_devlink_flash_update,
}; };
......
...@@ -625,6 +625,7 @@ static const struct pldmfw_ops ice_fwu_ops = { ...@@ -625,6 +625,7 @@ static const struct pldmfw_ops ice_fwu_ops = {
* ice_flash_pldm_image - Write a PLDM-formatted firmware image to the device * ice_flash_pldm_image - Write a PLDM-formatted firmware image to the device
* @pf: private device driver structure * @pf: private device driver structure
* @fw: firmware object pointing to the relevant firmware file * @fw: firmware object pointing to the relevant firmware file
* @preservation: preservation level to request from firmware
* @extack: netlink extended ACK structure * @extack: netlink extended ACK structure
* *
* Parse the data for a given firmware file, verifying that it is a valid PLDM * Parse the data for a given firmware file, verifying that it is a valid PLDM
...@@ -638,7 +639,7 @@ static const struct pldmfw_ops ice_fwu_ops = { ...@@ -638,7 +639,7 @@ static const struct pldmfw_ops ice_fwu_ops = {
* Returns: zero on success or a negative error code on failure. * Returns: zero on success or a negative error code on failure.
*/ */
int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw, int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw,
struct netlink_ext_ack *extack) u8 preservation, struct netlink_ext_ack *extack)
{ {
struct device *dev = ice_pf_to_dev(pf); struct device *dev = ice_pf_to_dev(pf);
struct ice_hw *hw = &pf->hw; struct ice_hw *hw = &pf->hw;
...@@ -646,13 +647,24 @@ int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw, ...@@ -646,13 +647,24 @@ int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw,
enum ice_status status; enum ice_status status;
int err; int err;
switch (preservation) {
case ICE_AQC_NVM_PRESERVE_ALL:
case ICE_AQC_NVM_PRESERVE_SELECTED:
case ICE_AQC_NVM_NO_PRESERVATION:
case ICE_AQC_NVM_FACTORY_DEFAULT:
break;
default:
WARN(1, "Unexpected preservation level request %u", preservation);
return -EINVAL;
}
memset(&priv, 0, sizeof(priv)); memset(&priv, 0, sizeof(priv));
priv.context.ops = &ice_fwu_ops; priv.context.ops = &ice_fwu_ops;
priv.context.dev = dev; priv.context.dev = dev;
priv.extack = extack; priv.extack = extack;
priv.pf = pf; priv.pf = pf;
priv.activate_flags = ICE_AQC_NVM_PRESERVE_ALL; priv.activate_flags = preservation;
status = ice_acquire_nvm(hw, ICE_RES_WRITE); status = ice_acquire_nvm(hw, ICE_RES_WRITE);
if (status) { if (status) {
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#define _ICE_FW_UPDATE_H_ #define _ICE_FW_UPDATE_H_
int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw, int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw,
struct netlink_ext_ack *extack); u8 preservation, struct netlink_ext_ack *extack);
int ice_check_for_pending_update(struct ice_pf *pf, const char *component, int ice_check_for_pending_update(struct ice_pf *pf, const char *component,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment