Commit 22ec3d23 authored by Jacob Keller's avatar Jacob Keller Committed by David S. Miller

devlink: check flash_update parameter support in net core

When implementing .flash_update, drivers which do not support
per-component update are manually checking the component parameter to
verify that it is NULL. Without this check, the driver might accept an
update request with a component specified even though it will not honor
such a request.

Instead of having each driver check this, move the logic into
net/core/devlink.c, and use a new `supported_flash_update_params` field
in the devlink_ops. Drivers which will support per-component update must
now specify this by setting DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT in
the supported_flash_update_params in their devlink_ops.

This helps ensure that drivers do not forget to check for a NULL
component if they do not support per-component update. This also enables
a slightly better error message by enabling the core stack to set the
netlink bad attribute message to indicate precisely the unsupported
attribute in the message.

Going forward, any new additional parameter to flash update will require
a bit in the supported_flash_update_params bitfield.
Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Reviewed-by: default avatarJakub Kicinski <kuba@kernel.org>
Cc: Jiri Pirko <jiri@mellanox.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michael Chan <michael.chan@broadcom.com>
Cc: Bin Luo <luobin9@huawei.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Ido Schimmel <idosch@mellanox.com>
Cc: Danielle Ratson <danieller@mellanox.com>
Cc: Shannon Nelson <snelson@pensando.io>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6fba737a
...@@ -23,9 +23,6 @@ bnxt_dl_flash_update(struct devlink *dl, const char *filename, ...@@ -23,9 +23,6 @@ bnxt_dl_flash_update(struct devlink *dl, const char *filename,
struct bnxt *bp = bnxt_get_bp_from_dl(dl); struct bnxt *bp = bnxt_get_bp_from_dl(dl);
int rc; int rc;
if (region)
return -EOPNOTSUPP;
if (!BNXT_PF(bp)) { if (!BNXT_PF(bp)) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"flash update not supported from a VF"); "flash update not supported from a VF");
...@@ -33,15 +30,12 @@ bnxt_dl_flash_update(struct devlink *dl, const char *filename, ...@@ -33,15 +30,12 @@ bnxt_dl_flash_update(struct devlink *dl, const char *filename,
} }
devlink_flash_update_begin_notify(dl); devlink_flash_update_begin_notify(dl);
devlink_flash_update_status_notify(dl, "Preparing to flash", region, 0, devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
0);
rc = bnxt_flash_package_from_file(bp->dev, filename, 0); rc = bnxt_flash_package_from_file(bp->dev, filename, 0);
if (!rc) if (!rc)
devlink_flash_update_status_notify(dl, "Flashing done", region, devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
0, 0);
else else
devlink_flash_update_status_notify(dl, "Flashing failed", devlink_flash_update_status_notify(dl, "Flashing failed", NULL, 0, 0);
region, 0, 0);
devlink_flash_update_end_notify(dl); devlink_flash_update_end_notify(dl);
return rc; return rc;
} }
......
...@@ -289,9 +289,6 @@ static int hinic_devlink_flash_update(struct devlink *devlink, ...@@ -289,9 +289,6 @@ static int hinic_devlink_flash_update(struct devlink *devlink,
const struct firmware *fw; const struct firmware *fw;
int err; int err;
if (component)
return -EOPNOTSUPP;
err = request_firmware_direct(&fw, file_name, err = request_firmware_direct(&fw, file_name,
&priv->hwdev->hwif->pdev->dev); &priv->hwdev->hwif->pdev->dev);
if (err) if (err)
......
...@@ -252,16 +252,12 @@ ice_devlink_flash_update(struct devlink *devlink, const char *path, ...@@ -252,16 +252,12 @@ ice_devlink_flash_update(struct devlink *devlink, const char *path,
const struct firmware *fw; const struct firmware *fw;
int err; int err;
/* individual component update is not yet supported */
if (component)
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;
} }
err = ice_check_for_pending_update(pf, component, extack); err = ice_check_for_pending_update(pf, NULL, extack);
if (err) if (err)
return err; return err;
...@@ -272,8 +268,7 @@ ice_devlink_flash_update(struct devlink *devlink, const char *path, ...@@ -272,8 +268,7 @@ ice_devlink_flash_update(struct devlink *devlink, const char *path,
} }
devlink_flash_update_begin_notify(devlink); devlink_flash_update_begin_notify(devlink);
devlink_flash_update_status_notify(devlink, "Preparing to flash", devlink_flash_update_status_notify(devlink, "Preparing to flash", NULL, 0, 0);
component, 0, 0);
err = ice_flash_pldm_image(pf, fw, extack); err = ice_flash_pldm_image(pf, fw, extack);
devlink_flash_update_end_notify(devlink); devlink_flash_update_end_notify(devlink);
......
...@@ -16,9 +16,6 @@ static int mlx5_devlink_flash_update(struct devlink *devlink, ...@@ -16,9 +16,6 @@ static int mlx5_devlink_flash_update(struct devlink *devlink,
const struct firmware *fw; const struct firmware *fw;
int err; int err;
if (component)
return -EOPNOTSUPP;
err = request_firmware_direct(&fw, file_name, &dev->pdev->dev); err = request_firmware_direct(&fw, file_name, &dev->pdev->dev);
if (err) if (err)
return err; return err;
......
...@@ -1108,9 +1108,6 @@ static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core, ...@@ -1108,9 +1108,6 @@ static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core,
const struct firmware *firmware; const struct firmware *firmware;
int err; int err;
if (component)
return -EOPNOTSUPP;
err = request_firmware_direct(&firmware, file_name, mlxsw_core->bus_info->dev); err = request_firmware_direct(&firmware, file_name, mlxsw_core->bus_info->dev);
if (err) if (err)
return err; return err;
......
...@@ -332,8 +332,6 @@ static int ...@@ -332,8 +332,6 @@ static int
nfp_devlink_flash_update(struct devlink *devlink, const char *path, nfp_devlink_flash_update(struct devlink *devlink, const char *path,
const char *component, struct netlink_ext_ack *extack) const char *component, struct netlink_ext_ack *extack)
{ {
if (component)
return -EOPNOTSUPP;
return nfp_flash_update_common(devlink_priv(devlink), path, extack); return nfp_flash_update_common(devlink_priv(devlink), path, extack);
} }
......
...@@ -16,9 +16,6 @@ static int ionic_dl_flash_update(struct devlink *dl, ...@@ -16,9 +16,6 @@ static int ionic_dl_flash_update(struct devlink *dl,
{ {
struct ionic *ionic = devlink_priv(dl); struct ionic *ionic = devlink_priv(dl);
if (component)
return -EOPNOTSUPP;
return ionic_firmware_update(ionic->lif, fwname, extack); return ionic_firmware_update(ionic->lif, fwname, extack);
} }
......
...@@ -879,6 +879,7 @@ nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink, ...@@ -879,6 +879,7 @@ nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
} }
static const struct devlink_ops nsim_dev_devlink_ops = { static const struct devlink_ops nsim_dev_devlink_ops = {
.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT,
.reload_down = nsim_dev_reload_down, .reload_down = nsim_dev_reload_down,
.reload_up = nsim_dev_reload_up, .reload_up = nsim_dev_reload_up,
.info_get = nsim_dev_info_get, .info_get = nsim_dev_info_get,
......
...@@ -550,6 +550,8 @@ enum devlink_param_generic_id { ...@@ -550,6 +550,8 @@ enum devlink_param_generic_id {
/* Firmware bundle identifier */ /* Firmware bundle identifier */
#define DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID "fw.bundle_id" #define DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID "fw.bundle_id"
#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT BIT(0)
struct devlink_region; struct devlink_region;
struct devlink_info_req; struct devlink_info_req;
...@@ -1037,6 +1039,12 @@ enum devlink_trap_group_generic_id { ...@@ -1037,6 +1039,12 @@ enum devlink_trap_group_generic_id {
} }
struct devlink_ops { struct devlink_ops {
/**
* @supported_flash_update_params:
* mask of parameters supported by the driver's .flash_update
* implemementation.
*/
u32 supported_flash_update_params;
int (*reload_down)(struct devlink *devlink, bool netns_change, int (*reload_down)(struct devlink *devlink, bool netns_change,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int (*reload_up)(struct devlink *devlink, int (*reload_up)(struct devlink *devlink,
...@@ -1097,6 +1105,13 @@ struct devlink_ops { ...@@ -1097,6 +1105,13 @@ struct devlink_ops {
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int (*info_get)(struct devlink *devlink, struct devlink_info_req *req, int (*info_get)(struct devlink *devlink, struct devlink_info_req *req,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
/**
* @flash_update: Device flash update function
*
* Used to perform a flash update for the device. The set of
* parameters supported by the driver should be set in
* supported_flash_update_params.
*/
int (*flash_update)(struct devlink *devlink, const char *file_name, int (*flash_update)(struct devlink *devlink, const char *file_name,
const char *component, const char *component,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
......
...@@ -3148,18 +3148,29 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb, ...@@ -3148,18 +3148,29 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
struct genl_info *info) struct genl_info *info)
{ {
struct devlink *devlink = info->user_ptr[0]; struct devlink *devlink = info->user_ptr[0];
const char *file_name, *component; const char *file_name, *component = NULL;
struct nlattr *nla_component; struct nlattr *nla_component;
u32 supported_params;
if (!devlink->ops->flash_update) if (!devlink->ops->flash_update)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]) if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
return -EINVAL; return -EINVAL;
supported_params = devlink->ops->supported_flash_update_params;
file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]); file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT]; nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
component = nla_component ? nla_data(nla_component) : NULL; if (nla_component) {
if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT)) {
NL_SET_ERR_MSG_ATTR(info->extack, nla_component,
"component update is not supported by this device");
return -EOPNOTSUPP;
}
component = nla_data(nla_component);
}
return devlink->ops->flash_update(devlink, file_name, component, return devlink->ops->flash_update(devlink, file_name, component,
info->extack); info->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