2 * net/core/devlink.c - Network physical/parent device Netlink interface
4 * Heavily inspired by net/wireless/
5 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/slab.h>
18 #include <linux/gfp.h>
19 #include <linux/device.h>
20 #include <linux/list.h>
21 #include <linux/netdevice.h>
22 #include <linux/spinlock.h>
23 #include <linux/refcount.h>
24 #include <rdma/ib_verbs.h>
25 #include <net/netlink.h>
26 #include <net/genetlink.h>
27 #include <net/rtnetlink.h>
28 #include <net/net_namespace.h>
30 #include <net/devlink.h>
31 #define CREATE_TRACE_POINTS
32 #include <trace/events/devlink.h>
34 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
36 .name = "destination mac",
37 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
42 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
44 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
45 .fields = devlink_dpipe_fields_ethernet,
46 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
49 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
51 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
53 .name = "destination ip",
54 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
59 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
61 .id = DEVLINK_DPIPE_HEADER_IPV4,
62 .fields = devlink_dpipe_fields_ipv4,
63 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
66 EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
68 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
70 .name = "destination ip",
71 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
76 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
78 .id = DEVLINK_DPIPE_HEADER_IPV6,
79 .fields = devlink_dpipe_fields_ipv6,
80 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
83 EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
85 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
86 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
88 static LIST_HEAD(devlink_list);
92 * An overall lock guarding every operation coming from userspace.
93 * It also guards devlink devices list and it is taken when
94 * driver registers/unregisters it.
96 static DEFINE_MUTEX(devlink_mutex);
98 static struct net *devlink_net(const struct devlink *devlink)
100 return read_pnet(&devlink->_net);
103 static void devlink_net_set(struct devlink *devlink, struct net *net)
105 write_pnet(&devlink->_net, net);
108 static struct devlink *devlink_get_from_attrs(struct net *net,
109 struct nlattr **attrs)
111 struct devlink *devlink;
115 if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
116 return ERR_PTR(-EINVAL);
118 busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
119 devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
121 lockdep_assert_held(&devlink_mutex);
123 list_for_each_entry(devlink, &devlink_list, list) {
124 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
125 strcmp(dev_name(devlink->dev), devname) == 0 &&
126 net_eq(devlink_net(devlink), net))
130 return ERR_PTR(-ENODEV);
133 static struct devlink *devlink_get_from_info(struct genl_info *info)
135 return devlink_get_from_attrs(genl_info_net(info), info->attrs);
138 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
141 struct devlink_port *devlink_port;
143 list_for_each_entry(devlink_port, &devlink->port_list, list) {
144 if (devlink_port->index == port_index)
150 static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
152 return devlink_port_get_by_index(devlink, port_index);
155 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
156 struct nlattr **attrs)
158 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
159 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
160 struct devlink_port *devlink_port;
162 devlink_port = devlink_port_get_by_index(devlink, port_index);
164 return ERR_PTR(-ENODEV);
167 return ERR_PTR(-EINVAL);
170 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
171 struct genl_info *info)
173 return devlink_port_get_from_attrs(devlink, info->attrs);
177 struct list_head list;
180 u16 ingress_pools_count;
181 u16 egress_pools_count;
182 u16 ingress_tc_count;
186 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
188 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
191 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
192 unsigned int sb_index)
194 struct devlink_sb *devlink_sb;
196 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
197 if (devlink_sb->index == sb_index)
203 static bool devlink_sb_index_exists(struct devlink *devlink,
204 unsigned int sb_index)
206 return devlink_sb_get_by_index(devlink, sb_index);
209 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
210 struct nlattr **attrs)
212 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
213 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
214 struct devlink_sb *devlink_sb;
216 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
218 return ERR_PTR(-ENODEV);
221 return ERR_PTR(-EINVAL);
224 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
225 struct genl_info *info)
227 return devlink_sb_get_from_attrs(devlink, info->attrs);
230 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
231 struct nlattr **attrs,
236 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
239 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
240 if (val >= devlink_sb_pool_count(devlink_sb))
246 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
247 struct genl_info *info,
250 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
255 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
256 enum devlink_sb_pool_type *p_pool_type)
260 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
263 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
264 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
265 val != DEVLINK_SB_POOL_TYPE_EGRESS)
272 devlink_sb_pool_type_get_from_info(struct genl_info *info,
273 enum devlink_sb_pool_type *p_pool_type)
275 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
279 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
280 enum devlink_sb_threshold_type *p_th_type)
284 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
287 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
288 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
289 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
296 devlink_sb_th_type_get_from_info(struct genl_info *info,
297 enum devlink_sb_threshold_type *p_th_type)
299 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
303 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
304 struct nlattr **attrs,
305 enum devlink_sb_pool_type pool_type,
310 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
313 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
314 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
315 val >= devlink_sb->ingress_tc_count)
317 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
318 val >= devlink_sb->egress_tc_count)
325 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
326 struct genl_info *info,
327 enum devlink_sb_pool_type pool_type,
330 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
331 pool_type, p_tc_index);
334 struct devlink_region {
335 struct devlink *devlink;
336 struct list_head list;
338 struct list_head snapshot_list;
344 struct devlink_snapshot {
345 struct list_head list;
346 struct devlink_region *region;
347 devlink_snapshot_data_dest_t *data_destructor;
353 static struct devlink_region *
354 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
356 struct devlink_region *region;
358 list_for_each_entry(region, &devlink->region_list, list)
359 if (!strcmp(region->name, region_name))
365 static struct devlink_snapshot *
366 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
368 struct devlink_snapshot *snapshot;
370 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
371 if (snapshot->id == id)
377 static void devlink_region_snapshot_del(struct devlink_snapshot *snapshot)
379 snapshot->region->cur_snapshots--;
380 list_del(&snapshot->list);
381 (*snapshot->data_destructor)(snapshot->data);
385 #define DEVLINK_NL_FLAG_NEED_DEVLINK BIT(0)
386 #define DEVLINK_NL_FLAG_NEED_PORT BIT(1)
387 #define DEVLINK_NL_FLAG_NEED_SB BIT(2)
389 /* The per devlink instance lock is taken by default in the pre-doit
390 * operation, yet several commands do not require this. The global
391 * devlink lock is taken and protects from disruption by user-calls.
393 #define DEVLINK_NL_FLAG_NO_LOCK BIT(3)
395 static int devlink_nl_pre_doit(const struct genl_ops *ops,
396 struct sk_buff *skb, struct genl_info *info)
398 struct devlink *devlink;
401 mutex_lock(&devlink_mutex);
402 devlink = devlink_get_from_info(info);
403 if (IS_ERR(devlink)) {
404 mutex_unlock(&devlink_mutex);
405 return PTR_ERR(devlink);
407 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
408 mutex_lock(&devlink->lock);
409 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
410 info->user_ptr[0] = devlink;
411 } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
412 struct devlink_port *devlink_port;
414 devlink_port = devlink_port_get_from_info(devlink, info);
415 if (IS_ERR(devlink_port)) {
416 err = PTR_ERR(devlink_port);
419 info->user_ptr[0] = devlink_port;
421 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
422 struct devlink_sb *devlink_sb;
424 devlink_sb = devlink_sb_get_from_info(devlink, info);
425 if (IS_ERR(devlink_sb)) {
426 err = PTR_ERR(devlink_sb);
429 info->user_ptr[1] = devlink_sb;
434 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
435 mutex_unlock(&devlink->lock);
436 mutex_unlock(&devlink_mutex);
440 static void devlink_nl_post_doit(const struct genl_ops *ops,
441 struct sk_buff *skb, struct genl_info *info)
443 struct devlink *devlink;
445 devlink = devlink_get_from_info(info);
446 if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
447 mutex_unlock(&devlink->lock);
448 mutex_unlock(&devlink_mutex);
451 static struct genl_family devlink_nl_family;
453 enum devlink_multicast_groups {
454 DEVLINK_MCGRP_CONFIG,
457 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
458 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
461 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
463 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
465 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
470 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
471 enum devlink_command cmd, u32 portid,
476 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
480 if (devlink_nl_put_handle(msg, devlink))
481 goto nla_put_failure;
483 genlmsg_end(msg, hdr);
487 genlmsg_cancel(msg, hdr);
491 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
496 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
498 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
502 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
508 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
509 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
512 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
513 struct devlink_port *devlink_port)
515 struct devlink_port_attrs *attrs = &devlink_port->attrs;
519 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
521 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, attrs->port_number))
525 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, attrs->port_number))
527 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
528 attrs->split_subport_number))
533 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
534 struct devlink_port *devlink_port,
535 enum devlink_command cmd, u32 portid,
540 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
544 if (devlink_nl_put_handle(msg, devlink))
545 goto nla_put_failure;
546 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
547 goto nla_put_failure;
549 spin_lock(&devlink_port->type_lock);
550 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
551 goto nla_put_failure_type_locked;
552 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
553 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
554 devlink_port->desired_type))
555 goto nla_put_failure_type_locked;
556 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
557 struct net_device *netdev = devlink_port->type_dev;
560 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
562 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
564 goto nla_put_failure_type_locked;
566 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
567 struct ib_device *ibdev = devlink_port->type_dev;
570 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
572 goto nla_put_failure_type_locked;
574 spin_unlock(&devlink_port->type_lock);
575 if (devlink_nl_port_attrs_put(msg, devlink_port))
576 goto nla_put_failure;
578 genlmsg_end(msg, hdr);
581 nla_put_failure_type_locked:
582 spin_unlock(&devlink_port->type_lock);
584 genlmsg_cancel(msg, hdr);
588 static void devlink_port_notify(struct devlink_port *devlink_port,
589 enum devlink_command cmd)
591 struct devlink *devlink = devlink_port->devlink;
595 if (!devlink_port->registered)
598 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
600 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
604 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
610 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
611 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
614 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
616 struct devlink *devlink = info->user_ptr[0];
620 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
624 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
625 info->snd_portid, info->snd_seq, 0);
631 return genlmsg_reply(msg, info);
634 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
635 struct netlink_callback *cb)
637 struct devlink *devlink;
638 int start = cb->args[0];
642 mutex_lock(&devlink_mutex);
643 list_for_each_entry(devlink, &devlink_list, list) {
644 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
650 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
651 NETLINK_CB(cb->skb).portid,
652 cb->nlh->nlmsg_seq, NLM_F_MULTI);
658 mutex_unlock(&devlink_mutex);
664 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
665 struct genl_info *info)
667 struct devlink_port *devlink_port = info->user_ptr[0];
668 struct devlink *devlink = devlink_port->devlink;
672 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
676 err = devlink_nl_port_fill(msg, devlink, devlink_port,
677 DEVLINK_CMD_PORT_NEW,
678 info->snd_portid, info->snd_seq, 0);
684 return genlmsg_reply(msg, info);
687 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
688 struct netlink_callback *cb)
690 struct devlink *devlink;
691 struct devlink_port *devlink_port;
692 int start = cb->args[0];
696 mutex_lock(&devlink_mutex);
697 list_for_each_entry(devlink, &devlink_list, list) {
698 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
700 mutex_lock(&devlink->lock);
701 list_for_each_entry(devlink_port, &devlink->port_list, list) {
706 err = devlink_nl_port_fill(msg, devlink, devlink_port,
708 NETLINK_CB(cb->skb).portid,
712 mutex_unlock(&devlink->lock);
717 mutex_unlock(&devlink->lock);
720 mutex_unlock(&devlink_mutex);
726 static int devlink_port_type_set(struct devlink *devlink,
727 struct devlink_port *devlink_port,
728 enum devlink_port_type port_type)
733 if (devlink->ops->port_type_set) {
734 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
736 if (port_type == devlink_port->type)
738 err = devlink->ops->port_type_set(devlink_port, port_type);
741 devlink_port->desired_type = port_type;
742 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
748 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
749 struct genl_info *info)
751 struct devlink_port *devlink_port = info->user_ptr[0];
752 struct devlink *devlink = devlink_port->devlink;
755 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
756 enum devlink_port_type port_type;
758 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
759 err = devlink_port_type_set(devlink, devlink_port, port_type);
766 static int devlink_port_split(struct devlink *devlink, u32 port_index,
767 u32 count, struct netlink_ext_ack *extack)
770 if (devlink->ops->port_split)
771 return devlink->ops->port_split(devlink, port_index, count,
776 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
777 struct genl_info *info)
779 struct devlink *devlink = info->user_ptr[0];
783 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
784 !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
787 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
788 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
789 return devlink_port_split(devlink, port_index, count, info->extack);
792 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
793 struct netlink_ext_ack *extack)
796 if (devlink->ops->port_unsplit)
797 return devlink->ops->port_unsplit(devlink, port_index, extack);
801 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
802 struct genl_info *info)
804 struct devlink *devlink = info->user_ptr[0];
807 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
810 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
811 return devlink_port_unsplit(devlink, port_index, info->extack);
814 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
815 struct devlink_sb *devlink_sb,
816 enum devlink_command cmd, u32 portid,
821 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
825 if (devlink_nl_put_handle(msg, devlink))
826 goto nla_put_failure;
827 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
828 goto nla_put_failure;
829 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
830 goto nla_put_failure;
831 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
832 devlink_sb->ingress_pools_count))
833 goto nla_put_failure;
834 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
835 devlink_sb->egress_pools_count))
836 goto nla_put_failure;
837 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
838 devlink_sb->ingress_tc_count))
839 goto nla_put_failure;
840 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
841 devlink_sb->egress_tc_count))
842 goto nla_put_failure;
844 genlmsg_end(msg, hdr);
848 genlmsg_cancel(msg, hdr);
852 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
853 struct genl_info *info)
855 struct devlink *devlink = info->user_ptr[0];
856 struct devlink_sb *devlink_sb = info->user_ptr[1];
860 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
864 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
866 info->snd_portid, info->snd_seq, 0);
872 return genlmsg_reply(msg, info);
875 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
876 struct netlink_callback *cb)
878 struct devlink *devlink;
879 struct devlink_sb *devlink_sb;
880 int start = cb->args[0];
884 mutex_lock(&devlink_mutex);
885 list_for_each_entry(devlink, &devlink_list, list) {
886 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
888 mutex_lock(&devlink->lock);
889 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
894 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
896 NETLINK_CB(cb->skb).portid,
900 mutex_unlock(&devlink->lock);
905 mutex_unlock(&devlink->lock);
908 mutex_unlock(&devlink_mutex);
914 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
915 struct devlink_sb *devlink_sb,
916 u16 pool_index, enum devlink_command cmd,
917 u32 portid, u32 seq, int flags)
919 struct devlink_sb_pool_info pool_info;
923 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
924 pool_index, &pool_info);
928 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
932 if (devlink_nl_put_handle(msg, devlink))
933 goto nla_put_failure;
934 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
935 goto nla_put_failure;
936 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
937 goto nla_put_failure;
938 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
939 goto nla_put_failure;
940 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
941 goto nla_put_failure;
942 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
943 pool_info.threshold_type))
944 goto nla_put_failure;
945 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
946 pool_info.cell_size))
947 goto nla_put_failure;
949 genlmsg_end(msg, hdr);
953 genlmsg_cancel(msg, hdr);
957 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
958 struct genl_info *info)
960 struct devlink *devlink = info->user_ptr[0];
961 struct devlink_sb *devlink_sb = info->user_ptr[1];
966 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
971 if (!devlink->ops->sb_pool_get)
974 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
978 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
979 DEVLINK_CMD_SB_POOL_NEW,
980 info->snd_portid, info->snd_seq, 0);
986 return genlmsg_reply(msg, info);
989 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
990 struct devlink *devlink,
991 struct devlink_sb *devlink_sb,
994 u16 pool_count = devlink_sb_pool_count(devlink_sb);
998 for (pool_index = 0; pool_index < pool_count; pool_index++) {
999 if (*p_idx < start) {
1003 err = devlink_nl_sb_pool_fill(msg, devlink,
1006 DEVLINK_CMD_SB_POOL_NEW,
1007 portid, seq, NLM_F_MULTI);
1015 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
1016 struct netlink_callback *cb)
1018 struct devlink *devlink;
1019 struct devlink_sb *devlink_sb;
1020 int start = cb->args[0];
1024 mutex_lock(&devlink_mutex);
1025 list_for_each_entry(devlink, &devlink_list, list) {
1026 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1027 !devlink->ops->sb_pool_get)
1029 mutex_lock(&devlink->lock);
1030 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1031 err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
1033 NETLINK_CB(cb->skb).portid,
1034 cb->nlh->nlmsg_seq);
1035 if (err && err != -EOPNOTSUPP) {
1036 mutex_unlock(&devlink->lock);
1040 mutex_unlock(&devlink->lock);
1043 mutex_unlock(&devlink_mutex);
1049 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
1050 u16 pool_index, u32 size,
1051 enum devlink_sb_threshold_type threshold_type,
1052 struct netlink_ext_ack *extack)
1055 const struct devlink_ops *ops = devlink->ops;
1057 if (ops->sb_pool_set)
1058 return ops->sb_pool_set(devlink, sb_index, pool_index,
1059 size, threshold_type, extack);
1063 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
1064 struct genl_info *info)
1066 struct devlink *devlink = info->user_ptr[0];
1067 struct devlink_sb *devlink_sb = info->user_ptr[1];
1068 enum devlink_sb_threshold_type threshold_type;
1073 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1078 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
1082 if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
1085 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
1086 return devlink_sb_pool_set(devlink, devlink_sb->index,
1087 pool_index, size, threshold_type,
1091 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
1092 struct devlink *devlink,
1093 struct devlink_port *devlink_port,
1094 struct devlink_sb *devlink_sb,
1096 enum devlink_command cmd,
1097 u32 portid, u32 seq, int flags)
1099 const struct devlink_ops *ops = devlink->ops;
1104 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1105 pool_index, &threshold);
1109 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1113 if (devlink_nl_put_handle(msg, devlink))
1114 goto nla_put_failure;
1115 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1116 goto nla_put_failure;
1117 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1118 goto nla_put_failure;
1119 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1120 goto nla_put_failure;
1121 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1122 goto nla_put_failure;
1124 if (ops->sb_occ_port_pool_get) {
1128 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1129 pool_index, &cur, &max);
1130 if (err && err != -EOPNOTSUPP)
1133 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1134 goto nla_put_failure;
1135 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1136 goto nla_put_failure;
1140 genlmsg_end(msg, hdr);
1144 genlmsg_cancel(msg, hdr);
1148 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1149 struct genl_info *info)
1151 struct devlink_port *devlink_port = info->user_ptr[0];
1152 struct devlink *devlink = devlink_port->devlink;
1153 struct devlink_sb *devlink_sb = info->user_ptr[1];
1154 struct sk_buff *msg;
1158 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1163 if (!devlink->ops->sb_port_pool_get)
1166 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1170 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1171 devlink_sb, pool_index,
1172 DEVLINK_CMD_SB_PORT_POOL_NEW,
1173 info->snd_portid, info->snd_seq, 0);
1179 return genlmsg_reply(msg, info);
1182 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1183 struct devlink *devlink,
1184 struct devlink_sb *devlink_sb,
1185 u32 portid, u32 seq)
1187 struct devlink_port *devlink_port;
1188 u16 pool_count = devlink_sb_pool_count(devlink_sb);
1192 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1193 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1194 if (*p_idx < start) {
1198 err = devlink_nl_sb_port_pool_fill(msg, devlink,
1202 DEVLINK_CMD_SB_PORT_POOL_NEW,
1213 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1214 struct netlink_callback *cb)
1216 struct devlink *devlink;
1217 struct devlink_sb *devlink_sb;
1218 int start = cb->args[0];
1222 mutex_lock(&devlink_mutex);
1223 list_for_each_entry(devlink, &devlink_list, list) {
1224 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1225 !devlink->ops->sb_port_pool_get)
1227 mutex_lock(&devlink->lock);
1228 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1229 err = __sb_port_pool_get_dumpit(msg, start, &idx,
1230 devlink, devlink_sb,
1231 NETLINK_CB(cb->skb).portid,
1232 cb->nlh->nlmsg_seq);
1233 if (err && err != -EOPNOTSUPP) {
1234 mutex_unlock(&devlink->lock);
1238 mutex_unlock(&devlink->lock);
1241 mutex_unlock(&devlink_mutex);
1247 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1248 unsigned int sb_index, u16 pool_index,
1250 struct netlink_ext_ack *extack)
1253 const struct devlink_ops *ops = devlink_port->devlink->ops;
1255 if (ops->sb_port_pool_set)
1256 return ops->sb_port_pool_set(devlink_port, sb_index,
1257 pool_index, threshold, extack);
1261 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1262 struct genl_info *info)
1264 struct devlink_port *devlink_port = info->user_ptr[0];
1265 struct devlink_sb *devlink_sb = info->user_ptr[1];
1270 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1275 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1278 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1279 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1280 pool_index, threshold, info->extack);
1284 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1285 struct devlink_port *devlink_port,
1286 struct devlink_sb *devlink_sb, u16 tc_index,
1287 enum devlink_sb_pool_type pool_type,
1288 enum devlink_command cmd,
1289 u32 portid, u32 seq, int flags)
1291 const struct devlink_ops *ops = devlink->ops;
1297 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1298 tc_index, pool_type,
1299 &pool_index, &threshold);
1303 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1307 if (devlink_nl_put_handle(msg, devlink))
1308 goto nla_put_failure;
1309 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1310 goto nla_put_failure;
1311 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1312 goto nla_put_failure;
1313 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1314 goto nla_put_failure;
1315 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1316 goto nla_put_failure;
1317 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1318 goto nla_put_failure;
1319 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1320 goto nla_put_failure;
1322 if (ops->sb_occ_tc_port_bind_get) {
1326 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1328 tc_index, pool_type,
1330 if (err && err != -EOPNOTSUPP)
1333 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1334 goto nla_put_failure;
1335 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1336 goto nla_put_failure;
1340 genlmsg_end(msg, hdr);
1344 genlmsg_cancel(msg, hdr);
1348 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1349 struct genl_info *info)
1351 struct devlink_port *devlink_port = info->user_ptr[0];
1352 struct devlink *devlink = devlink_port->devlink;
1353 struct devlink_sb *devlink_sb = info->user_ptr[1];
1354 struct sk_buff *msg;
1355 enum devlink_sb_pool_type pool_type;
1359 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1363 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1364 pool_type, &tc_index);
1368 if (!devlink->ops->sb_tc_pool_bind_get)
1371 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1375 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1376 devlink_sb, tc_index, pool_type,
1377 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1385 return genlmsg_reply(msg, info);
1388 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1389 int start, int *p_idx,
1390 struct devlink *devlink,
1391 struct devlink_sb *devlink_sb,
1392 u32 portid, u32 seq)
1394 struct devlink_port *devlink_port;
1398 list_for_each_entry(devlink_port, &devlink->port_list, list) {
1400 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1401 if (*p_idx < start) {
1405 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1409 DEVLINK_SB_POOL_TYPE_INGRESS,
1410 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1418 tc_index < devlink_sb->egress_tc_count; tc_index++) {
1419 if (*p_idx < start) {
1423 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1427 DEVLINK_SB_POOL_TYPE_EGRESS,
1428 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1440 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1441 struct netlink_callback *cb)
1443 struct devlink *devlink;
1444 struct devlink_sb *devlink_sb;
1445 int start = cb->args[0];
1449 mutex_lock(&devlink_mutex);
1450 list_for_each_entry(devlink, &devlink_list, list) {
1451 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1452 !devlink->ops->sb_tc_pool_bind_get)
1455 mutex_lock(&devlink->lock);
1456 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1457 err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1460 NETLINK_CB(cb->skb).portid,
1461 cb->nlh->nlmsg_seq);
1462 if (err && err != -EOPNOTSUPP) {
1463 mutex_unlock(&devlink->lock);
1467 mutex_unlock(&devlink->lock);
1470 mutex_unlock(&devlink_mutex);
1476 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1477 unsigned int sb_index, u16 tc_index,
1478 enum devlink_sb_pool_type pool_type,
1479 u16 pool_index, u32 threshold,
1480 struct netlink_ext_ack *extack)
1483 const struct devlink_ops *ops = devlink_port->devlink->ops;
1485 if (ops->sb_tc_pool_bind_set)
1486 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1487 tc_index, pool_type,
1488 pool_index, threshold, extack);
1492 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1493 struct genl_info *info)
1495 struct devlink_port *devlink_port = info->user_ptr[0];
1496 struct devlink_sb *devlink_sb = info->user_ptr[1];
1497 enum devlink_sb_pool_type pool_type;
1503 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1507 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1508 pool_type, &tc_index);
1512 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1517 if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1520 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1521 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1522 tc_index, pool_type,
1523 pool_index, threshold, info->extack);
1526 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1527 struct genl_info *info)
1529 struct devlink *devlink = info->user_ptr[0];
1530 struct devlink_sb *devlink_sb = info->user_ptr[1];
1531 const struct devlink_ops *ops = devlink->ops;
1533 if (ops->sb_occ_snapshot)
1534 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1538 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1539 struct genl_info *info)
1541 struct devlink *devlink = info->user_ptr[0];
1542 struct devlink_sb *devlink_sb = info->user_ptr[1];
1543 const struct devlink_ops *ops = devlink->ops;
1545 if (ops->sb_occ_max_clear)
1546 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1550 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1551 enum devlink_command cmd, u32 portid,
1554 const struct devlink_ops *ops = devlink->ops;
1555 u8 inline_mode, encap_mode;
1560 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1564 err = devlink_nl_put_handle(msg, devlink);
1566 goto nla_put_failure;
1568 if (ops->eswitch_mode_get) {
1569 err = ops->eswitch_mode_get(devlink, &mode);
1571 goto nla_put_failure;
1572 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1574 goto nla_put_failure;
1577 if (ops->eswitch_inline_mode_get) {
1578 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1580 goto nla_put_failure;
1581 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1584 goto nla_put_failure;
1587 if (ops->eswitch_encap_mode_get) {
1588 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1590 goto nla_put_failure;
1591 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1593 goto nla_put_failure;
1596 genlmsg_end(msg, hdr);
1600 genlmsg_cancel(msg, hdr);
1604 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1605 struct genl_info *info)
1607 struct devlink *devlink = info->user_ptr[0];
1608 struct sk_buff *msg;
1611 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1615 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1616 info->snd_portid, info->snd_seq, 0);
1623 return genlmsg_reply(msg, info);
1626 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1627 struct genl_info *info)
1629 struct devlink *devlink = info->user_ptr[0];
1630 const struct devlink_ops *ops = devlink->ops;
1631 u8 inline_mode, encap_mode;
1635 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1636 if (!ops->eswitch_mode_set)
1638 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1639 err = ops->eswitch_mode_set(devlink, mode, info->extack);
1644 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1645 if (!ops->eswitch_inline_mode_set)
1647 inline_mode = nla_get_u8(
1648 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1649 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
1655 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1656 if (!ops->eswitch_encap_mode_set)
1658 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1659 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
1668 int devlink_dpipe_match_put(struct sk_buff *skb,
1669 struct devlink_dpipe_match *match)
1671 struct devlink_dpipe_header *header = match->header;
1672 struct devlink_dpipe_field *field = &header->fields[match->field_id];
1673 struct nlattr *match_attr;
1675 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
1679 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1680 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1681 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1682 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1683 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1684 goto nla_put_failure;
1686 nla_nest_end(skb, match_attr);
1690 nla_nest_cancel(skb, match_attr);
1693 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1695 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1696 struct sk_buff *skb)
1698 struct nlattr *matches_attr;
1700 matches_attr = nla_nest_start_noflag(skb,
1701 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1705 if (table->table_ops->matches_dump(table->priv, skb))
1706 goto nla_put_failure;
1708 nla_nest_end(skb, matches_attr);
1712 nla_nest_cancel(skb, matches_attr);
1716 int devlink_dpipe_action_put(struct sk_buff *skb,
1717 struct devlink_dpipe_action *action)
1719 struct devlink_dpipe_header *header = action->header;
1720 struct devlink_dpipe_field *field = &header->fields[action->field_id];
1721 struct nlattr *action_attr;
1723 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
1727 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1728 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1729 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1730 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1731 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1732 goto nla_put_failure;
1734 nla_nest_end(skb, action_attr);
1738 nla_nest_cancel(skb, action_attr);
1741 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1743 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1744 struct sk_buff *skb)
1746 struct nlattr *actions_attr;
1748 actions_attr = nla_nest_start_noflag(skb,
1749 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1753 if (table->table_ops->actions_dump(table->priv, skb))
1754 goto nla_put_failure;
1756 nla_nest_end(skb, actions_attr);
1760 nla_nest_cancel(skb, actions_attr);
1764 static int devlink_dpipe_table_put(struct sk_buff *skb,
1765 struct devlink_dpipe_table *table)
1767 struct nlattr *table_attr;
1770 table_size = table->table_ops->size_get(table->priv);
1771 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
1775 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1776 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1778 goto nla_put_failure;
1779 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1780 table->counters_enabled))
1781 goto nla_put_failure;
1783 if (table->resource_valid) {
1784 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
1785 table->resource_id, DEVLINK_ATTR_PAD) ||
1786 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
1787 table->resource_units, DEVLINK_ATTR_PAD))
1788 goto nla_put_failure;
1790 if (devlink_dpipe_matches_put(table, skb))
1791 goto nla_put_failure;
1793 if (devlink_dpipe_actions_put(table, skb))
1794 goto nla_put_failure;
1796 nla_nest_end(skb, table_attr);
1800 nla_nest_cancel(skb, table_attr);
1804 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1805 struct genl_info *info)
1810 err = genlmsg_reply(*pskb, info);
1814 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1820 static int devlink_dpipe_tables_fill(struct genl_info *info,
1821 enum devlink_command cmd, int flags,
1822 struct list_head *dpipe_tables,
1823 const char *table_name)
1825 struct devlink *devlink = info->user_ptr[0];
1826 struct devlink_dpipe_table *table;
1827 struct nlattr *tables_attr;
1828 struct sk_buff *skb = NULL;
1829 struct nlmsghdr *nlh;
1835 table = list_first_entry(dpipe_tables,
1836 struct devlink_dpipe_table, list);
1838 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1842 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1843 &devlink_nl_family, NLM_F_MULTI, cmd);
1849 if (devlink_nl_put_handle(skb, devlink))
1850 goto nla_put_failure;
1851 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
1853 goto nla_put_failure;
1857 list_for_each_entry_from(table, dpipe_tables, list) {
1859 err = devlink_dpipe_table_put(skb, table);
1867 if (!strcmp(table->name, table_name)) {
1868 err = devlink_dpipe_table_put(skb, table);
1876 nla_nest_end(skb, tables_attr);
1877 genlmsg_end(skb, hdr);
1882 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1883 NLMSG_DONE, 0, flags | NLM_F_MULTI);
1885 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1891 return genlmsg_reply(skb, info);
1900 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1901 struct genl_info *info)
1903 struct devlink *devlink = info->user_ptr[0];
1904 const char *table_name = NULL;
1906 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1907 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1909 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1910 &devlink->dpipe_table_list,
1914 static int devlink_dpipe_value_put(struct sk_buff *skb,
1915 struct devlink_dpipe_value *value)
1917 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1918 value->value_size, value->value))
1921 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1922 value->value_size, value->mask))
1924 if (value->mapping_valid)
1925 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1926 value->mapping_value))
1931 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1932 struct devlink_dpipe_value *value)
1936 if (devlink_dpipe_action_put(skb, value->action))
1938 if (devlink_dpipe_value_put(skb, value))
1943 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1944 struct devlink_dpipe_value *values,
1945 unsigned int values_count)
1947 struct nlattr *action_attr;
1951 for (i = 0; i < values_count; i++) {
1952 action_attr = nla_nest_start_noflag(skb,
1953 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1956 err = devlink_dpipe_action_value_put(skb, &values[i]);
1958 goto err_action_value_put;
1959 nla_nest_end(skb, action_attr);
1963 err_action_value_put:
1964 nla_nest_cancel(skb, action_attr);
1968 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1969 struct devlink_dpipe_value *value)
1973 if (devlink_dpipe_match_put(skb, value->match))
1975 if (devlink_dpipe_value_put(skb, value))
1980 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1981 struct devlink_dpipe_value *values,
1982 unsigned int values_count)
1984 struct nlattr *match_attr;
1988 for (i = 0; i < values_count; i++) {
1989 match_attr = nla_nest_start_noflag(skb,
1990 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
1993 err = devlink_dpipe_match_value_put(skb, &values[i]);
1995 goto err_match_value_put;
1996 nla_nest_end(skb, match_attr);
2000 err_match_value_put:
2001 nla_nest_cancel(skb, match_attr);
2005 static int devlink_dpipe_entry_put(struct sk_buff *skb,
2006 struct devlink_dpipe_entry *entry)
2008 struct nlattr *entry_attr, *matches_attr, *actions_attr;
2011 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
2015 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
2017 goto nla_put_failure;
2018 if (entry->counter_valid)
2019 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
2020 entry->counter, DEVLINK_ATTR_PAD))
2021 goto nla_put_failure;
2023 matches_attr = nla_nest_start_noflag(skb,
2024 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
2026 goto nla_put_failure;
2028 err = devlink_dpipe_match_values_put(skb, entry->match_values,
2029 entry->match_values_count);
2031 nla_nest_cancel(skb, matches_attr);
2032 goto err_match_values_put;
2034 nla_nest_end(skb, matches_attr);
2036 actions_attr = nla_nest_start_noflag(skb,
2037 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
2039 goto nla_put_failure;
2041 err = devlink_dpipe_action_values_put(skb, entry->action_values,
2042 entry->action_values_count);
2044 nla_nest_cancel(skb, actions_attr);
2045 goto err_action_values_put;
2047 nla_nest_end(skb, actions_attr);
2049 nla_nest_end(skb, entry_attr);
2054 err_match_values_put:
2055 err_action_values_put:
2056 nla_nest_cancel(skb, entry_attr);
2060 static struct devlink_dpipe_table *
2061 devlink_dpipe_table_find(struct list_head *dpipe_tables,
2062 const char *table_name)
2064 struct devlink_dpipe_table *table;
2066 list_for_each_entry_rcu(table, dpipe_tables, list) {
2067 if (!strcmp(table->name, table_name))
2073 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
2075 struct devlink *devlink;
2078 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
2083 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
2084 dump_ctx->info->snd_portid,
2085 dump_ctx->info->snd_seq,
2086 &devlink_nl_family, NLM_F_MULTI,
2089 goto nla_put_failure;
2091 devlink = dump_ctx->info->user_ptr[0];
2092 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2093 goto nla_put_failure;
2094 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
2095 DEVLINK_ATTR_DPIPE_ENTRIES);
2096 if (!dump_ctx->nest)
2097 goto nla_put_failure;
2101 nlmsg_free(dump_ctx->skb);
2104 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2106 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2107 struct devlink_dpipe_entry *entry)
2109 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2111 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2113 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2115 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2116 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2119 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2121 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2124 unsigned int value_count, value_index;
2125 struct devlink_dpipe_value *value;
2127 value = entry->action_values;
2128 value_count = entry->action_values_count;
2129 for (value_index = 0; value_index < value_count; value_index++) {
2130 kfree(value[value_index].value);
2131 kfree(value[value_index].mask);
2134 value = entry->match_values;
2135 value_count = entry->match_values_count;
2136 for (value_index = 0; value_index < value_count; value_index++) {
2137 kfree(value[value_index].value);
2138 kfree(value[value_index].mask);
2141 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2143 static int devlink_dpipe_entries_fill(struct genl_info *info,
2144 enum devlink_command cmd, int flags,
2145 struct devlink_dpipe_table *table)
2147 struct devlink_dpipe_dump_ctx dump_ctx;
2148 struct nlmsghdr *nlh;
2151 dump_ctx.skb = NULL;
2153 dump_ctx.info = info;
2155 err = table->table_ops->entries_dump(table->priv,
2156 table->counters_enabled,
2162 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2163 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2165 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2170 return genlmsg_reply(dump_ctx.skb, info);
2173 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2174 struct genl_info *info)
2176 struct devlink *devlink = info->user_ptr[0];
2177 struct devlink_dpipe_table *table;
2178 const char *table_name;
2180 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2183 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2184 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2189 if (!table->table_ops->entries_dump)
2192 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2196 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2197 const struct devlink_dpipe_header *header)
2199 struct devlink_dpipe_field *field;
2200 struct nlattr *field_attr;
2203 for (i = 0; i < header->fields_count; i++) {
2204 field = &header->fields[i];
2205 field_attr = nla_nest_start_noflag(skb,
2206 DEVLINK_ATTR_DPIPE_FIELD);
2209 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2210 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2211 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2212 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2213 goto nla_put_failure;
2214 nla_nest_end(skb, field_attr);
2219 nla_nest_cancel(skb, field_attr);
2223 static int devlink_dpipe_header_put(struct sk_buff *skb,
2224 struct devlink_dpipe_header *header)
2226 struct nlattr *fields_attr, *header_attr;
2229 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
2233 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2234 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2235 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2236 goto nla_put_failure;
2238 fields_attr = nla_nest_start_noflag(skb,
2239 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2241 goto nla_put_failure;
2243 err = devlink_dpipe_fields_put(skb, header);
2245 nla_nest_cancel(skb, fields_attr);
2246 goto nla_put_failure;
2248 nla_nest_end(skb, fields_attr);
2249 nla_nest_end(skb, header_attr);
2254 nla_nest_cancel(skb, header_attr);
2258 static int devlink_dpipe_headers_fill(struct genl_info *info,
2259 enum devlink_command cmd, int flags,
2260 struct devlink_dpipe_headers *
2263 struct devlink *devlink = info->user_ptr[0];
2264 struct nlattr *headers_attr;
2265 struct sk_buff *skb = NULL;
2266 struct nlmsghdr *nlh;
2273 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2277 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2278 &devlink_nl_family, NLM_F_MULTI, cmd);
2284 if (devlink_nl_put_handle(skb, devlink))
2285 goto nla_put_failure;
2286 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2288 goto nla_put_failure;
2291 for (; i < dpipe_headers->headers_count; i++) {
2292 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2300 nla_nest_end(skb, headers_attr);
2301 genlmsg_end(skb, hdr);
2302 if (i != dpipe_headers->headers_count)
2306 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2307 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2309 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2314 return genlmsg_reply(skb, info);
2323 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2324 struct genl_info *info)
2326 struct devlink *devlink = info->user_ptr[0];
2328 if (!devlink->dpipe_headers)
2330 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2331 0, devlink->dpipe_headers);
2334 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2335 const char *table_name,
2338 struct devlink_dpipe_table *table;
2340 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2345 if (table->counter_control_extern)
2348 if (!(table->counters_enabled ^ enable))
2351 table->counters_enabled = enable;
2352 if (table->table_ops->counters_set_update)
2353 table->table_ops->counters_set_update(table->priv, enable);
2357 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2358 struct genl_info *info)
2360 struct devlink *devlink = info->user_ptr[0];
2361 const char *table_name;
2362 bool counters_enable;
2364 if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2365 !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2368 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2369 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2371 return devlink_dpipe_table_counters_set(devlink, table_name,
2375 static struct devlink_resource *
2376 devlink_resource_find(struct devlink *devlink,
2377 struct devlink_resource *resource, u64 resource_id)
2379 struct list_head *resource_list;
2382 resource_list = &resource->resource_list;
2384 resource_list = &devlink->resource_list;
2386 list_for_each_entry(resource, resource_list, list) {
2387 struct devlink_resource *child_resource;
2389 if (resource->id == resource_id)
2392 child_resource = devlink_resource_find(devlink, resource,
2395 return child_resource;
2401 devlink_resource_validate_children(struct devlink_resource *resource)
2403 struct devlink_resource *child_resource;
2404 bool size_valid = true;
2407 if (list_empty(&resource->resource_list))
2410 list_for_each_entry(child_resource, &resource->resource_list, list)
2411 parts_size += child_resource->size_new;
2413 if (parts_size > resource->size_new)
2416 resource->size_valid = size_valid;
2420 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2421 struct netlink_ext_ack *extack)
2426 if (size > resource->size_params.size_max) {
2427 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2431 if (size < resource->size_params.size_min) {
2432 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2436 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2438 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2445 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2446 struct genl_info *info)
2448 struct devlink *devlink = info->user_ptr[0];
2449 struct devlink_resource *resource;
2454 if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2455 !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2457 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2459 resource = devlink_resource_find(devlink, NULL, resource_id);
2463 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2464 err = devlink_resource_validate_size(resource, size, info->extack);
2468 resource->size_new = size;
2469 devlink_resource_validate_children(resource);
2470 if (resource->parent)
2471 devlink_resource_validate_children(resource->parent);
2476 devlink_resource_size_params_put(struct devlink_resource *resource,
2477 struct sk_buff *skb)
2479 struct devlink_resource_size_params *size_params;
2481 size_params = &resource->size_params;
2482 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2483 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2484 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2485 size_params->size_max, DEVLINK_ATTR_PAD) ||
2486 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2487 size_params->size_min, DEVLINK_ATTR_PAD) ||
2488 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2493 static int devlink_resource_occ_put(struct devlink_resource *resource,
2494 struct sk_buff *skb)
2496 if (!resource->occ_get)
2498 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2499 resource->occ_get(resource->occ_get_priv),
2503 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2504 struct devlink_resource *resource)
2506 struct devlink_resource *child_resource;
2507 struct nlattr *child_resource_attr;
2508 struct nlattr *resource_attr;
2510 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
2514 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2515 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2516 DEVLINK_ATTR_PAD) ||
2517 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2519 goto nla_put_failure;
2520 if (resource->size != resource->size_new)
2521 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2522 resource->size_new, DEVLINK_ATTR_PAD);
2523 if (devlink_resource_occ_put(resource, skb))
2524 goto nla_put_failure;
2525 if (devlink_resource_size_params_put(resource, skb))
2526 goto nla_put_failure;
2527 if (list_empty(&resource->resource_list))
2530 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2531 resource->size_valid))
2532 goto nla_put_failure;
2534 child_resource_attr = nla_nest_start_noflag(skb,
2535 DEVLINK_ATTR_RESOURCE_LIST);
2536 if (!child_resource_attr)
2537 goto nla_put_failure;
2539 list_for_each_entry(child_resource, &resource->resource_list, list) {
2540 if (devlink_resource_put(devlink, skb, child_resource))
2541 goto resource_put_failure;
2544 nla_nest_end(skb, child_resource_attr);
2546 nla_nest_end(skb, resource_attr);
2549 resource_put_failure:
2550 nla_nest_cancel(skb, child_resource_attr);
2552 nla_nest_cancel(skb, resource_attr);
2556 static int devlink_resource_fill(struct genl_info *info,
2557 enum devlink_command cmd, int flags)
2559 struct devlink *devlink = info->user_ptr[0];
2560 struct devlink_resource *resource;
2561 struct nlattr *resources_attr;
2562 struct sk_buff *skb = NULL;
2563 struct nlmsghdr *nlh;
2569 resource = list_first_entry(&devlink->resource_list,
2570 struct devlink_resource, list);
2572 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2576 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2577 &devlink_nl_family, NLM_F_MULTI, cmd);
2583 if (devlink_nl_put_handle(skb, devlink))
2584 goto nla_put_failure;
2586 resources_attr = nla_nest_start_noflag(skb,
2587 DEVLINK_ATTR_RESOURCE_LIST);
2588 if (!resources_attr)
2589 goto nla_put_failure;
2593 list_for_each_entry_from(resource, &devlink->resource_list, list) {
2594 err = devlink_resource_put(devlink, skb, resource);
2597 goto err_resource_put;
2603 nla_nest_end(skb, resources_attr);
2604 genlmsg_end(skb, hdr);
2608 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2609 NLMSG_DONE, 0, flags | NLM_F_MULTI);
2611 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2616 return genlmsg_reply(skb, info);
2625 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2626 struct genl_info *info)
2628 struct devlink *devlink = info->user_ptr[0];
2630 if (list_empty(&devlink->resource_list))
2633 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2637 devlink_resources_validate(struct devlink *devlink,
2638 struct devlink_resource *resource,
2639 struct genl_info *info)
2641 struct list_head *resource_list;
2645 resource_list = &resource->resource_list;
2647 resource_list = &devlink->resource_list;
2649 list_for_each_entry(resource, resource_list, list) {
2650 if (!resource->size_valid)
2652 err = devlink_resources_validate(devlink, resource, info);
2659 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2661 struct devlink *devlink = info->user_ptr[0];
2664 if (!devlink->ops->reload)
2667 err = devlink_resources_validate(devlink, NULL, info);
2669 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2672 return devlink->ops->reload(devlink, info->extack);
2675 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
2676 struct genl_info *info)
2678 struct devlink *devlink = info->user_ptr[0];
2679 const char *file_name, *component;
2680 struct nlattr *nla_component;
2682 if (!devlink->ops->flash_update)
2685 if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
2687 file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
2689 nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
2690 component = nla_component ? nla_data(nla_component) : NULL;
2692 return devlink->ops->flash_update(devlink, file_name, component,
2696 static const struct devlink_param devlink_param_generic[] = {
2698 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
2699 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
2700 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
2703 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
2704 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
2705 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
2708 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
2709 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
2710 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
2713 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
2714 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
2715 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
2718 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
2719 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
2720 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
2723 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
2724 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
2725 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
2728 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
2729 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
2730 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
2733 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
2734 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
2735 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
2739 static int devlink_param_generic_verify(const struct devlink_param *param)
2741 /* verify it match generic parameter by id and name */
2742 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
2744 if (strcmp(param->name, devlink_param_generic[param->id].name))
2747 WARN_ON(param->type != devlink_param_generic[param->id].type);
2752 static int devlink_param_driver_verify(const struct devlink_param *param)
2756 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
2758 /* verify no such name in generic params */
2759 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
2760 if (!strcmp(param->name, devlink_param_generic[i].name))
2766 static struct devlink_param_item *
2767 devlink_param_find_by_name(struct list_head *param_list,
2768 const char *param_name)
2770 struct devlink_param_item *param_item;
2772 list_for_each_entry(param_item, param_list, list)
2773 if (!strcmp(param_item->param->name, param_name))
2778 static struct devlink_param_item *
2779 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
2781 struct devlink_param_item *param_item;
2783 list_for_each_entry(param_item, param_list, list)
2784 if (param_item->param->id == param_id)
2790 devlink_param_cmode_is_supported(const struct devlink_param *param,
2791 enum devlink_param_cmode cmode)
2793 return test_bit(cmode, ¶m->supported_cmodes);
2796 static int devlink_param_get(struct devlink *devlink,
2797 const struct devlink_param *param,
2798 struct devlink_param_gset_ctx *ctx)
2802 return param->get(devlink, param->id, ctx);
2805 static int devlink_param_set(struct devlink *devlink,
2806 const struct devlink_param *param,
2807 struct devlink_param_gset_ctx *ctx)
2811 return param->set(devlink, param->id, ctx);
2815 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
2817 switch (param_type) {
2818 case DEVLINK_PARAM_TYPE_U8:
2820 case DEVLINK_PARAM_TYPE_U16:
2822 case DEVLINK_PARAM_TYPE_U32:
2824 case DEVLINK_PARAM_TYPE_STRING:
2826 case DEVLINK_PARAM_TYPE_BOOL:
2834 devlink_nl_param_value_fill_one(struct sk_buff *msg,
2835 enum devlink_param_type type,
2836 enum devlink_param_cmode cmode,
2837 union devlink_param_value val)
2839 struct nlattr *param_value_attr;
2841 param_value_attr = nla_nest_start_noflag(msg,
2842 DEVLINK_ATTR_PARAM_VALUE);
2843 if (!param_value_attr)
2844 goto nla_put_failure;
2846 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
2847 goto value_nest_cancel;
2850 case DEVLINK_PARAM_TYPE_U8:
2851 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
2852 goto value_nest_cancel;
2854 case DEVLINK_PARAM_TYPE_U16:
2855 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
2856 goto value_nest_cancel;
2858 case DEVLINK_PARAM_TYPE_U32:
2859 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
2860 goto value_nest_cancel;
2862 case DEVLINK_PARAM_TYPE_STRING:
2863 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
2865 goto value_nest_cancel;
2867 case DEVLINK_PARAM_TYPE_BOOL:
2869 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
2870 goto value_nest_cancel;
2874 nla_nest_end(msg, param_value_attr);
2878 nla_nest_cancel(msg, param_value_attr);
2883 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
2884 unsigned int port_index,
2885 struct devlink_param_item *param_item,
2886 enum devlink_command cmd,
2887 u32 portid, u32 seq, int flags)
2889 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
2890 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
2891 const struct devlink_param *param = param_item->param;
2892 struct devlink_param_gset_ctx ctx;
2893 struct nlattr *param_values_list;
2894 struct nlattr *param_attr;
2900 /* Get value from driver part to driverinit configuration mode */
2901 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
2902 if (!devlink_param_cmode_is_supported(param, i))
2904 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
2905 if (!param_item->driverinit_value_valid)
2907 param_value[i] = param_item->driverinit_value;
2909 if (!param_item->published)
2912 err = devlink_param_get(devlink, param, &ctx);
2915 param_value[i] = ctx.val;
2917 param_value_set[i] = true;
2920 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2924 if (devlink_nl_put_handle(msg, devlink))
2925 goto genlmsg_cancel;
2927 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
2928 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
2929 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
2930 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
2931 goto genlmsg_cancel;
2933 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
2935 goto genlmsg_cancel;
2936 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
2937 goto param_nest_cancel;
2938 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
2939 goto param_nest_cancel;
2941 nla_type = devlink_param_type_to_nla_type(param->type);
2943 goto param_nest_cancel;
2944 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
2945 goto param_nest_cancel;
2947 param_values_list = nla_nest_start_noflag(msg,
2948 DEVLINK_ATTR_PARAM_VALUES_LIST);
2949 if (!param_values_list)
2950 goto param_nest_cancel;
2952 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
2953 if (!param_value_set[i])
2955 err = devlink_nl_param_value_fill_one(msg, param->type,
2958 goto values_list_nest_cancel;
2961 nla_nest_end(msg, param_values_list);
2962 nla_nest_end(msg, param_attr);
2963 genlmsg_end(msg, hdr);
2966 values_list_nest_cancel:
2967 nla_nest_end(msg, param_values_list);
2969 nla_nest_cancel(msg, param_attr);
2971 genlmsg_cancel(msg, hdr);
2975 static void devlink_param_notify(struct devlink *devlink,
2976 unsigned int port_index,
2977 struct devlink_param_item *param_item,
2978 enum devlink_command cmd)
2980 struct sk_buff *msg;
2983 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
2984 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
2985 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
2987 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2990 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
2997 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2998 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3001 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
3002 struct netlink_callback *cb)
3004 struct devlink_param_item *param_item;
3005 struct devlink *devlink;
3006 int start = cb->args[0];
3010 mutex_lock(&devlink_mutex);
3011 list_for_each_entry(devlink, &devlink_list, list) {
3012 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3014 mutex_lock(&devlink->lock);
3015 list_for_each_entry(param_item, &devlink->param_list, list) {
3020 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3021 DEVLINK_CMD_PARAM_GET,
3022 NETLINK_CB(cb->skb).portid,
3026 mutex_unlock(&devlink->lock);
3031 mutex_unlock(&devlink->lock);
3034 mutex_unlock(&devlink_mutex);
3041 devlink_param_type_get_from_info(struct genl_info *info,
3042 enum devlink_param_type *param_type)
3044 if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
3047 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
3049 *param_type = DEVLINK_PARAM_TYPE_U8;
3052 *param_type = DEVLINK_PARAM_TYPE_U16;
3055 *param_type = DEVLINK_PARAM_TYPE_U32;
3058 *param_type = DEVLINK_PARAM_TYPE_STRING;
3061 *param_type = DEVLINK_PARAM_TYPE_BOOL;
3071 devlink_param_value_get_from_info(const struct devlink_param *param,
3072 struct genl_info *info,
3073 union devlink_param_value *value)
3077 if (param->type != DEVLINK_PARAM_TYPE_BOOL &&
3078 !info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])
3081 switch (param->type) {
3082 case DEVLINK_PARAM_TYPE_U8:
3083 value->vu8 = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3085 case DEVLINK_PARAM_TYPE_U16:
3086 value->vu16 = nla_get_u16(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3088 case DEVLINK_PARAM_TYPE_U32:
3089 value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3091 case DEVLINK_PARAM_TYPE_STRING:
3092 len = strnlen(nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]),
3093 nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3094 if (len == nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) ||
3095 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
3098 nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3100 case DEVLINK_PARAM_TYPE_BOOL:
3101 value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ?
3108 static struct devlink_param_item *
3109 devlink_param_get_from_info(struct list_head *param_list,
3110 struct genl_info *info)
3114 if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
3117 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
3118 return devlink_param_find_by_name(param_list, param_name);
3121 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
3122 struct genl_info *info)
3124 struct devlink *devlink = info->user_ptr[0];
3125 struct devlink_param_item *param_item;
3126 struct sk_buff *msg;
3129 param_item = devlink_param_get_from_info(&devlink->param_list, info);
3133 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3137 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3138 DEVLINK_CMD_PARAM_GET,
3139 info->snd_portid, info->snd_seq, 0);
3145 return genlmsg_reply(msg, info);
3148 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
3149 unsigned int port_index,
3150 struct list_head *param_list,
3151 struct genl_info *info,
3152 enum devlink_command cmd)
3154 enum devlink_param_type param_type;
3155 struct devlink_param_gset_ctx ctx;
3156 enum devlink_param_cmode cmode;
3157 struct devlink_param_item *param_item;
3158 const struct devlink_param *param;
3159 union devlink_param_value value;
3162 param_item = devlink_param_get_from_info(param_list, info);
3165 param = param_item->param;
3166 err = devlink_param_type_get_from_info(info, ¶m_type);
3169 if (param_type != param->type)
3171 err = devlink_param_value_get_from_info(param, info, &value);
3174 if (param->validate) {
3175 err = param->validate(devlink, param->id, value, info->extack);
3180 if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
3182 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
3183 if (!devlink_param_cmode_is_supported(param, cmode))
3186 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3187 if (param->type == DEVLINK_PARAM_TYPE_STRING)
3188 strcpy(param_item->driverinit_value.vstr, value.vstr);
3190 param_item->driverinit_value = value;
3191 param_item->driverinit_value_valid = true;
3197 err = devlink_param_set(devlink, param, &ctx);
3202 devlink_param_notify(devlink, port_index, param_item, cmd);
3206 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
3207 struct genl_info *info)
3209 struct devlink *devlink = info->user_ptr[0];
3211 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
3212 info, DEVLINK_CMD_PARAM_NEW);
3215 static int devlink_param_register_one(struct devlink *devlink,
3216 unsigned int port_index,
3217 struct list_head *param_list,
3218 const struct devlink_param *param,
3219 enum devlink_command cmd)
3221 struct devlink_param_item *param_item;
3223 if (devlink_param_find_by_name(param_list, param->name))
3226 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
3227 WARN_ON(param->get || param->set);
3229 WARN_ON(!param->get || !param->set);
3231 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
3234 param_item->param = param;
3236 list_add_tail(¶m_item->list, param_list);
3237 devlink_param_notify(devlink, port_index, param_item, cmd);
3241 static void devlink_param_unregister_one(struct devlink *devlink,
3242 unsigned int port_index,
3243 struct list_head *param_list,
3244 const struct devlink_param *param,
3245 enum devlink_command cmd)
3247 struct devlink_param_item *param_item;
3249 param_item = devlink_param_find_by_name(param_list, param->name);
3250 WARN_ON(!param_item);
3251 devlink_param_notify(devlink, port_index, param_item, cmd);
3252 list_del(¶m_item->list);
3256 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
3257 struct netlink_callback *cb)
3259 struct devlink_param_item *param_item;
3260 struct devlink_port *devlink_port;
3261 struct devlink *devlink;
3262 int start = cb->args[0];
3266 mutex_lock(&devlink_mutex);
3267 list_for_each_entry(devlink, &devlink_list, list) {
3268 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3270 mutex_lock(&devlink->lock);
3271 list_for_each_entry(devlink_port, &devlink->port_list, list) {
3272 list_for_each_entry(param_item,
3273 &devlink_port->param_list, list) {
3278 err = devlink_nl_param_fill(msg,
3279 devlink_port->devlink,
3280 devlink_port->index, param_item,
3281 DEVLINK_CMD_PORT_PARAM_GET,
3282 NETLINK_CB(cb->skb).portid,
3286 mutex_unlock(&devlink->lock);
3292 mutex_unlock(&devlink->lock);
3295 mutex_unlock(&devlink_mutex);
3301 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
3302 struct genl_info *info)
3304 struct devlink_port *devlink_port = info->user_ptr[0];
3305 struct devlink_param_item *param_item;
3306 struct sk_buff *msg;
3309 param_item = devlink_param_get_from_info(&devlink_port->param_list,
3314 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3318 err = devlink_nl_param_fill(msg, devlink_port->devlink,
3319 devlink_port->index, param_item,
3320 DEVLINK_CMD_PORT_PARAM_GET,
3321 info->snd_portid, info->snd_seq, 0);
3327 return genlmsg_reply(msg, info);
3330 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
3331 struct genl_info *info)
3333 struct devlink_port *devlink_port = info->user_ptr[0];
3335 return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
3336 devlink_port->index,
3337 &devlink_port->param_list, info,
3338 DEVLINK_CMD_PORT_PARAM_NEW);
3341 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
3342 struct devlink *devlink,
3343 struct devlink_snapshot *snapshot)
3345 struct nlattr *snap_attr;
3348 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
3352 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
3354 goto nla_put_failure;
3356 nla_nest_end(msg, snap_attr);
3360 nla_nest_cancel(msg, snap_attr);
3364 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
3365 struct devlink *devlink,
3366 struct devlink_region *region)
3368 struct devlink_snapshot *snapshot;
3369 struct nlattr *snapshots_attr;
3372 snapshots_attr = nla_nest_start_noflag(msg,
3373 DEVLINK_ATTR_REGION_SNAPSHOTS);
3374 if (!snapshots_attr)
3377 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
3378 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
3380 goto nla_put_failure;
3383 nla_nest_end(msg, snapshots_attr);
3387 nla_nest_cancel(msg, snapshots_attr);
3391 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3392 enum devlink_command cmd, u32 portid,
3394 struct devlink_region *region)
3399 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3403 err = devlink_nl_put_handle(msg, devlink);
3405 goto nla_put_failure;
3407 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->name);
3409 goto nla_put_failure;
3411 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3415 goto nla_put_failure;
3417 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
3419 goto nla_put_failure;
3421 genlmsg_end(msg, hdr);
3425 genlmsg_cancel(msg, hdr);
3429 static void devlink_nl_region_notify(struct devlink_region *region,
3430 struct devlink_snapshot *snapshot,
3431 enum devlink_command cmd)
3433 struct devlink *devlink = region->devlink;
3434 struct sk_buff *msg;
3438 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
3440 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3444 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
3448 err = devlink_nl_put_handle(msg, devlink);
3450 goto out_cancel_msg;
3452 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
3455 goto out_cancel_msg;
3458 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
3461 goto out_cancel_msg;
3463 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3464 region->size, DEVLINK_ATTR_PAD);
3466 goto out_cancel_msg;
3468 genlmsg_end(msg, hdr);
3470 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3471 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3476 genlmsg_cancel(msg, hdr);
3481 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
3482 struct genl_info *info)
3484 struct devlink *devlink = info->user_ptr[0];
3485 struct devlink_region *region;
3486 const char *region_name;
3487 struct sk_buff *msg;
3490 if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
3493 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3494 region = devlink_region_get_by_name(devlink, region_name);
3498 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3502 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
3503 info->snd_portid, info->snd_seq, 0,
3510 return genlmsg_reply(msg, info);
3513 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
3514 struct netlink_callback *cb)
3516 struct devlink_region *region;
3517 struct devlink *devlink;
3518 int start = cb->args[0];
3522 mutex_lock(&devlink_mutex);
3523 list_for_each_entry(devlink, &devlink_list, list) {
3524 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3527 mutex_lock(&devlink->lock);
3528 list_for_each_entry(region, &devlink->region_list, list) {
3533 err = devlink_nl_region_fill(msg, devlink,
3534 DEVLINK_CMD_REGION_GET,
3535 NETLINK_CB(cb->skb).portid,
3537 NLM_F_MULTI, region);
3539 mutex_unlock(&devlink->lock);
3544 mutex_unlock(&devlink->lock);
3547 mutex_unlock(&devlink_mutex);
3552 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
3553 struct genl_info *info)
3555 struct devlink *devlink = info->user_ptr[0];
3556 struct devlink_snapshot *snapshot;
3557 struct devlink_region *region;
3558 const char *region_name;
3561 if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
3562 !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
3565 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3566 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3568 region = devlink_region_get_by_name(devlink, region_name);
3572 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3576 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
3577 devlink_region_snapshot_del(snapshot);
3581 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
3582 struct devlink *devlink,
3583 u8 *chunk, u32 chunk_size,
3586 struct nlattr *chunk_attr;
3589 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
3593 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
3595 goto nla_put_failure;
3597 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
3600 goto nla_put_failure;
3602 nla_nest_end(msg, chunk_attr);
3606 nla_nest_cancel(msg, chunk_attr);
3610 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
3612 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
3613 struct devlink *devlink,
3614 struct devlink_region *region,
3615 struct nlattr **attrs,
3621 struct devlink_snapshot *snapshot;
3622 u64 curr_offset = start_offset;
3626 *new_offset = start_offset;
3628 snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3629 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3633 if (end_offset > snapshot->data_len || dump)
3634 end_offset = snapshot->data_len;
3636 while (curr_offset < end_offset) {
3640 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
3641 data_size = end_offset - curr_offset;
3643 data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
3645 data = &snapshot->data[curr_offset];
3646 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
3652 curr_offset += data_size;
3654 *new_offset = curr_offset;
3659 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
3660 struct netlink_callback *cb)
3662 u64 ret_offset, start_offset, end_offset = 0;
3663 struct devlink_region *region;
3664 struct nlattr *chunks_attr;
3665 const char *region_name;
3666 struct devlink *devlink;
3667 struct nlattr **attrs;
3672 start_offset = *((u64 *)&cb->args[0]);
3674 attrs = kmalloc_array(DEVLINK_ATTR_MAX + 1, sizeof(*attrs), GFP_KERNEL);
3678 err = nlmsg_parse_deprecated(cb->nlh,
3679 GENL_HDRLEN + devlink_nl_family.hdrsize,
3680 attrs, DEVLINK_ATTR_MAX,
3681 devlink_nl_family.policy, cb->extack);
3685 mutex_lock(&devlink_mutex);
3686 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
3687 if (IS_ERR(devlink)) {
3688 err = PTR_ERR(devlink);
3692 mutex_lock(&devlink->lock);
3694 if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
3695 !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
3700 region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
3701 region = devlink_region_get_by_name(devlink, region_name);
3707 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
3708 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
3709 DEVLINK_CMD_REGION_READ);
3715 err = devlink_nl_put_handle(skb, devlink);
3717 goto nla_put_failure;
3719 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
3721 goto nla_put_failure;
3723 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
3726 goto nla_put_failure;
3729 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
3730 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
3733 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3735 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3736 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
3740 err = devlink_nl_region_read_snapshot_fill(skb, devlink,
3746 if (err && err != -EMSGSIZE)
3747 goto nla_put_failure;
3749 /* Check if there was any progress done to prevent infinite loop */
3750 if (ret_offset == start_offset) {
3752 goto nla_put_failure;
3755 *((u64 *)&cb->args[0]) = ret_offset;
3757 nla_nest_end(skb, chunks_attr);
3758 genlmsg_end(skb, hdr);
3759 mutex_unlock(&devlink->lock);
3760 mutex_unlock(&devlink_mutex);
3766 genlmsg_cancel(skb, hdr);
3768 mutex_unlock(&devlink->lock);
3770 mutex_unlock(&devlink_mutex);
3776 struct devlink_info_req {
3777 struct sk_buff *msg;
3780 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
3782 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
3784 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
3786 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
3788 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
3790 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
3792 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
3793 const char *version_name,
3794 const char *version_value)
3796 struct nlattr *nest;
3799 nest = nla_nest_start_noflag(req->msg, attr);
3803 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
3806 goto nla_put_failure;
3808 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
3811 goto nla_put_failure;
3813 nla_nest_end(req->msg, nest);
3818 nla_nest_cancel(req->msg, nest);
3822 int devlink_info_version_fixed_put(struct devlink_info_req *req,
3823 const char *version_name,
3824 const char *version_value)
3826 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
3827 version_name, version_value);
3829 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
3831 int devlink_info_version_stored_put(struct devlink_info_req *req,
3832 const char *version_name,
3833 const char *version_value)
3835 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
3836 version_name, version_value);
3838 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
3840 int devlink_info_version_running_put(struct devlink_info_req *req,
3841 const char *version_name,
3842 const char *version_value)
3844 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
3845 version_name, version_value);
3847 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
3850 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
3851 enum devlink_command cmd, u32 portid,
3852 u32 seq, int flags, struct netlink_ext_ack *extack)
3854 struct devlink_info_req req;
3858 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3863 if (devlink_nl_put_handle(msg, devlink))
3864 goto err_cancel_msg;
3867 err = devlink->ops->info_get(devlink, &req, extack);
3869 goto err_cancel_msg;
3871 genlmsg_end(msg, hdr);
3875 genlmsg_cancel(msg, hdr);
3879 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
3880 struct genl_info *info)
3882 struct devlink *devlink = info->user_ptr[0];
3883 struct sk_buff *msg;
3886 if (!devlink->ops->info_get)
3889 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3893 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
3894 info->snd_portid, info->snd_seq, 0,
3901 return genlmsg_reply(msg, info);
3904 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
3905 struct netlink_callback *cb)
3907 struct devlink *devlink;
3908 int start = cb->args[0];
3912 mutex_lock(&devlink_mutex);
3913 list_for_each_entry(devlink, &devlink_list, list) {
3914 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3921 if (!devlink->ops->info_get) {
3926 mutex_lock(&devlink->lock);
3927 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
3928 NETLINK_CB(cb->skb).portid,
3929 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3931 mutex_unlock(&devlink->lock);
3936 mutex_unlock(&devlink_mutex);
3942 struct devlink_fmsg_item {
3943 struct list_head list;
3950 struct devlink_fmsg {
3951 struct list_head item_list;
3954 static struct devlink_fmsg *devlink_fmsg_alloc(void)
3956 struct devlink_fmsg *fmsg;
3958 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
3962 INIT_LIST_HEAD(&fmsg->item_list);
3967 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
3969 struct devlink_fmsg_item *item, *tmp;
3971 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
3972 list_del(&item->list);
3978 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
3981 struct devlink_fmsg_item *item;
3983 item = kzalloc(sizeof(*item), GFP_KERNEL);
3987 item->attrtype = attrtype;
3988 list_add_tail(&item->list, &fmsg->item_list);
3993 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
3995 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
3997 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
3999 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
4001 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
4004 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
4006 return devlink_fmsg_nest_end(fmsg);
4008 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
4010 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
4012 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
4014 struct devlink_fmsg_item *item;
4016 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
4019 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
4023 item->nla_type = NLA_NUL_STRING;
4024 item->len = strlen(name) + 1;
4025 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
4026 memcpy(&item->value, name, item->len);
4027 list_add_tail(&item->list, &fmsg->item_list);
4032 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
4036 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
4040 err = devlink_fmsg_put_name(fmsg, name);
4046 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
4048 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
4050 return devlink_fmsg_nest_end(fmsg);
4052 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
4054 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
4059 err = devlink_fmsg_pair_nest_start(fmsg, name);
4063 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
4069 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
4071 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
4075 err = devlink_fmsg_nest_end(fmsg);
4079 err = devlink_fmsg_nest_end(fmsg);
4085 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
4087 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
4088 const void *value, u16 value_len,
4091 struct devlink_fmsg_item *item;
4093 if (value_len > DEVLINK_FMSG_MAX_SIZE)
4096 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
4100 item->nla_type = value_nla_type;
4101 item->len = value_len;
4102 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4103 memcpy(&item->value, value, item->len);
4104 list_add_tail(&item->list, &fmsg->item_list);
4109 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
4111 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
4113 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
4115 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
4117 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
4119 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
4121 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
4123 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
4125 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
4127 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
4129 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
4131 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
4133 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
4135 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
4138 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
4140 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
4143 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
4145 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
4147 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
4152 err = devlink_fmsg_pair_nest_start(fmsg, name);
4156 err = devlink_fmsg_bool_put(fmsg, value);
4160 err = devlink_fmsg_pair_nest_end(fmsg);
4166 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
4168 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
4173 err = devlink_fmsg_pair_nest_start(fmsg, name);
4177 err = devlink_fmsg_u8_put(fmsg, value);
4181 err = devlink_fmsg_pair_nest_end(fmsg);
4187 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
4189 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
4194 err = devlink_fmsg_pair_nest_start(fmsg, name);
4198 err = devlink_fmsg_u32_put(fmsg, value);
4202 err = devlink_fmsg_pair_nest_end(fmsg);
4208 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
4210 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
4215 err = devlink_fmsg_pair_nest_start(fmsg, name);
4219 err = devlink_fmsg_u64_put(fmsg, value);
4223 err = devlink_fmsg_pair_nest_end(fmsg);
4229 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
4231 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
4236 err = devlink_fmsg_pair_nest_start(fmsg, name);
4240 err = devlink_fmsg_string_put(fmsg, value);
4244 err = devlink_fmsg_pair_nest_end(fmsg);
4250 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
4252 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
4253 const void *value, u16 value_len)
4257 err = devlink_fmsg_pair_nest_start(fmsg, name);
4261 err = devlink_fmsg_binary_put(fmsg, value, value_len);
4265 err = devlink_fmsg_pair_nest_end(fmsg);
4271 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
4274 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4276 switch (msg->nla_type) {
4281 case NLA_NUL_STRING:
4283 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
4291 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4293 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4296 switch (msg->nla_type) {
4298 /* Always provide flag data, regardless of its value */
4299 tmp = *(bool *) msg->value;
4301 return nla_put_u8(skb, attrtype, tmp);
4303 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
4305 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
4307 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
4309 case NLA_NUL_STRING:
4310 return nla_put_string(skb, attrtype, (char *) &msg->value);
4312 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
4319 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
4322 struct devlink_fmsg_item *item;
4323 struct nlattr *fmsg_nlattr;
4327 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
4331 list_for_each_entry(item, &fmsg->item_list, list) {
4337 switch (item->attrtype) {
4338 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
4339 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
4340 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
4341 case DEVLINK_ATTR_FMSG_NEST_END:
4342 err = nla_put_flag(skb, item->attrtype);
4344 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
4345 err = devlink_fmsg_item_fill_type(item, skb);
4348 err = devlink_fmsg_item_fill_data(item, skb);
4350 case DEVLINK_ATTR_FMSG_OBJ_NAME:
4351 err = nla_put_string(skb, item->attrtype,
4352 (char *) &item->value);
4364 nla_nest_end(skb, fmsg_nlattr);
4368 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
4369 struct genl_info *info,
4370 enum devlink_command cmd, int flags)
4372 struct nlmsghdr *nlh;
4373 struct sk_buff *skb;
4380 int tmp_index = index;
4382 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4386 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4387 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
4390 goto nla_put_failure;
4393 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
4396 else if (err != -EMSGSIZE || tmp_index == index)
4397 goto nla_put_failure;
4399 genlmsg_end(skb, hdr);
4400 err = genlmsg_reply(skb, info);
4405 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4408 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4409 NLMSG_DONE, 0, flags | NLM_F_MULTI);
4412 goto nla_put_failure;
4415 return genlmsg_reply(skb, info);
4422 struct devlink_health_reporter {
4423 struct list_head list;
4425 const struct devlink_health_reporter_ops *ops;
4426 struct devlink *devlink;
4427 struct devlink_fmsg *dump_fmsg;
4428 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
4429 u64 graceful_period;
4435 u64 last_recovery_ts;
4436 refcount_t refcount;
4440 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
4442 return reporter->priv;
4444 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
4446 static struct devlink_health_reporter *
4447 devlink_health_reporter_find_by_name(struct devlink *devlink,
4448 const char *reporter_name)
4450 struct devlink_health_reporter *reporter;
4452 lockdep_assert_held(&devlink->reporters_lock);
4453 list_for_each_entry(reporter, &devlink->reporter_list, list)
4454 if (!strcmp(reporter->ops->name, reporter_name))
4460 * devlink_health_reporter_create - create devlink health reporter
4464 * @graceful_period: to avoid recovery loops, in msecs
4465 * @auto_recover: auto recover when error occurs
4468 struct devlink_health_reporter *
4469 devlink_health_reporter_create(struct devlink *devlink,
4470 const struct devlink_health_reporter_ops *ops,
4471 u64 graceful_period, bool auto_recover,
4474 struct devlink_health_reporter *reporter;
4476 mutex_lock(&devlink->reporters_lock);
4477 if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
4478 reporter = ERR_PTR(-EEXIST);
4482 if (WARN_ON(auto_recover && !ops->recover) ||
4483 WARN_ON(graceful_period && !ops->recover)) {
4484 reporter = ERR_PTR(-EINVAL);
4488 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
4490 reporter = ERR_PTR(-ENOMEM);
4494 reporter->priv = priv;
4495 reporter->ops = ops;
4496 reporter->devlink = devlink;
4497 reporter->graceful_period = graceful_period;
4498 reporter->auto_recover = auto_recover;
4499 mutex_init(&reporter->dump_lock);
4500 refcount_set(&reporter->refcount, 1);
4501 list_add_tail(&reporter->list, &devlink->reporter_list);
4503 mutex_unlock(&devlink->reporters_lock);
4506 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
4509 * devlink_health_reporter_destroy - destroy devlink health reporter
4511 * @reporter: devlink health reporter to destroy
4514 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
4516 mutex_lock(&reporter->devlink->reporters_lock);
4517 list_del(&reporter->list);
4518 mutex_unlock(&reporter->devlink->reporters_lock);
4519 while (refcount_read(&reporter->refcount) > 1)
4521 mutex_destroy(&reporter->dump_lock);
4522 if (reporter->dump_fmsg)
4523 devlink_fmsg_free(reporter->dump_fmsg);
4526 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
4529 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
4530 enum devlink_health_reporter_state state)
4532 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
4533 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
4536 if (reporter->health_state == state)
4539 reporter->health_state = state;
4540 trace_devlink_health_reporter_state_update(reporter->devlink,
4541 reporter->ops->name, state);
4543 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
4546 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
4551 if (!reporter->ops->recover)
4554 err = reporter->ops->recover(reporter, priv_ctx);
4558 reporter->recovery_count++;
4559 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
4560 reporter->last_recovery_ts = jiffies;
4566 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
4568 if (!reporter->dump_fmsg)
4570 devlink_fmsg_free(reporter->dump_fmsg);
4571 reporter->dump_fmsg = NULL;
4574 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
4579 if (!reporter->ops->dump)
4582 if (reporter->dump_fmsg)
4585 reporter->dump_fmsg = devlink_fmsg_alloc();
4586 if (!reporter->dump_fmsg) {
4591 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
4595 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
4600 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
4604 reporter->dump_ts = jiffies;
4609 devlink_health_dump_clear(reporter);
4613 int devlink_health_report(struct devlink_health_reporter *reporter,
4614 const char *msg, void *priv_ctx)
4616 enum devlink_health_reporter_state prev_health_state;
4617 struct devlink *devlink = reporter->devlink;
4619 /* write a log message of the current error */
4621 trace_devlink_health_report(devlink, reporter->ops->name, msg);
4622 reporter->error_count++;
4623 prev_health_state = reporter->health_state;
4624 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4626 /* abort if the previous error wasn't recovered */
4627 if (reporter->auto_recover &&
4628 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
4629 jiffies - reporter->last_recovery_ts <
4630 msecs_to_jiffies(reporter->graceful_period))) {
4631 trace_devlink_health_recover_aborted(devlink,
4632 reporter->ops->name,
4633 reporter->health_state,
4635 reporter->last_recovery_ts);
4639 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4641 mutex_lock(&reporter->dump_lock);
4642 /* store current dump of current error, for later analysis */
4643 devlink_health_do_dump(reporter, priv_ctx);
4644 mutex_unlock(&reporter->dump_lock);
4646 if (reporter->auto_recover)
4647 return devlink_health_reporter_recover(reporter, priv_ctx);
4651 EXPORT_SYMBOL_GPL(devlink_health_report);
4653 static struct devlink_health_reporter *
4654 devlink_health_reporter_get_from_info(struct devlink *devlink,
4655 struct genl_info *info)
4657 struct devlink_health_reporter *reporter;
4658 char *reporter_name;
4660 if (!info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
4664 nla_data(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
4665 mutex_lock(&devlink->reporters_lock);
4666 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
4668 refcount_inc(&reporter->refcount);
4669 mutex_unlock(&devlink->reporters_lock);
4674 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
4676 refcount_dec(&reporter->refcount);
4680 devlink_nl_health_reporter_fill(struct sk_buff *msg,
4681 struct devlink *devlink,
4682 struct devlink_health_reporter *reporter,
4683 enum devlink_command cmd, u32 portid,
4686 struct nlattr *reporter_attr;
4689 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4693 if (devlink_nl_put_handle(msg, devlink))
4694 goto genlmsg_cancel;
4696 reporter_attr = nla_nest_start_noflag(msg,
4697 DEVLINK_ATTR_HEALTH_REPORTER);
4699 goto genlmsg_cancel;
4700 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
4701 reporter->ops->name))
4702 goto reporter_nest_cancel;
4703 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
4704 reporter->health_state))
4705 goto reporter_nest_cancel;
4706 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
4707 reporter->error_count, DEVLINK_ATTR_PAD))
4708 goto reporter_nest_cancel;
4709 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
4710 reporter->recovery_count, DEVLINK_ATTR_PAD))
4711 goto reporter_nest_cancel;
4712 if (reporter->ops->recover &&
4713 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
4714 reporter->graceful_period,
4716 goto reporter_nest_cancel;
4717 if (reporter->ops->recover &&
4718 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
4719 reporter->auto_recover))
4720 goto reporter_nest_cancel;
4721 if (reporter->dump_fmsg &&
4722 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
4723 jiffies_to_msecs(reporter->dump_ts),
4725 goto reporter_nest_cancel;
4727 nla_nest_end(msg, reporter_attr);
4728 genlmsg_end(msg, hdr);
4731 reporter_nest_cancel:
4732 nla_nest_end(msg, reporter_attr);
4734 genlmsg_cancel(msg, hdr);
4738 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
4739 struct genl_info *info)
4741 struct devlink *devlink = info->user_ptr[0];
4742 struct devlink_health_reporter *reporter;
4743 struct sk_buff *msg;
4746 reporter = devlink_health_reporter_get_from_info(devlink, info);
4750 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4756 err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
4757 DEVLINK_CMD_HEALTH_REPORTER_GET,
4758 info->snd_portid, info->snd_seq,
4765 err = genlmsg_reply(msg, info);
4767 devlink_health_reporter_put(reporter);
4772 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
4773 struct netlink_callback *cb)
4775 struct devlink_health_reporter *reporter;
4776 struct devlink *devlink;
4777 int start = cb->args[0];
4781 mutex_lock(&devlink_mutex);
4782 list_for_each_entry(devlink, &devlink_list, list) {
4783 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4785 mutex_lock(&devlink->reporters_lock);
4786 list_for_each_entry(reporter, &devlink->reporter_list,
4792 err = devlink_nl_health_reporter_fill(msg, devlink,
4794 DEVLINK_CMD_HEALTH_REPORTER_GET,
4795 NETLINK_CB(cb->skb).portid,
4799 mutex_unlock(&devlink->reporters_lock);
4804 mutex_unlock(&devlink->reporters_lock);
4807 mutex_unlock(&devlink_mutex);
4814 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
4815 struct genl_info *info)
4817 struct devlink *devlink = info->user_ptr[0];
4818 struct devlink_health_reporter *reporter;
4821 reporter = devlink_health_reporter_get_from_info(devlink, info);
4825 if (!reporter->ops->recover &&
4826 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
4827 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
4832 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
4833 reporter->graceful_period =
4834 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
4836 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
4837 reporter->auto_recover =
4838 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
4840 devlink_health_reporter_put(reporter);
4843 devlink_health_reporter_put(reporter);
4847 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
4848 struct genl_info *info)
4850 struct devlink *devlink = info->user_ptr[0];
4851 struct devlink_health_reporter *reporter;
4854 reporter = devlink_health_reporter_get_from_info(devlink, info);
4858 err = devlink_health_reporter_recover(reporter, NULL);
4860 devlink_health_reporter_put(reporter);
4864 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
4865 struct genl_info *info)
4867 struct devlink *devlink = info->user_ptr[0];
4868 struct devlink_health_reporter *reporter;
4869 struct devlink_fmsg *fmsg;
4872 reporter = devlink_health_reporter_get_from_info(devlink, info);
4876 if (!reporter->ops->diagnose) {
4877 devlink_health_reporter_put(reporter);
4881 fmsg = devlink_fmsg_alloc();
4883 devlink_health_reporter_put(reporter);
4887 err = devlink_fmsg_obj_nest_start(fmsg);
4891 err = reporter->ops->diagnose(reporter, fmsg);
4895 err = devlink_fmsg_obj_nest_end(fmsg);
4899 err = devlink_fmsg_snd(fmsg, info,
4900 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
4903 devlink_fmsg_free(fmsg);
4904 devlink_health_reporter_put(reporter);
4908 static int devlink_nl_cmd_health_reporter_dump_get_doit(struct sk_buff *skb,
4909 struct genl_info *info)
4911 struct devlink *devlink = info->user_ptr[0];
4912 struct devlink_health_reporter *reporter;
4915 reporter = devlink_health_reporter_get_from_info(devlink, info);
4919 if (!reporter->ops->dump) {
4920 devlink_health_reporter_put(reporter);
4924 mutex_lock(&reporter->dump_lock);
4925 err = devlink_health_do_dump(reporter, NULL);
4929 err = devlink_fmsg_snd(reporter->dump_fmsg, info,
4930 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, 0);
4933 mutex_unlock(&reporter->dump_lock);
4934 devlink_health_reporter_put(reporter);
4939 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
4940 struct genl_info *info)
4942 struct devlink *devlink = info->user_ptr[0];
4943 struct devlink_health_reporter *reporter;
4945 reporter = devlink_health_reporter_get_from_info(devlink, info);
4949 if (!reporter->ops->dump) {
4950 devlink_health_reporter_put(reporter);
4954 mutex_lock(&reporter->dump_lock);
4955 devlink_health_dump_clear(reporter);
4956 mutex_unlock(&reporter->dump_lock);
4957 devlink_health_reporter_put(reporter);
4961 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
4962 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
4963 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
4964 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
4965 [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
4966 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
4967 [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
4968 [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
4969 [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
4970 [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
4971 [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
4972 [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
4973 [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
4974 [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
4975 [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
4976 [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
4977 [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
4978 [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
4979 [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
4980 [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
4981 [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
4982 [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
4983 [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
4984 [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
4985 [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
4986 [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
4987 [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
4988 [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
4989 [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
4990 [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
4993 static const struct genl_ops devlink_nl_ops[] = {
4995 .cmd = DEVLINK_CMD_GET,
4996 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
4997 .doit = devlink_nl_cmd_get_doit,
4998 .dumpit = devlink_nl_cmd_get_dumpit,
4999 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5000 /* can be retrieved by unprivileged users */
5003 .cmd = DEVLINK_CMD_PORT_GET,
5004 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5005 .doit = devlink_nl_cmd_port_get_doit,
5006 .dumpit = devlink_nl_cmd_port_get_dumpit,
5007 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5008 /* can be retrieved by unprivileged users */
5011 .cmd = DEVLINK_CMD_PORT_SET,
5012 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5013 .doit = devlink_nl_cmd_port_set_doit,
5014 .flags = GENL_ADMIN_PERM,
5015 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5018 .cmd = DEVLINK_CMD_PORT_SPLIT,
5019 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5020 .doit = devlink_nl_cmd_port_split_doit,
5021 .flags = GENL_ADMIN_PERM,
5022 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5023 DEVLINK_NL_FLAG_NO_LOCK,
5026 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
5027 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5028 .doit = devlink_nl_cmd_port_unsplit_doit,
5029 .flags = GENL_ADMIN_PERM,
5030 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5031 DEVLINK_NL_FLAG_NO_LOCK,
5034 .cmd = DEVLINK_CMD_SB_GET,
5035 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5036 .doit = devlink_nl_cmd_sb_get_doit,
5037 .dumpit = devlink_nl_cmd_sb_get_dumpit,
5038 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5039 DEVLINK_NL_FLAG_NEED_SB,
5040 /* can be retrieved by unprivileged users */
5043 .cmd = DEVLINK_CMD_SB_POOL_GET,
5044 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5045 .doit = devlink_nl_cmd_sb_pool_get_doit,
5046 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
5047 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5048 DEVLINK_NL_FLAG_NEED_SB,
5049 /* can be retrieved by unprivileged users */
5052 .cmd = DEVLINK_CMD_SB_POOL_SET,
5053 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5054 .doit = devlink_nl_cmd_sb_pool_set_doit,
5055 .flags = GENL_ADMIN_PERM,
5056 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5057 DEVLINK_NL_FLAG_NEED_SB,
5060 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
5061 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5062 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
5063 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
5064 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5065 DEVLINK_NL_FLAG_NEED_SB,
5066 /* can be retrieved by unprivileged users */
5069 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
5070 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5071 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
5072 .flags = GENL_ADMIN_PERM,
5073 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5074 DEVLINK_NL_FLAG_NEED_SB,
5077 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
5078 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5079 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
5080 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
5081 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5082 DEVLINK_NL_FLAG_NEED_SB,
5083 /* can be retrieved by unprivileged users */
5086 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
5087 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5088 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
5089 .flags = GENL_ADMIN_PERM,
5090 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5091 DEVLINK_NL_FLAG_NEED_SB,
5094 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
5095 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5096 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
5097 .flags = GENL_ADMIN_PERM,
5098 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5099 DEVLINK_NL_FLAG_NEED_SB,
5102 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
5103 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5104 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
5105 .flags = GENL_ADMIN_PERM,
5106 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5107 DEVLINK_NL_FLAG_NEED_SB,
5110 .cmd = DEVLINK_CMD_ESWITCH_GET,
5111 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5112 .doit = devlink_nl_cmd_eswitch_get_doit,
5113 .flags = GENL_ADMIN_PERM,
5114 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5117 .cmd = DEVLINK_CMD_ESWITCH_SET,
5118 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5119 .doit = devlink_nl_cmd_eswitch_set_doit,
5120 .flags = GENL_ADMIN_PERM,
5121 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5122 DEVLINK_NL_FLAG_NO_LOCK,
5125 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
5126 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5127 .doit = devlink_nl_cmd_dpipe_table_get,
5128 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5129 /* can be retrieved by unprivileged users */
5132 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
5133 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5134 .doit = devlink_nl_cmd_dpipe_entries_get,
5135 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5136 /* can be retrieved by unprivileged users */
5139 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
5140 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5141 .doit = devlink_nl_cmd_dpipe_headers_get,
5142 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5143 /* can be retrieved by unprivileged users */
5146 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
5147 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5148 .doit = devlink_nl_cmd_dpipe_table_counters_set,
5149 .flags = GENL_ADMIN_PERM,
5150 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5153 .cmd = DEVLINK_CMD_RESOURCE_SET,
5154 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5155 .doit = devlink_nl_cmd_resource_set,
5156 .flags = GENL_ADMIN_PERM,
5157 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5160 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
5161 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5162 .doit = devlink_nl_cmd_resource_dump,
5163 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5164 /* can be retrieved by unprivileged users */
5167 .cmd = DEVLINK_CMD_RELOAD,
5168 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5169 .doit = devlink_nl_cmd_reload,
5170 .flags = GENL_ADMIN_PERM,
5171 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5172 DEVLINK_NL_FLAG_NO_LOCK,
5175 .cmd = DEVLINK_CMD_PARAM_GET,
5176 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5177 .doit = devlink_nl_cmd_param_get_doit,
5178 .dumpit = devlink_nl_cmd_param_get_dumpit,
5179 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5180 /* can be retrieved by unprivileged users */
5183 .cmd = DEVLINK_CMD_PARAM_SET,
5184 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5185 .doit = devlink_nl_cmd_param_set_doit,
5186 .flags = GENL_ADMIN_PERM,
5187 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5190 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
5191 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5192 .doit = devlink_nl_cmd_port_param_get_doit,
5193 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
5194 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5195 /* can be retrieved by unprivileged users */
5198 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
5199 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5200 .doit = devlink_nl_cmd_port_param_set_doit,
5201 .flags = GENL_ADMIN_PERM,
5202 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5205 .cmd = DEVLINK_CMD_REGION_GET,
5206 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5207 .doit = devlink_nl_cmd_region_get_doit,
5208 .dumpit = devlink_nl_cmd_region_get_dumpit,
5209 .flags = GENL_ADMIN_PERM,
5210 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5213 .cmd = DEVLINK_CMD_REGION_DEL,
5214 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5215 .doit = devlink_nl_cmd_region_del,
5216 .flags = GENL_ADMIN_PERM,
5217 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5220 .cmd = DEVLINK_CMD_REGION_READ,
5221 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5222 .dumpit = devlink_nl_cmd_region_read_dumpit,
5223 .flags = GENL_ADMIN_PERM,
5224 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5227 .cmd = DEVLINK_CMD_INFO_GET,
5228 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5229 .doit = devlink_nl_cmd_info_get_doit,
5230 .dumpit = devlink_nl_cmd_info_get_dumpit,
5231 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5232 /* can be retrieved by unprivileged users */
5235 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
5236 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5237 .doit = devlink_nl_cmd_health_reporter_get_doit,
5238 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
5239 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5240 DEVLINK_NL_FLAG_NO_LOCK,
5241 /* can be retrieved by unprivileged users */
5244 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
5245 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5246 .doit = devlink_nl_cmd_health_reporter_set_doit,
5247 .flags = GENL_ADMIN_PERM,
5248 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5249 DEVLINK_NL_FLAG_NO_LOCK,
5252 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
5253 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5254 .doit = devlink_nl_cmd_health_reporter_recover_doit,
5255 .flags = GENL_ADMIN_PERM,
5256 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5257 DEVLINK_NL_FLAG_NO_LOCK,
5260 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
5261 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5262 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
5263 .flags = GENL_ADMIN_PERM,
5264 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5265 DEVLINK_NL_FLAG_NO_LOCK,
5268 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
5269 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5270 .doit = devlink_nl_cmd_health_reporter_dump_get_doit,
5271 .flags = GENL_ADMIN_PERM,
5272 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5273 DEVLINK_NL_FLAG_NO_LOCK,
5276 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
5277 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5278 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
5279 .flags = GENL_ADMIN_PERM,
5280 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5281 DEVLINK_NL_FLAG_NO_LOCK,
5284 .cmd = DEVLINK_CMD_FLASH_UPDATE,
5285 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5286 .doit = devlink_nl_cmd_flash_update,
5287 .flags = GENL_ADMIN_PERM,
5288 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5292 static struct genl_family devlink_nl_family __ro_after_init = {
5293 .name = DEVLINK_GENL_NAME,
5294 .version = DEVLINK_GENL_VERSION,
5295 .maxattr = DEVLINK_ATTR_MAX,
5296 .policy = devlink_nl_policy,
5298 .pre_doit = devlink_nl_pre_doit,
5299 .post_doit = devlink_nl_post_doit,
5300 .module = THIS_MODULE,
5301 .ops = devlink_nl_ops,
5302 .n_ops = ARRAY_SIZE(devlink_nl_ops),
5303 .mcgrps = devlink_nl_mcgrps,
5304 .n_mcgrps = ARRAY_SIZE(devlink_nl_mcgrps),
5308 * devlink_alloc - Allocate new devlink instance resources
5311 * @priv_size: size of user private data
5313 * Allocate new devlink instance resources, including devlink index
5316 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
5318 struct devlink *devlink;
5323 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
5327 devlink_net_set(devlink, &init_net);
5328 INIT_LIST_HEAD(&devlink->port_list);
5329 INIT_LIST_HEAD(&devlink->sb_list);
5330 INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
5331 INIT_LIST_HEAD(&devlink->resource_list);
5332 INIT_LIST_HEAD(&devlink->param_list);
5333 INIT_LIST_HEAD(&devlink->region_list);
5334 INIT_LIST_HEAD(&devlink->reporter_list);
5335 mutex_init(&devlink->lock);
5336 mutex_init(&devlink->reporters_lock);
5339 EXPORT_SYMBOL_GPL(devlink_alloc);
5342 * devlink_register - Register devlink instance
5345 * @dev: parent device
5347 int devlink_register(struct devlink *devlink, struct device *dev)
5349 mutex_lock(&devlink_mutex);
5351 list_add_tail(&devlink->list, &devlink_list);
5352 devlink_notify(devlink, DEVLINK_CMD_NEW);
5353 mutex_unlock(&devlink_mutex);
5356 EXPORT_SYMBOL_GPL(devlink_register);
5359 * devlink_unregister - Unregister devlink instance
5363 void devlink_unregister(struct devlink *devlink)
5365 mutex_lock(&devlink_mutex);
5366 devlink_notify(devlink, DEVLINK_CMD_DEL);
5367 list_del(&devlink->list);
5368 mutex_unlock(&devlink_mutex);
5370 EXPORT_SYMBOL_GPL(devlink_unregister);
5373 * devlink_free - Free devlink instance resources
5377 void devlink_free(struct devlink *devlink)
5379 mutex_destroy(&devlink->reporters_lock);
5380 mutex_destroy(&devlink->lock);
5381 WARN_ON(!list_empty(&devlink->reporter_list));
5382 WARN_ON(!list_empty(&devlink->region_list));
5383 WARN_ON(!list_empty(&devlink->param_list));
5384 WARN_ON(!list_empty(&devlink->resource_list));
5385 WARN_ON(!list_empty(&devlink->dpipe_table_list));
5386 WARN_ON(!list_empty(&devlink->sb_list));
5387 WARN_ON(!list_empty(&devlink->port_list));
5391 EXPORT_SYMBOL_GPL(devlink_free);
5394 * devlink_port_register - Register devlink port
5397 * @devlink_port: devlink port
5398 * @port_index: driver-specific numerical identifier of the port
5400 * Register devlink port with provided port index. User can use
5401 * any indexing, even hw-related one. devlink_port structure
5402 * is convenient to be embedded inside user driver private structure.
5403 * Note that the caller should take care of zeroing the devlink_port
5406 int devlink_port_register(struct devlink *devlink,
5407 struct devlink_port *devlink_port,
5408 unsigned int port_index)
5410 mutex_lock(&devlink->lock);
5411 if (devlink_port_index_exists(devlink, port_index)) {
5412 mutex_unlock(&devlink->lock);
5415 devlink_port->devlink = devlink;
5416 devlink_port->index = port_index;
5417 devlink_port->registered = true;
5418 spin_lock_init(&devlink_port->type_lock);
5419 list_add_tail(&devlink_port->list, &devlink->port_list);
5420 INIT_LIST_HEAD(&devlink_port->param_list);
5421 mutex_unlock(&devlink->lock);
5422 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
5425 EXPORT_SYMBOL_GPL(devlink_port_register);
5428 * devlink_port_unregister - Unregister devlink port
5430 * @devlink_port: devlink port
5432 void devlink_port_unregister(struct devlink_port *devlink_port)
5434 struct devlink *devlink = devlink_port->devlink;
5436 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
5437 mutex_lock(&devlink->lock);
5438 list_del(&devlink_port->list);
5439 mutex_unlock(&devlink->lock);
5441 EXPORT_SYMBOL_GPL(devlink_port_unregister);
5443 static void __devlink_port_type_set(struct devlink_port *devlink_port,
5444 enum devlink_port_type type,
5447 if (WARN_ON(!devlink_port->registered))
5449 spin_lock(&devlink_port->type_lock);
5450 devlink_port->type = type;
5451 devlink_port->type_dev = type_dev;
5452 spin_unlock(&devlink_port->type_lock);
5453 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
5457 * devlink_port_type_eth_set - Set port type to Ethernet
5459 * @devlink_port: devlink port
5460 * @netdev: related netdevice
5462 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
5463 struct net_device *netdev)
5465 const struct net_device_ops *ops = netdev->netdev_ops;
5467 /* If driver registers devlink port, it should set devlink port
5468 * attributes accordingly so the compat functions are called
5469 * and the original ops are not used.
5471 if (ops->ndo_get_phys_port_name) {
5472 /* Some drivers use the same set of ndos for netdevs
5473 * that have devlink_port registered and also for
5474 * those who don't. Make sure that ndo_get_phys_port_name
5475 * returns -EOPNOTSUPP here in case it is defined.
5478 char name[IFNAMSIZ];
5481 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
5482 WARN_ON(err != -EOPNOTSUPP);
5484 if (ops->ndo_get_port_parent_id) {
5485 /* Some drivers use the same set of ndos for netdevs
5486 * that have devlink_port registered and also for
5487 * those who don't. Make sure that ndo_get_port_parent_id
5488 * returns -EOPNOTSUPP here in case it is defined.
5491 struct netdev_phys_item_id ppid;
5494 err = ops->ndo_get_port_parent_id(netdev, &ppid);
5495 WARN_ON(err != -EOPNOTSUPP);
5497 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
5499 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
5502 * devlink_port_type_ib_set - Set port type to InfiniBand
5504 * @devlink_port: devlink port
5505 * @ibdev: related IB device
5507 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
5508 struct ib_device *ibdev)
5510 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
5512 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
5515 * devlink_port_type_clear - Clear port type
5517 * @devlink_port: devlink port
5519 void devlink_port_type_clear(struct devlink_port *devlink_port)
5521 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
5523 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
5526 * devlink_port_attrs_set - Set port attributes
5528 * @devlink_port: devlink port
5529 * @flavour: flavour of the port
5530 * @port_number: number of the port that is facing user, for example
5531 * the front panel port number
5532 * @split: indicates if this is split port
5533 * @split_subport_number: if the port is split, this is the number
5535 * @switch_id: if the port is part of switch, this is buffer with ID,
5536 * otwerwise this is NULL
5537 * @switch_id_len: length of the switch_id buffer
5539 void devlink_port_attrs_set(struct devlink_port *devlink_port,
5540 enum devlink_port_flavour flavour,
5541 u32 port_number, bool split,
5542 u32 split_subport_number,
5543 const unsigned char *switch_id,
5544 unsigned char switch_id_len)
5546 struct devlink_port_attrs *attrs = &devlink_port->attrs;
5548 if (WARN_ON(devlink_port->registered))
5551 attrs->flavour = flavour;
5552 attrs->port_number = port_number;
5553 attrs->split = split;
5554 attrs->split_subport_number = split_subport_number;
5556 attrs->switch_port = true;
5557 if (WARN_ON(switch_id_len > MAX_PHYS_ITEM_ID_LEN))
5558 switch_id_len = MAX_PHYS_ITEM_ID_LEN;
5559 memcpy(attrs->switch_id.id, switch_id, switch_id_len);
5560 attrs->switch_id.id_len = switch_id_len;
5562 attrs->switch_port = false;
5565 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
5567 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
5568 char *name, size_t len)
5570 struct devlink_port_attrs *attrs = &devlink_port->attrs;
5576 switch (attrs->flavour) {
5577 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
5579 n = snprintf(name, len, "p%u", attrs->port_number);
5581 n = snprintf(name, len, "p%us%u", attrs->port_number,
5582 attrs->split_subport_number);
5584 case DEVLINK_PORT_FLAVOUR_CPU:
5585 case DEVLINK_PORT_FLAVOUR_DSA:
5586 /* As CPU and DSA ports do not have a netdevice associated
5587 * case should not ever happen.
5599 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
5600 u32 size, u16 ingress_pools_count,
5601 u16 egress_pools_count, u16 ingress_tc_count,
5602 u16 egress_tc_count)
5604 struct devlink_sb *devlink_sb;
5607 mutex_lock(&devlink->lock);
5608 if (devlink_sb_index_exists(devlink, sb_index)) {
5613 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
5618 devlink_sb->index = sb_index;
5619 devlink_sb->size = size;
5620 devlink_sb->ingress_pools_count = ingress_pools_count;
5621 devlink_sb->egress_pools_count = egress_pools_count;
5622 devlink_sb->ingress_tc_count = ingress_tc_count;
5623 devlink_sb->egress_tc_count = egress_tc_count;
5624 list_add_tail(&devlink_sb->list, &devlink->sb_list);
5626 mutex_unlock(&devlink->lock);
5629 EXPORT_SYMBOL_GPL(devlink_sb_register);
5631 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
5633 struct devlink_sb *devlink_sb;
5635 mutex_lock(&devlink->lock);
5636 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
5637 WARN_ON(!devlink_sb);
5638 list_del(&devlink_sb->list);
5639 mutex_unlock(&devlink->lock);
5642 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
5645 * devlink_dpipe_headers_register - register dpipe headers
5648 * @dpipe_headers: dpipe header array
5650 * Register the headers supported by hardware.
5652 int devlink_dpipe_headers_register(struct devlink *devlink,
5653 struct devlink_dpipe_headers *dpipe_headers)
5655 mutex_lock(&devlink->lock);
5656 devlink->dpipe_headers = dpipe_headers;
5657 mutex_unlock(&devlink->lock);
5660 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
5663 * devlink_dpipe_headers_unregister - unregister dpipe headers
5667 * Unregister the headers supported by hardware.
5669 void devlink_dpipe_headers_unregister(struct devlink *devlink)
5671 mutex_lock(&devlink->lock);
5672 devlink->dpipe_headers = NULL;
5673 mutex_unlock(&devlink->lock);
5675 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
5678 * devlink_dpipe_table_counter_enabled - check if counter allocation
5681 * @table_name: tables name
5683 * Used by driver to check if counter allocation is required.
5684 * After counter allocation is turned on the table entries
5685 * are updated to include counter statistics.
5687 * After that point on the driver must respect the counter
5688 * state so that each entry added to the table is added
5691 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
5692 const char *table_name)
5694 struct devlink_dpipe_table *table;
5698 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5702 enabled = table->counters_enabled;
5706 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
5709 * devlink_dpipe_table_register - register dpipe table
5712 * @table_name: table name
5713 * @table_ops: table ops
5715 * @counter_control_extern: external control for counters
5717 int devlink_dpipe_table_register(struct devlink *devlink,
5718 const char *table_name,
5719 struct devlink_dpipe_table_ops *table_ops,
5720 void *priv, bool counter_control_extern)
5722 struct devlink_dpipe_table *table;
5724 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
5727 if (WARN_ON(!table_ops->size_get))
5730 table = kzalloc(sizeof(*table), GFP_KERNEL);
5734 table->name = table_name;
5735 table->table_ops = table_ops;
5737 table->counter_control_extern = counter_control_extern;
5739 mutex_lock(&devlink->lock);
5740 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
5741 mutex_unlock(&devlink->lock);
5744 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
5747 * devlink_dpipe_table_unregister - unregister dpipe table
5750 * @table_name: table name
5752 void devlink_dpipe_table_unregister(struct devlink *devlink,
5753 const char *table_name)
5755 struct devlink_dpipe_table *table;
5757 mutex_lock(&devlink->lock);
5758 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5762 list_del_rcu(&table->list);
5763 mutex_unlock(&devlink->lock);
5764 kfree_rcu(table, rcu);
5767 mutex_unlock(&devlink->lock);
5769 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
5772 * devlink_resource_register - devlink resource register
5775 * @resource_name: resource's name
5776 * @resource_size: resource's size
5777 * @resource_id: resource's id
5778 * @parent_resource_id: resource's parent id
5779 * @size_params: size parameters
5781 int devlink_resource_register(struct devlink *devlink,
5782 const char *resource_name,
5785 u64 parent_resource_id,
5786 const struct devlink_resource_size_params *size_params)
5788 struct devlink_resource *resource;
5789 struct list_head *resource_list;
5793 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
5795 mutex_lock(&devlink->lock);
5796 resource = devlink_resource_find(devlink, NULL, resource_id);
5802 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
5808 if (top_hierarchy) {
5809 resource_list = &devlink->resource_list;
5811 struct devlink_resource *parent_resource;
5813 parent_resource = devlink_resource_find(devlink, NULL,
5814 parent_resource_id);
5815 if (parent_resource) {
5816 resource_list = &parent_resource->resource_list;
5817 resource->parent = parent_resource;
5825 resource->name = resource_name;
5826 resource->size = resource_size;
5827 resource->size_new = resource_size;
5828 resource->id = resource_id;
5829 resource->size_valid = true;
5830 memcpy(&resource->size_params, size_params,
5831 sizeof(resource->size_params));
5832 INIT_LIST_HEAD(&resource->resource_list);
5833 list_add_tail(&resource->list, resource_list);
5835 mutex_unlock(&devlink->lock);
5838 EXPORT_SYMBOL_GPL(devlink_resource_register);
5841 * devlink_resources_unregister - free all resources
5844 * @resource: resource
5846 void devlink_resources_unregister(struct devlink *devlink,
5847 struct devlink_resource *resource)
5849 struct devlink_resource *tmp, *child_resource;
5850 struct list_head *resource_list;
5853 resource_list = &resource->resource_list;
5855 resource_list = &devlink->resource_list;
5858 mutex_lock(&devlink->lock);
5860 list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
5861 devlink_resources_unregister(devlink, child_resource);
5862 list_del(&child_resource->list);
5863 kfree(child_resource);
5867 mutex_unlock(&devlink->lock);
5869 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
5872 * devlink_resource_size_get - get and update size
5875 * @resource_id: the requested resource id
5876 * @p_resource_size: ptr to update
5878 int devlink_resource_size_get(struct devlink *devlink,
5880 u64 *p_resource_size)
5882 struct devlink_resource *resource;
5885 mutex_lock(&devlink->lock);
5886 resource = devlink_resource_find(devlink, NULL, resource_id);
5891 *p_resource_size = resource->size_new;
5892 resource->size = resource->size_new;
5894 mutex_unlock(&devlink->lock);
5897 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
5900 * devlink_dpipe_table_resource_set - set the resource id
5903 * @table_name: table name
5904 * @resource_id: resource id
5905 * @resource_units: number of resource's units consumed per table's entry
5907 int devlink_dpipe_table_resource_set(struct devlink *devlink,
5908 const char *table_name, u64 resource_id,
5911 struct devlink_dpipe_table *table;
5914 mutex_lock(&devlink->lock);
5915 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5921 table->resource_id = resource_id;
5922 table->resource_units = resource_units;
5923 table->resource_valid = true;
5925 mutex_unlock(&devlink->lock);
5928 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
5931 * devlink_resource_occ_get_register - register occupancy getter
5934 * @resource_id: resource id
5935 * @occ_get: occupancy getter callback
5936 * @occ_get_priv: occupancy getter callback priv
5938 void devlink_resource_occ_get_register(struct devlink *devlink,
5940 devlink_resource_occ_get_t *occ_get,
5943 struct devlink_resource *resource;
5945 mutex_lock(&devlink->lock);
5946 resource = devlink_resource_find(devlink, NULL, resource_id);
5947 if (WARN_ON(!resource))
5949 WARN_ON(resource->occ_get);
5951 resource->occ_get = occ_get;
5952 resource->occ_get_priv = occ_get_priv;
5954 mutex_unlock(&devlink->lock);
5956 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
5959 * devlink_resource_occ_get_unregister - unregister occupancy getter
5962 * @resource_id: resource id
5964 void devlink_resource_occ_get_unregister(struct devlink *devlink,
5967 struct devlink_resource *resource;
5969 mutex_lock(&devlink->lock);
5970 resource = devlink_resource_find(devlink, NULL, resource_id);
5971 if (WARN_ON(!resource))
5973 WARN_ON(!resource->occ_get);
5975 resource->occ_get = NULL;
5976 resource->occ_get_priv = NULL;
5978 mutex_unlock(&devlink->lock);
5980 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
5982 static int devlink_param_verify(const struct devlink_param *param)
5984 if (!param || !param->name || !param->supported_cmodes)
5987 return devlink_param_generic_verify(param);
5989 return devlink_param_driver_verify(param);
5992 static int __devlink_params_register(struct devlink *devlink,
5993 unsigned int port_index,
5994 struct list_head *param_list,
5995 const struct devlink_param *params,
5996 size_t params_count,
5997 enum devlink_command reg_cmd,
5998 enum devlink_command unreg_cmd)
6000 const struct devlink_param *param = params;
6004 mutex_lock(&devlink->lock);
6005 for (i = 0; i < params_count; i++, param++) {
6006 err = devlink_param_verify(param);
6010 err = devlink_param_register_one(devlink, port_index,
6011 param_list, param, reg_cmd);
6016 mutex_unlock(&devlink->lock);
6022 for (param--; i > 0; i--, param--)
6023 devlink_param_unregister_one(devlink, port_index, param_list,
6026 mutex_unlock(&devlink->lock);
6030 static void __devlink_params_unregister(struct devlink *devlink,
6031 unsigned int port_index,
6032 struct list_head *param_list,
6033 const struct devlink_param *params,
6034 size_t params_count,
6035 enum devlink_command cmd)
6037 const struct devlink_param *param = params;
6040 mutex_lock(&devlink->lock);
6041 for (i = 0; i < params_count; i++, param++)
6042 devlink_param_unregister_one(devlink, 0, param_list, param,
6044 mutex_unlock(&devlink->lock);
6048 * devlink_params_register - register configuration parameters
6051 * @params: configuration parameters array
6052 * @params_count: number of parameters provided
6054 * Register the configuration parameters supported by the driver.
6056 int devlink_params_register(struct devlink *devlink,
6057 const struct devlink_param *params,
6058 size_t params_count)
6060 return __devlink_params_register(devlink, 0, &devlink->param_list,
6061 params, params_count,
6062 DEVLINK_CMD_PARAM_NEW,
6063 DEVLINK_CMD_PARAM_DEL);
6065 EXPORT_SYMBOL_GPL(devlink_params_register);
6068 * devlink_params_unregister - unregister configuration parameters
6070 * @params: configuration parameters to unregister
6071 * @params_count: number of parameters provided
6073 void devlink_params_unregister(struct devlink *devlink,
6074 const struct devlink_param *params,
6075 size_t params_count)
6077 return __devlink_params_unregister(devlink, 0, &devlink->param_list,
6078 params, params_count,
6079 DEVLINK_CMD_PARAM_DEL);
6081 EXPORT_SYMBOL_GPL(devlink_params_unregister);
6084 * devlink_params_publish - publish configuration parameters
6088 * Publish previously registered configuration parameters.
6090 void devlink_params_publish(struct devlink *devlink)
6092 struct devlink_param_item *param_item;
6094 list_for_each_entry(param_item, &devlink->param_list, list) {
6095 if (param_item->published)
6097 param_item->published = true;
6098 devlink_param_notify(devlink, 0, param_item,
6099 DEVLINK_CMD_PARAM_NEW);
6102 EXPORT_SYMBOL_GPL(devlink_params_publish);
6105 * devlink_params_unpublish - unpublish configuration parameters
6109 * Unpublish previously registered configuration parameters.
6111 void devlink_params_unpublish(struct devlink *devlink)
6113 struct devlink_param_item *param_item;
6115 list_for_each_entry(param_item, &devlink->param_list, list) {
6116 if (!param_item->published)
6118 param_item->published = false;
6119 devlink_param_notify(devlink, 0, param_item,
6120 DEVLINK_CMD_PARAM_DEL);
6123 EXPORT_SYMBOL_GPL(devlink_params_unpublish);
6126 * devlink_port_params_register - register port configuration parameters
6128 * @devlink_port: devlink port
6129 * @params: configuration parameters array
6130 * @params_count: number of parameters provided
6132 * Register the configuration parameters supported by the port.
6134 int devlink_port_params_register(struct devlink_port *devlink_port,
6135 const struct devlink_param *params,
6136 size_t params_count)
6138 return __devlink_params_register(devlink_port->devlink,
6139 devlink_port->index,
6140 &devlink_port->param_list, params,
6142 DEVLINK_CMD_PORT_PARAM_NEW,
6143 DEVLINK_CMD_PORT_PARAM_DEL);
6145 EXPORT_SYMBOL_GPL(devlink_port_params_register);
6148 * devlink_port_params_unregister - unregister port configuration
6151 * @devlink_port: devlink port
6152 * @params: configuration parameters array
6153 * @params_count: number of parameters provided
6155 void devlink_port_params_unregister(struct devlink_port *devlink_port,
6156 const struct devlink_param *params,
6157 size_t params_count)
6159 return __devlink_params_unregister(devlink_port->devlink,
6160 devlink_port->index,
6161 &devlink_port->param_list,
6162 params, params_count,
6163 DEVLINK_CMD_PORT_PARAM_DEL);
6165 EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
6168 __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
6169 union devlink_param_value *init_val)
6171 struct devlink_param_item *param_item;
6173 param_item = devlink_param_find_by_id(param_list, param_id);
6177 if (!param_item->driverinit_value_valid ||
6178 !devlink_param_cmode_is_supported(param_item->param,
6179 DEVLINK_PARAM_CMODE_DRIVERINIT))
6182 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
6183 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
6185 *init_val = param_item->driverinit_value;
6191 __devlink_param_driverinit_value_set(struct devlink *devlink,
6192 unsigned int port_index,
6193 struct list_head *param_list, u32 param_id,
6194 union devlink_param_value init_val,
6195 enum devlink_command cmd)
6197 struct devlink_param_item *param_item;
6199 param_item = devlink_param_find_by_id(param_list, param_id);
6203 if (!devlink_param_cmode_is_supported(param_item->param,
6204 DEVLINK_PARAM_CMODE_DRIVERINIT))
6207 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
6208 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
6210 param_item->driverinit_value = init_val;
6211 param_item->driverinit_value_valid = true;
6213 devlink_param_notify(devlink, port_index, param_item, cmd);
6218 * devlink_param_driverinit_value_get - get configuration parameter
6219 * value for driver initializing
6222 * @param_id: parameter ID
6223 * @init_val: value of parameter in driverinit configuration mode
6225 * This function should be used by the driver to get driverinit
6226 * configuration for initialization after reload command.
6228 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
6229 union devlink_param_value *init_val)
6231 if (!devlink->ops->reload)
6234 return __devlink_param_driverinit_value_get(&devlink->param_list,
6235 param_id, init_val);
6237 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
6240 * devlink_param_driverinit_value_set - set value of configuration
6241 * parameter for driverinit
6242 * configuration mode
6245 * @param_id: parameter ID
6246 * @init_val: value of parameter to set for driverinit configuration mode
6248 * This function should be used by the driver to set driverinit
6249 * configuration mode default value.
6251 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
6252 union devlink_param_value init_val)
6254 return __devlink_param_driverinit_value_set(devlink, 0,
6255 &devlink->param_list,
6257 DEVLINK_CMD_PARAM_NEW);
6259 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
6262 * devlink_port_param_driverinit_value_get - get configuration parameter
6263 * value for driver initializing
6265 * @devlink_port: devlink_port
6266 * @param_id: parameter ID
6267 * @init_val: value of parameter in driverinit configuration mode
6269 * This function should be used by the driver to get driverinit
6270 * configuration for initialization after reload command.
6272 int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
6274 union devlink_param_value *init_val)
6276 struct devlink *devlink = devlink_port->devlink;
6278 if (!devlink->ops->reload)
6281 return __devlink_param_driverinit_value_get(&devlink_port->param_list,
6282 param_id, init_val);
6284 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
6287 * devlink_port_param_driverinit_value_set - set value of configuration
6288 * parameter for driverinit
6289 * configuration mode
6291 * @devlink_port: devlink_port
6292 * @param_id: parameter ID
6293 * @init_val: value of parameter to set for driverinit configuration mode
6295 * This function should be used by the driver to set driverinit
6296 * configuration mode default value.
6298 int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
6300 union devlink_param_value init_val)
6302 return __devlink_param_driverinit_value_set(devlink_port->devlink,
6303 devlink_port->index,
6304 &devlink_port->param_list,
6306 DEVLINK_CMD_PORT_PARAM_NEW);
6308 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
6311 * devlink_param_value_changed - notify devlink on a parameter's value
6312 * change. Should be called by the driver
6313 * right after the change.
6316 * @param_id: parameter ID
6318 * This function should be used by the driver to notify devlink on value
6319 * change, excluding driverinit configuration mode.
6320 * For driverinit configuration mode driver should use the function
6322 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
6324 struct devlink_param_item *param_item;
6326 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
6327 WARN_ON(!param_item);
6329 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
6331 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
6334 * devlink_port_param_value_changed - notify devlink on a parameter's value
6335 * change. Should be called by the driver
6336 * right after the change.
6338 * @devlink_port: devlink_port
6339 * @param_id: parameter ID
6341 * This function should be used by the driver to notify devlink on value
6342 * change, excluding driverinit configuration mode.
6343 * For driverinit configuration mode driver should use the function
6344 * devlink_port_param_driverinit_value_set() instead.
6346 void devlink_port_param_value_changed(struct devlink_port *devlink_port,
6349 struct devlink_param_item *param_item;
6351 param_item = devlink_param_find_by_id(&devlink_port->param_list,
6353 WARN_ON(!param_item);
6355 devlink_param_notify(devlink_port->devlink, devlink_port->index,
6356 param_item, DEVLINK_CMD_PORT_PARAM_NEW);
6358 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
6361 * devlink_param_value_str_fill - Safely fill-up the string preventing
6362 * from overflow of the preallocated buffer
6364 * @dst_val: destination devlink_param_value
6365 * @src: source buffer
6367 void devlink_param_value_str_fill(union devlink_param_value *dst_val,
6372 len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
6373 WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
6375 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
6378 * devlink_region_create - create a new address region
6381 * @region_name: region name
6382 * @region_max_snapshots: Maximum supported number of snapshots for region
6383 * @region_size: size of region
6385 struct devlink_region *devlink_region_create(struct devlink *devlink,
6386 const char *region_name,
6387 u32 region_max_snapshots,
6390 struct devlink_region *region;
6393 mutex_lock(&devlink->lock);
6395 if (devlink_region_get_by_name(devlink, region_name)) {
6400 region = kzalloc(sizeof(*region), GFP_KERNEL);
6406 region->devlink = devlink;
6407 region->max_snapshots = region_max_snapshots;
6408 region->name = region_name;
6409 region->size = region_size;
6410 INIT_LIST_HEAD(®ion->snapshot_list);
6411 list_add_tail(®ion->list, &devlink->region_list);
6412 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
6414 mutex_unlock(&devlink->lock);
6418 mutex_unlock(&devlink->lock);
6419 return ERR_PTR(err);
6421 EXPORT_SYMBOL_GPL(devlink_region_create);
6424 * devlink_region_destroy - destroy address region
6426 * @region: devlink region to destroy
6428 void devlink_region_destroy(struct devlink_region *region)
6430 struct devlink *devlink = region->devlink;
6431 struct devlink_snapshot *snapshot, *ts;
6433 mutex_lock(&devlink->lock);
6435 /* Free all snapshots of region */
6436 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
6437 devlink_region_snapshot_del(snapshot);
6439 list_del(®ion->list);
6441 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
6442 mutex_unlock(&devlink->lock);
6445 EXPORT_SYMBOL_GPL(devlink_region_destroy);
6448 * devlink_region_shapshot_id_get - get snapshot ID
6450 * This callback should be called when adding a new snapshot,
6451 * Driver should use the same id for multiple snapshots taken
6452 * on multiple regions at the same time/by the same trigger.
6456 u32 devlink_region_shapshot_id_get(struct devlink *devlink)
6460 mutex_lock(&devlink->lock);
6461 id = ++devlink->snapshot_id;
6462 mutex_unlock(&devlink->lock);
6466 EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get);
6469 * devlink_region_snapshot_create - create a new snapshot
6470 * This will add a new snapshot of a region. The snapshot
6471 * will be stored on the region struct and can be accessed
6472 * from devlink. This is useful for future analyses of snapshots.
6473 * Multiple snapshots can be created on a region.
6474 * The @snapshot_id should be obtained using the getter function.
6476 * @region: devlink region of the snapshot
6477 * @data_len: size of snapshot data
6478 * @data: snapshot data
6479 * @snapshot_id: snapshot id to be created
6480 * @data_destructor: pointer to destructor function to free data
6482 int devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
6483 u8 *data, u32 snapshot_id,
6484 devlink_snapshot_data_dest_t *data_destructor)
6486 struct devlink *devlink = region->devlink;
6487 struct devlink_snapshot *snapshot;
6490 mutex_lock(&devlink->lock);
6492 /* check if region can hold one more snapshot */
6493 if (region->cur_snapshots == region->max_snapshots) {
6498 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
6503 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
6509 snapshot->id = snapshot_id;
6510 snapshot->region = region;
6511 snapshot->data = data;
6512 snapshot->data_len = data_len;
6513 snapshot->data_destructor = data_destructor;
6515 list_add_tail(&snapshot->list, ®ion->snapshot_list);
6517 region->cur_snapshots++;
6519 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
6520 mutex_unlock(&devlink->lock);
6524 mutex_unlock(&devlink->lock);
6527 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
6529 static void __devlink_compat_running_version(struct devlink *devlink,
6530 char *buf, size_t len)
6532 const struct nlattr *nlattr;
6533 struct devlink_info_req req;
6534 struct sk_buff *msg;
6537 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6542 err = devlink->ops->info_get(devlink, &req, NULL);
6546 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
6547 const struct nlattr *kv;
6550 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
6553 nla_for_each_nested(kv, nlattr, rem_kv) {
6554 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
6557 strlcat(buf, nla_data(kv), len);
6558 strlcat(buf, " ", len);
6565 void devlink_compat_running_version(struct net_device *dev,
6566 char *buf, size_t len)
6568 struct devlink *devlink;
6573 devlink = netdev_to_devlink(dev);
6574 if (!devlink || !devlink->ops->info_get)
6577 mutex_lock(&devlink->lock);
6578 __devlink_compat_running_version(devlink, buf, len);
6579 mutex_unlock(&devlink->lock);
6586 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
6588 struct devlink *devlink;
6594 devlink = netdev_to_devlink(dev);
6595 if (!devlink || !devlink->ops->flash_update) {
6600 mutex_lock(&devlink->lock);
6601 ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
6602 mutex_unlock(&devlink->lock);
6611 int devlink_compat_phys_port_name_get(struct net_device *dev,
6612 char *name, size_t len)
6614 struct devlink_port *devlink_port;
6616 /* RTNL mutex is held here which ensures that devlink_port
6617 * instance cannot disappear in the middle. No need to take
6618 * any devlink lock as only permanent values are accessed.
6622 devlink_port = netdev_to_devlink_port(dev);
6626 return __devlink_port_phys_port_name_get(devlink_port, name, len);
6629 int devlink_compat_switch_id_get(struct net_device *dev,
6630 struct netdev_phys_item_id *ppid)
6632 struct devlink_port *devlink_port;
6634 /* RTNL mutex is held here which ensures that devlink_port
6635 * instance cannot disappear in the middle. No need to take
6636 * any devlink lock as only permanent values are accessed.
6639 devlink_port = netdev_to_devlink_port(dev);
6640 if (!devlink_port || !devlink_port->attrs.switch_port)
6643 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
6648 static int __init devlink_init(void)
6650 return genl_register_family(&devlink_nl_family);
6653 subsys_initcall(devlink_init);