[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190115005009.16025-3-jakub.kicinski@netronome.com>
Date: Mon, 14 Jan 2019 16:50:04 -0800
From: Jakub Kicinski <jakub.kicinski@...ronome.com>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org, oss-drivers@...ronome.com,
jiri@...nulli.us, Jakub Kicinski <jakub.kicinski@...ronome.com>
Subject: [RFC net-next 2/6] devlink: add version reporting API
ethtool -i has a few fixed-size fields which can be used to report
firmware version and expansion ROM version. Unfortunately, modern
hardware has more firmware components. There is usually some
datapath microcode, management controller, PXE drivers, and a
CPLD load. Running ethtool -i on modern controllers reveals the
fact that vendors cram multiple values into firmware version field.
Here are some examples from systems I could lay my hands on quickly:
tg3: "FFV20.2.17 bc 5720-v1.39"
i40e: "6.01 0x800034a4 1.1747.0"
nfp: "0.0.3.5 0.25 sriov-2.1.16 nic"
Add a new devlink API to allow retrieving multiple versions, and
provide user-readable name for those versions.
While at it break down the versions into three categories:
- fixed - this is the board/fixed component version, usually vendors
report information like the board version in the PCI VPD,
but it will benefit from naming and common API as well;
- running - this is the running firmware version;
- stored - this is firmware in the flash, after firmware update
this value will reflect the flashed version, while the
running version may only be updated after reboot.
Signed-off-by: Jakub Kicinski <jakub.kicinski@...ronome.com>
---
include/net/devlink.h | 13 +++++++
include/uapi/linux/devlink.h | 6 ++++
net/core/devlink.c | 67 +++++++++++++++++++++++++++++++++++-
3 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 4358c111ce83..51f08edb1138 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -477,6 +477,8 @@ struct devlink_ops {
struct netlink_ext_ack *extack);
int (*serial_get)(struct devlink *devlink, u8 *buf, size_t buf_len,
size_t *len, struct netlink_ext_ack *extack);
+ int (*versions_get)(struct devlink *devlink, struct sk_buff *skb,
+ struct netlink_ext_ack *extack);
};
static inline void *devlink_priv(struct devlink *devlink)
@@ -586,6 +588,10 @@ int devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
u8 *data, u32 snapshot_id,
devlink_snapshot_data_dest_t *data_destructor);
+int devlink_versions_report(struct sk_buff *skb, enum devlink_attr attr,
+ const char *version_name,
+ const char *version_value);
+
#else
static inline struct devlink *devlink_alloc(const struct devlink_ops *ops,
@@ -846,6 +852,13 @@ devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
return 0;
}
+static inline int
+devlink_versions_report(struct sk_buff *skb, enum devlink_attr attr,
+ const char *version_name, const char *version_value)
+{
+ return 0;
+}
+
#endif
#endif /* _NET_DEVLINK_H_ */
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 760c9c360330..eb97a52246ef 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -288,6 +288,12 @@ enum devlink_attr {
DEVLINK_ATTR_REGION_CHUNK_LEN, /* u64 */
DEVLINK_ATTR_INFO_SERIAL_NUMBER, /* binary */
+ DEVLINK_ATTR_INFO_VERSIONS, /* nested */
+ DEVLINK_ATTR_INFO_VERSIONS_FIXED, /* nested */
+ DEVLINK_ATTR_INFO_VERSIONS_RUNNING, /* nested */
+ DEVLINK_ATTR_INFO_VERSIONS_STORED, /* nested */
+ DEVLINK_ATTR_INFO_VERSIONS_NAME, /* string */
+ DEVLINK_ATTR_INFO_VERSIONS_VALUE, /* string */
/* add new attributes above here, update the policy in devlink.c */
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 55b7b006df28..f35d917da7f2 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3615,6 +3615,32 @@ static int devlink_nl_info_sn_fill(struct sk_buff *msg, struct devlink *devlink,
return nla_put(msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, len, sn);
}
+static int devlink_nl_info_versions_fill(struct sk_buff *msg,
+ struct devlink *devlink,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *attr;
+ int err;
+
+ if (!devlink->ops->versions_get)
+ return 0;
+
+ attr = nla_nest_start(msg, DEVLINK_ATTR_INFO_VERSIONS);
+ if (!attr)
+ return -EMSGSIZE;
+
+ err = devlink->ops->versions_get(devlink, msg, extack);
+ if (err)
+ goto err_cancel;
+
+ nla_nest_end(msg, attr);
+ return 0;
+
+err_cancel:
+ nla_nest_cancel(msg, attr);
+ return err;
+}
+
static int
devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
enum devlink_command cmd, u32 portid,
@@ -3635,6 +3661,10 @@ devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
if (err)
goto err_cancel_msg;
+ err = devlink_nl_info_versions_fill(msg, devlink, extack);
+ if (err)
+ goto err_cancel_msg;
+
genlmsg_end(msg, hdr);
return 0;
@@ -3650,7 +3680,8 @@ static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
struct sk_buff *msg;
int err;
- if (!devlink->ops || !devlink->ops->serial_get)
+ if (!devlink->ops ||
+ (!devlink->ops->serial_get && !devlink->ops->versions_get))
return -EOPNOTSUPP;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -3701,6 +3732,40 @@ static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
return msg->len;
}
+int devlink_versions_report(struct sk_buff *skb, enum devlink_attr attr,
+ const char *version_name, const char *version_value)
+{
+ struct nlattr *nest;
+ int err;
+
+ if (attr < DEVLINK_ATTR_INFO_VERSIONS_FIXED ||
+ attr > DEVLINK_ATTR_INFO_VERSIONS_STORED)
+ return -EINVAL;
+
+ nest = nla_nest_start(skb, attr);
+ if (!nest)
+ return -EMSGSIZE;
+
+ err = nla_put_string(skb, DEVLINK_ATTR_INFO_VERSIONS_NAME,
+ version_name);
+ if (err)
+ goto nla_put_failure;
+
+ err = nla_put_string(skb, DEVLINK_ATTR_INFO_VERSIONS_VALUE,
+ version_value);
+ if (err)
+ goto nla_put_failure;
+
+ nla_nest_end(skb, nest);
+
+ return 0;
+
+nla_put_failure:
+ nla_nest_cancel(skb, nest);
+ return err;
+}
+EXPORT_SYMBOL_GPL(devlink_versions_report);
+
static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
--
2.19.2
Powered by blists - more mailing lists