Commit bace3f46 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-devlink-sync-flash-and-dev-info-commands'

Jiri Pirko says:

====================
net: devlink: sync flash and dev info commands

Purpose of this patchset is to introduce consistency between two devlink
commands:
  devlink dev info
    Shows versions of running default flash target and components.
  devlink dev flash
    Flashes default flash target or component name (if specified
    on cmdline).

Currently it is up to the driver what versions to expose and what flash
update component names to accept. This is inconsistent. Thankfully, only
netdevsim currently using components so it is still time
to sanitize this.

This patchset makes sure, that devlink.c calls into driver for
component flash update only in case the driver exposes the same version
name.

Example:
$ devlink dev info
netdevsim/netdevsim10:
  driver netdevsim
  versions:
      running:
        fw.mgmt 10.20.30
      stored:
        fw.mgmt 10.20.30
$ devlink dev flash netdevsim/netdevsim10 file somefile.bin
[fw.mgmt] Preparing to flash
[fw.mgmt] Flashing 100%
[fw.mgmt] Flash select
[fw.mgmt] Flashing done
$ devlink dev flash netdevsim/netdevsim10 file somefile.bin component fw.mgmt
[fw.mgmt] Preparing to flash
[fw.mgmt] Flashing 100%
[fw.mgmt] Flash select
[fw.mgmt] Flashing done

$ devlink dev flash netdevsim/netdevsim10 file somefile.bin component dummy
Error: selected component is not supported by this device.
====================

Link: https://lore.kernel.org/r/20220824122011.1204330-1-jiri@resnulli.usSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 88e500af f94b6063
......@@ -984,7 +984,17 @@ static int nsim_dev_info_get(struct devlink *devlink,
struct devlink_info_req *req,
struct netlink_ext_ack *extack)
{
return devlink_info_driver_name_put(req, DRV_NAME);
int err;
err = devlink_info_driver_name_put(req, DRV_NAME);
if (err)
return err;
err = devlink_info_version_stored_put_ext(req, "fw.mgmt", "10.20.30",
DEVLINK_INFO_VERSION_TYPE_COMPONENT);
if (err)
return err;
return devlink_info_version_running_put_ext(req, "fw.mgmt", "10.20.30",
DEVLINK_INFO_VERSION_TYPE_COMPONENT);
}
#define NSIM_DEV_FLASH_SIZE 500000
......@@ -1312,8 +1322,7 @@ nsim_dev_devlink_trap_drop_counter_get(struct devlink *devlink,
static const struct devlink_ops nsim_dev_devlink_ops = {
.eswitch_mode_set = nsim_devlink_eswitch_mode_set,
.eswitch_mode_get = nsim_devlink_eswitch_mode_get,
.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
.reload_down = nsim_dev_reload_down,
.reload_up = nsim_dev_reload_up,
......
......@@ -624,8 +624,7 @@ struct devlink_flash_update_params {
u32 overwrite_mask;
};
#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT BIT(0)
#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK BIT(1)
#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK BIT(0)
struct devlink_region;
struct devlink_info_req;
......@@ -1714,15 +1713,31 @@ int devlink_info_driver_name_put(struct devlink_info_req *req,
const char *name);
int devlink_info_board_serial_number_put(struct devlink_info_req *req,
const char *bsn);
enum devlink_info_version_type {
DEVLINK_INFO_VERSION_TYPE_NONE,
DEVLINK_INFO_VERSION_TYPE_COMPONENT, /* May be used as flash update
* component by name.
*/
};
int devlink_info_version_fixed_put(struct devlink_info_req *req,
const char *version_name,
const char *version_value);
int devlink_info_version_stored_put(struct devlink_info_req *req,
const char *version_name,
const char *version_value);
int devlink_info_version_stored_put_ext(struct devlink_info_req *req,
const char *version_name,
const char *version_value,
enum devlink_info_version_type version_type);
int devlink_info_version_running_put(struct devlink_info_req *req,
const char *version_name,
const char *version_value);
int devlink_info_version_running_put_ext(struct devlink_info_req *req,
const char *version_name,
const char *version_value,
enum devlink_info_version_type version_type);
int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg);
int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg);
......
......@@ -4742,10 +4742,76 @@ void devlink_flash_update_timeout_notify(struct devlink *devlink,
}
EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
struct devlink_info_req {
struct sk_buff *msg;
void (*version_cb)(const char *version_name,
enum devlink_info_version_type version_type,
void *version_cb_priv);
void *version_cb_priv;
};
struct devlink_flash_component_lookup_ctx {
const char *lookup_name;
bool lookup_name_found;
};
static void
devlink_flash_component_lookup_cb(const char *version_name,
enum devlink_info_version_type version_type,
void *version_cb_priv)
{
struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv;
if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT ||
lookup_ctx->lookup_name_found)
return;
lookup_ctx->lookup_name_found =
!strcmp(lookup_ctx->lookup_name, version_name);
}
static int devlink_flash_component_get(struct devlink *devlink,
struct nlattr *nla_component,
const char **p_component,
struct netlink_ext_ack *extack)
{
struct devlink_flash_component_lookup_ctx lookup_ctx = {};
struct devlink_info_req req = {};
const char *component;
int ret;
if (!nla_component)
return 0;
component = nla_data(nla_component);
if (!devlink->ops->info_get) {
NL_SET_ERR_MSG_ATTR(extack, nla_component,
"component update is not supported by this device");
return -EOPNOTSUPP;
}
lookup_ctx.lookup_name = component;
req.version_cb = devlink_flash_component_lookup_cb;
req.version_cb_priv = &lookup_ctx;
ret = devlink->ops->info_get(devlink, &req, NULL);
if (ret)
return ret;
if (!lookup_ctx.lookup_name_found) {
NL_SET_ERR_MSG_ATTR(extack, nla_component,
"selected component is not supported by this device");
return -EINVAL;
}
*p_component = component;
return 0;
}
static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
struct genl_info *info)
{
struct nlattr *nla_component, *nla_overwrite_mask, *nla_file_name;
struct nlattr *nla_overwrite_mask, *nla_file_name;
struct devlink_flash_update_params params = {};
struct devlink *devlink = info->user_ptr[0];
const char *file_name;
......@@ -4758,17 +4824,13 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
return -EINVAL;
supported_params = devlink->ops->supported_flash_update_params;
ret = devlink_flash_component_get(devlink,
info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT],
&params.component, info->extack);
if (ret)
return ret;
nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
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;
}
params.component = nla_data(nla_component);
}
supported_params = devlink->ops->supported_flash_update_params;
nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
if (nla_overwrite_mask) {
......@@ -6553,18 +6615,18 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
return err;
}
struct devlink_info_req {
struct sk_buff *msg;
};
int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
{
if (!req->msg)
return 0;
return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
}
EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
{
if (!req->msg)
return 0;
return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
}
EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
......@@ -6572,6 +6634,8 @@ EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
int devlink_info_board_serial_number_put(struct devlink_info_req *req,
const char *bsn)
{
if (!req->msg)
return 0;
return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
bsn);
}
......@@ -6579,11 +6643,19 @@ EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
static int devlink_info_version_put(struct devlink_info_req *req, int attr,
const char *version_name,
const char *version_value)
const char *version_value,
enum devlink_info_version_type version_type)
{
struct nlattr *nest;
int err;
if (req->version_cb)
req->version_cb(version_name, version_type,
req->version_cb_priv);
if (!req->msg)
return 0;
nest = nla_nest_start_noflag(req->msg, attr);
if (!nest)
return -EMSGSIZE;
......@@ -6612,7 +6684,8 @@ int devlink_info_version_fixed_put(struct devlink_info_req *req,
const char *version_value)
{
return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
version_name, version_value);
version_name, version_value,
DEVLINK_INFO_VERSION_TYPE_NONE);
}
EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
......@@ -6621,25 +6694,49 @@ int devlink_info_version_stored_put(struct devlink_info_req *req,
const char *version_value)
{
return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
version_name, version_value);
version_name, version_value,
DEVLINK_INFO_VERSION_TYPE_NONE);
}
EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
int devlink_info_version_stored_put_ext(struct devlink_info_req *req,
const char *version_name,
const char *version_value,
enum devlink_info_version_type version_type)
{
return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
version_name, version_value,
version_type);
}
EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext);
int devlink_info_version_running_put(struct devlink_info_req *req,
const char *version_name,
const char *version_value)
{
return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
version_name, version_value);
version_name, version_value,
DEVLINK_INFO_VERSION_TYPE_NONE);
}
EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
int devlink_info_version_running_put_ext(struct devlink_info_req *req,
const char *version_name,
const char *version_value,
enum devlink_info_version_type version_type)
{
return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
version_name, version_value,
version_type);
}
EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext);
static int
devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
enum devlink_command cmd, u32 portid,
u32 seq, int flags, struct netlink_ext_ack *extack)
{
struct devlink_info_req req;
struct devlink_info_req req = {};
void *hdr;
int err;
......@@ -12306,8 +12403,8 @@ EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
static void __devlink_compat_running_version(struct devlink *devlink,
char *buf, size_t len)
{
struct devlink_info_req req = {};
const struct nlattr *nlattr;
struct devlink_info_req req;
struct sk_buff *msg;
int rem, err;
......
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