diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c index 184b6d0513b2a..6b7b69ed62db0 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -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; } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 1471c9a362388..7b444fcb62891 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -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; @@ -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 @@ 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) { diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h index fa6fbde52bea1..0a57cb6a4a4bf 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h @@ -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); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c index 2630d667f3939..58d5646444b02 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c @@ -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 = { diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c index 511da59bd6f28..29d6192b15f32 100644 --- a/drivers/net/ethernet/intel/ice/ice_devlink.c +++ b/drivers/net/ethernet/intel/ice/ice_devlink.c @@ -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 = { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index a28f95df2901d..e2ed341648e4c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -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) diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c index bcd166911d444..46245e0b24623 100644 --- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c +++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c @@ -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); @@ -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: @@ -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); diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 1a86535c49685..630109f139a0b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -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, diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c index 97d2b03208de0..713ee3041d491 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c @@ -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 = { diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c index e672614d29065..742a420152b36 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c @@ -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; @@ -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; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.h b/drivers/net/ethernet/netronome/nfp/nfp_main.h index fa6b13a059419..a7dede946a33f 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.h +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.h @@ -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 { diff --git a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c index 51d64718ed9f0..b41301a5b0df8 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_devlink.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_devlink.c @@ -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, diff --git a/drivers/net/ethernet/pensando/ionic/ionic_devlink.h b/drivers/net/ethernet/pensando/ionic/ionic_devlink.h index 5c01a9e306d8d..0a77e8e810c5d 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_devlink.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_devlink.h @@ -6,7 +6,7 @@ #include -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); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_fw.c b/drivers/net/ethernet/pensando/ionic/ionic_fw.c index d7bbf336c6f65..5f40324cd243f 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_fw.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_fw.c @@ -91,7 +91,7 @@ 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; @@ -99,24 +99,16 @@ int ionic_firmware_update(struct ionic_lif *lif, const char *fw_name, 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, @@ -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; } diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index fe48817b39856..816af1f55e2cd 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -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); @@ -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; diff --git a/include/net/devlink.h b/include/net/devlink.h index b01bb9bca5a2a..457c537d0ef22 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -19,6 +19,7 @@ #include #include #include +#include #define DEVLINK_RELOAD_STATS_ARRAY_SIZE \ (__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX) @@ -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; }; @@ -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, diff --git a/net/core/devlink.c b/net/core/devlink.c index 4b0211590aacf..e6fb1fdedded8 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -3372,7 +3372,7 @@ static void __devlink_flash_update_notify(struct devlink *devlink, nlmsg_free(msg); } -void devlink_flash_update_begin_notify(struct devlink *devlink) +static void devlink_flash_update_begin_notify(struct devlink *devlink) { struct devlink_flash_notify params = { 0 }; @@ -3380,9 +3380,8 @@ void devlink_flash_update_begin_notify(struct devlink *devlink) DEVLINK_CMD_FLASH_UPDATE, ¶ms); } -EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify); -void devlink_flash_update_end_notify(struct devlink *devlink) +static void devlink_flash_update_end_notify(struct devlink *devlink) { struct devlink_flash_notify params = { 0 }; @@ -3390,7 +3389,6 @@ void devlink_flash_update_end_notify(struct devlink *devlink) DEVLINK_CMD_FLASH_UPDATE_END, ¶ms); } -EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify); void devlink_flash_update_status_notify(struct devlink *devlink, const char *status_msg, @@ -3431,10 +3429,12 @@ EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify); static int devlink_nl_cmd_flash_update(struct sk_buff *skb, struct genl_info *info) { - struct nlattr *nla_component, *nla_overwrite_mask; + struct nlattr *nla_component, *nla_overwrite_mask, *nla_file_name; struct devlink_flash_update_params params = {}; struct devlink *devlink = info->user_ptr[0]; + const char *file_name; u32 supported_params; + int ret; if (!devlink->ops->flash_update) return -EOPNOTSUPP; @@ -3444,8 +3444,6 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb, supported_params = devlink->ops->supported_flash_update_params; - params.file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]); - nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT]; if (nla_component) { if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT)) { @@ -3469,7 +3467,21 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb, params.overwrite_mask = sections.value & sections.selector; } - return devlink->ops->flash_update(devlink, ¶ms, info->extack); + nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]; + file_name = nla_data(nla_file_name); + ret = request_firmware(¶ms.fw, file_name, devlink->dev); + if (ret) { + NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file"); + return ret; + } + + devlink_flash_update_begin_notify(devlink); + ret = devlink->ops->flash_update(devlink, ¶ms, info->extack); + devlink_flash_update_end_notify(devlink); + + release_firmware(params.fw); + + return ret; } static const struct devlink_param devlink_param_generic[] = { @@ -10227,12 +10239,18 @@ int devlink_compat_flash_update(struct net_device *dev, const char *file_name) goto out; } - params.file_name = file_name; + ret = request_firmware(¶ms.fw, file_name, devlink->dev); + if (ret) + goto out; mutex_lock(&devlink->lock); + devlink_flash_update_begin_notify(devlink); ret = devlink->ops->flash_update(devlink, ¶ms, NULL); + devlink_flash_update_end_notify(devlink); mutex_unlock(&devlink->lock); + release_firmware(params.fw); + out: rtnl_lock(); dev_put(dev);