From patchwork Tue Jan 15 00:50:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 1024890 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="MYdmDijp"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43dsFW6QWcz9s3l for ; Tue, 15 Jan 2019 11:50:23 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727590AbfAOAuW (ORCPT ); Mon, 14 Jan 2019 19:50:22 -0500 Received: from mail-qk1-f193.google.com ([209.85.222.193]:37761 "EHLO mail-qk1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727560AbfAOAuV (ORCPT ); Mon, 14 Jan 2019 19:50:21 -0500 Received: by mail-qk1-f193.google.com with SMTP id g125so647464qke.4 for ; Mon, 14 Jan 2019 16:50:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PCVAPuCuljUwTUgZE3maFOfk7CUlpEqRXr7aZ7v7ZE4=; b=MYdmDijpEojQfe6y3YWkGWx9/P5sY7GthPnkB7WevKECkvmYiqeJd1EXgRRcy641b6 l2ue4SR27CdkIQKGEfnwrKhXqIVXt9ox9vQo+qoNwJlFEfHsoQAn9GNfG0F2bEPjRJ9C neSNOwwPIOcNJMC6MXzNPwkVRNgpd1nPixKOYzk15zW5+y+ZJsovisX9z36PNuNVJcm0 DM06LEg/pwVWokAeSSc/N38tHPZdDcGVfavmUzqSjAKU92yfKxfijKx6HWu3w5xItqeV PYdW87tO+0+dkN48FjD4nUxyOFbcBM9xp2mJvLY3TcpKtqv3DlRxtolaQiuyqRHs3yvJ 08WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PCVAPuCuljUwTUgZE3maFOfk7CUlpEqRXr7aZ7v7ZE4=; b=h7O0MOqGazs3nup7dKdSl8wbDbOzKvpr4wg5+hNnmi3ZGizmyFc9oF4e7Kb+RRi0YA FFeHuD9H1siysRup6S867SjUrY9Bgw1D0d8fMZGQLL8ElwnZgJ9g9BEZLzBz1b7m6Le/ Z4ejuop0t9zQj9unSZNAsAgXfLnNvixjmvKDvOmH872z/mWsEVs4yYNaddRrGoyNZkxj 5BdKXs4FKwz5IQBTLPU2+KG31eaGONmkeGgl12e6TV0BXfYwtxgt30iiPnu4AvZWfgZG 7oFCh+gVburLn82kN9b0nasqvRRMrwfrFNkZYsM5/rBRKUL6DgjvmHSqB1io/Lz76yp2 PDUA== X-Gm-Message-State: AJcUukfiOnTZ4Z6TPsNxnJOSM3XMXqxHIn1eoUs8w2M5g2XPGX9U+13F lbuog05KujnhrNxR0E/zq0JcHQ== X-Google-Smtp-Source: ALg8bN7lvnbL4UJM9LcQ3JZzVA1dzdo2MZzWqHB/Jb3yiTmCBm8981Oi8NPQ689hdzaaQIva/U6dCA== X-Received: by 2002:a37:ae41:: with SMTP id x62mr847214qke.354.1547513420221; Mon, 14 Jan 2019 16:50:20 -0800 (PST) Received: from jkicinski-Precision-T1700.netronome.com ([66.60.152.14]) by smtp.gmail.com with ESMTPSA id p47sm63945227qta.36.2019.01.14.16.50.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 14 Jan 2019 16:50:19 -0800 (PST) From: Jakub Kicinski To: davem@davemloft.net Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, jiri@resnulli.us, Jakub Kicinski Subject: [RFC net-next 2/6] devlink: add version reporting API Date: Mon, 14 Jan 2019 16:50:04 -0800 Message-Id: <20190115005009.16025-3-jakub.kicinski@netronome.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190115005009.16025-1-jakub.kicinski@netronome.com> References: <20190115005009.16025-1-jakub.kicinski@netronome.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 --- 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 },