summaryrefslogtreecommitdiff
path: root/net/core/devlink.c
diff options
context:
space:
mode:
authorJiri Pirko <jiri@nvidia.com>2022-04-25 06:44:23 +0300
committerDavid S. Miller <davem@davemloft.net>2022-04-25 10:42:28 +0100
commit28b2d1f1ac41dda0b239830765d85c7ae4434182 (patch)
treead118d767f90b4f9539c87dd8e7c836a94bc5c9e /net/core/devlink.c
parent276910aecc6a4076f5fbfd8160ff70695d6c1eb5 (diff)
devlink: introduce line card device info infrastructure
Extend the line card info message with information (e.g., FW version) about devices found on the line card. Example: $ devlink lc info pci/0000:01:00.0 lc 8 pci/0000:01:00.0: lc 8 versions: fixed: hw.revision 0 running: ini.version 4 devices: device 0 versions: running: fw 19.2010.1310 device 1 versions: running: fw 19.2010.1310 device 2 versions: running: fw 19.2010.1310 device 3 versions: running: fw 19.2010.1310 Signed-off-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/devlink.c')
-rw-r--r--net/core/devlink.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 5facd10de64a..5f441a0e34f4 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -2062,6 +2062,7 @@ struct devlink_linecard_type {
struct devlink_linecard_device {
struct list_head list;
unsigned int index;
+ void *priv;
};
static int
@@ -2429,6 +2430,68 @@ struct devlink_info_req {
};
static int
+devlink_nl_linecard_device_info_fill(struct sk_buff *msg,
+ struct devlink_linecard *linecard,
+ struct devlink_linecard_device *linecard_device,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *attr;
+
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE);
+ if (!attr)
+ return -EMSGSIZE;
+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_DEVICE_INDEX,
+ linecard_device->index)) {
+ nla_nest_cancel(msg, attr);
+ return -EMSGSIZE;
+ }
+ if (linecard->ops->device_info_get) {
+ struct devlink_info_req req;
+ int err;
+
+ req.msg = msg;
+ err = linecard->ops->device_info_get(linecard_device,
+ linecard_device->priv,
+ &req, extack);
+ if (err) {
+ nla_nest_cancel(msg, attr);
+ return err;
+ }
+ }
+ nla_nest_end(msg, attr);
+
+ return 0;
+}
+
+static int devlink_nl_linecard_devices_info_fill(struct sk_buff *msg,
+ struct devlink_linecard *linecard,
+ struct netlink_ext_ack *extack)
+{
+ struct devlink_linecard_device *linecard_device;
+ struct nlattr *attr;
+ int err;
+
+ if (list_empty(&linecard->device_list))
+ return 0;
+
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE_LIST);
+ if (!attr)
+ return -EMSGSIZE;
+ list_for_each_entry(linecard_device, &linecard->device_list, list) {
+ err = devlink_nl_linecard_device_info_fill(msg, linecard,
+ linecard_device,
+ extack);
+ if (err) {
+ nla_nest_cancel(msg, attr);
+ return err;
+ }
+ }
+ nla_nest_end(msg, attr);
+
+ return 0;
+}
+
+static int
devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
struct devlink_linecard *linecard,
enum devlink_command cmd, u32 portid,
@@ -2453,6 +2516,10 @@ devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
if (err)
goto nla_put_failure;
+ err = devlink_nl_linecard_devices_info_fill(msg, linecard, extack);
+ if (err)
+ goto nla_put_failure;
+
genlmsg_end(msg, hdr);
return 0;
@@ -10483,12 +10550,13 @@ EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
*
* @linecard: devlink linecard
* @device_index: index of the linecard device
+ * @priv: user priv pointer
*
* Return: Line card device structure or an ERR_PTR() encoded error code.
*/
struct devlink_linecard_device *
devlink_linecard_device_create(struct devlink_linecard *linecard,
- unsigned int device_index)
+ unsigned int device_index, void *priv)
{
struct devlink_linecard_device *linecard_device;
@@ -10496,6 +10564,7 @@ devlink_linecard_device_create(struct devlink_linecard *linecard,
if (!linecard_device)
return ERR_PTR(-ENOMEM);
linecard_device->index = device_index;
+ linecard_device->priv = priv;
mutex_lock(&linecard->state_lock);
list_add_tail(&linecard_device->list, &linecard->device_list);
devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);