Commit ac75b096 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'devlink-move-common-flash_update-calls-to-core'

Jacob Keller says:

====================
devlink: move common flash_update calls to core

This series moves a couple common pieces done by all drivers of the
->flash_update interface into devlink.c flash update handler. Specifically,
the core code will now request_firmware and
devlink_flash_update_(begin|end)_notify.

This cleanup is intended to simplify driver implementations so that they
have less work to do and are less capable of doing the "wrong" thing.

For request_firmware, this simplification is done as it is not expected that
drivers would do anything else. It also standardizes all drivers so that
they use the same interface (request_firmware, as opposed to
request_firmware_direct), and allows reporting the netlink extended ack with
the file name attribute.

For status notification, this change prevents drivers from sending a status
message without properly sending the status end notification. The current
userspace implementation of devlink relies on this end notification to
properly close the flash update channel. Without this, the flash update
process may hang indefinitely. By moving the begin and end calls into the
core code, it is no longer possible for a driver author to get this wrong.

Changes since v3
* picked up acked-by and reviewed-by comments
* fixed the ionic driver to leave the print statement in place

For the original patch that moved request_firmware, see [1]. For the v2 see
[2]. For further discussion of the issues with devlink flash status see [3].
For v3 see [4].

[1] https://lore.kernel.org/netdev/20201113000142.3563690-1-jacob.e.keller@intel.com/
[2] https://lore.kernel.org/netdev/20201113224559.3910864-1-jacob.e.keller@intel.com/
[3] https://lore.kernel.org/netdev/6352e9d3-02af-721e-3a54-ef99a666be29@intel.com/
[4] https://lore.kernel.org/netdev/20201117200820.854115-1-jacob.e.keller@intel.com/
====================

Link: https://lore.kernel.org/r/20201118190636.1235045-1-jacob.e.keller@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 56495a24 52cc5f3a
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -30,14 +30,12 @@ bnxt_dl_flash_update(struct devlink *dl,
		return -EPERM;
	}

	devlink_flash_update_begin_notify(dl);
	devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
	rc = bnxt_flash_package_from_file(bp->dev, params->file_name, 0);
	rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0);
	if (!rc)
		devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
	else
		devlink_flash_update_status_notify(dl, "Flashing failed", NULL, 0, 0);
	devlink_flash_update_end_notify(dl);
	return rc;
}

+22 −11
Original line number Diff line number Diff line
@@ -2419,13 +2419,12 @@ static int bnxt_flash_firmware_from_file(struct net_device *dev,
	return rc;
}

int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,
int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware *fw,
				   u32 install_type)
{
	struct bnxt *bp = netdev_priv(dev);
	struct hwrm_nvm_install_update_output *resp = bp->hwrm_cmd_resp_addr;
	struct hwrm_nvm_install_update_input install = {0};
	const struct firmware *fw;
	u32 item_len;
	int rc = 0;
	u16 index;
@@ -2440,13 +2439,6 @@ int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,
		return rc;
	}

	rc = request_firmware(&fw, filename, &dev->dev);
	if (rc != 0) {
		netdev_err(dev, "PKG error %d requesting file: %s\n",
			   rc, filename);
		return rc;
	}

	if (fw->size > item_len) {
		netdev_err(dev, "PKG insufficient update area in nvram: %lu\n",
			   (unsigned long)fw->size);
@@ -2478,7 +2470,6 @@ int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,
					  dma_handle);
		}
	}
	release_firmware(fw);
	if (rc)
		goto err_exit;

@@ -2517,6 +2508,26 @@ err_exit:
	return rc;
}

static int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,
					u32 install_type)
{
	const struct firmware *fw;
	int rc;

	rc = request_firmware(&fw, filename, &dev->dev);
	if (rc != 0) {
		netdev_err(dev, "PKG error %d requesting file: %s\n",
			   rc, filename);
		return rc;
	}

	rc = bnxt_flash_package_from_fw_obj(dev, fw, install_type);

	release_firmware(fw);

	return rc;
}

static int bnxt_flash_device(struct net_device *dev,
			     struct ethtool_flash *flash)
{
+2 −2
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ u32 bnxt_fw_to_ethtool_speed(u16);
u16 bnxt_get_fw_auto_link_speeds(u32);
int bnxt_hwrm_nvm_get_dev_info(struct bnxt *bp,
			       struct hwrm_nvm_get_dev_info_output *nvm_dev_info);
int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,
int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware *fw,
				   u32 install_type);
void bnxt_ethtool_init(struct bnxt *bp);
void bnxt_ethtool_free(struct bnxt *bp);
+1 −11
Original line number Diff line number Diff line
@@ -285,18 +285,8 @@ static int hinic_devlink_flash_update(struct devlink *devlink,
				      struct netlink_ext_ack *extack)
{
	struct hinic_devlink_priv *priv = devlink_priv(devlink);
	const struct firmware *fw;
	int err;

	err = request_firmware_direct(&fw, params->file_name,
				      &priv->hwdev->hwif->pdev->dev);
	if (err)
		return err;

	err = hinic_firmware_update(priv, fw, extack);
	release_firmware(fw);

	return err;
	return hinic_firmware_update(priv, params->fw, extack);
}

static const struct devlink_ops hinic_devlink_ops = {
+1 −16
Original line number Diff line number Diff line
@@ -247,9 +247,7 @@ ice_devlink_flash_update(struct devlink *devlink,
			 struct netlink_ext_ack *extack)
{
	struct ice_pf *pf = devlink_priv(devlink);
	struct device *dev = &pf->pdev->dev;
	struct ice_hw *hw = &pf->hw;
	const struct firmware *fw;
	u8 preservation;
	int err;

@@ -277,22 +275,9 @@ ice_devlink_flash_update(struct devlink *devlink,
	if (err)
		return err;

	err = request_firmware(&fw, params->file_name, dev);
	if (err) {
		NL_SET_ERR_MSG_MOD(extack, "Unable to read file from disk");
		return err;
	}

	dev_dbg(dev, "Beginning flash update with file '%s'\n", params->file_name);

	devlink_flash_update_begin_notify(devlink);
	devlink_flash_update_status_notify(devlink, "Preparing to flash", NULL, 0, 0);
	err = ice_flash_pldm_image(pf, fw, preservation, extack);
	devlink_flash_update_end_notify(devlink);

	release_firmware(fw);

	return err;
	return ice_flash_pldm_image(pf, params->fw, preservation, extack);
}

static const struct devlink_ops ice_devlink_ops = {
Loading