Skip to content

Commit

Permalink
Merge branch 'devlink-move-common-flash_update-calls-to-core'
Browse files Browse the repository at this point in the history
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: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Nov 20, 2020
2 parents 56495a2 + 52cc5f3 commit ac75b09
Show file tree
Hide file tree
Showing 17 changed files with 68 additions and 113 deletions.
4 changes: 1 addition & 3 deletions drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
33 changes: 22 additions & 11 deletions drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
u32 install_type)
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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -2517,6 +2508,26 @@ int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,
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)
{
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ 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,
u32 install_type);
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);

Expand Down
12 changes: 1 addition & 11 deletions drivers/net/ethernet/huawei/hinic/hinic_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
17 changes: 1 addition & 16 deletions drivers/net/ethernet/intel/ice/ice_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 = {
Expand Down
11 changes: 1 addition & 10 deletions drivers/net/ethernet/mellanox/mlx5/core/devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,8 @@ static int mlx5_devlink_flash_update(struct devlink *devlink,
struct netlink_ext_ack *extack)
{
struct mlx5_core_dev *dev = devlink_priv(devlink);
const struct firmware *fw;
int err;

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

err = mlx5_firmware_flash(dev, fw, extack);
release_firmware(fw);

return err;
return mlx5_firmware_flash(dev, params->fw, extack);
}

static u8 mlx5_fw_ver_major(u32 version)
Expand Down
3 changes: 0 additions & 3 deletions drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
}

mlxfw_info(mlxfw_dev, "Initialize firmware flash process\n");
devlink_flash_update_begin_notify(mlxfw_dev->devlink);
mlxfw_status_notify(mlxfw_dev, "Initializing firmware flash process",
NULL, 0, 0);
err = mlxfw_dev->ops->fsm_lock(mlxfw_dev, &fwhandle);
Expand Down Expand Up @@ -417,7 +416,6 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
mlxfw_info(mlxfw_dev, "Firmware flash done\n");
mlxfw_status_notify(mlxfw_dev, "Firmware flash done", NULL, 0, 0);
mlxfw_mfa2_file_fini(mfa2_file);
devlink_flash_update_end_notify(mlxfw_dev->devlink);
return 0;

err_state_wait_activate_to_locked:
Expand All @@ -429,7 +427,6 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
mlxfw_dev->ops->fsm_release(mlxfw_dev, fwhandle);
err_fsm_lock:
mlxfw_mfa2_file_fini(mfa2_file);
devlink_flash_update_end_notify(mlxfw_dev->devlink);
return err;
}
EXPORT_SYMBOL(mlxfw_firmware_flash);
Expand Down
11 changes: 1 addition & 10 deletions drivers/net/ethernet/mellanox/mlxsw/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,16 +1117,7 @@ static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core,
struct devlink_flash_update_params *params,
struct netlink_ext_ack *extack)
{
const struct firmware *firmware;
int err;

err = request_firmware_direct(&firmware, params->file_name, mlxsw_core->bus_info->dev);
if (err)
return err;
err = mlxsw_core_fw_flash(mlxsw_core, firmware, extack);
release_firmware(firmware);

return err;
return mlxsw_core_fw_flash(mlxsw_core, params->fw, extack);
}

static int mlxsw_core_devlink_param_fw_load_policy_validate(struct devlink *devlink, u32 id,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/netronome/nfp/nfp_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ nfp_devlink_flash_update(struct devlink *devlink,
struct devlink_flash_update_params *params,
struct netlink_ext_ack *extack)
{
return nfp_flash_update_common(devlink_priv(devlink), params->file_name, extack);
return nfp_flash_update_common(devlink_priv(devlink), params->fw, extack);
}

const struct devlink_ops nfp_devlink_ops = {
Expand Down
17 changes: 2 additions & 15 deletions drivers/net/ethernet/netronome/nfp/nfp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,11 +301,10 @@ static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs)
return nfp_pcie_sriov_enable(pdev, num_vfs);
}

int nfp_flash_update_common(struct nfp_pf *pf, const char *path,
int nfp_flash_update_common(struct nfp_pf *pf, const struct firmware *fw,
struct netlink_ext_ack *extack)
{
struct device *dev = &pf->pdev->dev;
const struct firmware *fw;
struct nfp_nsp *nsp;
int err;

Expand All @@ -319,24 +318,12 @@ int nfp_flash_update_common(struct nfp_pf *pf, const char *path,
return err;
}

err = request_firmware_direct(&fw, path, dev);
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"unable to read flash file from disk");
goto exit_close_nsp;
}

dev_info(dev, "Please be patient while writing flash image: %s\n",
path);

err = nfp_nsp_write_flash(nsp, fw);
if (err < 0)
goto exit_release_fw;
goto exit_close_nsp;
dev_info(dev, "Finished writing flash image\n");
err = 0;

exit_release_fw:
release_firmware(fw);
exit_close_nsp:
nfp_nsp_close(nsp);
return err;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/netronome/nfp/nfp_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ nfp_pf_map_rtsym(struct nfp_pf *pf, const char *name, const char *sym_fmt,
unsigned int min_size, struct nfp_cpp_area **area);
int nfp_mbox_cmd(struct nfp_pf *pf, u32 cmd, void *in_data, u64 in_length,
void *out_data, u64 out_length);
int nfp_flash_update_common(struct nfp_pf *pf, const char *path,
int nfp_flash_update_common(struct nfp_pf *pf, const struct firmware *fw,
struct netlink_ext_ack *extack);

enum nfp_dump_diag {
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/pensando/ionic/ionic_devlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static int ionic_dl_flash_update(struct devlink *dl,
{
struct ionic *ionic = devlink_priv(dl);

return ionic_firmware_update(ionic->lif, params->file_name, extack);
return ionic_firmware_update(ionic->lif, params->fw, extack);
}

static int ionic_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/pensando/ionic/ionic_devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include <net/devlink.h>

int ionic_firmware_update(struct ionic_lif *lif, const char *fw_name,
int ionic_firmware_update(struct ionic_lif *lif, const struct firmware *fw,
struct netlink_ext_ack *extack);

struct ionic *ionic_devlink_alloc(struct device *dev);
Expand Down
14 changes: 2 additions & 12 deletions drivers/net/ethernet/pensando/ionic/ionic_fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,24 @@ static int ionic_fw_status_long_wait(struct ionic *ionic,
return err;
}

int ionic_firmware_update(struct ionic_lif *lif, const char *fw_name,
int ionic_firmware_update(struct ionic_lif *lif, const struct firmware *fw,
struct netlink_ext_ack *extack)
{
struct ionic_dev *idev = &lif->ionic->idev;
struct net_device *netdev = lif->netdev;
struct ionic *ionic = lif->ionic;
union ionic_dev_cmd_comp comp;
u32 buf_sz, copy_sz, offset;
const struct firmware *fw;
struct devlink *dl;
int next_interval;
int err = 0;
u8 fw_slot;

netdev_info(netdev, "Installing firmware %s\n", fw_name);
netdev_info(netdev, "Installing firmware\n");

dl = priv_to_devlink(ionic);
devlink_flash_update_begin_notify(dl);
devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);

err = request_firmware(&fw, fw_name, ionic->dev);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Unable to find firmware file");
goto err_out;
}

buf_sz = sizeof(idev->dev_cmd_regs->data);

netdev_dbg(netdev,
Expand Down Expand Up @@ -200,7 +192,5 @@ int ionic_firmware_update(struct ionic_lif *lif, const char *fw_name,
devlink_flash_update_status_notify(dl, "Flash failed", NULL, 0, 0);
else
devlink_flash_update_status_notify(dl, "Flash done", NULL, 0, 0);
release_firmware(fw);
devlink_flash_update_end_notify(dl);
return err;
}
2 changes: 0 additions & 2 deletions drivers/net/netdevsim/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,6 @@ static int nsim_dev_flash_update(struct devlink *devlink,
return -EOPNOTSUPP;

if (nsim_dev->fw_update_status) {
devlink_flash_update_begin_notify(devlink);
devlink_flash_update_status_notify(devlink,
"Preparing to flash",
params->component, 0, 0);
Expand All @@ -790,7 +789,6 @@ static int nsim_dev_flash_update(struct devlink *devlink,
params->component, 81);
devlink_flash_update_status_notify(devlink, "Flashing done",
params->component, 0, 0);
devlink_flash_update_end_notify(devlink);
}

return 0;
Expand Down
9 changes: 4 additions & 5 deletions include/net/devlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <net/flow_offload.h>
#include <uapi/linux/devlink.h>
#include <linux/xarray.h>
#include <linux/firmware.h>

#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
(__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX)
Expand Down Expand Up @@ -566,15 +567,15 @@ enum devlink_param_generic_id {

/**
* struct devlink_flash_update_params - Flash Update parameters
* @file_name: the name of the flash firmware file to update from
* @fw: pointer to the firmware data to update from
* @component: the flash component to update
*
* With the exception of file_name, drivers must opt-in to parameters by
* With the exception of fw, drivers must opt-in to parameters by
* setting the appropriate bit in the supported_flash_update_params field in
* their devlink_ops structure.
*/
struct devlink_flash_update_params {
const char *file_name;
const struct firmware *fw;
const char *component;
u32 overwrite_mask;
};
Expand Down Expand Up @@ -1576,8 +1577,6 @@ void devlink_remote_reload_actions_performed(struct devlink *devlink,
enum devlink_reload_limit limit,
u32 actions_performed);

void devlink_flash_update_begin_notify(struct devlink *devlink);
void devlink_flash_update_end_notify(struct devlink *devlink);
void devlink_flash_update_status_notify(struct devlink *devlink,
const char *status_msg,
const char *component,
Expand Down
Loading

0 comments on commit ac75b09

Please sign in to comment.