diff options
Diffstat (limited to 'net/core/devlink.c')
-rw-r--r-- | net/core/devlink.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c index 4b0211590aac..7c5a5da8e338 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -3431,10 +3431,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 +3446,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 +3469,19 @@ 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; + } + + ret = devlink->ops->flash_update(devlink, ¶ms, info->extack); + + release_firmware(params.fw); + + return ret; } static const struct devlink_param devlink_param_generic[] = { @@ -10227,12 +10239,16 @@ 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); ret = devlink->ops->flash_update(devlink, ¶ms, NULL); mutex_unlock(&devlink->lock); + release_firmware(params.fw); + out: rtnl_lock(); dev_put(dev); |