devlink: convert flash_update to use params structure
The devlink core recently gained support for checking whether the driver supports a flash_update parameter, via `supported_flash_update_params`. However, parameters are specified as function arguments. Adding a new parameter still requires modifying the signature of the .flash_update callback in all drivers. Convert the .flash_update function to take a new `struct devlink_flash_update_params` instead. By using this structure, and the `supported_flash_update_params` bit field, a new parameter to flash_update can be added without requiring modification to existing drivers. As before, all parameters except file_name will require driver opt-in. Because file_name is a necessary field to for the flash_update to make sense, no "SUPPORTED" bitflag is provided and it is always considered valid. All future additional parameters will require a new bit in the supported_flash_update_params bitfield. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Jakub Kicinski <kuba@kernel.org> Cc: Jiri Pirko <jiri@mellanox.com> Cc: Jakub Kicinski <kuba@kernel.org> 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> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
22ec3d232f
commit
bc75c054f0
@ -17,8 +17,9 @@
|
|||||||
#include "bnxt_ethtool.h"
|
#include "bnxt_ethtool.h"
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bnxt_dl_flash_update(struct devlink *dl, const char *filename,
|
bnxt_dl_flash_update(struct devlink *dl,
|
||||||
const char *region, struct netlink_ext_ack *extack)
|
struct devlink_flash_update_params *params,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
|
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
|
||||||
int rc;
|
int rc;
|
||||||
@ -31,7 +32,7 @@ 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", NULL, 0, 0);
|
devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
|
||||||
rc = bnxt_flash_package_from_file(bp->dev, filename, 0);
|
rc = bnxt_flash_package_from_file(bp->dev, params->file_name, 0);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
|
devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
|
||||||
else
|
else
|
||||||
|
@ -281,15 +281,14 @@ static int hinic_firmware_update(struct hinic_devlink_priv *priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int hinic_devlink_flash_update(struct devlink *devlink,
|
static int hinic_devlink_flash_update(struct devlink *devlink,
|
||||||
const char *file_name,
|
struct devlink_flash_update_params *params,
|
||||||
const char *component,
|
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct hinic_devlink_priv *priv = devlink_priv(devlink);
|
struct hinic_devlink_priv *priv = devlink_priv(devlink);
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = request_firmware_direct(&fw, file_name,
|
err = request_firmware_direct(&fw, params->file_name,
|
||||||
&priv->hwdev->hwif->pdev->dev);
|
&priv->hwdev->hwif->pdev->dev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -233,8 +233,7 @@ static int ice_devlink_info_get(struct devlink *devlink,
|
|||||||
/**
|
/**
|
||||||
* ice_devlink_flash_update - Update firmware stored in flash on the device
|
* ice_devlink_flash_update - Update firmware stored in flash on the device
|
||||||
* @devlink: pointer to devlink associated with device to update
|
* @devlink: pointer to devlink associated with device to update
|
||||||
* @path: the path of the firmware file to use via request_firmware
|
* @params: flash update parameters
|
||||||
* @component: name of the component to update, or NULL
|
|
||||||
* @extack: netlink extended ACK structure
|
* @extack: netlink extended ACK structure
|
||||||
*
|
*
|
||||||
* Perform a device flash update. The bulk of the update logic is contained
|
* Perform a device flash update. The bulk of the update logic is contained
|
||||||
@ -243,8 +242,9 @@ static int ice_devlink_info_get(struct devlink *devlink,
|
|||||||
* Returns: zero on success, or an error code on failure.
|
* Returns: zero on success, or an error code on failure.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ice_devlink_flash_update(struct devlink *devlink, const char *path,
|
ice_devlink_flash_update(struct devlink *devlink,
|
||||||
const char *component, struct netlink_ext_ack *extack)
|
struct devlink_flash_update_params *params,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct ice_pf *pf = devlink_priv(devlink);
|
struct ice_pf *pf = devlink_priv(devlink);
|
||||||
struct device *dev = &pf->pdev->dev;
|
struct device *dev = &pf->pdev->dev;
|
||||||
@ -261,7 +261,7 @@ ice_devlink_flash_update(struct devlink *devlink, const char *path,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = request_firmware(&fw, path, dev);
|
err = request_firmware(&fw, params->file_name, dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
NL_SET_ERR_MSG_MOD(extack, "Unable to read file from disk");
|
NL_SET_ERR_MSG_MOD(extack, "Unable to read file from disk");
|
||||||
return err;
|
return err;
|
||||||
|
@ -8,15 +8,14 @@
|
|||||||
#include "eswitch.h"
|
#include "eswitch.h"
|
||||||
|
|
||||||
static int mlx5_devlink_flash_update(struct devlink *devlink,
|
static int mlx5_devlink_flash_update(struct devlink *devlink,
|
||||||
const char *file_name,
|
struct devlink_flash_update_params *params,
|
||||||
const char *component,
|
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct mlx5_core_dev *dev = devlink_priv(devlink);
|
struct mlx5_core_dev *dev = devlink_priv(devlink);
|
||||||
const struct firmware *fw;
|
const struct firmware *fw;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = request_firmware_direct(&fw, file_name, &dev->pdev->dev);
|
err = request_firmware_direct(&fw, params->file_name, &dev->pdev->dev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -1102,13 +1102,13 @@ static int mlxsw_core_fw_rev_validate(struct mlxsw_core *mlxsw_core,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core,
|
static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core,
|
||||||
const char *file_name, const char *component,
|
struct devlink_flash_update_params *params,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
const struct firmware *firmware;
|
const struct firmware *firmware;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = request_firmware_direct(&firmware, file_name, mlxsw_core->bus_info->dev);
|
err = request_firmware_direct(&firmware, params->file_name, mlxsw_core->bus_info->dev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
err = mlxsw_core_fw_flash(mlxsw_core, firmware, extack);
|
err = mlxsw_core_fw_flash(mlxsw_core, firmware, extack);
|
||||||
@ -1431,13 +1431,12 @@ mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int mlxsw_devlink_flash_update(struct devlink *devlink,
|
static int mlxsw_devlink_flash_update(struct devlink *devlink,
|
||||||
const char *file_name,
|
struct devlink_flash_update_params *params,
|
||||||
const char *component,
|
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
|
struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
|
||||||
|
|
||||||
return mlxsw_core_fw_flash_update(mlxsw_core, file_name, component, extack);
|
return mlxsw_core_fw_flash_update(mlxsw_core, params, extack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlxsw_devlink_trap_init(struct devlink *devlink,
|
static int mlxsw_devlink_trap_init(struct devlink *devlink,
|
||||||
|
@ -329,10 +329,11 @@ err_close_nsp:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nfp_devlink_flash_update(struct devlink *devlink, const char *path,
|
nfp_devlink_flash_update(struct devlink *devlink,
|
||||||
const char *component, struct netlink_ext_ack *extack)
|
struct devlink_flash_update_params *params,
|
||||||
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
return nfp_flash_update_common(devlink_priv(devlink), path, extack);
|
return nfp_flash_update_common(devlink_priv(devlink), params->file_name, extack);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct devlink_ops nfp_devlink_ops = {
|
const struct devlink_ops nfp_devlink_ops = {
|
||||||
|
@ -10,13 +10,12 @@
|
|||||||
#include "ionic_devlink.h"
|
#include "ionic_devlink.h"
|
||||||
|
|
||||||
static int ionic_dl_flash_update(struct devlink *dl,
|
static int ionic_dl_flash_update(struct devlink *dl,
|
||||||
const char *fwname,
|
struct devlink_flash_update_params *params,
|
||||||
const char *component,
|
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct ionic *ionic = devlink_priv(dl);
|
struct ionic *ionic = devlink_priv(dl);
|
||||||
|
|
||||||
return ionic_firmware_update(ionic->lif, fwname, extack);
|
return ionic_firmware_update(ionic->lif, params->file_name, extack);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ionic_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
static int ionic_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
|
||||||
|
@ -742,8 +742,8 @@ static int nsim_dev_info_get(struct devlink *devlink,
|
|||||||
#define NSIM_DEV_FLASH_CHUNK_SIZE 1000
|
#define NSIM_DEV_FLASH_CHUNK_SIZE 1000
|
||||||
#define NSIM_DEV_FLASH_CHUNK_TIME_MS 10
|
#define NSIM_DEV_FLASH_CHUNK_TIME_MS 10
|
||||||
|
|
||||||
static int nsim_dev_flash_update(struct devlink *devlink, const char *file_name,
|
static int nsim_dev_flash_update(struct devlink *devlink,
|
||||||
const char *component,
|
struct devlink_flash_update_params *params,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct nsim_dev *nsim_dev = devlink_priv(devlink);
|
struct nsim_dev *nsim_dev = devlink_priv(devlink);
|
||||||
@ -753,13 +753,13 @@ static int nsim_dev_flash_update(struct devlink *devlink, const char *file_name,
|
|||||||
devlink_flash_update_begin_notify(devlink);
|
devlink_flash_update_begin_notify(devlink);
|
||||||
devlink_flash_update_status_notify(devlink,
|
devlink_flash_update_status_notify(devlink,
|
||||||
"Preparing to flash",
|
"Preparing to flash",
|
||||||
component, 0, 0);
|
params->component, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) {
|
for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) {
|
||||||
if (nsim_dev->fw_update_status)
|
if (nsim_dev->fw_update_status)
|
||||||
devlink_flash_update_status_notify(devlink, "Flashing",
|
devlink_flash_update_status_notify(devlink, "Flashing",
|
||||||
component,
|
params->component,
|
||||||
i * NSIM_DEV_FLASH_CHUNK_SIZE,
|
i * NSIM_DEV_FLASH_CHUNK_SIZE,
|
||||||
NSIM_DEV_FLASH_SIZE);
|
NSIM_DEV_FLASH_SIZE);
|
||||||
msleep(NSIM_DEV_FLASH_CHUNK_TIME_MS);
|
msleep(NSIM_DEV_FLASH_CHUNK_TIME_MS);
|
||||||
@ -767,13 +767,13 @@ static int nsim_dev_flash_update(struct devlink *devlink, const char *file_name,
|
|||||||
|
|
||||||
if (nsim_dev->fw_update_status) {
|
if (nsim_dev->fw_update_status) {
|
||||||
devlink_flash_update_status_notify(devlink, "Flashing",
|
devlink_flash_update_status_notify(devlink, "Flashing",
|
||||||
component,
|
params->component,
|
||||||
NSIM_DEV_FLASH_SIZE,
|
NSIM_DEV_FLASH_SIZE,
|
||||||
NSIM_DEV_FLASH_SIZE);
|
NSIM_DEV_FLASH_SIZE);
|
||||||
devlink_flash_update_timeout_notify(devlink, "Flash select",
|
devlink_flash_update_timeout_notify(devlink, "Flash select",
|
||||||
component, 81);
|
params->component, 81);
|
||||||
devlink_flash_update_status_notify(devlink, "Flashing done",
|
devlink_flash_update_status_notify(devlink, "Flashing done",
|
||||||
component, 0, 0);
|
params->component, 0, 0);
|
||||||
devlink_flash_update_end_notify(devlink);
|
devlink_flash_update_end_notify(devlink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,6 +550,20 @@ 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"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct devlink_flash_update_params - Flash Update parameters
|
||||||
|
* @file_name: the name of the flash firmware file to update from
|
||||||
|
* @component: the flash component to update
|
||||||
|
*
|
||||||
|
* With the exception of file_name, 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 char *component;
|
||||||
|
};
|
||||||
|
|
||||||
#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT BIT(0)
|
#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT BIT(0)
|
||||||
|
|
||||||
struct devlink_region;
|
struct devlink_region;
|
||||||
@ -1112,8 +1126,8 @@ struct devlink_ops {
|
|||||||
* parameters supported by the driver should be set in
|
* parameters supported by the driver should be set in
|
||||||
* supported_flash_update_params.
|
* supported_flash_update_params.
|
||||||
*/
|
*/
|
||||||
int (*flash_update)(struct devlink *devlink, const char *file_name,
|
int (*flash_update)(struct devlink *devlink,
|
||||||
const char *component,
|
struct devlink_flash_update_params *params,
|
||||||
struct netlink_ext_ack *extack);
|
struct netlink_ext_ack *extack);
|
||||||
/**
|
/**
|
||||||
* @trap_init: Trap initialization function.
|
* @trap_init: Trap initialization function.
|
||||||
|
@ -3147,8 +3147,8 @@ EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
|
|||||||
static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
|
static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
|
||||||
struct genl_info *info)
|
struct genl_info *info)
|
||||||
{
|
{
|
||||||
|
struct devlink_flash_update_params params = {};
|
||||||
struct devlink *devlink = info->user_ptr[0];
|
struct devlink *devlink = info->user_ptr[0];
|
||||||
const char *file_name, *component = NULL;
|
|
||||||
struct nlattr *nla_component;
|
struct nlattr *nla_component;
|
||||||
u32 supported_params;
|
u32 supported_params;
|
||||||
|
|
||||||
@ -3160,7 +3160,7 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
|
|||||||
|
|
||||||
supported_params = devlink->ops->supported_flash_update_params;
|
supported_params = devlink->ops->supported_flash_update_params;
|
||||||
|
|
||||||
file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
|
params.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];
|
||||||
if (nla_component) {
|
if (nla_component) {
|
||||||
@ -3169,11 +3169,10 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
|
|||||||
"component update is not supported by this device");
|
"component update is not supported by this device");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
component = nla_data(nla_component);
|
params.component = nla_data(nla_component);
|
||||||
}
|
}
|
||||||
|
|
||||||
return devlink->ops->flash_update(devlink, file_name, component,
|
return devlink->ops->flash_update(devlink, ¶ms, info->extack);
|
||||||
info->extack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct devlink_param devlink_param_generic[] = {
|
static const struct devlink_param devlink_param_generic[] = {
|
||||||
@ -9651,6 +9650,7 @@ out:
|
|||||||
|
|
||||||
int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
|
int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
|
||||||
{
|
{
|
||||||
|
struct devlink_flash_update_params params = {};
|
||||||
struct devlink *devlink;
|
struct devlink *devlink;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -9663,8 +9663,10 @@ int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params.file_name = file_name;
|
||||||
|
|
||||||
mutex_lock(&devlink->lock);
|
mutex_lock(&devlink->lock);
|
||||||
ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
|
ret = devlink->ops->flash_update(devlink, ¶ms, NULL);
|
||||||
mutex_unlock(&devlink->lock);
|
mutex_unlock(&devlink->lock);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -23,6 +23,9 @@ fw_flash_test()
|
|||||||
devlink dev flash $DL_HANDLE file dummy
|
devlink dev flash $DL_HANDLE file dummy
|
||||||
check_err $? "Failed to flash with status updates on"
|
check_err $? "Failed to flash with status updates on"
|
||||||
|
|
||||||
|
devlink dev flash $DL_HANDLE file dummy component fw.mgmt
|
||||||
|
check_err $? "Failed to flash with component attribute"
|
||||||
|
|
||||||
echo "n"> $DEBUGFS_DIR/fw_update_status
|
echo "n"> $DEBUGFS_DIR/fw_update_status
|
||||||
check_err $? "Failed to disable status updates"
|
check_err $? "Failed to disable status updates"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user