1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * net/core/devlink.c - Network physical/parent device Netlink interface
5 * Heavily inspired by net/wireless/
6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
10 #include <linux/etherdevice.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/types.h>
14 #include <linux/slab.h>
15 #include <linux/gfp.h>
16 #include <linux/device.h>
17 #include <linux/list.h>
18 #include <linux/netdevice.h>
19 #include <linux/spinlock.h>
20 #include <linux/refcount.h>
21 #include <linux/workqueue.h>
22 #include <linux/u64_stats_sync.h>
23 #include <linux/timekeeping.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 #include "devl_internal.h"
36 struct devlink_linecard {
37 struct list_head list;
38 struct devlink *devlink;
41 const struct devlink_linecard_ops *ops;
43 enum devlink_linecard_state state;
44 struct mutex state_lock; /* Protects state */
46 struct devlink_linecard_type *types;
47 unsigned int types_count;
48 struct devlink *nested_devlink;
52 * struct devlink_resource - devlink resource
53 * @name: name of the resource
54 * @id: id, per devlink instance
55 * @size: size of the resource
56 * @size_new: updated size of the resource, reload is needed
57 * @size_valid: valid in case the total size of the resource is valid
58 * including its children
59 * @parent: parent resource
60 * @size_params: size parameters
62 * @resource_list: list of child resources
63 * @occ_get: occupancy getter callback
64 * @occ_get_priv: occupancy getter callback priv
66 struct devlink_resource {
72 struct devlink_resource *parent;
73 struct devlink_resource_size_params size_params;
74 struct list_head list;
75 struct list_head resource_list;
76 devlink_resource_occ_get_t *occ_get;
80 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
82 .name = "destination mac",
83 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
88 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
90 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
91 .fields = devlink_dpipe_fields_ethernet,
92 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
95 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
97 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
99 .name = "destination ip",
100 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
105 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
107 .id = DEVLINK_DPIPE_HEADER_IPV4,
108 .fields = devlink_dpipe_fields_ipv4,
109 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
112 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
114 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
116 .name = "destination ip",
117 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
122 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
124 .id = DEVLINK_DPIPE_HEADER_IPV6,
125 .fields = devlink_dpipe_fields_ipv6,
126 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
129 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
131 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
132 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
133 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
135 #define DEVLINK_PORT_FN_CAPS_VALID_MASK \
136 (_BITUL(__DEVLINK_PORT_FN_ATTR_CAPS_MAX) - 1)
138 static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
139 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
140 [DEVLINK_PORT_FN_ATTR_STATE] =
141 NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE,
142 DEVLINK_PORT_FN_STATE_ACTIVE),
143 [DEVLINK_PORT_FN_ATTR_CAPS] =
144 NLA_POLICY_BITFIELD32(DEVLINK_PORT_FN_CAPS_VALID_MASK),
147 static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = {
148 [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG },
151 #define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port) \
152 WARN_ON_ONCE(!(devlink_port)->registered)
153 #define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port) \
154 WARN_ON_ONCE((devlink_port)->registered)
155 #define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port) \
156 WARN_ON_ONCE(!(devlink_port)->initialized)
158 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
159 unsigned int port_index)
161 return xa_load(&devlink->ports, port_index);
164 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
165 struct nlattr **attrs)
167 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
168 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
169 struct devlink_port *devlink_port;
171 devlink_port = devlink_port_get_by_index(devlink, port_index);
173 return ERR_PTR(-ENODEV);
176 return ERR_PTR(-EINVAL);
179 struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
180 struct genl_info *info)
182 return devlink_port_get_from_attrs(devlink, info->attrs);
186 devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
188 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
192 devlink_rate_is_node(struct devlink_rate *devlink_rate)
194 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
197 static struct devlink_rate *
198 devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
200 struct devlink_rate *devlink_rate;
201 struct devlink_port *devlink_port;
203 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
204 if (IS_ERR(devlink_port))
205 return ERR_CAST(devlink_port);
206 devlink_rate = devlink_port->devlink_rate;
207 return devlink_rate ?: ERR_PTR(-ENODEV);
210 static struct devlink_rate *
211 devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
213 static struct devlink_rate *devlink_rate;
215 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
216 if (devlink_rate_is_node(devlink_rate) &&
217 !strcmp(node_name, devlink_rate->name))
220 return ERR_PTR(-ENODEV);
223 static struct devlink_rate *
224 devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
226 const char *rate_node_name;
229 if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
230 return ERR_PTR(-EINVAL);
231 rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
232 len = strlen(rate_node_name);
233 /* Name cannot be empty or decimal number */
234 if (!len || strspn(rate_node_name, "0123456789") == len)
235 return ERR_PTR(-EINVAL);
237 return devlink_rate_node_get_by_name(devlink, rate_node_name);
240 struct devlink_rate *
241 devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
243 return devlink_rate_node_get_from_attrs(devlink, info->attrs);
246 struct devlink_rate *
247 devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
249 struct nlattr **attrs = info->attrs;
251 if (attrs[DEVLINK_ATTR_PORT_INDEX])
252 return devlink_rate_leaf_get_from_info(devlink, info);
253 else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
254 return devlink_rate_node_get_from_info(devlink, info);
256 return ERR_PTR(-EINVAL);
259 static struct devlink_linecard *
260 devlink_linecard_get_by_index(struct devlink *devlink,
261 unsigned int linecard_index)
263 struct devlink_linecard *devlink_linecard;
265 list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
266 if (devlink_linecard->index == linecard_index)
267 return devlink_linecard;
272 static bool devlink_linecard_index_exists(struct devlink *devlink,
273 unsigned int linecard_index)
275 return devlink_linecard_get_by_index(devlink, linecard_index);
278 static struct devlink_linecard *
279 devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
281 if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
282 u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
283 struct devlink_linecard *linecard;
285 mutex_lock(&devlink->linecards_lock);
286 linecard = devlink_linecard_get_by_index(devlink, linecard_index);
288 refcount_inc(&linecard->refcount);
289 mutex_unlock(&devlink->linecards_lock);
291 return ERR_PTR(-ENODEV);
294 return ERR_PTR(-EINVAL);
297 struct devlink_linecard *
298 devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
300 return devlink_linecard_get_from_attrs(devlink, info->attrs);
303 void devlink_linecard_put(struct devlink_linecard *linecard)
305 if (refcount_dec_and_test(&linecard->refcount)) {
306 mutex_destroy(&linecard->state_lock);
312 struct list_head list;
315 u16 ingress_pools_count;
316 u16 egress_pools_count;
317 u16 ingress_tc_count;
321 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
323 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
326 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
327 unsigned int sb_index)
329 struct devlink_sb *devlink_sb;
331 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
332 if (devlink_sb->index == sb_index)
338 static bool devlink_sb_index_exists(struct devlink *devlink,
339 unsigned int sb_index)
341 return devlink_sb_get_by_index(devlink, sb_index);
344 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
345 struct nlattr **attrs)
347 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
348 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
349 struct devlink_sb *devlink_sb;
351 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
353 return ERR_PTR(-ENODEV);
356 return ERR_PTR(-EINVAL);
359 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
360 struct genl_info *info)
362 return devlink_sb_get_from_attrs(devlink, info->attrs);
365 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
366 struct nlattr **attrs,
371 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
374 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
375 if (val >= devlink_sb_pool_count(devlink_sb))
381 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
382 struct genl_info *info,
385 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
390 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
391 enum devlink_sb_pool_type *p_pool_type)
395 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
398 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
399 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
400 val != DEVLINK_SB_POOL_TYPE_EGRESS)
407 devlink_sb_pool_type_get_from_info(struct genl_info *info,
408 enum devlink_sb_pool_type *p_pool_type)
410 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
414 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
415 enum devlink_sb_threshold_type *p_th_type)
419 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
422 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
423 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
424 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
431 devlink_sb_th_type_get_from_info(struct genl_info *info,
432 enum devlink_sb_threshold_type *p_th_type)
434 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
438 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
439 struct nlattr **attrs,
440 enum devlink_sb_pool_type pool_type,
445 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
448 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
449 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
450 val >= devlink_sb->ingress_tc_count)
452 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
453 val >= devlink_sb->egress_tc_count)
459 static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps,
460 u32 cap, bool is_enable)
462 caps->selector |= cap;
467 static int devlink_port_fn_roce_fill(const struct devlink_ops *ops,
468 struct devlink_port *devlink_port,
469 struct nla_bitfield32 *caps,
470 struct netlink_ext_ack *extack)
475 if (!ops->port_fn_roce_get)
478 err = ops->port_fn_roce_get(devlink_port, &is_enable, extack);
480 if (err == -EOPNOTSUPP)
485 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_ROCE, is_enable);
489 static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops,
490 struct devlink_port *devlink_port,
491 struct nla_bitfield32 *caps,
492 struct netlink_ext_ack *extack)
497 if (!ops->port_fn_migratable_get ||
498 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF)
501 err = ops->port_fn_migratable_get(devlink_port, &is_enable, extack);
503 if (err == -EOPNOTSUPP)
508 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_MIGRATABLE, is_enable);
512 static int devlink_port_fn_caps_fill(const struct devlink_ops *ops,
513 struct devlink_port *devlink_port,
515 struct netlink_ext_ack *extack,
518 struct nla_bitfield32 caps = {};
521 err = devlink_port_fn_roce_fill(ops, devlink_port, &caps, extack);
525 err = devlink_port_fn_migratable_fill(ops, devlink_port, &caps, extack);
531 err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value,
541 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
542 struct genl_info *info,
543 enum devlink_sb_pool_type pool_type,
546 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
547 pool_type, p_tc_index);
550 struct devlink_region {
551 struct devlink *devlink;
552 struct devlink_port *port;
553 struct list_head list;
555 const struct devlink_region_ops *ops;
556 const struct devlink_port_region_ops *port_ops;
558 struct mutex snapshot_lock; /* protects snapshot_list,
559 * max_snapshots and cur_snapshots
562 struct list_head snapshot_list;
568 struct devlink_snapshot {
569 struct list_head list;
570 struct devlink_region *region;
575 static struct devlink_region *
576 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
578 struct devlink_region *region;
580 list_for_each_entry(region, &devlink->region_list, list)
581 if (!strcmp(region->ops->name, region_name))
587 static struct devlink_region *
588 devlink_port_region_get_by_name(struct devlink_port *port,
589 const char *region_name)
591 struct devlink_region *region;
593 list_for_each_entry(region, &port->region_list, list)
594 if (!strcmp(region->ops->name, region_name))
600 static struct devlink_snapshot *
601 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
603 struct devlink_snapshot *snapshot;
605 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
606 if (snapshot->id == id)
612 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
614 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
616 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
621 static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
623 struct nlattr *nested_attr;
625 nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
628 if (devlink_nl_put_handle(msg, devlink))
629 goto nla_put_failure;
631 nla_nest_end(msg, nested_attr);
635 nla_nest_cancel(msg, nested_attr);
639 int devlink_nl_port_handle_fill(struct sk_buff *msg, struct devlink_port *devlink_port)
641 if (devlink_nl_put_handle(msg, devlink_port->devlink))
643 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
648 size_t devlink_nl_port_handle_size(struct devlink_port *devlink_port)
650 struct devlink *devlink = devlink_port->devlink;
652 return nla_total_size(strlen(devlink->dev->bus->name) + 1) /* DEVLINK_ATTR_BUS_NAME */
653 + nla_total_size(strlen(dev_name(devlink->dev)) + 1) /* DEVLINK_ATTR_DEV_NAME */
654 + nla_total_size(4); /* DEVLINK_ATTR_PORT_INDEX */
657 struct devlink_reload_combination {
658 enum devlink_reload_action action;
659 enum devlink_reload_limit limit;
662 static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
664 /* can't reinitialize driver with no down time */
665 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
666 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
671 devlink_reload_combination_is_invalid(enum devlink_reload_action action,
672 enum devlink_reload_limit limit)
676 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
677 if (devlink_reload_invalid_combinations[i].action == action &&
678 devlink_reload_invalid_combinations[i].limit == limit)
684 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
686 return test_bit(action, &devlink->ops->reload_actions);
690 devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
692 return test_bit(limit, &devlink->ops->reload_limits);
695 static int devlink_reload_stat_put(struct sk_buff *msg,
696 enum devlink_reload_limit limit, u32 value)
698 struct nlattr *reload_stats_entry;
700 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
701 if (!reload_stats_entry)
704 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
705 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
706 goto nla_put_failure;
707 nla_nest_end(msg, reload_stats_entry);
711 nla_nest_cancel(msg, reload_stats_entry);
715 static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
717 struct nlattr *reload_stats_attr, *act_info, *act_stats;
722 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
724 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
726 if (!reload_stats_attr)
729 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
731 !devlink_reload_action_is_supported(devlink, i)) ||
732 i == DEVLINK_RELOAD_ACTION_UNSPEC)
734 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
736 goto nla_put_failure;
738 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
739 goto action_info_nest_cancel;
740 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
742 goto action_info_nest_cancel;
744 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
745 /* Remote stats are shown even if not locally supported.
746 * Stats of actions with unspecified limit are shown
747 * though drivers don't need to register unspecified
750 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
751 !devlink_reload_limit_is_supported(devlink, j)) ||
752 devlink_reload_combination_is_invalid(i, j))
755 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
757 value = devlink->stats.reload_stats[stat_idx];
759 value = devlink->stats.remote_reload_stats[stat_idx];
760 if (devlink_reload_stat_put(msg, j, value))
761 goto action_stats_nest_cancel;
763 nla_nest_end(msg, act_stats);
764 nla_nest_end(msg, act_info);
766 nla_nest_end(msg, reload_stats_attr);
769 action_stats_nest_cancel:
770 nla_nest_cancel(msg, act_stats);
771 action_info_nest_cancel:
772 nla_nest_cancel(msg, act_info);
774 nla_nest_cancel(msg, reload_stats_attr);
778 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
779 enum devlink_command cmd, u32 portid,
782 struct nlattr *dev_stats;
785 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
789 if (devlink_nl_put_handle(msg, devlink))
790 goto nla_put_failure;
791 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
792 goto nla_put_failure;
794 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
796 goto nla_put_failure;
798 if (devlink_reload_stats_put(msg, devlink, false))
799 goto dev_stats_nest_cancel;
800 if (devlink_reload_stats_put(msg, devlink, true))
801 goto dev_stats_nest_cancel;
803 nla_nest_end(msg, dev_stats);
804 genlmsg_end(msg, hdr);
807 dev_stats_nest_cancel:
808 nla_nest_cancel(msg, dev_stats);
810 genlmsg_cancel(msg, hdr);
814 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
819 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
820 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
822 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
826 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
832 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
833 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
836 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
837 struct devlink_port *devlink_port)
839 struct devlink_port_attrs *attrs = &devlink_port->attrs;
841 if (!devlink_port->attrs_set)
844 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
847 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
849 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
851 switch (devlink_port->attrs.flavour) {
852 case DEVLINK_PORT_FLAVOUR_PCI_PF:
853 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
854 attrs->pci_pf.controller) ||
855 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
857 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
860 case DEVLINK_PORT_FLAVOUR_PCI_VF:
861 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
862 attrs->pci_vf.controller) ||
863 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
864 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
866 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
869 case DEVLINK_PORT_FLAVOUR_PCI_SF:
870 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
871 attrs->pci_sf.controller) ||
872 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
874 nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
878 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
879 case DEVLINK_PORT_FLAVOUR_CPU:
880 case DEVLINK_PORT_FLAVOUR_DSA:
881 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
882 attrs->phys.port_number))
886 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
887 attrs->phys.port_number))
889 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
890 attrs->phys.split_subport_number))
899 static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops,
900 struct devlink_port *port,
902 struct netlink_ext_ack *extack,
905 u8 hw_addr[MAX_ADDR_LEN];
909 if (!ops->port_function_hw_addr_get)
912 err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len,
915 if (err == -EOPNOTSUPP)
919 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
926 static int devlink_nl_rate_fill(struct sk_buff *msg,
927 struct devlink_rate *devlink_rate,
928 enum devlink_command cmd, u32 portid, u32 seq,
929 int flags, struct netlink_ext_ack *extack)
931 struct devlink *devlink = devlink_rate->devlink;
934 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
938 if (devlink_nl_put_handle(msg, devlink))
939 goto nla_put_failure;
941 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
942 goto nla_put_failure;
944 if (devlink_rate_is_leaf(devlink_rate)) {
945 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
946 devlink_rate->devlink_port->index))
947 goto nla_put_failure;
948 } else if (devlink_rate_is_node(devlink_rate)) {
949 if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
951 goto nla_put_failure;
954 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE,
955 devlink_rate->tx_share, DEVLINK_ATTR_PAD))
956 goto nla_put_failure;
958 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX,
959 devlink_rate->tx_max, DEVLINK_ATTR_PAD))
960 goto nla_put_failure;
962 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
963 devlink_rate->tx_priority))
964 goto nla_put_failure;
966 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT,
967 devlink_rate->tx_weight))
968 goto nla_put_failure;
970 if (devlink_rate->parent)
971 if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
972 devlink_rate->parent->name))
973 goto nla_put_failure;
975 genlmsg_end(msg, hdr);
979 genlmsg_cancel(msg, hdr);
984 devlink_port_fn_state_valid(enum devlink_port_fn_state state)
986 return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
987 state == DEVLINK_PORT_FN_STATE_ACTIVE;
991 devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
993 return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
994 opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
997 static int devlink_port_fn_state_fill(const struct devlink_ops *ops,
998 struct devlink_port *port,
1000 struct netlink_ext_ack *extack,
1003 enum devlink_port_fn_opstate opstate;
1004 enum devlink_port_fn_state state;
1007 if (!ops->port_fn_state_get)
1010 err = ops->port_fn_state_get(port, &state, &opstate, extack);
1012 if (err == -EOPNOTSUPP)
1016 if (!devlink_port_fn_state_valid(state)) {
1018 NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver");
1021 if (!devlink_port_fn_opstate_valid(opstate)) {
1023 NL_SET_ERR_MSG_MOD(extack,
1024 "Invalid operational state read from driver");
1027 if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
1028 nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
1030 *msg_updated = true;
1035 devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable,
1036 struct netlink_ext_ack *extack)
1038 const struct devlink_ops *ops = devlink_port->devlink->ops;
1040 return ops->port_fn_migratable_set(devlink_port, enable, extack);
1044 devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable,
1045 struct netlink_ext_ack *extack)
1047 const struct devlink_ops *ops = devlink_port->devlink->ops;
1049 return ops->port_fn_roce_set(devlink_port, enable, extack);
1052 static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
1053 const struct nlattr *attr,
1054 struct netlink_ext_ack *extack)
1056 struct nla_bitfield32 caps;
1060 caps = nla_get_bitfield32(attr);
1061 caps_value = caps.value & caps.selector;
1062 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE) {
1063 err = devlink_port_fn_roce_set(devlink_port,
1064 caps_value & DEVLINK_PORT_FN_CAP_ROCE,
1069 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
1070 err = devlink_port_fn_mig_set(devlink_port, caps_value &
1071 DEVLINK_PORT_FN_CAP_MIGRATABLE,
1080 devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
1081 struct netlink_ext_ack *extack)
1083 const struct devlink_ops *ops;
1084 struct nlattr *function_attr;
1085 bool msg_updated = false;
1088 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
1092 ops = port->devlink->ops;
1093 err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack,
1097 err = devlink_port_fn_caps_fill(ops, port, msg, extack,
1101 err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated);
1103 if (err || !msg_updated)
1104 nla_nest_cancel(msg, function_attr);
1106 nla_nest_end(msg, function_attr);
1110 static int devlink_nl_port_fill(struct sk_buff *msg,
1111 struct devlink_port *devlink_port,
1112 enum devlink_command cmd, u32 portid, u32 seq,
1113 int flags, struct netlink_ext_ack *extack)
1115 struct devlink *devlink = devlink_port->devlink;
1118 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1122 if (devlink_nl_put_handle(msg, devlink))
1123 goto nla_put_failure;
1124 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1125 goto nla_put_failure;
1127 spin_lock_bh(&devlink_port->type_lock);
1128 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
1129 goto nla_put_failure_type_locked;
1130 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
1131 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
1132 devlink_port->desired_type))
1133 goto nla_put_failure_type_locked;
1134 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
1135 if (devlink_port->type_eth.netdev &&
1136 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
1137 devlink_port->type_eth.ifindex) ||
1138 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
1139 devlink_port->type_eth.ifname)))
1140 goto nla_put_failure_type_locked;
1142 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
1143 struct ib_device *ibdev = devlink_port->type_ib.ibdev;
1146 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
1148 goto nla_put_failure_type_locked;
1150 spin_unlock_bh(&devlink_port->type_lock);
1151 if (devlink_nl_port_attrs_put(msg, devlink_port))
1152 goto nla_put_failure;
1153 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
1154 goto nla_put_failure;
1155 if (devlink_port->linecard &&
1156 nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX,
1157 devlink_port->linecard->index))
1158 goto nla_put_failure;
1160 genlmsg_end(msg, hdr);
1163 nla_put_failure_type_locked:
1164 spin_unlock_bh(&devlink_port->type_lock);
1166 genlmsg_cancel(msg, hdr);
1170 static void devlink_port_notify(struct devlink_port *devlink_port,
1171 enum devlink_command cmd)
1173 struct devlink *devlink = devlink_port->devlink;
1174 struct sk_buff *msg;
1177 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
1179 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1182 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1186 err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
1192 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1193 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1196 static void devlink_rate_notify(struct devlink_rate *devlink_rate,
1197 enum devlink_command cmd)
1199 struct devlink *devlink = devlink_rate->devlink;
1200 struct sk_buff *msg;
1203 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
1205 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1208 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1212 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
1218 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1219 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1223 devlink_nl_cmd_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1224 struct netlink_callback *cb)
1226 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1227 struct devlink_rate *devlink_rate;
1231 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
1232 enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
1233 u32 id = NETLINK_CB(cb->skb).portid;
1235 if (idx < state->idx) {
1239 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
1252 const struct devlink_gen_cmd devl_gen_rate_get = {
1253 .dump_one = devlink_nl_cmd_rate_get_dump_one,
1256 static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
1257 struct genl_info *info)
1259 struct devlink_rate *devlink_rate = info->user_ptr[1];
1260 struct sk_buff *msg;
1263 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1267 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
1268 info->snd_portid, info->snd_seq, 0,
1275 return genlmsg_reply(msg, info);
1279 devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
1280 struct devlink_rate *parent)
1283 if (parent == devlink_rate)
1285 parent = parent->parent;
1290 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
1292 struct devlink *devlink = info->user_ptr[0];
1293 struct sk_buff *msg;
1296 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1300 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1301 info->snd_portid, info->snd_seq, 0);
1307 return genlmsg_reply(msg, info);
1310 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
1311 struct netlink_callback *cb)
1313 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1314 struct devlink *devlink;
1317 devlink_dump_for_each_instance_get(msg, state, devlink) {
1319 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1320 NETLINK_CB(cb->skb).portid,
1321 cb->nlh->nlmsg_seq, NLM_F_MULTI);
1322 devl_unlock(devlink);
1323 devlink_put(devlink);
1332 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
1333 struct genl_info *info)
1335 struct devlink_port *devlink_port = info->user_ptr[1];
1336 struct sk_buff *msg;
1339 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1343 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
1344 info->snd_portid, info->snd_seq, 0,
1351 return genlmsg_reply(msg, info);
1354 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
1355 struct netlink_callback *cb)
1357 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1358 struct devlink *devlink;
1361 devlink_dump_for_each_instance_get(msg, state, devlink) {
1362 struct devlink_port *devlink_port;
1363 unsigned long port_index;
1367 xa_for_each(&devlink->ports, port_index, devlink_port) {
1368 if (idx < state->idx) {
1372 err = devlink_nl_port_fill(msg, devlink_port,
1374 NETLINK_CB(cb->skb).portid,
1376 NLM_F_MULTI, cb->extack);
1378 devl_unlock(devlink);
1379 devlink_put(devlink);
1385 devl_unlock(devlink);
1386 devlink_put(devlink);
1392 static int devlink_port_type_set(struct devlink_port *devlink_port,
1393 enum devlink_port_type port_type)
1398 if (!devlink_port->devlink->ops->port_type_set)
1401 if (port_type == devlink_port->type)
1404 err = devlink_port->devlink->ops->port_type_set(devlink_port,
1409 devlink_port->desired_type = port_type;
1410 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1414 static int devlink_port_function_hw_addr_set(struct devlink_port *port,
1415 const struct nlattr *attr,
1416 struct netlink_ext_ack *extack)
1418 const struct devlink_ops *ops = port->devlink->ops;
1422 hw_addr = nla_data(attr);
1423 hw_addr_len = nla_len(attr);
1424 if (hw_addr_len > MAX_ADDR_LEN) {
1425 NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
1428 if (port->type == DEVLINK_PORT_TYPE_ETH) {
1429 if (hw_addr_len != ETH_ALEN) {
1430 NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
1433 if (!is_unicast_ether_addr(hw_addr)) {
1434 NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
1439 return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len,
1443 static int devlink_port_fn_state_set(struct devlink_port *port,
1444 const struct nlattr *attr,
1445 struct netlink_ext_ack *extack)
1447 enum devlink_port_fn_state state;
1448 const struct devlink_ops *ops;
1450 state = nla_get_u8(attr);
1451 ops = port->devlink->ops;
1452 return ops->port_fn_state_set(port, state, extack);
1455 static int devlink_port_function_validate(struct devlink_port *devlink_port,
1457 struct netlink_ext_ack *extack)
1459 const struct devlink_ops *ops = devlink_port->devlink->ops;
1460 struct nlattr *attr;
1462 if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] &&
1463 !ops->port_function_hw_addr_set) {
1464 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
1465 "Port doesn't support function attributes");
1468 if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) {
1469 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
1470 "Function does not support state setting");
1473 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1475 struct nla_bitfield32 caps;
1477 caps = nla_get_bitfield32(attr);
1478 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE &&
1479 !ops->port_fn_roce_set) {
1480 NL_SET_ERR_MSG_ATTR(extack, attr,
1481 "Port doesn't support RoCE function attribute");
1484 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
1485 if (!ops->port_fn_migratable_set) {
1486 NL_SET_ERR_MSG_ATTR(extack, attr,
1487 "Port doesn't support migratable function attribute");
1490 if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) {
1491 NL_SET_ERR_MSG_ATTR(extack, attr,
1492 "migratable function attribute supported for VFs only");
1500 static int devlink_port_function_set(struct devlink_port *port,
1501 const struct nlattr *attr,
1502 struct netlink_ext_ack *extack)
1504 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
1507 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
1508 devlink_function_nl_policy, extack);
1510 NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
1514 err = devlink_port_function_validate(port, tb, extack);
1518 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
1520 err = devlink_port_function_hw_addr_set(port, attr, extack);
1525 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1527 err = devlink_port_fn_caps_set(port, attr, extack);
1532 /* Keep this as the last function attribute set, so that when
1533 * multiple port function attributes are set along with state,
1534 * Those can be applied first before activating the state.
1536 attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
1538 err = devlink_port_fn_state_set(port, attr, extack);
1541 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
1545 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
1546 struct genl_info *info)
1548 struct devlink_port *devlink_port = info->user_ptr[1];
1551 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
1552 enum devlink_port_type port_type;
1554 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
1555 err = devlink_port_type_set(devlink_port, port_type);
1560 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
1561 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
1562 struct netlink_ext_ack *extack = info->extack;
1564 err = devlink_port_function_set(devlink_port, attr, extack);
1572 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
1573 struct genl_info *info)
1575 struct devlink_port *devlink_port = info->user_ptr[1];
1576 struct devlink *devlink = info->user_ptr[0];
1579 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT))
1581 if (!devlink->ops->port_split)
1584 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
1586 if (!devlink_port->attrs.splittable) {
1587 /* Split ports cannot be split. */
1588 if (devlink_port->attrs.split)
1589 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further");
1591 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
1595 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
1596 NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count");
1600 return devlink->ops->port_split(devlink, devlink_port, count,
1604 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
1605 struct genl_info *info)
1607 struct devlink_port *devlink_port = info->user_ptr[1];
1608 struct devlink *devlink = info->user_ptr[0];
1610 if (!devlink->ops->port_unsplit)
1612 return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
1615 static int devlink_port_new_notify(struct devlink *devlink,
1616 unsigned int port_index,
1617 struct genl_info *info)
1619 struct devlink_port *devlink_port;
1620 struct sk_buff *msg;
1623 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1627 lockdep_assert_held(&devlink->lock);
1628 devlink_port = devlink_port_get_by_index(devlink, port_index);
1629 if (!devlink_port) {
1634 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
1635 info->snd_portid, info->snd_seq, 0, NULL);
1639 return genlmsg_reply(msg, info);
1646 static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
1647 struct genl_info *info)
1649 struct netlink_ext_ack *extack = info->extack;
1650 struct devlink_port_new_attrs new_attrs = {};
1651 struct devlink *devlink = info->user_ptr[0];
1652 unsigned int new_port_index;
1655 if (!devlink->ops->port_new || !devlink->ops->port_del)
1658 if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
1659 !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) {
1660 NL_SET_ERR_MSG_MOD(extack, "Port flavour or PCI PF are not specified");
1663 new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
1665 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
1667 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1668 /* Port index of the new port being created by driver. */
1669 new_attrs.port_index =
1670 nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1671 new_attrs.port_index_valid = true;
1673 if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) {
1674 new_attrs.controller =
1675 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]);
1676 new_attrs.controller_valid = true;
1678 if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
1679 info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) {
1680 new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]);
1681 new_attrs.sfnum_valid = true;
1684 err = devlink->ops->port_new(devlink, &new_attrs, extack,
1689 err = devlink_port_new_notify(devlink, new_port_index, info);
1690 if (err && err != -ENODEV) {
1691 /* Fail to send the response; destroy newly created port. */
1692 devlink->ops->port_del(devlink, new_port_index, extack);
1697 static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
1698 struct genl_info *info)
1700 struct netlink_ext_ack *extack = info->extack;
1701 struct devlink *devlink = info->user_ptr[0];
1702 unsigned int port_index;
1704 if (!devlink->ops->port_del)
1707 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) {
1708 NL_SET_ERR_MSG_MOD(extack, "Port index is not specified");
1711 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1713 return devlink->ops->port_del(devlink, port_index, extack);
1717 devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
1718 struct genl_info *info,
1719 struct nlattr *nla_parent)
1721 struct devlink *devlink = devlink_rate->devlink;
1722 const char *parent_name = nla_data(nla_parent);
1723 const struct devlink_ops *ops = devlink->ops;
1724 size_t len = strlen(parent_name);
1725 struct devlink_rate *parent;
1726 int err = -EOPNOTSUPP;
1728 parent = devlink_rate->parent;
1730 if (parent && !len) {
1731 if (devlink_rate_is_leaf(devlink_rate))
1732 err = ops->rate_leaf_parent_set(devlink_rate, NULL,
1733 devlink_rate->priv, NULL,
1735 else if (devlink_rate_is_node(devlink_rate))
1736 err = ops->rate_node_parent_set(devlink_rate, NULL,
1737 devlink_rate->priv, NULL,
1742 refcount_dec(&parent->refcnt);
1743 devlink_rate->parent = NULL;
1745 parent = devlink_rate_node_get_by_name(devlink, parent_name);
1749 if (parent == devlink_rate) {
1750 NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed");
1754 if (devlink_rate_is_node(devlink_rate) &&
1755 devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
1756 NL_SET_ERR_MSG_MOD(info->extack, "Node is already a parent of parent node.");
1760 if (devlink_rate_is_leaf(devlink_rate))
1761 err = ops->rate_leaf_parent_set(devlink_rate, parent,
1762 devlink_rate->priv, parent->priv,
1764 else if (devlink_rate_is_node(devlink_rate))
1765 err = ops->rate_node_parent_set(devlink_rate, parent,
1766 devlink_rate->priv, parent->priv,
1771 if (devlink_rate->parent)
1772 /* we're reassigning to other parent in this case */
1773 refcount_dec(&devlink_rate->parent->refcnt);
1775 refcount_inc(&parent->refcnt);
1776 devlink_rate->parent = parent;
1782 static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
1783 const struct devlink_ops *ops,
1784 struct genl_info *info)
1786 struct nlattr *nla_parent, **attrs = info->attrs;
1787 int err = -EOPNOTSUPP;
1792 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
1793 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
1794 if (devlink_rate_is_leaf(devlink_rate))
1795 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
1796 rate, info->extack);
1797 else if (devlink_rate_is_node(devlink_rate))
1798 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
1799 rate, info->extack);
1802 devlink_rate->tx_share = rate;
1805 if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
1806 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
1807 if (devlink_rate_is_leaf(devlink_rate))
1808 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
1809 rate, info->extack);
1810 else if (devlink_rate_is_node(devlink_rate))
1811 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
1812 rate, info->extack);
1815 devlink_rate->tx_max = rate;
1818 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) {
1819 priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]);
1820 if (devlink_rate_is_leaf(devlink_rate))
1821 err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv,
1822 priority, info->extack);
1823 else if (devlink_rate_is_node(devlink_rate))
1824 err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv,
1825 priority, info->extack);
1829 devlink_rate->tx_priority = priority;
1832 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) {
1833 weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]);
1834 if (devlink_rate_is_leaf(devlink_rate))
1835 err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv,
1836 weight, info->extack);
1837 else if (devlink_rate_is_node(devlink_rate))
1838 err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv,
1839 weight, info->extack);
1843 devlink_rate->tx_weight = weight;
1846 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
1848 err = devlink_nl_rate_parent_node_set(devlink_rate, info,
1857 static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
1858 struct genl_info *info,
1859 enum devlink_rate_type type)
1861 struct nlattr **attrs = info->attrs;
1863 if (type == DEVLINK_RATE_TYPE_LEAF) {
1864 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
1865 NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the leafs");
1868 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
1869 NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the leafs");
1872 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1873 !ops->rate_leaf_parent_set) {
1874 NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs");
1877 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) {
1878 NL_SET_ERR_MSG_ATTR(info->extack,
1879 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
1880 "TX priority set isn't supported for the leafs");
1883 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) {
1884 NL_SET_ERR_MSG_ATTR(info->extack,
1885 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
1886 "TX weight set isn't supported for the leafs");
1889 } else if (type == DEVLINK_RATE_TYPE_NODE) {
1890 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
1891 NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes");
1894 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
1895 NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the nodes");
1898 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1899 !ops->rate_node_parent_set) {
1900 NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes");
1903 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) {
1904 NL_SET_ERR_MSG_ATTR(info->extack,
1905 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
1906 "TX priority set isn't supported for the nodes");
1909 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) {
1910 NL_SET_ERR_MSG_ATTR(info->extack,
1911 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
1912 "TX weight set isn't supported for the nodes");
1916 WARN(1, "Unknown type of rate object");
1923 static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
1924 struct genl_info *info)
1926 struct devlink_rate *devlink_rate = info->user_ptr[1];
1927 struct devlink *devlink = devlink_rate->devlink;
1928 const struct devlink_ops *ops = devlink->ops;
1931 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
1934 err = devlink_nl_rate_set(devlink_rate, ops, info);
1937 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
1941 static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
1942 struct genl_info *info)
1944 struct devlink *devlink = info->user_ptr[0];
1945 struct devlink_rate *rate_node;
1946 const struct devlink_ops *ops;
1950 if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
1951 NL_SET_ERR_MSG_MOD(info->extack, "Rate nodes aren't supported");
1955 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
1958 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
1959 if (!IS_ERR(rate_node))
1961 else if (rate_node == ERR_PTR(-EINVAL))
1964 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
1968 rate_node->devlink = devlink;
1969 rate_node->type = DEVLINK_RATE_TYPE_NODE;
1970 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
1971 if (!rate_node->name) {
1976 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
1980 err = devlink_nl_rate_set(rate_node, ops, info);
1984 refcount_set(&rate_node->refcnt, 1);
1985 list_add(&rate_node->list, &devlink->rate_list);
1986 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
1990 ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1992 kfree(rate_node->name);
1998 static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
1999 struct genl_info *info)
2001 struct devlink_rate *rate_node = info->user_ptr[1];
2002 struct devlink *devlink = rate_node->devlink;
2003 const struct devlink_ops *ops = devlink->ops;
2006 if (refcount_read(&rate_node->refcnt) > 1) {
2007 NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node.");
2011 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
2012 err = ops->rate_node_del(rate_node, rate_node->priv, info->extack);
2013 if (rate_node->parent)
2014 refcount_dec(&rate_node->parent->refcnt);
2015 list_del(&rate_node->list);
2016 kfree(rate_node->name);
2021 struct devlink_linecard_type {
2026 static int devlink_nl_linecard_fill(struct sk_buff *msg,
2027 struct devlink *devlink,
2028 struct devlink_linecard *linecard,
2029 enum devlink_command cmd, u32 portid,
2031 struct netlink_ext_ack *extack)
2033 struct devlink_linecard_type *linecard_type;
2034 struct nlattr *attr;
2038 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2042 if (devlink_nl_put_handle(msg, devlink))
2043 goto nla_put_failure;
2044 if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
2045 goto nla_put_failure;
2046 if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state))
2047 goto nla_put_failure;
2048 if (linecard->type &&
2049 nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type))
2050 goto nla_put_failure;
2052 if (linecard->types_count) {
2053 attr = nla_nest_start(msg,
2054 DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
2056 goto nla_put_failure;
2057 for (i = 0; i < linecard->types_count; i++) {
2058 linecard_type = &linecard->types[i];
2059 if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE,
2060 linecard_type->type)) {
2061 nla_nest_cancel(msg, attr);
2062 goto nla_put_failure;
2065 nla_nest_end(msg, attr);
2068 if (linecard->nested_devlink &&
2069 devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
2070 goto nla_put_failure;
2072 genlmsg_end(msg, hdr);
2076 genlmsg_cancel(msg, hdr);
2080 static void devlink_linecard_notify(struct devlink_linecard *linecard,
2081 enum devlink_command cmd)
2083 struct devlink *devlink = linecard->devlink;
2084 struct sk_buff *msg;
2087 WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
2088 cmd != DEVLINK_CMD_LINECARD_DEL);
2090 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
2093 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2097 err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
2104 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2105 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2108 static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
2109 struct genl_info *info)
2111 struct devlink_linecard *linecard = info->user_ptr[1];
2112 struct devlink *devlink = linecard->devlink;
2113 struct sk_buff *msg;
2116 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2120 mutex_lock(&linecard->state_lock);
2121 err = devlink_nl_linecard_fill(msg, devlink, linecard,
2122 DEVLINK_CMD_LINECARD_NEW,
2123 info->snd_portid, info->snd_seq, 0,
2125 mutex_unlock(&linecard->state_lock);
2131 return genlmsg_reply(msg, info);
2134 static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg,
2135 struct netlink_callback *cb)
2137 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2138 struct devlink_linecard *linecard;
2139 struct devlink *devlink;
2142 devlink_dump_for_each_instance_get(msg, state, devlink) {
2145 mutex_lock(&devlink->linecards_lock);
2146 list_for_each_entry(linecard, &devlink->linecard_list, list) {
2147 if (idx < state->idx) {
2151 mutex_lock(&linecard->state_lock);
2152 err = devlink_nl_linecard_fill(msg, devlink, linecard,
2153 DEVLINK_CMD_LINECARD_NEW,
2154 NETLINK_CB(cb->skb).portid,
2158 mutex_unlock(&linecard->state_lock);
2160 mutex_unlock(&devlink->linecards_lock);
2161 devlink_put(devlink);
2167 mutex_unlock(&devlink->linecards_lock);
2168 devlink_put(devlink);
2174 static struct devlink_linecard_type *
2175 devlink_linecard_type_lookup(struct devlink_linecard *linecard,
2178 struct devlink_linecard_type *linecard_type;
2181 for (i = 0; i < linecard->types_count; i++) {
2182 linecard_type = &linecard->types[i];
2183 if (!strcmp(type, linecard_type->type))
2184 return linecard_type;
2189 static int devlink_linecard_type_set(struct devlink_linecard *linecard,
2191 struct netlink_ext_ack *extack)
2193 const struct devlink_linecard_ops *ops = linecard->ops;
2194 struct devlink_linecard_type *linecard_type;
2197 mutex_lock(&linecard->state_lock);
2198 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2199 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
2203 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2204 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2209 linecard_type = devlink_linecard_type_lookup(linecard, type);
2210 if (!linecard_type) {
2211 NL_SET_ERR_MSG_MOD(extack, "Unsupported line card type provided");
2216 if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED &&
2217 linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2218 NL_SET_ERR_MSG_MOD(extack, "Line card already provisioned");
2220 /* Check if the line card is provisioned in the same
2221 * way the user asks. In case it is, make the operation
2222 * to return success.
2224 if (ops->same_provision &&
2225 ops->same_provision(linecard, linecard->priv,
2226 linecard_type->type,
2227 linecard_type->priv))
2232 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING;
2233 linecard->type = linecard_type->type;
2234 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2235 mutex_unlock(&linecard->state_lock);
2236 err = ops->provision(linecard, linecard->priv, linecard_type->type,
2237 linecard_type->priv, extack);
2239 /* Provisioning failed. Assume the linecard is unprovisioned
2240 * for future operations.
2242 mutex_lock(&linecard->state_lock);
2243 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2244 linecard->type = NULL;
2245 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2246 mutex_unlock(&linecard->state_lock);
2251 mutex_unlock(&linecard->state_lock);
2255 static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
2256 struct netlink_ext_ack *extack)
2260 mutex_lock(&linecard->state_lock);
2261 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2262 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
2266 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2267 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2271 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2272 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2273 linecard->type = NULL;
2274 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2279 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) {
2280 NL_SET_ERR_MSG_MOD(extack, "Line card is not provisioned");
2284 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING;
2285 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2286 mutex_unlock(&linecard->state_lock);
2287 err = linecard->ops->unprovision(linecard, linecard->priv,
2290 /* Unprovisioning failed. Assume the linecard is unprovisioned
2291 * for future operations.
2293 mutex_lock(&linecard->state_lock);
2294 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2295 linecard->type = NULL;
2296 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2297 mutex_unlock(&linecard->state_lock);
2302 mutex_unlock(&linecard->state_lock);
2306 static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
2307 struct genl_info *info)
2309 struct devlink_linecard *linecard = info->user_ptr[1];
2310 struct netlink_ext_ack *extack = info->extack;
2313 if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
2316 type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
2317 if (strcmp(type, "")) {
2318 err = devlink_linecard_type_set(linecard, type, extack);
2322 err = devlink_linecard_type_unset(linecard, extack);
2331 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
2332 struct devlink_sb *devlink_sb,
2333 enum devlink_command cmd, u32 portid,
2338 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2342 if (devlink_nl_put_handle(msg, devlink))
2343 goto nla_put_failure;
2344 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2345 goto nla_put_failure;
2346 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
2347 goto nla_put_failure;
2348 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
2349 devlink_sb->ingress_pools_count))
2350 goto nla_put_failure;
2351 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
2352 devlink_sb->egress_pools_count))
2353 goto nla_put_failure;
2354 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
2355 devlink_sb->ingress_tc_count))
2356 goto nla_put_failure;
2357 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
2358 devlink_sb->egress_tc_count))
2359 goto nla_put_failure;
2361 genlmsg_end(msg, hdr);
2365 genlmsg_cancel(msg, hdr);
2369 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
2370 struct genl_info *info)
2372 struct devlink *devlink = info->user_ptr[0];
2373 struct devlink_sb *devlink_sb;
2374 struct sk_buff *msg;
2377 devlink_sb = devlink_sb_get_from_info(devlink, info);
2378 if (IS_ERR(devlink_sb))
2379 return PTR_ERR(devlink_sb);
2381 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2385 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2387 info->snd_portid, info->snd_seq, 0);
2393 return genlmsg_reply(msg, info);
2396 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
2397 struct netlink_callback *cb)
2399 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2400 struct devlink *devlink;
2403 devlink_dump_for_each_instance_get(msg, state, devlink) {
2404 struct devlink_sb *devlink_sb;
2408 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2409 if (idx < state->idx) {
2413 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2415 NETLINK_CB(cb->skb).portid,
2419 devl_unlock(devlink);
2420 devlink_put(devlink);
2426 devl_unlock(devlink);
2427 devlink_put(devlink);
2433 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
2434 struct devlink_sb *devlink_sb,
2435 u16 pool_index, enum devlink_command cmd,
2436 u32 portid, u32 seq, int flags)
2438 struct devlink_sb_pool_info pool_info;
2442 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
2443 pool_index, &pool_info);
2447 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2451 if (devlink_nl_put_handle(msg, devlink))
2452 goto nla_put_failure;
2453 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2454 goto nla_put_failure;
2455 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2456 goto nla_put_failure;
2457 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
2458 goto nla_put_failure;
2459 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
2460 goto nla_put_failure;
2461 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
2462 pool_info.threshold_type))
2463 goto nla_put_failure;
2464 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
2465 pool_info.cell_size))
2466 goto nla_put_failure;
2468 genlmsg_end(msg, hdr);
2472 genlmsg_cancel(msg, hdr);
2476 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
2477 struct genl_info *info)
2479 struct devlink *devlink = info->user_ptr[0];
2480 struct devlink_sb *devlink_sb;
2481 struct sk_buff *msg;
2485 devlink_sb = devlink_sb_get_from_info(devlink, info);
2486 if (IS_ERR(devlink_sb))
2487 return PTR_ERR(devlink_sb);
2489 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2494 if (!devlink->ops->sb_pool_get)
2497 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2501 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
2502 DEVLINK_CMD_SB_POOL_NEW,
2503 info->snd_portid, info->snd_seq, 0);
2509 return genlmsg_reply(msg, info);
2512 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2513 struct devlink *devlink,
2514 struct devlink_sb *devlink_sb,
2515 u32 portid, u32 seq)
2517 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2521 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2522 if (*p_idx < start) {
2526 err = devlink_nl_sb_pool_fill(msg, devlink,
2529 DEVLINK_CMD_SB_POOL_NEW,
2530 portid, seq, NLM_F_MULTI);
2538 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
2539 struct netlink_callback *cb)
2541 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2542 struct devlink *devlink;
2545 devlink_dump_for_each_instance_get(msg, state, devlink) {
2546 struct devlink_sb *devlink_sb;
2549 if (!devlink->ops->sb_pool_get)
2553 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2554 err = __sb_pool_get_dumpit(msg, state->idx, &idx,
2555 devlink, devlink_sb,
2556 NETLINK_CB(cb->skb).portid,
2557 cb->nlh->nlmsg_seq);
2558 if (err == -EOPNOTSUPP) {
2561 devl_unlock(devlink);
2562 devlink_put(devlink);
2567 devl_unlock(devlink);
2569 devlink_put(devlink);
2572 if (err != -EMSGSIZE)
2578 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
2579 u16 pool_index, u32 size,
2580 enum devlink_sb_threshold_type threshold_type,
2581 struct netlink_ext_ack *extack)
2584 const struct devlink_ops *ops = devlink->ops;
2586 if (ops->sb_pool_set)
2587 return ops->sb_pool_set(devlink, sb_index, pool_index,
2588 size, threshold_type, extack);
2592 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
2593 struct genl_info *info)
2595 struct devlink *devlink = info->user_ptr[0];
2596 enum devlink_sb_threshold_type threshold_type;
2597 struct devlink_sb *devlink_sb;
2602 devlink_sb = devlink_sb_get_from_info(devlink, info);
2603 if (IS_ERR(devlink_sb))
2604 return PTR_ERR(devlink_sb);
2606 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2611 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
2615 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE))
2618 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
2619 return devlink_sb_pool_set(devlink, devlink_sb->index,
2620 pool_index, size, threshold_type,
2624 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
2625 struct devlink *devlink,
2626 struct devlink_port *devlink_port,
2627 struct devlink_sb *devlink_sb,
2629 enum devlink_command cmd,
2630 u32 portid, u32 seq, int flags)
2632 const struct devlink_ops *ops = devlink->ops;
2637 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
2638 pool_index, &threshold);
2642 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2646 if (devlink_nl_put_handle(msg, devlink))
2647 goto nla_put_failure;
2648 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2649 goto nla_put_failure;
2650 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2651 goto nla_put_failure;
2652 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2653 goto nla_put_failure;
2654 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2655 goto nla_put_failure;
2657 if (ops->sb_occ_port_pool_get) {
2661 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
2662 pool_index, &cur, &max);
2663 if (err && err != -EOPNOTSUPP)
2664 goto sb_occ_get_failure;
2666 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2667 goto nla_put_failure;
2668 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2669 goto nla_put_failure;
2673 genlmsg_end(msg, hdr);
2679 genlmsg_cancel(msg, hdr);
2683 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
2684 struct genl_info *info)
2686 struct devlink_port *devlink_port = info->user_ptr[1];
2687 struct devlink *devlink = devlink_port->devlink;
2688 struct devlink_sb *devlink_sb;
2689 struct sk_buff *msg;
2693 devlink_sb = devlink_sb_get_from_info(devlink, info);
2694 if (IS_ERR(devlink_sb))
2695 return PTR_ERR(devlink_sb);
2697 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2702 if (!devlink->ops->sb_port_pool_get)
2705 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2709 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
2710 devlink_sb, pool_index,
2711 DEVLINK_CMD_SB_PORT_POOL_NEW,
2712 info->snd_portid, info->snd_seq, 0);
2718 return genlmsg_reply(msg, info);
2721 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2722 struct devlink *devlink,
2723 struct devlink_sb *devlink_sb,
2724 u32 portid, u32 seq)
2726 struct devlink_port *devlink_port;
2727 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2728 unsigned long port_index;
2732 xa_for_each(&devlink->ports, port_index, devlink_port) {
2733 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2734 if (*p_idx < start) {
2738 err = devlink_nl_sb_port_pool_fill(msg, devlink,
2742 DEVLINK_CMD_SB_PORT_POOL_NEW,
2753 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
2754 struct netlink_callback *cb)
2756 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2757 struct devlink *devlink;
2760 devlink_dump_for_each_instance_get(msg, state, devlink) {
2761 struct devlink_sb *devlink_sb;
2764 if (!devlink->ops->sb_port_pool_get)
2768 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2769 err = __sb_port_pool_get_dumpit(msg, state->idx, &idx,
2770 devlink, devlink_sb,
2771 NETLINK_CB(cb->skb).portid,
2772 cb->nlh->nlmsg_seq);
2773 if (err == -EOPNOTSUPP) {
2776 devl_unlock(devlink);
2777 devlink_put(devlink);
2782 devl_unlock(devlink);
2784 devlink_put(devlink);
2787 if (err != -EMSGSIZE)
2793 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
2794 unsigned int sb_index, u16 pool_index,
2796 struct netlink_ext_ack *extack)
2799 const struct devlink_ops *ops = devlink_port->devlink->ops;
2801 if (ops->sb_port_pool_set)
2802 return ops->sb_port_pool_set(devlink_port, sb_index,
2803 pool_index, threshold, extack);
2807 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
2808 struct genl_info *info)
2810 struct devlink_port *devlink_port = info->user_ptr[1];
2811 struct devlink *devlink = info->user_ptr[0];
2812 struct devlink_sb *devlink_sb;
2817 devlink_sb = devlink_sb_get_from_info(devlink, info);
2818 if (IS_ERR(devlink_sb))
2819 return PTR_ERR(devlink_sb);
2821 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2826 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
2829 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
2830 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
2831 pool_index, threshold, info->extack);
2835 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
2836 struct devlink_port *devlink_port,
2837 struct devlink_sb *devlink_sb, u16 tc_index,
2838 enum devlink_sb_pool_type pool_type,
2839 enum devlink_command cmd,
2840 u32 portid, u32 seq, int flags)
2842 const struct devlink_ops *ops = devlink->ops;
2848 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
2849 tc_index, pool_type,
2850 &pool_index, &threshold);
2854 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2858 if (devlink_nl_put_handle(msg, devlink))
2859 goto nla_put_failure;
2860 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2861 goto nla_put_failure;
2862 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2863 goto nla_put_failure;
2864 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
2865 goto nla_put_failure;
2866 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
2867 goto nla_put_failure;
2868 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2869 goto nla_put_failure;
2870 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2871 goto nla_put_failure;
2873 if (ops->sb_occ_tc_port_bind_get) {
2877 err = ops->sb_occ_tc_port_bind_get(devlink_port,
2879 tc_index, pool_type,
2881 if (err && err != -EOPNOTSUPP)
2884 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2885 goto nla_put_failure;
2886 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2887 goto nla_put_failure;
2891 genlmsg_end(msg, hdr);
2895 genlmsg_cancel(msg, hdr);
2899 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
2900 struct genl_info *info)
2902 struct devlink_port *devlink_port = info->user_ptr[1];
2903 struct devlink *devlink = devlink_port->devlink;
2904 struct devlink_sb *devlink_sb;
2905 struct sk_buff *msg;
2906 enum devlink_sb_pool_type pool_type;
2910 devlink_sb = devlink_sb_get_from_info(devlink, info);
2911 if (IS_ERR(devlink_sb))
2912 return PTR_ERR(devlink_sb);
2914 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
2918 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
2919 pool_type, &tc_index);
2923 if (!devlink->ops->sb_tc_pool_bind_get)
2926 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2930 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
2931 devlink_sb, tc_index, pool_type,
2932 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2940 return genlmsg_reply(msg, info);
2943 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
2944 int start, int *p_idx,
2945 struct devlink *devlink,
2946 struct devlink_sb *devlink_sb,
2947 u32 portid, u32 seq)
2949 struct devlink_port *devlink_port;
2950 unsigned long port_index;
2954 xa_for_each(&devlink->ports, port_index, devlink_port) {
2956 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
2957 if (*p_idx < start) {
2961 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2965 DEVLINK_SB_POOL_TYPE_INGRESS,
2966 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2974 tc_index < devlink_sb->egress_tc_count; tc_index++) {
2975 if (*p_idx < start) {
2979 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2983 DEVLINK_SB_POOL_TYPE_EGRESS,
2984 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2996 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
2997 struct netlink_callback *cb)
2999 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
3000 struct devlink *devlink;
3003 devlink_dump_for_each_instance_get(msg, state, devlink) {
3004 struct devlink_sb *devlink_sb;
3007 if (!devlink->ops->sb_tc_pool_bind_get)
3011 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
3012 err = __sb_tc_pool_bind_get_dumpit(msg, state->idx, &idx,
3013 devlink, devlink_sb,
3014 NETLINK_CB(cb->skb).portid,
3015 cb->nlh->nlmsg_seq);
3016 if (err == -EOPNOTSUPP) {
3019 devl_unlock(devlink);
3020 devlink_put(devlink);
3025 devl_unlock(devlink);
3027 devlink_put(devlink);
3030 if (err != -EMSGSIZE)
3036 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
3037 unsigned int sb_index, u16 tc_index,
3038 enum devlink_sb_pool_type pool_type,
3039 u16 pool_index, u32 threshold,
3040 struct netlink_ext_ack *extack)
3043 const struct devlink_ops *ops = devlink_port->devlink->ops;
3045 if (ops->sb_tc_pool_bind_set)
3046 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
3047 tc_index, pool_type,
3048 pool_index, threshold, extack);
3052 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
3053 struct genl_info *info)
3055 struct devlink_port *devlink_port = info->user_ptr[1];
3056 struct devlink *devlink = info->user_ptr[0];
3057 enum devlink_sb_pool_type pool_type;
3058 struct devlink_sb *devlink_sb;
3064 devlink_sb = devlink_sb_get_from_info(devlink, info);
3065 if (IS_ERR(devlink_sb))
3066 return PTR_ERR(devlink_sb);
3068 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
3072 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
3073 pool_type, &tc_index);
3077 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
3082 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
3085 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
3086 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
3087 tc_index, pool_type,
3088 pool_index, threshold, info->extack);
3091 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
3092 struct genl_info *info)
3094 struct devlink *devlink = info->user_ptr[0];
3095 const struct devlink_ops *ops = devlink->ops;
3096 struct devlink_sb *devlink_sb;
3098 devlink_sb = devlink_sb_get_from_info(devlink, info);
3099 if (IS_ERR(devlink_sb))
3100 return PTR_ERR(devlink_sb);
3102 if (ops->sb_occ_snapshot)
3103 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
3107 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
3108 struct genl_info *info)
3110 struct devlink *devlink = info->user_ptr[0];
3111 const struct devlink_ops *ops = devlink->ops;
3112 struct devlink_sb *devlink_sb;
3114 devlink_sb = devlink_sb_get_from_info(devlink, info);
3115 if (IS_ERR(devlink_sb))
3116 return PTR_ERR(devlink_sb);
3118 if (ops->sb_occ_max_clear)
3119 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
3123 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
3124 enum devlink_command cmd, u32 portid,
3127 const struct devlink_ops *ops = devlink->ops;
3128 enum devlink_eswitch_encap_mode encap_mode;
3134 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3138 err = devlink_nl_put_handle(msg, devlink);
3140 goto nla_put_failure;
3142 if (ops->eswitch_mode_get) {
3143 err = ops->eswitch_mode_get(devlink, &mode);
3145 goto nla_put_failure;
3146 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
3148 goto nla_put_failure;
3151 if (ops->eswitch_inline_mode_get) {
3152 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
3154 goto nla_put_failure;
3155 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
3158 goto nla_put_failure;
3161 if (ops->eswitch_encap_mode_get) {
3162 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
3164 goto nla_put_failure;
3165 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
3167 goto nla_put_failure;
3170 genlmsg_end(msg, hdr);
3174 genlmsg_cancel(msg, hdr);
3178 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
3179 struct genl_info *info)
3181 struct devlink *devlink = info->user_ptr[0];
3182 struct sk_buff *msg;
3185 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3189 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
3190 info->snd_portid, info->snd_seq, 0);
3197 return genlmsg_reply(msg, info);
3200 static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
3201 struct netlink_ext_ack *extack)
3203 struct devlink_rate *devlink_rate;
3205 list_for_each_entry(devlink_rate, &devlink->rate_list, list)
3206 if (devlink_rate_is_node(devlink_rate)) {
3207 NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists.");
3213 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
3214 struct genl_info *info)
3216 struct devlink *devlink = info->user_ptr[0];
3217 const struct devlink_ops *ops = devlink->ops;
3218 enum devlink_eswitch_encap_mode encap_mode;
3223 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
3224 if (!ops->eswitch_mode_set)
3226 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
3227 err = devlink_rate_nodes_check(devlink, mode, info->extack);
3230 err = ops->eswitch_mode_set(devlink, mode, info->extack);
3235 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
3236 if (!ops->eswitch_inline_mode_set)
3238 inline_mode = nla_get_u8(
3239 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
3240 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
3246 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
3247 if (!ops->eswitch_encap_mode_set)
3249 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
3250 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
3259 int devlink_dpipe_match_put(struct sk_buff *skb,
3260 struct devlink_dpipe_match *match)
3262 struct devlink_dpipe_header *header = match->header;
3263 struct devlink_dpipe_field *field = &header->fields[match->field_id];
3264 struct nlattr *match_attr;
3266 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
3270 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
3271 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
3272 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3273 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3274 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3275 goto nla_put_failure;
3277 nla_nest_end(skb, match_attr);
3281 nla_nest_cancel(skb, match_attr);
3284 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
3286 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
3287 struct sk_buff *skb)
3289 struct nlattr *matches_attr;
3291 matches_attr = nla_nest_start_noflag(skb,
3292 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
3296 if (table->table_ops->matches_dump(table->priv, skb))
3297 goto nla_put_failure;
3299 nla_nest_end(skb, matches_attr);
3303 nla_nest_cancel(skb, matches_attr);
3307 int devlink_dpipe_action_put(struct sk_buff *skb,
3308 struct devlink_dpipe_action *action)
3310 struct devlink_dpipe_header *header = action->header;
3311 struct devlink_dpipe_field *field = &header->fields[action->field_id];
3312 struct nlattr *action_attr;
3314 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
3318 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
3319 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
3320 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3321 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3322 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3323 goto nla_put_failure;
3325 nla_nest_end(skb, action_attr);
3329 nla_nest_cancel(skb, action_attr);
3332 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
3334 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
3335 struct sk_buff *skb)
3337 struct nlattr *actions_attr;
3339 actions_attr = nla_nest_start_noflag(skb,
3340 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
3344 if (table->table_ops->actions_dump(table->priv, skb))
3345 goto nla_put_failure;
3347 nla_nest_end(skb, actions_attr);
3351 nla_nest_cancel(skb, actions_attr);
3355 static int devlink_dpipe_table_put(struct sk_buff *skb,
3356 struct devlink_dpipe_table *table)
3358 struct nlattr *table_attr;
3361 table_size = table->table_ops->size_get(table->priv);
3362 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
3366 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
3367 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
3369 goto nla_put_failure;
3370 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
3371 table->counters_enabled))
3372 goto nla_put_failure;
3374 if (table->resource_valid) {
3375 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
3376 table->resource_id, DEVLINK_ATTR_PAD) ||
3377 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
3378 table->resource_units, DEVLINK_ATTR_PAD))
3379 goto nla_put_failure;
3381 if (devlink_dpipe_matches_put(table, skb))
3382 goto nla_put_failure;
3384 if (devlink_dpipe_actions_put(table, skb))
3385 goto nla_put_failure;
3387 nla_nest_end(skb, table_attr);
3391 nla_nest_cancel(skb, table_attr);
3395 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
3396 struct genl_info *info)
3401 err = genlmsg_reply(*pskb, info);
3405 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
3411 static int devlink_dpipe_tables_fill(struct genl_info *info,
3412 enum devlink_command cmd, int flags,
3413 struct list_head *dpipe_tables,
3414 const char *table_name)
3416 struct devlink *devlink = info->user_ptr[0];
3417 struct devlink_dpipe_table *table;
3418 struct nlattr *tables_attr;
3419 struct sk_buff *skb = NULL;
3420 struct nlmsghdr *nlh;
3426 table = list_first_entry(dpipe_tables,
3427 struct devlink_dpipe_table, list);
3429 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3433 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3434 &devlink_nl_family, NLM_F_MULTI, cmd);
3440 if (devlink_nl_put_handle(skb, devlink))
3441 goto nla_put_failure;
3442 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
3444 goto nla_put_failure;
3448 list_for_each_entry_from(table, dpipe_tables, list) {
3450 err = devlink_dpipe_table_put(skb, table);
3458 if (!strcmp(table->name, table_name)) {
3459 err = devlink_dpipe_table_put(skb, table);
3467 nla_nest_end(skb, tables_attr);
3468 genlmsg_end(skb, hdr);
3473 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3474 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3476 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3482 return genlmsg_reply(skb, info);
3491 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
3492 struct genl_info *info)
3494 struct devlink *devlink = info->user_ptr[0];
3495 const char *table_name = NULL;
3497 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
3498 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3500 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
3501 &devlink->dpipe_table_list,
3505 static int devlink_dpipe_value_put(struct sk_buff *skb,
3506 struct devlink_dpipe_value *value)
3508 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
3509 value->value_size, value->value))
3512 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
3513 value->value_size, value->mask))
3515 if (value->mapping_valid)
3516 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
3517 value->mapping_value))
3522 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
3523 struct devlink_dpipe_value *value)
3527 if (devlink_dpipe_action_put(skb, value->action))
3529 if (devlink_dpipe_value_put(skb, value))
3534 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
3535 struct devlink_dpipe_value *values,
3536 unsigned int values_count)
3538 struct nlattr *action_attr;
3542 for (i = 0; i < values_count; i++) {
3543 action_attr = nla_nest_start_noflag(skb,
3544 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
3547 err = devlink_dpipe_action_value_put(skb, &values[i]);
3549 goto err_action_value_put;
3550 nla_nest_end(skb, action_attr);
3554 err_action_value_put:
3555 nla_nest_cancel(skb, action_attr);
3559 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
3560 struct devlink_dpipe_value *value)
3564 if (devlink_dpipe_match_put(skb, value->match))
3566 if (devlink_dpipe_value_put(skb, value))
3571 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
3572 struct devlink_dpipe_value *values,
3573 unsigned int values_count)
3575 struct nlattr *match_attr;
3579 for (i = 0; i < values_count; i++) {
3580 match_attr = nla_nest_start_noflag(skb,
3581 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
3584 err = devlink_dpipe_match_value_put(skb, &values[i]);
3586 goto err_match_value_put;
3587 nla_nest_end(skb, match_attr);
3591 err_match_value_put:
3592 nla_nest_cancel(skb, match_attr);
3596 static int devlink_dpipe_entry_put(struct sk_buff *skb,
3597 struct devlink_dpipe_entry *entry)
3599 struct nlattr *entry_attr, *matches_attr, *actions_attr;
3602 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
3606 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
3608 goto nla_put_failure;
3609 if (entry->counter_valid)
3610 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
3611 entry->counter, DEVLINK_ATTR_PAD))
3612 goto nla_put_failure;
3614 matches_attr = nla_nest_start_noflag(skb,
3615 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
3617 goto nla_put_failure;
3619 err = devlink_dpipe_match_values_put(skb, entry->match_values,
3620 entry->match_values_count);
3622 nla_nest_cancel(skb, matches_attr);
3623 goto err_match_values_put;
3625 nla_nest_end(skb, matches_attr);
3627 actions_attr = nla_nest_start_noflag(skb,
3628 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
3630 goto nla_put_failure;
3632 err = devlink_dpipe_action_values_put(skb, entry->action_values,
3633 entry->action_values_count);
3635 nla_nest_cancel(skb, actions_attr);
3636 goto err_action_values_put;
3638 nla_nest_end(skb, actions_attr);
3640 nla_nest_end(skb, entry_attr);
3645 err_match_values_put:
3646 err_action_values_put:
3647 nla_nest_cancel(skb, entry_attr);
3651 static struct devlink_dpipe_table *
3652 devlink_dpipe_table_find(struct list_head *dpipe_tables,
3653 const char *table_name, struct devlink *devlink)
3655 struct devlink_dpipe_table *table;
3656 list_for_each_entry_rcu(table, dpipe_tables, list,
3657 lockdep_is_held(&devlink->lock)) {
3658 if (!strcmp(table->name, table_name))
3664 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
3666 struct devlink *devlink;
3669 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
3674 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
3675 dump_ctx->info->snd_portid,
3676 dump_ctx->info->snd_seq,
3677 &devlink_nl_family, NLM_F_MULTI,
3680 goto nla_put_failure;
3682 devlink = dump_ctx->info->user_ptr[0];
3683 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
3684 goto nla_put_failure;
3685 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
3686 DEVLINK_ATTR_DPIPE_ENTRIES);
3687 if (!dump_ctx->nest)
3688 goto nla_put_failure;
3692 nlmsg_free(dump_ctx->skb);
3695 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
3697 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
3698 struct devlink_dpipe_entry *entry)
3700 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
3702 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
3704 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
3706 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
3707 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
3710 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
3712 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
3715 unsigned int value_count, value_index;
3716 struct devlink_dpipe_value *value;
3718 value = entry->action_values;
3719 value_count = entry->action_values_count;
3720 for (value_index = 0; value_index < value_count; value_index++) {
3721 kfree(value[value_index].value);
3722 kfree(value[value_index].mask);
3725 value = entry->match_values;
3726 value_count = entry->match_values_count;
3727 for (value_index = 0; value_index < value_count; value_index++) {
3728 kfree(value[value_index].value);
3729 kfree(value[value_index].mask);
3732 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
3734 static int devlink_dpipe_entries_fill(struct genl_info *info,
3735 enum devlink_command cmd, int flags,
3736 struct devlink_dpipe_table *table)
3738 struct devlink_dpipe_dump_ctx dump_ctx;
3739 struct nlmsghdr *nlh;
3742 dump_ctx.skb = NULL;
3744 dump_ctx.info = info;
3746 err = table->table_ops->entries_dump(table->priv,
3747 table->counters_enabled,
3753 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
3754 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3756 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
3761 return genlmsg_reply(dump_ctx.skb, info);
3764 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
3765 struct genl_info *info)
3767 struct devlink *devlink = info->user_ptr[0];
3768 struct devlink_dpipe_table *table;
3769 const char *table_name;
3771 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
3774 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3775 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3776 table_name, devlink);
3780 if (!table->table_ops->entries_dump)
3783 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
3787 static int devlink_dpipe_fields_put(struct sk_buff *skb,
3788 const struct devlink_dpipe_header *header)
3790 struct devlink_dpipe_field *field;
3791 struct nlattr *field_attr;
3794 for (i = 0; i < header->fields_count; i++) {
3795 field = &header->fields[i];
3796 field_attr = nla_nest_start_noflag(skb,
3797 DEVLINK_ATTR_DPIPE_FIELD);
3800 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
3801 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3802 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
3803 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
3804 goto nla_put_failure;
3805 nla_nest_end(skb, field_attr);
3810 nla_nest_cancel(skb, field_attr);
3814 static int devlink_dpipe_header_put(struct sk_buff *skb,
3815 struct devlink_dpipe_header *header)
3817 struct nlattr *fields_attr, *header_attr;
3820 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
3824 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
3825 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3826 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3827 goto nla_put_failure;
3829 fields_attr = nla_nest_start_noflag(skb,
3830 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
3832 goto nla_put_failure;
3834 err = devlink_dpipe_fields_put(skb, header);
3836 nla_nest_cancel(skb, fields_attr);
3837 goto nla_put_failure;
3839 nla_nest_end(skb, fields_attr);
3840 nla_nest_end(skb, header_attr);
3845 nla_nest_cancel(skb, header_attr);
3849 static int devlink_dpipe_headers_fill(struct genl_info *info,
3850 enum devlink_command cmd, int flags,
3851 struct devlink_dpipe_headers *
3854 struct devlink *devlink = info->user_ptr[0];
3855 struct nlattr *headers_attr;
3856 struct sk_buff *skb = NULL;
3857 struct nlmsghdr *nlh;
3864 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3868 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3869 &devlink_nl_family, NLM_F_MULTI, cmd);
3875 if (devlink_nl_put_handle(skb, devlink))
3876 goto nla_put_failure;
3877 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
3879 goto nla_put_failure;
3882 for (; i < dpipe_headers->headers_count; i++) {
3883 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
3891 nla_nest_end(skb, headers_attr);
3892 genlmsg_end(skb, hdr);
3893 if (i != dpipe_headers->headers_count)
3897 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3898 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3900 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3905 return genlmsg_reply(skb, info);
3914 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
3915 struct genl_info *info)
3917 struct devlink *devlink = info->user_ptr[0];
3919 if (!devlink->dpipe_headers)
3921 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
3922 0, devlink->dpipe_headers);
3925 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
3926 const char *table_name,
3929 struct devlink_dpipe_table *table;
3931 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3932 table_name, devlink);
3936 if (table->counter_control_extern)
3939 if (!(table->counters_enabled ^ enable))
3942 table->counters_enabled = enable;
3943 if (table->table_ops->counters_set_update)
3944 table->table_ops->counters_set_update(table->priv, enable);
3948 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
3949 struct genl_info *info)
3951 struct devlink *devlink = info->user_ptr[0];
3952 const char *table_name;
3953 bool counters_enable;
3955 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) ||
3956 GENL_REQ_ATTR_CHECK(info,
3957 DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED))
3960 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3961 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
3963 return devlink_dpipe_table_counters_set(devlink, table_name,
3967 static struct devlink_resource *
3968 devlink_resource_find(struct devlink *devlink,
3969 struct devlink_resource *resource, u64 resource_id)
3971 struct list_head *resource_list;
3974 resource_list = &resource->resource_list;
3976 resource_list = &devlink->resource_list;
3978 list_for_each_entry(resource, resource_list, list) {
3979 struct devlink_resource *child_resource;
3981 if (resource->id == resource_id)
3984 child_resource = devlink_resource_find(devlink, resource,
3987 return child_resource;
3993 devlink_resource_validate_children(struct devlink_resource *resource)
3995 struct devlink_resource *child_resource;
3996 bool size_valid = true;
3999 if (list_empty(&resource->resource_list))
4002 list_for_each_entry(child_resource, &resource->resource_list, list)
4003 parts_size += child_resource->size_new;
4005 if (parts_size > resource->size_new)
4008 resource->size_valid = size_valid;
4012 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
4013 struct netlink_ext_ack *extack)
4018 if (size > resource->size_params.size_max) {
4019 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
4023 if (size < resource->size_params.size_min) {
4024 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
4028 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
4030 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
4037 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
4038 struct genl_info *info)
4040 struct devlink *devlink = info->user_ptr[0];
4041 struct devlink_resource *resource;
4046 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) ||
4047 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE))
4049 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
4051 resource = devlink_resource_find(devlink, NULL, resource_id);
4055 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
4056 err = devlink_resource_validate_size(resource, size, info->extack);
4060 resource->size_new = size;
4061 devlink_resource_validate_children(resource);
4062 if (resource->parent)
4063 devlink_resource_validate_children(resource->parent);
4068 devlink_resource_size_params_put(struct devlink_resource *resource,
4069 struct sk_buff *skb)
4071 struct devlink_resource_size_params *size_params;
4073 size_params = &resource->size_params;
4074 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
4075 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
4076 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
4077 size_params->size_max, DEVLINK_ATTR_PAD) ||
4078 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
4079 size_params->size_min, DEVLINK_ATTR_PAD) ||
4080 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
4085 static int devlink_resource_occ_put(struct devlink_resource *resource,
4086 struct sk_buff *skb)
4088 if (!resource->occ_get)
4090 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
4091 resource->occ_get(resource->occ_get_priv),
4095 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
4096 struct devlink_resource *resource)
4098 struct devlink_resource *child_resource;
4099 struct nlattr *child_resource_attr;
4100 struct nlattr *resource_attr;
4102 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
4106 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
4107 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
4108 DEVLINK_ATTR_PAD) ||
4109 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
4111 goto nla_put_failure;
4112 if (resource->size != resource->size_new &&
4113 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
4114 resource->size_new, DEVLINK_ATTR_PAD))
4115 goto nla_put_failure;
4116 if (devlink_resource_occ_put(resource, skb))
4117 goto nla_put_failure;
4118 if (devlink_resource_size_params_put(resource, skb))
4119 goto nla_put_failure;
4120 if (list_empty(&resource->resource_list))
4123 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
4124 resource->size_valid))
4125 goto nla_put_failure;
4127 child_resource_attr = nla_nest_start_noflag(skb,
4128 DEVLINK_ATTR_RESOURCE_LIST);
4129 if (!child_resource_attr)
4130 goto nla_put_failure;
4132 list_for_each_entry(child_resource, &resource->resource_list, list) {
4133 if (devlink_resource_put(devlink, skb, child_resource))
4134 goto resource_put_failure;
4137 nla_nest_end(skb, child_resource_attr);
4139 nla_nest_end(skb, resource_attr);
4142 resource_put_failure:
4143 nla_nest_cancel(skb, child_resource_attr);
4145 nla_nest_cancel(skb, resource_attr);
4149 static int devlink_resource_fill(struct genl_info *info,
4150 enum devlink_command cmd, int flags)
4152 struct devlink *devlink = info->user_ptr[0];
4153 struct devlink_resource *resource;
4154 struct nlattr *resources_attr;
4155 struct sk_buff *skb = NULL;
4156 struct nlmsghdr *nlh;
4162 resource = list_first_entry(&devlink->resource_list,
4163 struct devlink_resource, list);
4165 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4169 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4170 &devlink_nl_family, NLM_F_MULTI, cmd);
4176 if (devlink_nl_put_handle(skb, devlink))
4177 goto nla_put_failure;
4179 resources_attr = nla_nest_start_noflag(skb,
4180 DEVLINK_ATTR_RESOURCE_LIST);
4181 if (!resources_attr)
4182 goto nla_put_failure;
4186 list_for_each_entry_from(resource, &devlink->resource_list, list) {
4187 err = devlink_resource_put(devlink, skb, resource);
4190 goto err_resource_put;
4196 nla_nest_end(skb, resources_attr);
4197 genlmsg_end(skb, hdr);
4201 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4202 NLMSG_DONE, 0, flags | NLM_F_MULTI);
4204 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4209 return genlmsg_reply(skb, info);
4218 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
4219 struct genl_info *info)
4221 struct devlink *devlink = info->user_ptr[0];
4223 if (list_empty(&devlink->resource_list))
4226 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
4230 devlink_resources_validate(struct devlink *devlink,
4231 struct devlink_resource *resource,
4232 struct genl_info *info)
4234 struct list_head *resource_list;
4238 resource_list = &resource->resource_list;
4240 resource_list = &devlink->resource_list;
4242 list_for_each_entry(resource, resource_list, list) {
4243 if (!resource->size_valid)
4245 err = devlink_resources_validate(devlink, resource, info);
4252 static struct net *devlink_netns_get(struct sk_buff *skb,
4253 struct genl_info *info)
4255 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
4256 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
4257 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
4260 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
4261 NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified");
4262 return ERR_PTR(-EINVAL);
4265 if (netns_pid_attr) {
4266 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
4267 } else if (netns_fd_attr) {
4268 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
4269 } else if (netns_id_attr) {
4270 net = get_net_ns_by_id(sock_net(skb->sk),
4271 nla_get_u32(netns_id_attr));
4273 net = ERR_PTR(-EINVAL);
4276 net = ERR_PTR(-EINVAL);
4279 NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
4280 return ERR_PTR(-EINVAL);
4282 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
4284 return ERR_PTR(-EPERM);
4289 static void devlink_param_notify(struct devlink *devlink,
4290 unsigned int port_index,
4291 struct devlink_param_item *param_item,
4292 enum devlink_command cmd);
4294 static void devlink_ns_change_notify(struct devlink *devlink,
4295 struct net *dest_net, struct net *curr_net,
4298 struct devlink_param_item *param_item;
4299 enum devlink_command cmd;
4301 /* Userspace needs to be notified about devlink objects
4302 * removed from original and entering new network namespace.
4303 * The rest of the devlink objects are re-created during
4304 * reload process so the notifications are generated separatelly.
4307 if (!dest_net || net_eq(dest_net, curr_net))
4311 devlink_notify(devlink, DEVLINK_CMD_NEW);
4313 cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL;
4314 list_for_each_entry(param_item, &devlink->param_list, list)
4315 devlink_param_notify(devlink, 0, param_item, cmd);
4318 devlink_notify(devlink, DEVLINK_CMD_DEL);
4321 static void devlink_reload_failed_set(struct devlink *devlink,
4324 if (devlink->reload_failed == reload_failed)
4326 devlink->reload_failed = reload_failed;
4327 devlink_notify(devlink, DEVLINK_CMD_NEW);
4330 bool devlink_is_reload_failed(const struct devlink *devlink)
4332 return devlink->reload_failed;
4334 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
4337 __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats,
4338 enum devlink_reload_limit limit, u32 actions_performed)
4340 unsigned long actions = actions_performed;
4344 for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) {
4345 stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action;
4346 reload_stats[stat_idx]++;
4348 devlink_notify(devlink, DEVLINK_CMD_NEW);
4352 devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit,
4353 u32 actions_performed)
4355 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit,
4360 * devlink_remote_reload_actions_performed - Update devlink on reload actions
4361 * performed which are not a direct result of devlink reload call.
4363 * This should be called by a driver after performing reload actions in case it was not
4364 * a result of devlink reload call. For example fw_activate was performed as a result
4365 * of devlink reload triggered fw_activate on another host.
4366 * The motivation for this function is to keep data on reload actions performed on this
4367 * function whether it was done due to direct devlink reload call or not.
4370 * @limit: reload limit
4371 * @actions_performed: bitmask of actions performed
4373 void devlink_remote_reload_actions_performed(struct devlink *devlink,
4374 enum devlink_reload_limit limit,
4375 u32 actions_performed)
4377 if (WARN_ON(!actions_performed ||
4378 actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
4379 actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) ||
4380 limit > DEVLINK_RELOAD_LIMIT_MAX))
4383 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit,
4386 EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed);
4388 int devlink_reload(struct devlink *devlink, struct net *dest_net,
4389 enum devlink_reload_action action,
4390 enum devlink_reload_limit limit,
4391 u32 *actions_performed, struct netlink_ext_ack *extack)
4393 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
4394 struct net *curr_net;
4397 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
4398 sizeof(remote_reload_stats));
4400 curr_net = devlink_net(devlink);
4401 devlink_ns_change_notify(devlink, dest_net, curr_net, false);
4402 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
4406 if (dest_net && !net_eq(dest_net, curr_net)) {
4407 move_netdevice_notifier_net(curr_net, dest_net,
4408 &devlink->netdevice_nb);
4409 write_pnet(&devlink->_net, dest_net);
4412 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
4413 devlink_reload_failed_set(devlink, !!err);
4417 devlink_ns_change_notify(devlink, dest_net, curr_net, true);
4418 WARN_ON(!(*actions_performed & BIT(action)));
4419 /* Catch driver on updating the remote action within devlink reload */
4420 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
4421 sizeof(remote_reload_stats)));
4422 devlink_reload_stats_update(devlink, limit, *actions_performed);
4427 devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
4428 enum devlink_command cmd, struct genl_info *info)
4430 struct sk_buff *msg;
4433 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4437 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
4441 if (devlink_nl_put_handle(msg, devlink))
4442 goto nla_put_failure;
4444 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
4446 goto nla_put_failure;
4447 genlmsg_end(msg, hdr);
4449 return genlmsg_reply(msg, info);
4452 genlmsg_cancel(msg, hdr);
4458 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
4460 struct devlink *devlink = info->user_ptr[0];
4461 enum devlink_reload_action action;
4462 enum devlink_reload_limit limit;
4463 struct net *dest_net = NULL;
4464 u32 actions_performed;
4467 if (!(devlink->features & DEVLINK_F_RELOAD))
4470 err = devlink_resources_validate(devlink, NULL, info);
4472 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
4476 if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
4477 action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
4479 action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
4481 if (!devlink_reload_action_is_supported(devlink, action)) {
4482 NL_SET_ERR_MSG_MOD(info->extack,
4483 "Requested reload action is not supported by the driver");
4487 limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
4488 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
4489 struct nla_bitfield32 limits;
4490 u32 limits_selected;
4492 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
4493 limits_selected = limits.value & limits.selector;
4494 if (!limits_selected) {
4495 NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected");
4498 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
4499 if (limits_selected & BIT(limit))
4501 /* UAPI enables multiselection, but currently it is not used */
4502 if (limits_selected != BIT(limit)) {
4503 NL_SET_ERR_MSG_MOD(info->extack,
4504 "Multiselection of limit is not supported");
4507 if (!devlink_reload_limit_is_supported(devlink, limit)) {
4508 NL_SET_ERR_MSG_MOD(info->extack,
4509 "Requested limit is not supported by the driver");
4512 if (devlink_reload_combination_is_invalid(action, limit)) {
4513 NL_SET_ERR_MSG_MOD(info->extack,
4514 "Requested limit is invalid for this action");
4518 if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
4519 info->attrs[DEVLINK_ATTR_NETNS_FD] ||
4520 info->attrs[DEVLINK_ATTR_NETNS_ID]) {
4521 dest_net = devlink_netns_get(skb, info);
4522 if (IS_ERR(dest_net))
4523 return PTR_ERR(dest_net);
4526 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
4533 /* For backward compatibility generate reply only if attributes used by user */
4534 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
4537 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
4538 DEVLINK_CMD_RELOAD, info);
4541 static int devlink_nl_flash_update_fill(struct sk_buff *msg,
4542 struct devlink *devlink,
4543 enum devlink_command cmd,
4544 struct devlink_flash_notify *params)
4548 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
4552 if (devlink_nl_put_handle(msg, devlink))
4553 goto nla_put_failure;
4555 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
4558 if (params->status_msg &&
4559 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
4560 params->status_msg))
4561 goto nla_put_failure;
4562 if (params->component &&
4563 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
4565 goto nla_put_failure;
4566 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
4567 params->done, DEVLINK_ATTR_PAD))
4568 goto nla_put_failure;
4569 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
4570 params->total, DEVLINK_ATTR_PAD))
4571 goto nla_put_failure;
4572 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT,
4573 params->timeout, DEVLINK_ATTR_PAD))
4574 goto nla_put_failure;
4577 genlmsg_end(msg, hdr);
4581 genlmsg_cancel(msg, hdr);
4585 static void __devlink_flash_update_notify(struct devlink *devlink,
4586 enum devlink_command cmd,
4587 struct devlink_flash_notify *params)
4589 struct sk_buff *msg;
4592 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
4593 cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
4594 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
4596 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
4599 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4603 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params);
4607 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
4608 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4615 static void devlink_flash_update_begin_notify(struct devlink *devlink)
4617 struct devlink_flash_notify params = {};
4619 __devlink_flash_update_notify(devlink,
4620 DEVLINK_CMD_FLASH_UPDATE,
4624 static void devlink_flash_update_end_notify(struct devlink *devlink)
4626 struct devlink_flash_notify params = {};
4628 __devlink_flash_update_notify(devlink,
4629 DEVLINK_CMD_FLASH_UPDATE_END,
4633 void devlink_flash_update_status_notify(struct devlink *devlink,
4634 const char *status_msg,
4635 const char *component,
4637 unsigned long total)
4639 struct devlink_flash_notify params = {
4640 .status_msg = status_msg,
4641 .component = component,
4646 __devlink_flash_update_notify(devlink,
4647 DEVLINK_CMD_FLASH_UPDATE_STATUS,
4650 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
4652 void devlink_flash_update_timeout_notify(struct devlink *devlink,
4653 const char *status_msg,
4654 const char *component,
4655 unsigned long timeout)
4657 struct devlink_flash_notify params = {
4658 .status_msg = status_msg,
4659 .component = component,
4663 __devlink_flash_update_notify(devlink,
4664 DEVLINK_CMD_FLASH_UPDATE_STATUS,
4667 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
4669 struct devlink_info_req {
4670 struct sk_buff *msg;
4671 void (*version_cb)(const char *version_name,
4672 enum devlink_info_version_type version_type,
4673 void *version_cb_priv);
4674 void *version_cb_priv;
4677 struct devlink_flash_component_lookup_ctx {
4678 const char *lookup_name;
4679 bool lookup_name_found;
4683 devlink_flash_component_lookup_cb(const char *version_name,
4684 enum devlink_info_version_type version_type,
4685 void *version_cb_priv)
4687 struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv;
4689 if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT ||
4690 lookup_ctx->lookup_name_found)
4693 lookup_ctx->lookup_name_found =
4694 !strcmp(lookup_ctx->lookup_name, version_name);
4697 static int devlink_flash_component_get(struct devlink *devlink,
4698 struct nlattr *nla_component,
4699 const char **p_component,
4700 struct netlink_ext_ack *extack)
4702 struct devlink_flash_component_lookup_ctx lookup_ctx = {};
4703 struct devlink_info_req req = {};
4704 const char *component;
4710 component = nla_data(nla_component);
4712 if (!devlink->ops->info_get) {
4713 NL_SET_ERR_MSG_ATTR(extack, nla_component,
4714 "component update is not supported by this device");
4718 lookup_ctx.lookup_name = component;
4719 req.version_cb = devlink_flash_component_lookup_cb;
4720 req.version_cb_priv = &lookup_ctx;
4722 ret = devlink->ops->info_get(devlink, &req, NULL);
4726 if (!lookup_ctx.lookup_name_found) {
4727 NL_SET_ERR_MSG_ATTR(extack, nla_component,
4728 "selected component is not supported by this device");
4731 *p_component = component;
4735 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
4736 struct genl_info *info)
4738 struct nlattr *nla_overwrite_mask, *nla_file_name;
4739 struct devlink_flash_update_params params = {};
4740 struct devlink *devlink = info->user_ptr[0];
4741 const char *file_name;
4742 u32 supported_params;
4745 if (!devlink->ops->flash_update)
4748 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME))
4751 ret = devlink_flash_component_get(devlink,
4752 info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT],
4753 ¶ms.component, info->extack);
4757 supported_params = devlink->ops->supported_flash_update_params;
4759 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
4760 if (nla_overwrite_mask) {
4761 struct nla_bitfield32 sections;
4763 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
4764 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask,
4765 "overwrite settings are not supported by this device");
4768 sections = nla_get_bitfield32(nla_overwrite_mask);
4769 params.overwrite_mask = sections.value & sections.selector;
4772 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME];
4773 file_name = nla_data(nla_file_name);
4774 ret = request_firmware(¶ms.fw, file_name, devlink->dev);
4776 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file");
4780 devlink_flash_update_begin_notify(devlink);
4781 ret = devlink->ops->flash_update(devlink, ¶ms, info->extack);
4782 devlink_flash_update_end_notify(devlink);
4784 release_firmware(params.fw);
4790 devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink,
4791 u32 portid, u32 seq, int flags,
4792 struct netlink_ext_ack *extack)
4794 struct nlattr *selftests;
4799 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags,
4800 DEVLINK_CMD_SELFTESTS_GET);
4805 if (devlink_nl_put_handle(msg, devlink))
4806 goto err_cancel_msg;
4808 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
4810 goto err_cancel_msg;
4812 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
4813 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
4814 if (devlink->ops->selftest_check(devlink, i, extack)) {
4815 err = nla_put_flag(msg, i);
4817 goto err_cancel_msg;
4821 nla_nest_end(msg, selftests);
4822 genlmsg_end(msg, hdr);
4826 genlmsg_cancel(msg, hdr);
4830 static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb,
4831 struct genl_info *info)
4833 struct devlink *devlink = info->user_ptr[0];
4834 struct sk_buff *msg;
4837 if (!devlink->ops->selftest_check)
4840 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4844 err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid,
4845 info->snd_seq, 0, info->extack);
4851 return genlmsg_reply(msg, info);
4854 static int devlink_nl_cmd_selftests_get_dumpit(struct sk_buff *msg,
4855 struct netlink_callback *cb)
4857 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
4858 struct devlink *devlink;
4861 devlink_dump_for_each_instance_get(msg, state, devlink) {
4862 if (!devlink->ops->selftest_check) {
4863 devlink_put(devlink);
4868 err = devlink_nl_selftests_fill(msg, devlink,
4869 NETLINK_CB(cb->skb).portid,
4870 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4872 devl_unlock(devlink);
4874 devlink_put(devlink);
4878 devlink_put(devlink);
4881 if (err != -EMSGSIZE)
4887 static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id,
4888 enum devlink_selftest_status test_status)
4890 struct nlattr *result_attr;
4892 result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT);
4896 if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) ||
4897 nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS,
4899 goto nla_put_failure;
4901 nla_nest_end(skb, result_attr);
4905 nla_nest_cancel(skb, result_attr);
4909 static int devlink_nl_cmd_selftests_run(struct sk_buff *skb,
4910 struct genl_info *info)
4912 struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1];
4913 struct devlink *devlink = info->user_ptr[0];
4914 struct nlattr *attrs, *selftests;
4915 struct sk_buff *msg;
4920 if (!devlink->ops->selftest_run || !devlink->ops->selftest_check)
4923 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS))
4926 attrs = info->attrs[DEVLINK_ATTR_SELFTESTS];
4928 err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs,
4929 devlink_selftest_nl_policy, info->extack);
4933 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4938 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
4939 &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN);
4943 if (devlink_nl_put_handle(msg, devlink))
4944 goto genlmsg_cancel;
4946 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
4948 goto genlmsg_cancel;
4950 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
4951 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
4952 enum devlink_selftest_status test_status;
4954 if (nla_get_flag(tb[i])) {
4955 if (!devlink->ops->selftest_check(devlink, i,
4957 if (devlink_selftest_result_put(msg, i,
4958 DEVLINK_SELFTEST_STATUS_SKIP))
4959 goto selftests_nest_cancel;
4963 test_status = devlink->ops->selftest_run(devlink, i,
4965 if (devlink_selftest_result_put(msg, i, test_status))
4966 goto selftests_nest_cancel;
4970 nla_nest_end(msg, selftests);
4971 genlmsg_end(msg, hdr);
4972 return genlmsg_reply(msg, info);
4974 selftests_nest_cancel:
4975 nla_nest_cancel(msg, selftests);
4977 genlmsg_cancel(msg, hdr);
4983 static const struct devlink_param devlink_param_generic[] = {
4985 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
4986 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
4987 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
4990 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
4991 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
4992 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
4995 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
4996 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
4997 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
5000 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
5001 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
5002 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
5005 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
5006 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
5007 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
5010 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
5011 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
5012 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
5015 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
5016 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
5017 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
5020 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
5021 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
5022 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
5025 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
5026 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
5027 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
5030 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
5031 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
5032 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
5035 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
5036 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
5037 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
5040 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
5041 .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
5042 .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
5045 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
5046 .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
5047 .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
5050 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
5051 .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
5052 .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
5055 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
5056 .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
5057 .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
5060 .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
5061 .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
5062 .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
5065 .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
5066 .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
5067 .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
5071 static int devlink_param_generic_verify(const struct devlink_param *param)
5073 /* verify it match generic parameter by id and name */
5074 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
5076 if (strcmp(param->name, devlink_param_generic[param->id].name))
5079 WARN_ON(param->type != devlink_param_generic[param->id].type);
5084 static int devlink_param_driver_verify(const struct devlink_param *param)
5088 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
5090 /* verify no such name in generic params */
5091 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
5092 if (!strcmp(param->name, devlink_param_generic[i].name))
5098 static struct devlink_param_item *
5099 devlink_param_find_by_name(struct list_head *param_list,
5100 const char *param_name)
5102 struct devlink_param_item *param_item;
5104 list_for_each_entry(param_item, param_list, list)
5105 if (!strcmp(param_item->param->name, param_name))
5110 static struct devlink_param_item *
5111 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
5113 struct devlink_param_item *param_item;
5115 list_for_each_entry(param_item, param_list, list)
5116 if (param_item->param->id == param_id)
5122 devlink_param_cmode_is_supported(const struct devlink_param *param,
5123 enum devlink_param_cmode cmode)
5125 return test_bit(cmode, ¶m->supported_cmodes);
5128 static int devlink_param_get(struct devlink *devlink,
5129 const struct devlink_param *param,
5130 struct devlink_param_gset_ctx *ctx)
5132 if (!param->get || devlink->reload_failed)
5134 return param->get(devlink, param->id, ctx);
5137 static int devlink_param_set(struct devlink *devlink,
5138 const struct devlink_param *param,
5139 struct devlink_param_gset_ctx *ctx)
5141 if (!param->set || devlink->reload_failed)
5143 return param->set(devlink, param->id, ctx);
5147 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
5149 switch (param_type) {
5150 case DEVLINK_PARAM_TYPE_U8:
5152 case DEVLINK_PARAM_TYPE_U16:
5154 case DEVLINK_PARAM_TYPE_U32:
5156 case DEVLINK_PARAM_TYPE_STRING:
5158 case DEVLINK_PARAM_TYPE_BOOL:
5166 devlink_nl_param_value_fill_one(struct sk_buff *msg,
5167 enum devlink_param_type type,
5168 enum devlink_param_cmode cmode,
5169 union devlink_param_value val)
5171 struct nlattr *param_value_attr;
5173 param_value_attr = nla_nest_start_noflag(msg,
5174 DEVLINK_ATTR_PARAM_VALUE);
5175 if (!param_value_attr)
5176 goto nla_put_failure;
5178 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
5179 goto value_nest_cancel;
5182 case DEVLINK_PARAM_TYPE_U8:
5183 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
5184 goto value_nest_cancel;
5186 case DEVLINK_PARAM_TYPE_U16:
5187 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
5188 goto value_nest_cancel;
5190 case DEVLINK_PARAM_TYPE_U32:
5191 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
5192 goto value_nest_cancel;
5194 case DEVLINK_PARAM_TYPE_STRING:
5195 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
5197 goto value_nest_cancel;
5199 case DEVLINK_PARAM_TYPE_BOOL:
5201 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
5202 goto value_nest_cancel;
5206 nla_nest_end(msg, param_value_attr);
5210 nla_nest_cancel(msg, param_value_attr);
5215 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
5216 unsigned int port_index,
5217 struct devlink_param_item *param_item,
5218 enum devlink_command cmd,
5219 u32 portid, u32 seq, int flags)
5221 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
5222 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
5223 const struct devlink_param *param = param_item->param;
5224 struct devlink_param_gset_ctx ctx;
5225 struct nlattr *param_values_list;
5226 struct nlattr *param_attr;
5232 /* Get value from driver part to driverinit configuration mode */
5233 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5234 if (!devlink_param_cmode_is_supported(param, i))
5236 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5237 if (!param_item->driverinit_value_valid)
5239 param_value[i] = param_item->driverinit_value;
5242 err = devlink_param_get(devlink, param, &ctx);
5245 param_value[i] = ctx.val;
5247 param_value_set[i] = true;
5250 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5254 if (devlink_nl_put_handle(msg, devlink))
5255 goto genlmsg_cancel;
5257 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
5258 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
5259 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
5260 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
5261 goto genlmsg_cancel;
5263 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
5265 goto genlmsg_cancel;
5266 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
5267 goto param_nest_cancel;
5268 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
5269 goto param_nest_cancel;
5271 nla_type = devlink_param_type_to_nla_type(param->type);
5273 goto param_nest_cancel;
5274 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
5275 goto param_nest_cancel;
5277 param_values_list = nla_nest_start_noflag(msg,
5278 DEVLINK_ATTR_PARAM_VALUES_LIST);
5279 if (!param_values_list)
5280 goto param_nest_cancel;
5282 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5283 if (!param_value_set[i])
5285 err = devlink_nl_param_value_fill_one(msg, param->type,
5288 goto values_list_nest_cancel;
5291 nla_nest_end(msg, param_values_list);
5292 nla_nest_end(msg, param_attr);
5293 genlmsg_end(msg, hdr);
5296 values_list_nest_cancel:
5297 nla_nest_end(msg, param_values_list);
5299 nla_nest_cancel(msg, param_attr);
5301 genlmsg_cancel(msg, hdr);
5305 static void devlink_param_notify(struct devlink *devlink,
5306 unsigned int port_index,
5307 struct devlink_param_item *param_item,
5308 enum devlink_command cmd)
5310 struct sk_buff *msg;
5313 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
5314 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
5315 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
5316 ASSERT_DEVLINK_REGISTERED(devlink);
5318 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5321 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
5328 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
5329 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5332 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
5333 struct netlink_callback *cb)
5335 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5336 struct devlink *devlink;
5339 devlink_dump_for_each_instance_get(msg, state, devlink) {
5340 struct devlink_param_item *param_item;
5344 list_for_each_entry(param_item, &devlink->param_list, list) {
5345 if (idx < state->idx) {
5349 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5350 DEVLINK_CMD_PARAM_GET,
5351 NETLINK_CB(cb->skb).portid,
5354 if (err == -EOPNOTSUPP) {
5357 devl_unlock(devlink);
5358 devlink_put(devlink);
5364 devl_unlock(devlink);
5365 devlink_put(devlink);
5368 if (err != -EMSGSIZE)
5375 devlink_param_type_get_from_info(struct genl_info *info,
5376 enum devlink_param_type *param_type)
5378 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
5381 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
5383 *param_type = DEVLINK_PARAM_TYPE_U8;
5386 *param_type = DEVLINK_PARAM_TYPE_U16;
5389 *param_type = DEVLINK_PARAM_TYPE_U32;
5392 *param_type = DEVLINK_PARAM_TYPE_STRING;
5395 *param_type = DEVLINK_PARAM_TYPE_BOOL;
5405 devlink_param_value_get_from_info(const struct devlink_param *param,
5406 struct genl_info *info,
5407 union devlink_param_value *value)
5409 struct nlattr *param_data;
5412 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
5414 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
5417 switch (param->type) {
5418 case DEVLINK_PARAM_TYPE_U8:
5419 if (nla_len(param_data) != sizeof(u8))
5421 value->vu8 = nla_get_u8(param_data);
5423 case DEVLINK_PARAM_TYPE_U16:
5424 if (nla_len(param_data) != sizeof(u16))
5426 value->vu16 = nla_get_u16(param_data);
5428 case DEVLINK_PARAM_TYPE_U32:
5429 if (nla_len(param_data) != sizeof(u32))
5431 value->vu32 = nla_get_u32(param_data);
5433 case DEVLINK_PARAM_TYPE_STRING:
5434 len = strnlen(nla_data(param_data), nla_len(param_data));
5435 if (len == nla_len(param_data) ||
5436 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
5438 strcpy(value->vstr, nla_data(param_data));
5440 case DEVLINK_PARAM_TYPE_BOOL:
5441 if (param_data && nla_len(param_data))
5443 value->vbool = nla_get_flag(param_data);
5449 static struct devlink_param_item *
5450 devlink_param_get_from_info(struct list_head *param_list,
5451 struct genl_info *info)
5455 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
5458 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
5459 return devlink_param_find_by_name(param_list, param_name);
5462 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
5463 struct genl_info *info)
5465 struct devlink *devlink = info->user_ptr[0];
5466 struct devlink_param_item *param_item;
5467 struct sk_buff *msg;
5470 param_item = devlink_param_get_from_info(&devlink->param_list, info);
5474 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5478 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5479 DEVLINK_CMD_PARAM_GET,
5480 info->snd_portid, info->snd_seq, 0);
5486 return genlmsg_reply(msg, info);
5489 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
5490 unsigned int port_index,
5491 struct list_head *param_list,
5492 struct genl_info *info,
5493 enum devlink_command cmd)
5495 enum devlink_param_type param_type;
5496 struct devlink_param_gset_ctx ctx;
5497 enum devlink_param_cmode cmode;
5498 struct devlink_param_item *param_item;
5499 const struct devlink_param *param;
5500 union devlink_param_value value;
5503 param_item = devlink_param_get_from_info(param_list, info);
5506 param = param_item->param;
5507 err = devlink_param_type_get_from_info(info, ¶m_type);
5510 if (param_type != param->type)
5512 err = devlink_param_value_get_from_info(param, info, &value);
5515 if (param->validate) {
5516 err = param->validate(devlink, param->id, value, info->extack);
5521 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
5523 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
5524 if (!devlink_param_cmode_is_supported(param, cmode))
5527 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5528 if (param->type == DEVLINK_PARAM_TYPE_STRING)
5529 strcpy(param_item->driverinit_value.vstr, value.vstr);
5531 param_item->driverinit_value = value;
5532 param_item->driverinit_value_valid = true;
5538 err = devlink_param_set(devlink, param, &ctx);
5543 devlink_param_notify(devlink, port_index, param_item, cmd);
5547 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
5548 struct genl_info *info)
5550 struct devlink *devlink = info->user_ptr[0];
5552 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
5553 info, DEVLINK_CMD_PARAM_NEW);
5556 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
5557 struct netlink_callback *cb)
5559 NL_SET_ERR_MSG_MOD(cb->extack, "Port params are not supported");
5563 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
5564 struct genl_info *info)
5566 NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
5570 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
5571 struct genl_info *info)
5573 NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
5577 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
5578 struct devlink *devlink,
5579 struct devlink_snapshot *snapshot)
5581 struct nlattr *snap_attr;
5584 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
5588 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
5590 goto nla_put_failure;
5592 nla_nest_end(msg, snap_attr);
5596 nla_nest_cancel(msg, snap_attr);
5600 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
5601 struct devlink *devlink,
5602 struct devlink_region *region)
5604 struct devlink_snapshot *snapshot;
5605 struct nlattr *snapshots_attr;
5608 snapshots_attr = nla_nest_start_noflag(msg,
5609 DEVLINK_ATTR_REGION_SNAPSHOTS);
5610 if (!snapshots_attr)
5613 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
5614 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
5616 goto nla_put_failure;
5619 nla_nest_end(msg, snapshots_attr);
5623 nla_nest_cancel(msg, snapshots_attr);
5627 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
5628 enum devlink_command cmd, u32 portid,
5630 struct devlink_region *region)
5635 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5639 err = devlink_nl_put_handle(msg, devlink);
5641 goto nla_put_failure;
5644 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5645 region->port->index);
5647 goto nla_put_failure;
5650 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
5652 goto nla_put_failure;
5654 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5658 goto nla_put_failure;
5660 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
5661 region->max_snapshots);
5663 goto nla_put_failure;
5665 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
5667 goto nla_put_failure;
5669 genlmsg_end(msg, hdr);
5673 genlmsg_cancel(msg, hdr);
5677 static struct sk_buff *
5678 devlink_nl_region_notify_build(struct devlink_region *region,
5679 struct devlink_snapshot *snapshot,
5680 enum devlink_command cmd, u32 portid, u32 seq)
5682 struct devlink *devlink = region->devlink;
5683 struct sk_buff *msg;
5688 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5690 return ERR_PTR(-ENOMEM);
5692 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
5698 err = devlink_nl_put_handle(msg, devlink);
5700 goto out_cancel_msg;
5703 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5704 region->port->index);
5706 goto out_cancel_msg;
5709 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
5712 goto out_cancel_msg;
5715 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
5718 goto out_cancel_msg;
5720 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5721 region->size, DEVLINK_ATTR_PAD);
5723 goto out_cancel_msg;
5725 genlmsg_end(msg, hdr);
5730 genlmsg_cancel(msg, hdr);
5733 return ERR_PTR(err);
5736 static void devlink_nl_region_notify(struct devlink_region *region,
5737 struct devlink_snapshot *snapshot,
5738 enum devlink_command cmd)
5740 struct devlink *devlink = region->devlink;
5741 struct sk_buff *msg;
5743 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
5744 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
5747 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
5751 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
5752 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5756 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
5757 * @devlink: devlink instance
5758 * @id: the snapshot id
5760 * Track when a new snapshot begins using an id. Load the count for the
5761 * given id from the snapshot xarray, increment it, and store it back.
5763 * Called when a new snapshot is created with the given id.
5765 * The id *must* have been previously allocated by
5766 * devlink_region_snapshot_id_get().
5768 * Returns 0 on success, or an error on failure.
5770 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
5772 unsigned long count;
5776 xa_lock(&devlink->snapshot_ids);
5777 p = xa_load(&devlink->snapshot_ids, id);
5783 if (WARN_ON(!xa_is_value(p))) {
5788 count = xa_to_value(p);
5791 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5794 xa_unlock(&devlink->snapshot_ids);
5799 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
5800 * @devlink: devlink instance
5801 * @id: the snapshot id
5803 * Track when a snapshot is deleted and stops using an id. Load the count
5804 * for the given id from the snapshot xarray, decrement it, and store it
5807 * If the count reaches zero, erase this id from the xarray, freeing it
5808 * up for future re-use by devlink_region_snapshot_id_get().
5810 * Called when a snapshot using the given id is deleted, and when the
5811 * initial allocator of the id is finished using it.
5813 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
5815 unsigned long count;
5818 xa_lock(&devlink->snapshot_ids);
5819 p = xa_load(&devlink->snapshot_ids, id);
5823 if (WARN_ON(!xa_is_value(p)))
5826 count = xa_to_value(p);
5830 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5833 /* If this was the last user, we can erase this id */
5834 __xa_erase(&devlink->snapshot_ids, id);
5837 xa_unlock(&devlink->snapshot_ids);
5841 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
5842 * @devlink: devlink instance
5843 * @id: the snapshot id
5845 * Mark the given snapshot id as used by inserting a zero value into the
5848 * This must be called while holding the devlink instance lock. Unlike
5849 * devlink_snapshot_id_get, the initial reference count is zero, not one.
5850 * It is expected that the id will immediately be used before
5851 * releasing the devlink instance lock.
5853 * Returns zero on success, or an error code if the snapshot id could not
5856 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
5860 xa_lock(&devlink->snapshot_ids);
5861 if (xa_load(&devlink->snapshot_ids, id)) {
5862 xa_unlock(&devlink->snapshot_ids);
5865 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
5867 xa_unlock(&devlink->snapshot_ids);
5872 * __devlink_region_snapshot_id_get - get snapshot ID
5873 * @devlink: devlink instance
5874 * @id: storage to return snapshot id
5876 * Allocates a new snapshot id. Returns zero on success, or a negative
5877 * error on failure. Must be called while holding the devlink instance
5880 * Snapshot IDs are tracked using an xarray which stores the number of
5881 * users of the snapshot id.
5883 * Note that the caller of this function counts as a 'user', in order to
5884 * avoid race conditions. The caller must release its hold on the
5885 * snapshot by using devlink_region_snapshot_id_put.
5887 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
5889 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
5890 xa_limit_32b, GFP_KERNEL);
5894 * __devlink_region_snapshot_create - create a new snapshot
5895 * This will add a new snapshot of a region. The snapshot
5896 * will be stored on the region struct and can be accessed
5897 * from devlink. This is useful for future analyses of snapshots.
5898 * Multiple snapshots can be created on a region.
5899 * The @snapshot_id should be obtained using the getter function.
5901 * Must be called only while holding the region snapshot lock.
5903 * @region: devlink region of the snapshot
5904 * @data: snapshot data
5905 * @snapshot_id: snapshot id to be created
5908 __devlink_region_snapshot_create(struct devlink_region *region,
5909 u8 *data, u32 snapshot_id)
5911 struct devlink *devlink = region->devlink;
5912 struct devlink_snapshot *snapshot;
5915 lockdep_assert_held(®ion->snapshot_lock);
5917 /* check if region can hold one more snapshot */
5918 if (region->cur_snapshots == region->max_snapshots)
5921 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
5924 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
5928 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
5930 goto err_snapshot_id_increment;
5932 snapshot->id = snapshot_id;
5933 snapshot->region = region;
5934 snapshot->data = data;
5936 list_add_tail(&snapshot->list, ®ion->snapshot_list);
5938 region->cur_snapshots++;
5940 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
5943 err_snapshot_id_increment:
5948 static void devlink_region_snapshot_del(struct devlink_region *region,
5949 struct devlink_snapshot *snapshot)
5951 struct devlink *devlink = region->devlink;
5953 lockdep_assert_held(®ion->snapshot_lock);
5955 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
5956 region->cur_snapshots--;
5957 list_del(&snapshot->list);
5958 region->ops->destructor(snapshot->data);
5959 __devlink_snapshot_id_decrement(devlink, snapshot->id);
5963 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
5964 struct genl_info *info)
5966 struct devlink *devlink = info->user_ptr[0];
5967 struct devlink_port *port = NULL;
5968 struct devlink_region *region;
5969 const char *region_name;
5970 struct sk_buff *msg;
5974 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
5977 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
5978 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
5980 port = devlink_port_get_by_index(devlink, index);
5985 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
5987 region = devlink_port_region_get_by_name(port, region_name);
5989 region = devlink_region_get_by_name(devlink, region_name);
5994 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5998 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
5999 info->snd_portid, info->snd_seq, 0,
6006 return genlmsg_reply(msg, info);
6009 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
6010 struct netlink_callback *cb,
6011 struct devlink_port *port,
6015 struct devlink_region *region;
6018 list_for_each_entry(region, &port->region_list, list) {
6023 err = devlink_nl_region_fill(msg, port->devlink,
6024 DEVLINK_CMD_REGION_GET,
6025 NETLINK_CB(cb->skb).portid,
6027 NLM_F_MULTI, region);
6037 static int devlink_nl_cmd_region_get_devlink_dumpit(struct sk_buff *msg,
6038 struct netlink_callback *cb,
6039 struct devlink *devlink,
6043 struct devlink_region *region;
6044 struct devlink_port *port;
6045 unsigned long port_index;
6048 list_for_each_entry(region, &devlink->region_list, list) {
6053 err = devlink_nl_region_fill(msg, devlink,
6054 DEVLINK_CMD_REGION_GET,
6055 NETLINK_CB(cb->skb).portid,
6057 NLM_F_MULTI, region);
6063 xa_for_each(&devlink->ports, port_index, port) {
6064 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, idx,
6073 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
6074 struct netlink_callback *cb)
6076 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
6077 struct devlink *devlink;
6080 devlink_dump_for_each_instance_get(msg, state, devlink) {
6084 err = devlink_nl_cmd_region_get_devlink_dumpit(msg, cb, devlink,
6086 devl_unlock(devlink);
6087 devlink_put(devlink);
6097 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
6098 struct genl_info *info)
6100 struct devlink *devlink = info->user_ptr[0];
6101 struct devlink_snapshot *snapshot;
6102 struct devlink_port *port = NULL;
6103 struct devlink_region *region;
6104 const char *region_name;
6108 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
6109 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
6112 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6113 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
6115 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6116 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6118 port = devlink_port_get_by_index(devlink, index);
6124 region = devlink_port_region_get_by_name(port, region_name);
6126 region = devlink_region_get_by_name(devlink, region_name);
6131 mutex_lock(®ion->snapshot_lock);
6132 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6134 mutex_unlock(®ion->snapshot_lock);
6138 devlink_region_snapshot_del(region, snapshot);
6139 mutex_unlock(®ion->snapshot_lock);
6144 devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
6146 struct devlink *devlink = info->user_ptr[0];
6147 struct devlink_snapshot *snapshot;
6148 struct devlink_port *port = NULL;
6149 struct nlattr *snapshot_id_attr;
6150 struct devlink_region *region;
6151 const char *region_name;
6157 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
6158 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
6162 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6164 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6165 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6167 port = devlink_port_get_by_index(devlink, index);
6173 region = devlink_port_region_get_by_name(port, region_name);
6175 region = devlink_region_get_by_name(devlink, region_name);
6178 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
6182 if (!region->ops->snapshot) {
6183 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
6187 mutex_lock(®ion->snapshot_lock);
6189 if (region->cur_snapshots == region->max_snapshots) {
6190 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
6195 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
6196 if (snapshot_id_attr) {
6197 snapshot_id = nla_get_u32(snapshot_id_attr);
6199 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
6200 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
6205 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
6209 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
6211 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
6217 err = region->port_ops->snapshot(port, region->port_ops,
6218 info->extack, &data);
6220 err = region->ops->snapshot(devlink, region->ops,
6221 info->extack, &data);
6223 goto err_snapshot_capture;
6225 err = __devlink_region_snapshot_create(region, data, snapshot_id);
6227 goto err_snapshot_create;
6229 if (!snapshot_id_attr) {
6230 struct sk_buff *msg;
6232 snapshot = devlink_region_snapshot_get_by_id(region,
6234 if (WARN_ON(!snapshot)) {
6239 msg = devlink_nl_region_notify_build(region, snapshot,
6240 DEVLINK_CMD_REGION_NEW,
6243 err = PTR_ERR_OR_ZERO(msg);
6247 err = genlmsg_reply(msg, info);
6252 mutex_unlock(®ion->snapshot_lock);
6255 err_snapshot_create:
6256 region->ops->destructor(data);
6257 err_snapshot_capture:
6258 __devlink_snapshot_id_decrement(devlink, snapshot_id);
6259 mutex_unlock(®ion->snapshot_lock);
6263 devlink_region_snapshot_del(region, snapshot);
6265 mutex_unlock(®ion->snapshot_lock);
6269 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
6270 u8 *chunk, u32 chunk_size,
6273 struct nlattr *chunk_attr;
6276 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
6280 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
6282 goto nla_put_failure;
6284 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
6287 goto nla_put_failure;
6289 nla_nest_end(msg, chunk_attr);
6293 nla_nest_cancel(msg, chunk_attr);
6297 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
6299 typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size,
6301 struct netlink_ext_ack *extack);
6304 devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb,
6305 void *cb_priv, u64 start_offset, u64 end_offset,
6306 u64 *new_offset, struct netlink_ext_ack *extack)
6308 u64 curr_offset = start_offset;
6312 /* Allocate and re-use a single buffer */
6313 data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL);
6317 *new_offset = start_offset;
6319 while (curr_offset < end_offset) {
6322 data_size = min_t(u32, end_offset - curr_offset,
6323 DEVLINK_REGION_READ_CHUNK_SIZE);
6325 err = cb(cb_priv, data, data_size, curr_offset, extack);
6329 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset);
6333 curr_offset += data_size;
6335 *new_offset = curr_offset;
6343 devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6345 struct netlink_ext_ack __always_unused *extack)
6347 struct devlink_snapshot *snapshot = cb_priv;
6349 memcpy(chunk, &snapshot->data[curr_offset], chunk_size);
6355 devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6356 u64 curr_offset, struct netlink_ext_ack *extack)
6358 struct devlink_region *region = cb_priv;
6360 return region->port_ops->read(region->port, region->port_ops, extack,
6361 curr_offset, chunk_size, chunk);
6365 devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6366 u64 curr_offset, struct netlink_ext_ack *extack)
6368 struct devlink_region *region = cb_priv;
6370 return region->ops->read(region->devlink, region->ops, extack,
6371 curr_offset, chunk_size, chunk);
6374 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
6375 struct netlink_callback *cb)
6377 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
6378 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
6379 struct nlattr *chunks_attr, *region_attr, *snapshot_attr;
6380 u64 ret_offset, start_offset, end_offset = U64_MAX;
6381 struct nlattr **attrs = info->attrs;
6382 struct devlink_port *port = NULL;
6383 devlink_chunk_fill_t *region_cb;
6384 struct devlink_region *region;
6385 const char *region_name;
6386 struct devlink *devlink;
6388 void *region_cb_priv;
6392 start_offset = state->start_offset;
6394 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
6395 if (IS_ERR(devlink))
6396 return PTR_ERR(devlink);
6400 if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
6401 NL_SET_ERR_MSG(cb->extack, "No region name provided");
6406 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6407 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6409 port = devlink_port_get_by_index(devlink, index);
6416 region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
6417 region_name = nla_data(region_attr);
6420 region = devlink_port_region_get_by_name(port, region_name);
6422 region = devlink_region_get_by_name(devlink, region_name);
6425 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
6430 snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
6431 if (!snapshot_attr) {
6432 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
6433 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided");
6438 if (!region->ops->read) {
6439 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
6445 region_cb = &devlink_region_port_direct_fill;
6447 region_cb = &devlink_region_direct_fill;
6448 region_cb_priv = region;
6450 struct devlink_snapshot *snapshot;
6453 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
6454 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot");
6459 snapshot_id = nla_get_u32(snapshot_attr);
6460 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6462 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
6466 region_cb = &devlink_region_snapshot_fill;
6467 region_cb_priv = snapshot;
6470 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
6471 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
6474 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6476 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6477 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
6480 if (end_offset > region->size)
6481 end_offset = region->size;
6483 /* return 0 if there is no further data to read */
6484 if (start_offset == end_offset) {
6489 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
6490 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
6491 DEVLINK_CMD_REGION_READ);
6497 err = devlink_nl_put_handle(skb, devlink);
6499 goto nla_put_failure;
6502 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
6503 region->port->index);
6505 goto nla_put_failure;
6508 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
6510 goto nla_put_failure;
6512 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
6515 goto nla_put_failure;
6518 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
6519 start_offset, end_offset, &ret_offset,
6522 if (err && err != -EMSGSIZE)
6523 goto nla_put_failure;
6525 /* Check if there was any progress done to prevent infinite loop */
6526 if (ret_offset == start_offset) {
6528 goto nla_put_failure;
6531 state->start_offset = ret_offset;
6533 nla_nest_end(skb, chunks_attr);
6534 genlmsg_end(skb, hdr);
6535 devl_unlock(devlink);
6536 devlink_put(devlink);
6540 genlmsg_cancel(skb, hdr);
6542 devl_unlock(devlink);
6543 devlink_put(devlink);
6547 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
6551 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
6553 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
6555 int devlink_info_board_serial_number_put(struct devlink_info_req *req,
6560 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
6563 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
6565 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
6566 const char *version_name,
6567 const char *version_value,
6568 enum devlink_info_version_type version_type)
6570 struct nlattr *nest;
6573 if (req->version_cb)
6574 req->version_cb(version_name, version_type,
6575 req->version_cb_priv);
6580 nest = nla_nest_start_noflag(req->msg, attr);
6584 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
6587 goto nla_put_failure;
6589 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
6592 goto nla_put_failure;
6594 nla_nest_end(req->msg, nest);
6599 nla_nest_cancel(req->msg, nest);
6603 int devlink_info_version_fixed_put(struct devlink_info_req *req,
6604 const char *version_name,
6605 const char *version_value)
6607 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
6608 version_name, version_value,
6609 DEVLINK_INFO_VERSION_TYPE_NONE);
6611 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
6613 int devlink_info_version_stored_put(struct devlink_info_req *req,
6614 const char *version_name,
6615 const char *version_value)
6617 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6618 version_name, version_value,
6619 DEVLINK_INFO_VERSION_TYPE_NONE);
6621 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
6623 int devlink_info_version_stored_put_ext(struct devlink_info_req *req,
6624 const char *version_name,
6625 const char *version_value,
6626 enum devlink_info_version_type version_type)
6628 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6629 version_name, version_value,
6632 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext);
6634 int devlink_info_version_running_put(struct devlink_info_req *req,
6635 const char *version_name,
6636 const char *version_value)
6638 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6639 version_name, version_value,
6640 DEVLINK_INFO_VERSION_TYPE_NONE);
6642 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
6644 int devlink_info_version_running_put_ext(struct devlink_info_req *req,
6645 const char *version_name,
6646 const char *version_value,
6647 enum devlink_info_version_type version_type)
6649 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6650 version_name, version_value,
6653 EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext);
6655 static int devlink_nl_driver_info_get(struct device_driver *drv,
6656 struct devlink_info_req *req)
6662 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME,
6669 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
6670 enum devlink_command cmd, u32 portid,
6671 u32 seq, int flags, struct netlink_ext_ack *extack)
6673 struct device *dev = devlink_to_dev(devlink);
6674 struct devlink_info_req req = {};
6678 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6683 if (devlink_nl_put_handle(msg, devlink))
6684 goto err_cancel_msg;
6687 if (devlink->ops->info_get) {
6688 err = devlink->ops->info_get(devlink, &req, extack);
6690 goto err_cancel_msg;
6693 err = devlink_nl_driver_info_get(dev->driver, &req);
6695 goto err_cancel_msg;
6697 genlmsg_end(msg, hdr);
6701 genlmsg_cancel(msg, hdr);
6705 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
6706 struct genl_info *info)
6708 struct devlink *devlink = info->user_ptr[0];
6709 struct sk_buff *msg;
6712 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6716 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6717 info->snd_portid, info->snd_seq, 0,
6724 return genlmsg_reply(msg, info);
6727 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
6728 struct netlink_callback *cb)
6730 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
6731 struct devlink *devlink;
6734 devlink_dump_for_each_instance_get(msg, state, devlink) {
6736 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6737 NETLINK_CB(cb->skb).portid,
6738 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6740 devl_unlock(devlink);
6741 if (err == -EOPNOTSUPP)
6744 devlink_put(devlink);
6747 devlink_put(devlink);
6750 if (err != -EMSGSIZE)
6756 struct devlink_fmsg_item {
6757 struct list_head list;
6764 struct devlink_fmsg {
6765 struct list_head item_list;
6766 bool putting_binary; /* This flag forces enclosing of binary data
6767 * in an array brackets. It forces using
6768 * of designated API:
6769 * devlink_fmsg_binary_pair_nest_start()
6770 * devlink_fmsg_binary_pair_nest_end()
6774 static struct devlink_fmsg *devlink_fmsg_alloc(void)
6776 struct devlink_fmsg *fmsg;
6778 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
6782 INIT_LIST_HEAD(&fmsg->item_list);
6787 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
6789 struct devlink_fmsg_item *item, *tmp;
6791 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
6792 list_del(&item->list);
6798 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
6801 struct devlink_fmsg_item *item;
6803 item = kzalloc(sizeof(*item), GFP_KERNEL);
6807 item->attrtype = attrtype;
6808 list_add_tail(&item->list, &fmsg->item_list);
6813 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
6815 if (fmsg->putting_binary)
6818 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
6820 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
6822 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
6824 if (fmsg->putting_binary)
6827 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
6830 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
6832 if (fmsg->putting_binary)
6835 return devlink_fmsg_nest_end(fmsg);
6837 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
6839 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
6841 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
6843 struct devlink_fmsg_item *item;
6845 if (fmsg->putting_binary)
6848 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
6851 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
6855 item->nla_type = NLA_NUL_STRING;
6856 item->len = strlen(name) + 1;
6857 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
6858 memcpy(&item->value, name, item->len);
6859 list_add_tail(&item->list, &fmsg->item_list);
6864 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
6868 if (fmsg->putting_binary)
6871 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
6875 err = devlink_fmsg_put_name(fmsg, name);
6881 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
6883 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
6885 if (fmsg->putting_binary)
6888 return devlink_fmsg_nest_end(fmsg);
6890 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
6892 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
6897 if (fmsg->putting_binary)
6900 err = devlink_fmsg_pair_nest_start(fmsg, name);
6904 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
6910 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
6912 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
6916 if (fmsg->putting_binary)
6919 err = devlink_fmsg_nest_end(fmsg);
6923 err = devlink_fmsg_nest_end(fmsg);
6929 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
6931 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
6936 err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
6940 fmsg->putting_binary = true;
6943 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
6945 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
6947 if (!fmsg->putting_binary)
6950 fmsg->putting_binary = false;
6951 return devlink_fmsg_arr_pair_nest_end(fmsg);
6953 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
6955 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
6956 const void *value, u16 value_len,
6959 struct devlink_fmsg_item *item;
6961 if (value_len > DEVLINK_FMSG_MAX_SIZE)
6964 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
6968 item->nla_type = value_nla_type;
6969 item->len = value_len;
6970 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
6971 memcpy(&item->value, value, item->len);
6972 list_add_tail(&item->list, &fmsg->item_list);
6977 static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
6979 if (fmsg->putting_binary)
6982 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
6985 static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
6987 if (fmsg->putting_binary)
6990 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
6993 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
6995 if (fmsg->putting_binary)
6998 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
7000 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
7002 static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
7004 if (fmsg->putting_binary)
7007 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
7010 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
7012 if (fmsg->putting_binary)
7015 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
7018 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
7020 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
7023 if (!fmsg->putting_binary)
7026 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
7028 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
7030 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
7035 err = devlink_fmsg_pair_nest_start(fmsg, name);
7039 err = devlink_fmsg_bool_put(fmsg, value);
7043 err = devlink_fmsg_pair_nest_end(fmsg);
7049 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
7051 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
7056 err = devlink_fmsg_pair_nest_start(fmsg, name);
7060 err = devlink_fmsg_u8_put(fmsg, value);
7064 err = devlink_fmsg_pair_nest_end(fmsg);
7070 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
7072 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
7077 err = devlink_fmsg_pair_nest_start(fmsg, name);
7081 err = devlink_fmsg_u32_put(fmsg, value);
7085 err = devlink_fmsg_pair_nest_end(fmsg);
7091 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
7093 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
7098 err = devlink_fmsg_pair_nest_start(fmsg, name);
7102 err = devlink_fmsg_u64_put(fmsg, value);
7106 err = devlink_fmsg_pair_nest_end(fmsg);
7112 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
7114 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
7119 err = devlink_fmsg_pair_nest_start(fmsg, name);
7123 err = devlink_fmsg_string_put(fmsg, value);
7127 err = devlink_fmsg_pair_nest_end(fmsg);
7133 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
7135 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
7136 const void *value, u32 value_len)
7143 err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
7147 for (offset = 0; offset < value_len; offset += data_size) {
7148 data_size = value_len - offset;
7149 if (data_size > DEVLINK_FMSG_MAX_SIZE)
7150 data_size = DEVLINK_FMSG_MAX_SIZE;
7151 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
7154 /* Exit from loop with a break (instead of
7155 * return) to make sure putting_binary is turned off in
7156 * devlink_fmsg_binary_pair_nest_end
7160 end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
7166 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
7169 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
7171 switch (msg->nla_type) {
7176 case NLA_NUL_STRING:
7178 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
7186 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
7188 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
7191 switch (msg->nla_type) {
7193 /* Always provide flag data, regardless of its value */
7194 tmp = *(bool *) msg->value;
7196 return nla_put_u8(skb, attrtype, tmp);
7198 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
7200 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
7202 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
7204 case NLA_NUL_STRING:
7205 return nla_put_string(skb, attrtype, (char *) &msg->value);
7207 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
7214 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7217 struct devlink_fmsg_item *item;
7218 struct nlattr *fmsg_nlattr;
7222 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
7226 list_for_each_entry(item, &fmsg->item_list, list) {
7232 switch (item->attrtype) {
7233 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
7234 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
7235 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
7236 case DEVLINK_ATTR_FMSG_NEST_END:
7237 err = nla_put_flag(skb, item->attrtype);
7239 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
7240 err = devlink_fmsg_item_fill_type(item, skb);
7243 err = devlink_fmsg_item_fill_data(item, skb);
7245 case DEVLINK_ATTR_FMSG_OBJ_NAME:
7246 err = nla_put_string(skb, item->attrtype,
7247 (char *) &item->value);
7259 nla_nest_end(skb, fmsg_nlattr);
7263 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
7264 struct genl_info *info,
7265 enum devlink_command cmd, int flags)
7267 struct nlmsghdr *nlh;
7268 struct sk_buff *skb;
7275 int tmp_index = index;
7277 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7281 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
7282 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
7285 goto nla_put_failure;
7288 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7291 else if (err != -EMSGSIZE || tmp_index == index)
7292 goto nla_put_failure;
7294 genlmsg_end(skb, hdr);
7295 err = genlmsg_reply(skb, info);
7300 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7303 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
7304 NLMSG_DONE, 0, flags | NLM_F_MULTI);
7307 goto nla_put_failure;
7310 return genlmsg_reply(skb, info);
7317 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7318 struct netlink_callback *cb,
7319 enum devlink_command cmd)
7321 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7322 int index = state->idx;
7323 int tmp_index = index;
7327 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7328 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
7331 goto nla_put_failure;
7334 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7335 if ((err && err != -EMSGSIZE) || tmp_index == index)
7336 goto nla_put_failure;
7339 genlmsg_end(skb, hdr);
7343 genlmsg_cancel(skb, hdr);
7347 struct devlink_health_reporter {
7348 struct list_head list;
7350 const struct devlink_health_reporter_ops *ops;
7351 struct devlink *devlink;
7352 struct devlink_port *devlink_port;
7353 struct devlink_fmsg *dump_fmsg;
7354 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
7355 u64 graceful_period;
7363 u64 last_recovery_ts;
7364 refcount_t refcount;
7368 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
7370 return reporter->priv;
7372 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
7374 static struct devlink_health_reporter *
7375 __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
7376 struct mutex *list_lock,
7377 const char *reporter_name)
7379 struct devlink_health_reporter *reporter;
7381 lockdep_assert_held(list_lock);
7382 list_for_each_entry(reporter, reporter_list, list)
7383 if (!strcmp(reporter->ops->name, reporter_name))
7388 static struct devlink_health_reporter *
7389 devlink_health_reporter_find_by_name(struct devlink *devlink,
7390 const char *reporter_name)
7392 return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
7393 &devlink->reporters_lock,
7397 static struct devlink_health_reporter *
7398 devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
7399 const char *reporter_name)
7401 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
7402 &devlink_port->reporters_lock,
7406 static struct devlink_health_reporter *
7407 __devlink_health_reporter_create(struct devlink *devlink,
7408 const struct devlink_health_reporter_ops *ops,
7409 u64 graceful_period, void *priv)
7411 struct devlink_health_reporter *reporter;
7413 if (WARN_ON(graceful_period && !ops->recover))
7414 return ERR_PTR(-EINVAL);
7416 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
7418 return ERR_PTR(-ENOMEM);
7420 reporter->priv = priv;
7421 reporter->ops = ops;
7422 reporter->devlink = devlink;
7423 reporter->graceful_period = graceful_period;
7424 reporter->auto_recover = !!ops->recover;
7425 reporter->auto_dump = !!ops->dump;
7426 mutex_init(&reporter->dump_lock);
7427 refcount_set(&reporter->refcount, 1);
7432 * devlink_port_health_reporter_create - create devlink health reporter for
7433 * specified port instance
7435 * @port: devlink_port which should contain the new reporter
7437 * @graceful_period: to avoid recovery loops, in msecs
7440 struct devlink_health_reporter *
7441 devlink_port_health_reporter_create(struct devlink_port *port,
7442 const struct devlink_health_reporter_ops *ops,
7443 u64 graceful_period, void *priv)
7445 struct devlink_health_reporter *reporter;
7447 mutex_lock(&port->reporters_lock);
7448 if (__devlink_health_reporter_find_by_name(&port->reporter_list,
7449 &port->reporters_lock, ops->name)) {
7450 reporter = ERR_PTR(-EEXIST);
7454 reporter = __devlink_health_reporter_create(port->devlink, ops,
7455 graceful_period, priv);
7456 if (IS_ERR(reporter))
7459 reporter->devlink_port = port;
7460 list_add_tail(&reporter->list, &port->reporter_list);
7462 mutex_unlock(&port->reporters_lock);
7465 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
7468 * devlink_health_reporter_create - create devlink health reporter
7472 * @graceful_period: to avoid recovery loops, in msecs
7475 struct devlink_health_reporter *
7476 devlink_health_reporter_create(struct devlink *devlink,
7477 const struct devlink_health_reporter_ops *ops,
7478 u64 graceful_period, void *priv)
7480 struct devlink_health_reporter *reporter;
7482 mutex_lock(&devlink->reporters_lock);
7483 if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
7484 reporter = ERR_PTR(-EEXIST);
7488 reporter = __devlink_health_reporter_create(devlink, ops,
7489 graceful_period, priv);
7490 if (IS_ERR(reporter))
7493 list_add_tail(&reporter->list, &devlink->reporter_list);
7495 mutex_unlock(&devlink->reporters_lock);
7498 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
7501 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
7503 mutex_destroy(&reporter->dump_lock);
7504 if (reporter->dump_fmsg)
7505 devlink_fmsg_free(reporter->dump_fmsg);
7510 devlink_health_reporter_put(struct devlink_health_reporter *reporter)
7512 if (refcount_dec_and_test(&reporter->refcount))
7513 devlink_health_reporter_free(reporter);
7517 __devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7519 list_del(&reporter->list);
7520 devlink_health_reporter_put(reporter);
7524 * devlink_health_reporter_destroy - destroy devlink health reporter
7526 * @reporter: devlink health reporter to destroy
7529 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7531 struct mutex *lock = &reporter->devlink->reporters_lock;
7534 __devlink_health_reporter_destroy(reporter);
7537 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
7540 * devlink_port_health_reporter_destroy - destroy devlink port health reporter
7542 * @reporter: devlink health reporter to destroy
7545 devlink_port_health_reporter_destroy(struct devlink_health_reporter *reporter)
7547 struct mutex *lock = &reporter->devlink_port->reporters_lock;
7550 __devlink_health_reporter_destroy(reporter);
7553 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_destroy);
7556 devlink_nl_health_reporter_fill(struct sk_buff *msg,
7557 struct devlink_health_reporter *reporter,
7558 enum devlink_command cmd, u32 portid,
7561 struct devlink *devlink = reporter->devlink;
7562 struct nlattr *reporter_attr;
7565 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7569 if (devlink_nl_put_handle(msg, devlink))
7570 goto genlmsg_cancel;
7572 if (reporter->devlink_port) {
7573 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
7574 goto genlmsg_cancel;
7576 reporter_attr = nla_nest_start_noflag(msg,
7577 DEVLINK_ATTR_HEALTH_REPORTER);
7579 goto genlmsg_cancel;
7580 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
7581 reporter->ops->name))
7582 goto reporter_nest_cancel;
7583 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
7584 reporter->health_state))
7585 goto reporter_nest_cancel;
7586 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
7587 reporter->error_count, DEVLINK_ATTR_PAD))
7588 goto reporter_nest_cancel;
7589 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
7590 reporter->recovery_count, DEVLINK_ATTR_PAD))
7591 goto reporter_nest_cancel;
7592 if (reporter->ops->recover &&
7593 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
7594 reporter->graceful_period,
7596 goto reporter_nest_cancel;
7597 if (reporter->ops->recover &&
7598 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
7599 reporter->auto_recover))
7600 goto reporter_nest_cancel;
7601 if (reporter->dump_fmsg &&
7602 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
7603 jiffies_to_msecs(reporter->dump_ts),
7605 goto reporter_nest_cancel;
7606 if (reporter->dump_fmsg &&
7607 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
7608 reporter->dump_real_ts, DEVLINK_ATTR_PAD))
7609 goto reporter_nest_cancel;
7610 if (reporter->ops->dump &&
7611 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
7612 reporter->auto_dump))
7613 goto reporter_nest_cancel;
7615 nla_nest_end(msg, reporter_attr);
7616 genlmsg_end(msg, hdr);
7619 reporter_nest_cancel:
7620 nla_nest_end(msg, reporter_attr);
7622 genlmsg_cancel(msg, hdr);
7626 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
7627 enum devlink_command cmd)
7629 struct devlink *devlink = reporter->devlink;
7630 struct sk_buff *msg;
7633 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7634 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
7636 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7640 err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0);
7646 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
7647 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7651 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
7653 reporter->recovery_count++;
7654 reporter->last_recovery_ts = jiffies;
7656 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
7659 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
7660 void *priv_ctx, struct netlink_ext_ack *extack)
7664 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
7667 if (!reporter->ops->recover)
7670 err = reporter->ops->recover(reporter, priv_ctx, extack);
7674 devlink_health_reporter_recovery_done(reporter);
7675 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
7676 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7682 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
7684 if (!reporter->dump_fmsg)
7686 devlink_fmsg_free(reporter->dump_fmsg);
7687 reporter->dump_fmsg = NULL;
7690 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
7692 struct netlink_ext_ack *extack)
7696 if (!reporter->ops->dump)
7699 if (reporter->dump_fmsg)
7702 reporter->dump_fmsg = devlink_fmsg_alloc();
7703 if (!reporter->dump_fmsg) {
7708 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
7712 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
7717 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
7721 reporter->dump_ts = jiffies;
7722 reporter->dump_real_ts = ktime_get_real_ns();
7727 devlink_health_dump_clear(reporter);
7731 int devlink_health_report(struct devlink_health_reporter *reporter,
7732 const char *msg, void *priv_ctx)
7734 enum devlink_health_reporter_state prev_health_state;
7735 struct devlink *devlink = reporter->devlink;
7736 unsigned long recover_ts_threshold;
7739 /* write a log message of the current error */
7741 trace_devlink_health_report(devlink, reporter->ops->name, msg);
7742 reporter->error_count++;
7743 prev_health_state = reporter->health_state;
7744 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
7745 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7747 /* abort if the previous error wasn't recovered */
7748 recover_ts_threshold = reporter->last_recovery_ts +
7749 msecs_to_jiffies(reporter->graceful_period);
7750 if (reporter->auto_recover &&
7751 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
7752 (reporter->last_recovery_ts && reporter->recovery_count &&
7753 time_is_after_jiffies(recover_ts_threshold)))) {
7754 trace_devlink_health_recover_aborted(devlink,
7755 reporter->ops->name,
7756 reporter->health_state,
7758 reporter->last_recovery_ts);
7762 if (reporter->auto_dump) {
7763 mutex_lock(&reporter->dump_lock);
7764 /* store current dump of current error, for later analysis */
7765 devlink_health_do_dump(reporter, priv_ctx, NULL);
7766 mutex_unlock(&reporter->dump_lock);
7769 if (!reporter->auto_recover)
7773 ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL);
7774 devl_unlock(devlink);
7778 EXPORT_SYMBOL_GPL(devlink_health_report);
7780 static struct devlink_health_reporter *
7781 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
7782 struct nlattr **attrs)
7784 struct devlink_health_reporter *reporter;
7785 struct devlink_port *devlink_port;
7786 char *reporter_name;
7788 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
7791 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
7792 devlink_port = devlink_port_get_from_attrs(devlink, attrs);
7793 if (IS_ERR(devlink_port)) {
7794 mutex_lock(&devlink->reporters_lock);
7795 reporter = devlink_health_reporter_find_by_name(devlink, reporter_name);
7797 refcount_inc(&reporter->refcount);
7798 mutex_unlock(&devlink->reporters_lock);
7800 mutex_lock(&devlink_port->reporters_lock);
7801 reporter = devlink_port_health_reporter_find_by_name(devlink_port, reporter_name);
7803 refcount_inc(&reporter->refcount);
7804 mutex_unlock(&devlink_port->reporters_lock);
7810 static struct devlink_health_reporter *
7811 devlink_health_reporter_get_from_info(struct devlink *devlink,
7812 struct genl_info *info)
7814 return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
7817 static struct devlink_health_reporter *
7818 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
7820 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
7821 struct devlink_health_reporter *reporter;
7822 struct nlattr **attrs = info->attrs;
7823 struct devlink *devlink;
7825 devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
7826 if (IS_ERR(devlink))
7829 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
7830 devlink_put(devlink);
7835 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
7836 enum devlink_health_reporter_state state)
7838 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
7839 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
7842 if (reporter->health_state == state)
7845 reporter->health_state = state;
7846 trace_devlink_health_reporter_state_update(reporter->devlink,
7847 reporter->ops->name, state);
7848 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7850 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
7852 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
7853 struct genl_info *info)
7855 struct devlink *devlink = info->user_ptr[0];
7856 struct devlink_health_reporter *reporter;
7857 struct sk_buff *msg;
7860 reporter = devlink_health_reporter_get_from_info(devlink, info);
7864 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7870 err = devlink_nl_health_reporter_fill(msg, reporter,
7871 DEVLINK_CMD_HEALTH_REPORTER_GET,
7872 info->snd_portid, info->snd_seq,
7879 err = genlmsg_reply(msg, info);
7881 devlink_health_reporter_put(reporter);
7886 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
7887 struct netlink_callback *cb)
7889 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7890 struct devlink *devlink;
7893 devlink_dump_for_each_instance_get(msg, state, devlink) {
7894 struct devlink_health_reporter *reporter;
7895 struct devlink_port *port;
7896 unsigned long port_index;
7899 mutex_lock(&devlink->reporters_lock);
7900 list_for_each_entry(reporter, &devlink->reporter_list,
7902 if (idx < state->idx) {
7906 err = devlink_nl_health_reporter_fill(
7907 msg, reporter, DEVLINK_CMD_HEALTH_REPORTER_GET,
7908 NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7911 mutex_unlock(&devlink->reporters_lock);
7912 devlink_put(devlink);
7918 mutex_unlock(&devlink->reporters_lock);
7921 xa_for_each(&devlink->ports, port_index, port) {
7922 mutex_lock(&port->reporters_lock);
7923 list_for_each_entry(reporter, &port->reporter_list, list) {
7924 if (idx < state->idx) {
7928 err = devlink_nl_health_reporter_fill(
7930 DEVLINK_CMD_HEALTH_REPORTER_GET,
7931 NETLINK_CB(cb->skb).portid,
7932 cb->nlh->nlmsg_seq, NLM_F_MULTI);
7934 mutex_unlock(&port->reporters_lock);
7935 devl_unlock(devlink);
7936 devlink_put(devlink);
7942 mutex_unlock(&port->reporters_lock);
7944 devl_unlock(devlink);
7945 devlink_put(devlink);
7952 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
7953 struct genl_info *info)
7955 struct devlink *devlink = info->user_ptr[0];
7956 struct devlink_health_reporter *reporter;
7959 reporter = devlink_health_reporter_get_from_info(devlink, info);
7963 if (!reporter->ops->recover &&
7964 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
7965 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) {
7969 if (!reporter->ops->dump &&
7970 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]) {
7975 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
7976 reporter->graceful_period =
7977 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
7979 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
7980 reporter->auto_recover =
7981 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
7983 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7984 reporter->auto_dump =
7985 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
7987 devlink_health_reporter_put(reporter);
7990 devlink_health_reporter_put(reporter);
7994 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
7995 struct genl_info *info)
7997 struct devlink *devlink = info->user_ptr[0];
7998 struct devlink_health_reporter *reporter;
8001 reporter = devlink_health_reporter_get_from_info(devlink, info);
8005 err = devlink_health_reporter_recover(reporter, NULL, info->extack);
8007 devlink_health_reporter_put(reporter);
8011 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
8012 struct genl_info *info)
8014 struct devlink *devlink = info->user_ptr[0];
8015 struct devlink_health_reporter *reporter;
8016 struct devlink_fmsg *fmsg;
8019 reporter = devlink_health_reporter_get_from_info(devlink, info);
8023 if (!reporter->ops->diagnose) {
8024 devlink_health_reporter_put(reporter);
8028 fmsg = devlink_fmsg_alloc();
8030 devlink_health_reporter_put(reporter);
8034 err = devlink_fmsg_obj_nest_start(fmsg);
8038 err = reporter->ops->diagnose(reporter, fmsg, info->extack);
8042 err = devlink_fmsg_obj_nest_end(fmsg);
8046 err = devlink_fmsg_snd(fmsg, info,
8047 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
8050 devlink_fmsg_free(fmsg);
8051 devlink_health_reporter_put(reporter);
8056 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
8057 struct netlink_callback *cb)
8059 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8060 struct devlink_health_reporter *reporter;
8063 reporter = devlink_health_reporter_get_from_cb(cb);
8067 if (!reporter->ops->dump) {
8071 mutex_lock(&reporter->dump_lock);
8073 err = devlink_health_do_dump(reporter, NULL, cb->extack);
8076 state->dump_ts = reporter->dump_ts;
8078 if (!reporter->dump_fmsg || state->dump_ts != reporter->dump_ts) {
8079 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
8084 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
8085 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
8087 mutex_unlock(&reporter->dump_lock);
8089 devlink_health_reporter_put(reporter);
8094 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
8095 struct genl_info *info)
8097 struct devlink *devlink = info->user_ptr[0];
8098 struct devlink_health_reporter *reporter;
8100 reporter = devlink_health_reporter_get_from_info(devlink, info);
8104 if (!reporter->ops->dump) {
8105 devlink_health_reporter_put(reporter);
8109 mutex_lock(&reporter->dump_lock);
8110 devlink_health_dump_clear(reporter);
8111 mutex_unlock(&reporter->dump_lock);
8112 devlink_health_reporter_put(reporter);
8116 static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
8117 struct genl_info *info)
8119 struct devlink *devlink = info->user_ptr[0];
8120 struct devlink_health_reporter *reporter;
8123 reporter = devlink_health_reporter_get_from_info(devlink, info);
8127 if (!reporter->ops->test) {
8128 devlink_health_reporter_put(reporter);
8132 err = reporter->ops->test(reporter, info->extack);
8134 devlink_health_reporter_put(reporter);
8138 struct devlink_stats {
8139 u64_stats_t rx_bytes;
8140 u64_stats_t rx_packets;
8141 struct u64_stats_sync syncp;
8145 * struct devlink_trap_policer_item - Packet trap policer attributes.
8146 * @policer: Immutable packet trap policer attributes.
8147 * @rate: Rate in packets / sec.
8148 * @burst: Burst size in packets.
8149 * @list: trap_policer_list member.
8151 * Describes packet trap policer attributes. Created by devlink during trap
8152 * policer registration.
8154 struct devlink_trap_policer_item {
8155 const struct devlink_trap_policer *policer;
8158 struct list_head list;
8162 * struct devlink_trap_group_item - Packet trap group attributes.
8163 * @group: Immutable packet trap group attributes.
8164 * @policer_item: Associated policer item. Can be NULL.
8165 * @list: trap_group_list member.
8166 * @stats: Trap group statistics.
8168 * Describes packet trap group attributes. Created by devlink during trap
8169 * group registration.
8171 struct devlink_trap_group_item {
8172 const struct devlink_trap_group *group;
8173 struct devlink_trap_policer_item *policer_item;
8174 struct list_head list;
8175 struct devlink_stats __percpu *stats;
8179 * struct devlink_trap_item - Packet trap attributes.
8180 * @trap: Immutable packet trap attributes.
8181 * @group_item: Associated group item.
8182 * @list: trap_list member.
8183 * @action: Trap action.
8184 * @stats: Trap statistics.
8185 * @priv: Driver private information.
8187 * Describes both mutable and immutable packet trap attributes. Created by
8188 * devlink during trap registration and used for all trap related operations.
8190 struct devlink_trap_item {
8191 const struct devlink_trap *trap;
8192 struct devlink_trap_group_item *group_item;
8193 struct list_head list;
8194 enum devlink_trap_action action;
8195 struct devlink_stats __percpu *stats;
8199 static struct devlink_trap_policer_item *
8200 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
8202 struct devlink_trap_policer_item *policer_item;
8204 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8205 if (policer_item->policer->id == id)
8206 return policer_item;
8212 static struct devlink_trap_item *
8213 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
8215 struct devlink_trap_item *trap_item;
8217 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8218 if (!strcmp(trap_item->trap->name, name))
8225 static struct devlink_trap_item *
8226 devlink_trap_item_get_from_info(struct devlink *devlink,
8227 struct genl_info *info)
8229 struct nlattr *attr;
8231 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
8233 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
8235 return devlink_trap_item_lookup(devlink, nla_data(attr));
8239 devlink_trap_action_get_from_info(struct genl_info *info,
8240 enum devlink_trap_action *p_trap_action)
8244 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
8246 case DEVLINK_TRAP_ACTION_DROP:
8247 case DEVLINK_TRAP_ACTION_TRAP:
8248 case DEVLINK_TRAP_ACTION_MIRROR:
8249 *p_trap_action = val;
8258 static int devlink_trap_metadata_put(struct sk_buff *msg,
8259 const struct devlink_trap *trap)
8261 struct nlattr *attr;
8263 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
8267 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
8268 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
8269 goto nla_put_failure;
8270 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
8271 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
8272 goto nla_put_failure;
8274 nla_nest_end(msg, attr);
8279 nla_nest_cancel(msg, attr);
8283 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
8284 struct devlink_stats *stats)
8288 memset(stats, 0, sizeof(*stats));
8289 for_each_possible_cpu(i) {
8290 struct devlink_stats *cpu_stats;
8291 u64 rx_packets, rx_bytes;
8294 cpu_stats = per_cpu_ptr(trap_stats, i);
8296 start = u64_stats_fetch_begin(&cpu_stats->syncp);
8297 rx_packets = u64_stats_read(&cpu_stats->rx_packets);
8298 rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
8299 } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
8301 u64_stats_add(&stats->rx_packets, rx_packets);
8302 u64_stats_add(&stats->rx_bytes, rx_bytes);
8307 devlink_trap_group_stats_put(struct sk_buff *msg,
8308 struct devlink_stats __percpu *trap_stats)
8310 struct devlink_stats stats;
8311 struct nlattr *attr;
8313 devlink_trap_stats_read(trap_stats, &stats);
8315 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8319 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8320 u64_stats_read(&stats.rx_packets),
8322 goto nla_put_failure;
8324 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8325 u64_stats_read(&stats.rx_bytes),
8327 goto nla_put_failure;
8329 nla_nest_end(msg, attr);
8334 nla_nest_cancel(msg, attr);
8338 static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
8339 const struct devlink_trap_item *trap_item)
8341 struct devlink_stats stats;
8342 struct nlattr *attr;
8346 if (devlink->ops->trap_drop_counter_get) {
8347 err = devlink->ops->trap_drop_counter_get(devlink,
8354 devlink_trap_stats_read(trap_item->stats, &stats);
8356 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8360 if (devlink->ops->trap_drop_counter_get &&
8361 nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8363 goto nla_put_failure;
8365 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8366 u64_stats_read(&stats.rx_packets),
8368 goto nla_put_failure;
8370 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8371 u64_stats_read(&stats.rx_bytes),
8373 goto nla_put_failure;
8375 nla_nest_end(msg, attr);
8380 nla_nest_cancel(msg, attr);
8384 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
8385 const struct devlink_trap_item *trap_item,
8386 enum devlink_command cmd, u32 portid, u32 seq,
8389 struct devlink_trap_group_item *group_item = trap_item->group_item;
8393 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8397 if (devlink_nl_put_handle(msg, devlink))
8398 goto nla_put_failure;
8400 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8401 group_item->group->name))
8402 goto nla_put_failure;
8404 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
8405 goto nla_put_failure;
8407 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
8408 goto nla_put_failure;
8410 if (trap_item->trap->generic &&
8411 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8412 goto nla_put_failure;
8414 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
8415 goto nla_put_failure;
8417 err = devlink_trap_metadata_put(msg, trap_item->trap);
8419 goto nla_put_failure;
8421 err = devlink_trap_stats_put(msg, devlink, trap_item);
8423 goto nla_put_failure;
8425 genlmsg_end(msg, hdr);
8430 genlmsg_cancel(msg, hdr);
8434 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
8435 struct genl_info *info)
8437 struct netlink_ext_ack *extack = info->extack;
8438 struct devlink *devlink = info->user_ptr[0];
8439 struct devlink_trap_item *trap_item;
8440 struct sk_buff *msg;
8443 if (list_empty(&devlink->trap_list))
8446 trap_item = devlink_trap_item_get_from_info(devlink, info);
8448 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8452 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8456 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8457 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
8462 return genlmsg_reply(msg, info);
8469 static int devlink_nl_cmd_trap_get_dumpit(struct sk_buff *msg,
8470 struct netlink_callback *cb)
8472 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8473 struct devlink *devlink;
8476 devlink_dump_for_each_instance_get(msg, state, devlink) {
8477 struct devlink_trap_item *trap_item;
8481 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8482 if (idx < state->idx) {
8486 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8487 DEVLINK_CMD_TRAP_NEW,
8488 NETLINK_CB(cb->skb).portid,
8492 devl_unlock(devlink);
8493 devlink_put(devlink);
8499 devl_unlock(devlink);
8500 devlink_put(devlink);
8506 static int __devlink_trap_action_set(struct devlink *devlink,
8507 struct devlink_trap_item *trap_item,
8508 enum devlink_trap_action trap_action,
8509 struct netlink_ext_ack *extack)
8513 if (trap_item->action != trap_action &&
8514 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
8515 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
8519 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
8520 trap_action, extack);
8524 trap_item->action = trap_action;
8529 static int devlink_trap_action_set(struct devlink *devlink,
8530 struct devlink_trap_item *trap_item,
8531 struct genl_info *info)
8533 enum devlink_trap_action trap_action;
8536 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8539 err = devlink_trap_action_get_from_info(info, &trap_action);
8541 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8545 return __devlink_trap_action_set(devlink, trap_item, trap_action,
8549 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
8550 struct genl_info *info)
8552 struct netlink_ext_ack *extack = info->extack;
8553 struct devlink *devlink = info->user_ptr[0];
8554 struct devlink_trap_item *trap_item;
8556 if (list_empty(&devlink->trap_list))
8559 trap_item = devlink_trap_item_get_from_info(devlink, info);
8561 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8565 return devlink_trap_action_set(devlink, trap_item, info);
8568 static struct devlink_trap_group_item *
8569 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
8571 struct devlink_trap_group_item *group_item;
8573 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8574 if (!strcmp(group_item->group->name, name))
8581 static struct devlink_trap_group_item *
8582 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
8584 struct devlink_trap_group_item *group_item;
8586 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8587 if (group_item->group->id == id)
8594 static struct devlink_trap_group_item *
8595 devlink_trap_group_item_get_from_info(struct devlink *devlink,
8596 struct genl_info *info)
8600 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
8602 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
8604 return devlink_trap_group_item_lookup(devlink, name);
8608 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
8609 const struct devlink_trap_group_item *group_item,
8610 enum devlink_command cmd, u32 portid, u32 seq,
8616 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8620 if (devlink_nl_put_handle(msg, devlink))
8621 goto nla_put_failure;
8623 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8624 group_item->group->name))
8625 goto nla_put_failure;
8627 if (group_item->group->generic &&
8628 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8629 goto nla_put_failure;
8631 if (group_item->policer_item &&
8632 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8633 group_item->policer_item->policer->id))
8634 goto nla_put_failure;
8636 err = devlink_trap_group_stats_put(msg, group_item->stats);
8638 goto nla_put_failure;
8640 genlmsg_end(msg, hdr);
8645 genlmsg_cancel(msg, hdr);
8649 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
8650 struct genl_info *info)
8652 struct netlink_ext_ack *extack = info->extack;
8653 struct devlink *devlink = info->user_ptr[0];
8654 struct devlink_trap_group_item *group_item;
8655 struct sk_buff *msg;
8658 if (list_empty(&devlink->trap_group_list))
8661 group_item = devlink_trap_group_item_get_from_info(devlink, info);
8663 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8667 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8671 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8672 DEVLINK_CMD_TRAP_GROUP_NEW,
8673 info->snd_portid, info->snd_seq, 0);
8675 goto err_trap_group_fill;
8677 return genlmsg_reply(msg, info);
8679 err_trap_group_fill:
8684 static int devlink_nl_cmd_trap_group_get_dumpit(struct sk_buff *msg,
8685 struct netlink_callback *cb)
8687 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8688 enum devlink_command cmd = DEVLINK_CMD_TRAP_GROUP_NEW;
8689 u32 portid = NETLINK_CB(cb->skb).portid;
8690 struct devlink *devlink;
8693 devlink_dump_for_each_instance_get(msg, state, devlink) {
8694 struct devlink_trap_group_item *group_item;
8698 list_for_each_entry(group_item, &devlink->trap_group_list,
8700 if (idx < state->idx) {
8704 err = devlink_nl_trap_group_fill(msg, devlink,
8710 devl_unlock(devlink);
8711 devlink_put(devlink);
8717 devl_unlock(devlink);
8718 devlink_put(devlink);
8725 __devlink_trap_group_action_set(struct devlink *devlink,
8726 struct devlink_trap_group_item *group_item,
8727 enum devlink_trap_action trap_action,
8728 struct netlink_ext_ack *extack)
8730 const char *group_name = group_item->group->name;
8731 struct devlink_trap_item *trap_item;
8734 if (devlink->ops->trap_group_action_set) {
8735 err = devlink->ops->trap_group_action_set(devlink, group_item->group,
8736 trap_action, extack);
8740 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8741 if (strcmp(trap_item->group_item->group->name, group_name))
8743 if (trap_item->action != trap_action &&
8744 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
8746 trap_item->action = trap_action;
8752 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8753 if (strcmp(trap_item->group_item->group->name, group_name))
8755 err = __devlink_trap_action_set(devlink, trap_item,
8756 trap_action, extack);
8765 devlink_trap_group_action_set(struct devlink *devlink,
8766 struct devlink_trap_group_item *group_item,
8767 struct genl_info *info, bool *p_modified)
8769 enum devlink_trap_action trap_action;
8772 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8775 err = devlink_trap_action_get_from_info(info, &trap_action);
8777 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8781 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
8791 static int devlink_trap_group_set(struct devlink *devlink,
8792 struct devlink_trap_group_item *group_item,
8793 struct genl_info *info)
8795 struct devlink_trap_policer_item *policer_item;
8796 struct netlink_ext_ack *extack = info->extack;
8797 const struct devlink_trap_policer *policer;
8798 struct nlattr **attrs = info->attrs;
8801 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8804 if (!devlink->ops->trap_group_set)
8807 policer_item = group_item->policer_item;
8808 if (attrs[DEVLINK_ATTR_TRAP_POLICER_ID]) {
8811 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8812 policer_item = devlink_trap_policer_item_lookup(devlink,
8814 if (policer_id && !policer_item) {
8815 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8819 policer = policer_item ? policer_item->policer : NULL;
8821 err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
8826 group_item->policer_item = policer_item;
8831 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
8832 struct genl_info *info)
8834 struct netlink_ext_ack *extack = info->extack;
8835 struct devlink *devlink = info->user_ptr[0];
8836 struct devlink_trap_group_item *group_item;
8837 bool modified = false;
8840 if (list_empty(&devlink->trap_group_list))
8843 group_item = devlink_trap_group_item_get_from_info(devlink, info);
8845 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8849 err = devlink_trap_group_action_set(devlink, group_item, info,
8854 err = devlink_trap_group_set(devlink, group_item, info);
8856 goto err_trap_group_set;
8862 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
8866 static struct devlink_trap_policer_item *
8867 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
8868 struct genl_info *info)
8872 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8874 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8876 return devlink_trap_policer_item_lookup(devlink, id);
8880 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
8881 const struct devlink_trap_policer *policer)
8883 struct nlattr *attr;
8887 if (!devlink->ops->trap_policer_counter_get)
8890 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
8894 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8898 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8900 goto nla_put_failure;
8902 nla_nest_end(msg, attr);
8907 nla_nest_cancel(msg, attr);
8912 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
8913 const struct devlink_trap_policer_item *policer_item,
8914 enum devlink_command cmd, u32 portid, u32 seq,
8920 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8924 if (devlink_nl_put_handle(msg, devlink))
8925 goto nla_put_failure;
8927 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8928 policer_item->policer->id))
8929 goto nla_put_failure;
8931 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
8932 policer_item->rate, DEVLINK_ATTR_PAD))
8933 goto nla_put_failure;
8935 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
8936 policer_item->burst, DEVLINK_ATTR_PAD))
8937 goto nla_put_failure;
8939 err = devlink_trap_policer_stats_put(msg, devlink,
8940 policer_item->policer);
8942 goto nla_put_failure;
8944 genlmsg_end(msg, hdr);
8949 genlmsg_cancel(msg, hdr);
8953 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
8954 struct genl_info *info)
8956 struct devlink_trap_policer_item *policer_item;
8957 struct netlink_ext_ack *extack = info->extack;
8958 struct devlink *devlink = info->user_ptr[0];
8959 struct sk_buff *msg;
8962 if (list_empty(&devlink->trap_policer_list))
8965 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8966 if (!policer_item) {
8967 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8971 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8975 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8976 DEVLINK_CMD_TRAP_POLICER_NEW,
8977 info->snd_portid, info->snd_seq, 0);
8979 goto err_trap_policer_fill;
8981 return genlmsg_reply(msg, info);
8983 err_trap_policer_fill:
8988 static int devlink_nl_cmd_trap_policer_get_dumpit(struct sk_buff *msg,
8989 struct netlink_callback *cb)
8991 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8992 enum devlink_command cmd = DEVLINK_CMD_TRAP_POLICER_NEW;
8993 u32 portid = NETLINK_CB(cb->skb).portid;
8994 struct devlink *devlink;
8997 devlink_dump_for_each_instance_get(msg, state, devlink) {
8998 struct devlink_trap_policer_item *policer_item;
9002 list_for_each_entry(policer_item, &devlink->trap_policer_list,
9004 if (idx < state->idx) {
9008 err = devlink_nl_trap_policer_fill(msg, devlink,
9014 devl_unlock(devlink);
9015 devlink_put(devlink);
9021 devl_unlock(devlink);
9022 devlink_put(devlink);
9029 devlink_trap_policer_set(struct devlink *devlink,
9030 struct devlink_trap_policer_item *policer_item,
9031 struct genl_info *info)
9033 struct netlink_ext_ack *extack = info->extack;
9034 struct nlattr **attrs = info->attrs;
9038 rate = policer_item->rate;
9039 burst = policer_item->burst;
9041 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
9042 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
9044 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
9045 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
9047 if (rate < policer_item->policer->min_rate) {
9048 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
9052 if (rate > policer_item->policer->max_rate) {
9053 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
9057 if (burst < policer_item->policer->min_burst) {
9058 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
9062 if (burst > policer_item->policer->max_burst) {
9063 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
9067 err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
9068 rate, burst, info->extack);
9072 policer_item->rate = rate;
9073 policer_item->burst = burst;
9078 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
9079 struct genl_info *info)
9081 struct devlink_trap_policer_item *policer_item;
9082 struct netlink_ext_ack *extack = info->extack;
9083 struct devlink *devlink = info->user_ptr[0];
9085 if (list_empty(&devlink->trap_policer_list))
9088 if (!devlink->ops->trap_policer_set)
9091 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
9092 if (!policer_item) {
9093 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
9097 return devlink_trap_policer_set(devlink, policer_item, info);
9100 const struct genl_small_ops devlink_nl_ops[56] = {
9102 .cmd = DEVLINK_CMD_GET,
9103 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9104 .doit = devlink_nl_cmd_get_doit,
9105 .dumpit = devlink_nl_cmd_get_dumpit,
9106 /* can be retrieved by unprivileged users */
9109 .cmd = DEVLINK_CMD_PORT_GET,
9110 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9111 .doit = devlink_nl_cmd_port_get_doit,
9112 .dumpit = devlink_nl_cmd_port_get_dumpit,
9113 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9114 /* can be retrieved by unprivileged users */
9117 .cmd = DEVLINK_CMD_PORT_SET,
9118 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9119 .doit = devlink_nl_cmd_port_set_doit,
9120 .flags = GENL_ADMIN_PERM,
9121 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9124 .cmd = DEVLINK_CMD_RATE_GET,
9125 .doit = devlink_nl_cmd_rate_get_doit,
9126 .dumpit = devlink_nl_instance_iter_dump,
9127 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
9128 /* can be retrieved by unprivileged users */
9131 .cmd = DEVLINK_CMD_RATE_SET,
9132 .doit = devlink_nl_cmd_rate_set_doit,
9133 .flags = GENL_ADMIN_PERM,
9134 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
9137 .cmd = DEVLINK_CMD_RATE_NEW,
9138 .doit = devlink_nl_cmd_rate_new_doit,
9139 .flags = GENL_ADMIN_PERM,
9142 .cmd = DEVLINK_CMD_RATE_DEL,
9143 .doit = devlink_nl_cmd_rate_del_doit,
9144 .flags = GENL_ADMIN_PERM,
9145 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
9148 .cmd = DEVLINK_CMD_PORT_SPLIT,
9149 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9150 .doit = devlink_nl_cmd_port_split_doit,
9151 .flags = GENL_ADMIN_PERM,
9152 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9155 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
9156 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9157 .doit = devlink_nl_cmd_port_unsplit_doit,
9158 .flags = GENL_ADMIN_PERM,
9159 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9162 .cmd = DEVLINK_CMD_PORT_NEW,
9163 .doit = devlink_nl_cmd_port_new_doit,
9164 .flags = GENL_ADMIN_PERM,
9167 .cmd = DEVLINK_CMD_PORT_DEL,
9168 .doit = devlink_nl_cmd_port_del_doit,
9169 .flags = GENL_ADMIN_PERM,
9172 .cmd = DEVLINK_CMD_LINECARD_GET,
9173 .doit = devlink_nl_cmd_linecard_get_doit,
9174 .dumpit = devlink_nl_cmd_linecard_get_dumpit,
9175 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9176 /* can be retrieved by unprivileged users */
9179 .cmd = DEVLINK_CMD_LINECARD_SET,
9180 .doit = devlink_nl_cmd_linecard_set_doit,
9181 .flags = GENL_ADMIN_PERM,
9182 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9185 .cmd = DEVLINK_CMD_SB_GET,
9186 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9187 .doit = devlink_nl_cmd_sb_get_doit,
9188 .dumpit = devlink_nl_cmd_sb_get_dumpit,
9189 /* can be retrieved by unprivileged users */
9192 .cmd = DEVLINK_CMD_SB_POOL_GET,
9193 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9194 .doit = devlink_nl_cmd_sb_pool_get_doit,
9195 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
9196 /* can be retrieved by unprivileged users */
9199 .cmd = DEVLINK_CMD_SB_POOL_SET,
9200 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9201 .doit = devlink_nl_cmd_sb_pool_set_doit,
9202 .flags = GENL_ADMIN_PERM,
9205 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
9206 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9207 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
9208 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
9209 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9210 /* can be retrieved by unprivileged users */
9213 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
9214 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9215 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
9216 .flags = GENL_ADMIN_PERM,
9217 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9220 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
9221 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9222 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
9223 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
9224 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9225 /* can be retrieved by unprivileged users */
9228 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
9229 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9230 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
9231 .flags = GENL_ADMIN_PERM,
9232 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9235 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
9236 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9237 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
9238 .flags = GENL_ADMIN_PERM,
9241 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
9242 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9243 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
9244 .flags = GENL_ADMIN_PERM,
9247 .cmd = DEVLINK_CMD_ESWITCH_GET,
9248 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9249 .doit = devlink_nl_cmd_eswitch_get_doit,
9250 .flags = GENL_ADMIN_PERM,
9253 .cmd = DEVLINK_CMD_ESWITCH_SET,
9254 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9255 .doit = devlink_nl_cmd_eswitch_set_doit,
9256 .flags = GENL_ADMIN_PERM,
9259 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
9260 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9261 .doit = devlink_nl_cmd_dpipe_table_get,
9262 /* can be retrieved by unprivileged users */
9265 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
9266 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9267 .doit = devlink_nl_cmd_dpipe_entries_get,
9268 /* can be retrieved by unprivileged users */
9271 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
9272 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9273 .doit = devlink_nl_cmd_dpipe_headers_get,
9274 /* can be retrieved by unprivileged users */
9277 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
9278 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9279 .doit = devlink_nl_cmd_dpipe_table_counters_set,
9280 .flags = GENL_ADMIN_PERM,
9283 .cmd = DEVLINK_CMD_RESOURCE_SET,
9284 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9285 .doit = devlink_nl_cmd_resource_set,
9286 .flags = GENL_ADMIN_PERM,
9289 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
9290 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9291 .doit = devlink_nl_cmd_resource_dump,
9292 /* can be retrieved by unprivileged users */
9295 .cmd = DEVLINK_CMD_RELOAD,
9296 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9297 .doit = devlink_nl_cmd_reload,
9298 .flags = GENL_ADMIN_PERM,
9301 .cmd = DEVLINK_CMD_PARAM_GET,
9302 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9303 .doit = devlink_nl_cmd_param_get_doit,
9304 .dumpit = devlink_nl_cmd_param_get_dumpit,
9305 /* can be retrieved by unprivileged users */
9308 .cmd = DEVLINK_CMD_PARAM_SET,
9309 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9310 .doit = devlink_nl_cmd_param_set_doit,
9311 .flags = GENL_ADMIN_PERM,
9314 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
9315 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9316 .doit = devlink_nl_cmd_port_param_get_doit,
9317 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
9318 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9319 /* can be retrieved by unprivileged users */
9322 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
9323 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9324 .doit = devlink_nl_cmd_port_param_set_doit,
9325 .flags = GENL_ADMIN_PERM,
9326 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9329 .cmd = DEVLINK_CMD_REGION_GET,
9330 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9331 .doit = devlink_nl_cmd_region_get_doit,
9332 .dumpit = devlink_nl_cmd_region_get_dumpit,
9333 .flags = GENL_ADMIN_PERM,
9336 .cmd = DEVLINK_CMD_REGION_NEW,
9337 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9338 .doit = devlink_nl_cmd_region_new,
9339 .flags = GENL_ADMIN_PERM,
9342 .cmd = DEVLINK_CMD_REGION_DEL,
9343 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9344 .doit = devlink_nl_cmd_region_del,
9345 .flags = GENL_ADMIN_PERM,
9348 .cmd = DEVLINK_CMD_REGION_READ,
9349 .validate = GENL_DONT_VALIDATE_STRICT |
9350 GENL_DONT_VALIDATE_DUMP_STRICT,
9351 .dumpit = devlink_nl_cmd_region_read_dumpit,
9352 .flags = GENL_ADMIN_PERM,
9355 .cmd = DEVLINK_CMD_INFO_GET,
9356 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9357 .doit = devlink_nl_cmd_info_get_doit,
9358 .dumpit = devlink_nl_cmd_info_get_dumpit,
9359 /* can be retrieved by unprivileged users */
9362 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
9363 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9364 .doit = devlink_nl_cmd_health_reporter_get_doit,
9365 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
9366 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9367 /* can be retrieved by unprivileged users */
9370 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
9371 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9372 .doit = devlink_nl_cmd_health_reporter_set_doit,
9373 .flags = GENL_ADMIN_PERM,
9374 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9377 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
9378 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9379 .doit = devlink_nl_cmd_health_reporter_recover_doit,
9380 .flags = GENL_ADMIN_PERM,
9381 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9384 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
9385 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9386 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
9387 .flags = GENL_ADMIN_PERM,
9388 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9391 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
9392 .validate = GENL_DONT_VALIDATE_STRICT |
9393 GENL_DONT_VALIDATE_DUMP_STRICT,
9394 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
9395 .flags = GENL_ADMIN_PERM,
9398 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
9399 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9400 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
9401 .flags = GENL_ADMIN_PERM,
9402 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9405 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
9406 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9407 .doit = devlink_nl_cmd_health_reporter_test_doit,
9408 .flags = GENL_ADMIN_PERM,
9409 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9412 .cmd = DEVLINK_CMD_FLASH_UPDATE,
9413 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9414 .doit = devlink_nl_cmd_flash_update,
9415 .flags = GENL_ADMIN_PERM,
9418 .cmd = DEVLINK_CMD_TRAP_GET,
9419 .doit = devlink_nl_cmd_trap_get_doit,
9420 .dumpit = devlink_nl_cmd_trap_get_dumpit,
9421 /* can be retrieved by unprivileged users */
9424 .cmd = DEVLINK_CMD_TRAP_SET,
9425 .doit = devlink_nl_cmd_trap_set_doit,
9426 .flags = GENL_ADMIN_PERM,
9429 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
9430 .doit = devlink_nl_cmd_trap_group_get_doit,
9431 .dumpit = devlink_nl_cmd_trap_group_get_dumpit,
9432 /* can be retrieved by unprivileged users */
9435 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
9436 .doit = devlink_nl_cmd_trap_group_set_doit,
9437 .flags = GENL_ADMIN_PERM,
9440 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
9441 .doit = devlink_nl_cmd_trap_policer_get_doit,
9442 .dumpit = devlink_nl_cmd_trap_policer_get_dumpit,
9443 /* can be retrieved by unprivileged users */
9446 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
9447 .doit = devlink_nl_cmd_trap_policer_set_doit,
9448 .flags = GENL_ADMIN_PERM,
9451 .cmd = DEVLINK_CMD_SELFTESTS_GET,
9452 .doit = devlink_nl_cmd_selftests_get_doit,
9453 .dumpit = devlink_nl_cmd_selftests_get_dumpit
9454 /* can be retrieved by unprivileged users */
9457 .cmd = DEVLINK_CMD_SELFTESTS_RUN,
9458 .doit = devlink_nl_cmd_selftests_run,
9459 .flags = GENL_ADMIN_PERM,
9461 /* -- No new ops here! Use split ops going forward! -- */
9464 bool devlink_reload_actions_valid(const struct devlink_ops *ops)
9466 const struct devlink_reload_combination *comb;
9469 if (!devlink_reload_supported(ops)) {
9470 if (WARN_ON(ops->reload_actions))
9475 if (WARN_ON(!ops->reload_actions ||
9476 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
9477 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
9480 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
9481 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
9484 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) {
9485 comb = &devlink_reload_invalid_combinations[i];
9486 if (ops->reload_actions == BIT(comb->action) &&
9487 ops->reload_limits == BIT(comb->limit))
9494 devlink_trap_policer_notify(struct devlink *devlink,
9495 const struct devlink_trap_policer_item *policer_item,
9496 enum devlink_command cmd);
9498 devlink_trap_group_notify(struct devlink *devlink,
9499 const struct devlink_trap_group_item *group_item,
9500 enum devlink_command cmd);
9501 static void devlink_trap_notify(struct devlink *devlink,
9502 const struct devlink_trap_item *trap_item,
9503 enum devlink_command cmd);
9505 void devlink_notify_register(struct devlink *devlink)
9507 struct devlink_trap_policer_item *policer_item;
9508 struct devlink_trap_group_item *group_item;
9509 struct devlink_param_item *param_item;
9510 struct devlink_trap_item *trap_item;
9511 struct devlink_port *devlink_port;
9512 struct devlink_linecard *linecard;
9513 struct devlink_rate *rate_node;
9514 struct devlink_region *region;
9515 unsigned long port_index;
9517 devlink_notify(devlink, DEVLINK_CMD_NEW);
9518 list_for_each_entry(linecard, &devlink->linecard_list, list)
9519 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
9521 xa_for_each(&devlink->ports, port_index, devlink_port)
9522 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9524 list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
9525 devlink_trap_policer_notify(devlink, policer_item,
9526 DEVLINK_CMD_TRAP_POLICER_NEW);
9528 list_for_each_entry(group_item, &devlink->trap_group_list, list)
9529 devlink_trap_group_notify(devlink, group_item,
9530 DEVLINK_CMD_TRAP_GROUP_NEW);
9532 list_for_each_entry(trap_item, &devlink->trap_list, list)
9533 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
9535 list_for_each_entry(rate_node, &devlink->rate_list, list)
9536 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9538 list_for_each_entry(region, &devlink->region_list, list)
9539 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9541 list_for_each_entry(param_item, &devlink->param_list, list)
9542 devlink_param_notify(devlink, 0, param_item,
9543 DEVLINK_CMD_PARAM_NEW);
9546 void devlink_notify_unregister(struct devlink *devlink)
9548 struct devlink_trap_policer_item *policer_item;
9549 struct devlink_trap_group_item *group_item;
9550 struct devlink_param_item *param_item;
9551 struct devlink_trap_item *trap_item;
9552 struct devlink_port *devlink_port;
9553 struct devlink_rate *rate_node;
9554 struct devlink_region *region;
9555 unsigned long port_index;
9557 list_for_each_entry_reverse(param_item, &devlink->param_list, list)
9558 devlink_param_notify(devlink, 0, param_item,
9559 DEVLINK_CMD_PARAM_DEL);
9561 list_for_each_entry_reverse(region, &devlink->region_list, list)
9562 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
9564 list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
9565 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
9567 list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
9568 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
9570 list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
9571 devlink_trap_group_notify(devlink, group_item,
9572 DEVLINK_CMD_TRAP_GROUP_DEL);
9573 list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
9575 devlink_trap_policer_notify(devlink, policer_item,
9576 DEVLINK_CMD_TRAP_POLICER_DEL);
9578 xa_for_each(&devlink->ports, port_index, devlink_port)
9579 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9580 devlink_notify(devlink, DEVLINK_CMD_DEL);
9583 static void devlink_port_type_warn(struct work_struct *work)
9585 WARN(true, "Type was not set for devlink port.");
9588 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
9590 /* Ignore CPU and DSA flavours. */
9591 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
9592 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
9593 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
9596 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
9598 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
9600 if (!devlink_port_type_should_warn(devlink_port))
9602 /* Schedule a work to WARN in case driver does not set port
9603 * type within timeout.
9605 schedule_delayed_work(&devlink_port->type_warn_dw,
9606 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
9609 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
9611 if (!devlink_port_type_should_warn(devlink_port))
9613 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
9617 * devlink_port_init() - Init devlink port
9620 * @devlink_port: devlink port
9622 * Initialize essencial stuff that is needed for functions
9623 * that may be called before devlink port registration.
9624 * Call to this function is optional and not needed
9625 * in case the driver does not use such functions.
9627 void devlink_port_init(struct devlink *devlink,
9628 struct devlink_port *devlink_port)
9630 if (devlink_port->initialized)
9632 devlink_port->devlink = devlink;
9633 INIT_LIST_HEAD(&devlink_port->region_list);
9634 devlink_port->initialized = true;
9636 EXPORT_SYMBOL_GPL(devlink_port_init);
9639 * devlink_port_fini() - Deinitialize devlink port
9641 * @devlink_port: devlink port
9643 * Deinitialize essencial stuff that is in use for functions
9644 * that may be called after devlink port unregistration.
9645 * Call to this function is optional and not needed
9646 * in case the driver does not use such functions.
9648 void devlink_port_fini(struct devlink_port *devlink_port)
9650 WARN_ON(!list_empty(&devlink_port->region_list));
9652 EXPORT_SYMBOL_GPL(devlink_port_fini);
9655 * devl_port_register() - Register devlink port
9658 * @devlink_port: devlink port
9659 * @port_index: driver-specific numerical identifier of the port
9661 * Register devlink port with provided port index. User can use
9662 * any indexing, even hw-related one. devlink_port structure
9663 * is convenient to be embedded inside user driver private structure.
9664 * Note that the caller should take care of zeroing the devlink_port
9667 int devl_port_register(struct devlink *devlink,
9668 struct devlink_port *devlink_port,
9669 unsigned int port_index)
9673 devl_assert_locked(devlink);
9675 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9677 devlink_port_init(devlink, devlink_port);
9678 devlink_port->registered = true;
9679 devlink_port->index = port_index;
9680 spin_lock_init(&devlink_port->type_lock);
9681 INIT_LIST_HEAD(&devlink_port->reporter_list);
9682 mutex_init(&devlink_port->reporters_lock);
9683 err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL);
9685 mutex_destroy(&devlink_port->reporters_lock);
9689 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
9690 devlink_port_type_warn_schedule(devlink_port);
9691 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9694 EXPORT_SYMBOL_GPL(devl_port_register);
9697 * devlink_port_register - Register devlink port
9700 * @devlink_port: devlink port
9701 * @port_index: driver-specific numerical identifier of the port
9703 * Register devlink port with provided port index. User can use
9704 * any indexing, even hw-related one. devlink_port structure
9705 * is convenient to be embedded inside user driver private structure.
9706 * Note that the caller should take care of zeroing the devlink_port
9709 * Context: Takes and release devlink->lock <mutex>.
9711 int devlink_port_register(struct devlink *devlink,
9712 struct devlink_port *devlink_port,
9713 unsigned int port_index)
9718 err = devl_port_register(devlink, devlink_port, port_index);
9719 devl_unlock(devlink);
9722 EXPORT_SYMBOL_GPL(devlink_port_register);
9725 * devl_port_unregister() - Unregister devlink port
9727 * @devlink_port: devlink port
9729 void devl_port_unregister(struct devlink_port *devlink_port)
9731 lockdep_assert_held(&devlink_port->devlink->lock);
9732 WARN_ON(devlink_port->type != DEVLINK_PORT_TYPE_NOTSET);
9734 devlink_port_type_warn_cancel(devlink_port);
9735 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9736 xa_erase(&devlink_port->devlink->ports, devlink_port->index);
9737 WARN_ON(!list_empty(&devlink_port->reporter_list));
9738 mutex_destroy(&devlink_port->reporters_lock);
9739 devlink_port->registered = false;
9741 EXPORT_SYMBOL_GPL(devl_port_unregister);
9744 * devlink_port_unregister - Unregister devlink port
9746 * @devlink_port: devlink port
9748 * Context: Takes and release devlink->lock <mutex>.
9750 void devlink_port_unregister(struct devlink_port *devlink_port)
9752 struct devlink *devlink = devlink_port->devlink;
9755 devl_port_unregister(devlink_port);
9756 devl_unlock(devlink);
9758 EXPORT_SYMBOL_GPL(devlink_port_unregister);
9760 static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
9761 struct net_device *netdev)
9763 const struct net_device_ops *ops = netdev->netdev_ops;
9765 /* If driver registers devlink port, it should set devlink port
9766 * attributes accordingly so the compat functions are called
9767 * and the original ops are not used.
9769 if (ops->ndo_get_phys_port_name) {
9770 /* Some drivers use the same set of ndos for netdevs
9771 * that have devlink_port registered and also for
9772 * those who don't. Make sure that ndo_get_phys_port_name
9773 * returns -EOPNOTSUPP here in case it is defined.
9776 char name[IFNAMSIZ];
9779 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
9780 WARN_ON(err != -EOPNOTSUPP);
9782 if (ops->ndo_get_port_parent_id) {
9783 /* Some drivers use the same set of ndos for netdevs
9784 * that have devlink_port registered and also for
9785 * those who don't. Make sure that ndo_get_port_parent_id
9786 * returns -EOPNOTSUPP here in case it is defined.
9789 struct netdev_phys_item_id ppid;
9792 err = ops->ndo_get_port_parent_id(netdev, &ppid);
9793 WARN_ON(err != -EOPNOTSUPP);
9797 static void __devlink_port_type_set(struct devlink_port *devlink_port,
9798 enum devlink_port_type type,
9801 struct net_device *netdev = type_dev;
9803 ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
9805 if (type == DEVLINK_PORT_TYPE_NOTSET) {
9806 devlink_port_type_warn_schedule(devlink_port);
9808 devlink_port_type_warn_cancel(devlink_port);
9809 if (type == DEVLINK_PORT_TYPE_ETH && netdev)
9810 devlink_port_type_netdev_checks(devlink_port, netdev);
9813 spin_lock_bh(&devlink_port->type_lock);
9814 devlink_port->type = type;
9816 case DEVLINK_PORT_TYPE_ETH:
9817 devlink_port->type_eth.netdev = netdev;
9820 devlink_port->type_eth.ifindex = netdev->ifindex;
9821 BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) !=
9822 sizeof(netdev->name));
9823 strcpy(devlink_port->type_eth.ifname, netdev->name);
9826 case DEVLINK_PORT_TYPE_IB:
9827 devlink_port->type_ib.ibdev = type_dev;
9832 spin_unlock_bh(&devlink_port->type_lock);
9833 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9837 * devlink_port_type_eth_set - Set port type to Ethernet
9839 * @devlink_port: devlink port
9841 * If driver is calling this, most likely it is doing something wrong.
9843 void devlink_port_type_eth_set(struct devlink_port *devlink_port)
9845 dev_warn(devlink_port->devlink->dev,
9846 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
9847 devlink_port->index);
9848 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
9850 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
9853 * devlink_port_type_ib_set - Set port type to InfiniBand
9855 * @devlink_port: devlink port
9856 * @ibdev: related IB device
9858 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
9859 struct ib_device *ibdev)
9861 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
9863 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
9866 * devlink_port_type_clear - Clear port type
9868 * @devlink_port: devlink port
9870 * If driver is calling this for clearing Ethernet type, most likely
9871 * it is doing something wrong.
9873 void devlink_port_type_clear(struct devlink_port *devlink_port)
9875 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH)
9876 dev_warn(devlink_port->devlink->dev,
9877 "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
9878 devlink_port->index);
9879 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
9881 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
9883 int devlink_port_netdevice_event(struct notifier_block *nb,
9884 unsigned long event, void *ptr)
9886 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
9887 struct devlink_port *devlink_port = netdev->devlink_port;
9888 struct devlink *devlink;
9890 devlink = container_of(nb, struct devlink, netdevice_nb);
9892 if (!devlink_port || devlink_port->devlink != devlink)
9896 case NETDEV_POST_INIT:
9897 /* Set the type but not netdev pointer. It is going to be set
9898 * later on by NETDEV_REGISTER event. Happens once during
9899 * netdevice register
9901 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH,
9904 case NETDEV_REGISTER:
9905 case NETDEV_CHANGENAME:
9906 /* Set the netdev on top of previously set type. Note this
9907 * event happens also during net namespace change so here
9908 * we take into account netdev pointer appearing in this
9911 __devlink_port_type_set(devlink_port, devlink_port->type,
9914 case NETDEV_UNREGISTER:
9915 /* Clear netdev pointer, but not the type. This event happens
9916 * also during net namespace change so we need to clear
9917 * pointer to netdev that is going to another net namespace.
9919 __devlink_port_type_set(devlink_port, devlink_port->type,
9922 case NETDEV_PRE_UNINIT:
9923 /* Clear the type and the netdev pointer. Happens one during
9924 * netdevice unregister.
9926 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET,
9934 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
9935 enum devlink_port_flavour flavour)
9937 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9939 devlink_port->attrs_set = true;
9940 attrs->flavour = flavour;
9941 if (attrs->switch_id.id_len) {
9942 devlink_port->switch_port = true;
9943 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
9944 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
9946 devlink_port->switch_port = false;
9952 * devlink_port_attrs_set - Set port attributes
9954 * @devlink_port: devlink port
9955 * @attrs: devlink port attrs
9957 void devlink_port_attrs_set(struct devlink_port *devlink_port,
9958 struct devlink_port_attrs *attrs)
9962 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9964 devlink_port->attrs = *attrs;
9965 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
9968 WARN_ON(attrs->splittable && attrs->split);
9970 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
9973 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
9975 * @devlink_port: devlink port
9976 * @controller: associated controller number for the devlink port instance
9977 * @pf: associated PF for the devlink port instance
9978 * @external: indicates if the port is for an external controller
9980 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
9981 u16 pf, bool external)
9983 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9986 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9988 ret = __devlink_port_attrs_set(devlink_port,
9989 DEVLINK_PORT_FLAVOUR_PCI_PF);
9992 attrs->pci_pf.controller = controller;
9993 attrs->pci_pf.pf = pf;
9994 attrs->pci_pf.external = external;
9996 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
9999 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
10001 * @devlink_port: devlink port
10002 * @controller: associated controller number for the devlink port instance
10003 * @pf: associated PF for the devlink port instance
10004 * @vf: associated VF of a PF for the devlink port instance
10005 * @external: indicates if the port is for an external controller
10007 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
10008 u16 pf, u16 vf, bool external)
10010 struct devlink_port_attrs *attrs = &devlink_port->attrs;
10013 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10015 ret = __devlink_port_attrs_set(devlink_port,
10016 DEVLINK_PORT_FLAVOUR_PCI_VF);
10019 attrs->pci_vf.controller = controller;
10020 attrs->pci_vf.pf = pf;
10021 attrs->pci_vf.vf = vf;
10022 attrs->pci_vf.external = external;
10024 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
10027 * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
10029 * @devlink_port: devlink port
10030 * @controller: associated controller number for the devlink port instance
10031 * @pf: associated PF for the devlink port instance
10032 * @sf: associated SF of a PF for the devlink port instance
10033 * @external: indicates if the port is for an external controller
10035 void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
10036 u16 pf, u32 sf, bool external)
10038 struct devlink_port_attrs *attrs = &devlink_port->attrs;
10041 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10043 ret = __devlink_port_attrs_set(devlink_port,
10044 DEVLINK_PORT_FLAVOUR_PCI_SF);
10047 attrs->pci_sf.controller = controller;
10048 attrs->pci_sf.pf = pf;
10049 attrs->pci_sf.sf = sf;
10050 attrs->pci_sf.external = external;
10052 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
10055 * devl_rate_node_create - create devlink rate node
10056 * @devlink: devlink instance
10057 * @priv: driver private data
10058 * @node_name: name of the resulting node
10059 * @parent: parent devlink_rate struct
10061 * Create devlink rate object of type node
10063 struct devlink_rate *
10064 devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
10065 struct devlink_rate *parent)
10067 struct devlink_rate *rate_node;
10069 rate_node = devlink_rate_node_get_by_name(devlink, node_name);
10070 if (!IS_ERR(rate_node))
10071 return ERR_PTR(-EEXIST);
10073 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
10075 return ERR_PTR(-ENOMEM);
10078 rate_node->parent = parent;
10079 refcount_inc(&rate_node->parent->refcnt);
10082 rate_node->type = DEVLINK_RATE_TYPE_NODE;
10083 rate_node->devlink = devlink;
10084 rate_node->priv = priv;
10086 rate_node->name = kstrdup(node_name, GFP_KERNEL);
10087 if (!rate_node->name) {
10089 return ERR_PTR(-ENOMEM);
10092 refcount_set(&rate_node->refcnt, 1);
10093 list_add(&rate_node->list, &devlink->rate_list);
10094 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
10097 EXPORT_SYMBOL_GPL(devl_rate_node_create);
10100 * devl_rate_leaf_create - create devlink rate leaf
10101 * @devlink_port: devlink port object to create rate object on
10102 * @priv: driver private data
10103 * @parent: parent devlink_rate struct
10105 * Create devlink rate object of type leaf on provided @devlink_port.
10107 int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
10108 struct devlink_rate *parent)
10110 struct devlink *devlink = devlink_port->devlink;
10111 struct devlink_rate *devlink_rate;
10113 devl_assert_locked(devlink_port->devlink);
10115 if (WARN_ON(devlink_port->devlink_rate))
10118 devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
10123 devlink_rate->parent = parent;
10124 refcount_inc(&devlink_rate->parent->refcnt);
10127 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
10128 devlink_rate->devlink = devlink;
10129 devlink_rate->devlink_port = devlink_port;
10130 devlink_rate->priv = priv;
10131 list_add_tail(&devlink_rate->list, &devlink->rate_list);
10132 devlink_port->devlink_rate = devlink_rate;
10133 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
10137 EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
10140 * devl_rate_leaf_destroy - destroy devlink rate leaf
10142 * @devlink_port: devlink port linked to the rate object
10144 * Destroy the devlink rate object of type leaf on provided @devlink_port.
10146 void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
10148 struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
10150 devl_assert_locked(devlink_port->devlink);
10154 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
10155 if (devlink_rate->parent)
10156 refcount_dec(&devlink_rate->parent->refcnt);
10157 list_del(&devlink_rate->list);
10158 devlink_port->devlink_rate = NULL;
10159 kfree(devlink_rate);
10161 EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
10164 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
10165 * @devlink: devlink instance
10167 * Unset parent for all rate objects and destroy all rate nodes
10168 * on specified device.
10170 void devl_rate_nodes_destroy(struct devlink *devlink)
10172 static struct devlink_rate *devlink_rate, *tmp;
10173 const struct devlink_ops *ops = devlink->ops;
10175 devl_assert_locked(devlink);
10177 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
10178 if (!devlink_rate->parent)
10181 refcount_dec(&devlink_rate->parent->refcnt);
10182 if (devlink_rate_is_leaf(devlink_rate))
10183 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
10185 else if (devlink_rate_is_node(devlink_rate))
10186 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
10189 list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
10190 if (devlink_rate_is_node(devlink_rate)) {
10191 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
10192 list_del(&devlink_rate->list);
10193 kfree(devlink_rate->name);
10194 kfree(devlink_rate);
10198 EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
10201 * devlink_port_linecard_set - Link port with a linecard
10203 * @devlink_port: devlink port
10204 * @linecard: devlink linecard
10206 void devlink_port_linecard_set(struct devlink_port *devlink_port,
10207 struct devlink_linecard *linecard)
10209 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10211 devlink_port->linecard = linecard;
10213 EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
10215 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
10216 char *name, size_t len)
10218 struct devlink_port_attrs *attrs = &devlink_port->attrs;
10221 if (!devlink_port->attrs_set)
10222 return -EOPNOTSUPP;
10224 switch (attrs->flavour) {
10225 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
10226 if (devlink_port->linecard)
10227 n = snprintf(name, len, "l%u",
10228 devlink_port->linecard->index);
10230 n += snprintf(name + n, len - n, "p%u",
10231 attrs->phys.port_number);
10232 if (n < len && attrs->split)
10233 n += snprintf(name + n, len - n, "s%u",
10234 attrs->phys.split_subport_number);
10236 case DEVLINK_PORT_FLAVOUR_CPU:
10237 case DEVLINK_PORT_FLAVOUR_DSA:
10238 case DEVLINK_PORT_FLAVOUR_UNUSED:
10239 /* As CPU and DSA ports do not have a netdevice associated
10240 * case should not ever happen.
10244 case DEVLINK_PORT_FLAVOUR_PCI_PF:
10245 if (attrs->pci_pf.external) {
10246 n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
10252 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
10254 case DEVLINK_PORT_FLAVOUR_PCI_VF:
10255 if (attrs->pci_vf.external) {
10256 n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
10262 n = snprintf(name, len, "pf%uvf%u",
10263 attrs->pci_vf.pf, attrs->pci_vf.vf);
10265 case DEVLINK_PORT_FLAVOUR_PCI_SF:
10266 if (attrs->pci_sf.external) {
10267 n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
10273 n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
10276 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
10277 return -EOPNOTSUPP;
10286 static int devlink_linecard_types_init(struct devlink_linecard *linecard)
10288 struct devlink_linecard_type *linecard_type;
10289 unsigned int count;
10292 count = linecard->ops->types_count(linecard, linecard->priv);
10293 linecard->types = kmalloc_array(count, sizeof(*linecard_type),
10295 if (!linecard->types)
10297 linecard->types_count = count;
10299 for (i = 0; i < count; i++) {
10300 linecard_type = &linecard->types[i];
10301 linecard->ops->types_get(linecard, linecard->priv, i,
10302 &linecard_type->type,
10303 &linecard_type->priv);
10308 static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
10310 kfree(linecard->types);
10314 * devlink_linecard_create - Create devlink linecard
10316 * @devlink: devlink
10317 * @linecard_index: driver-specific numerical identifier of the linecard
10318 * @ops: linecards ops
10319 * @priv: user priv pointer
10321 * Create devlink linecard instance with provided linecard index.
10322 * Caller can use any indexing, even hw-related one.
10324 * Return: Line card structure or an ERR_PTR() encoded error code.
10326 struct devlink_linecard *
10327 devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
10328 const struct devlink_linecard_ops *ops, void *priv)
10330 struct devlink_linecard *linecard;
10333 if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
10334 !ops->types_count || !ops->types_get))
10335 return ERR_PTR(-EINVAL);
10337 mutex_lock(&devlink->linecards_lock);
10338 if (devlink_linecard_index_exists(devlink, linecard_index)) {
10339 mutex_unlock(&devlink->linecards_lock);
10340 return ERR_PTR(-EEXIST);
10343 linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
10345 mutex_unlock(&devlink->linecards_lock);
10346 return ERR_PTR(-ENOMEM);
10349 linecard->devlink = devlink;
10350 linecard->index = linecard_index;
10351 linecard->ops = ops;
10352 linecard->priv = priv;
10353 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10354 mutex_init(&linecard->state_lock);
10356 err = devlink_linecard_types_init(linecard);
10358 mutex_destroy(&linecard->state_lock);
10360 mutex_unlock(&devlink->linecards_lock);
10361 return ERR_PTR(err);
10364 list_add_tail(&linecard->list, &devlink->linecard_list);
10365 refcount_set(&linecard->refcount, 1);
10366 mutex_unlock(&devlink->linecards_lock);
10367 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10370 EXPORT_SYMBOL_GPL(devlink_linecard_create);
10373 * devlink_linecard_destroy - Destroy devlink linecard
10375 * @linecard: devlink linecard
10377 void devlink_linecard_destroy(struct devlink_linecard *linecard)
10379 struct devlink *devlink = linecard->devlink;
10381 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
10382 mutex_lock(&devlink->linecards_lock);
10383 list_del(&linecard->list);
10384 devlink_linecard_types_fini(linecard);
10385 mutex_unlock(&devlink->linecards_lock);
10386 devlink_linecard_put(linecard);
10388 EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
10391 * devlink_linecard_provision_set - Set provisioning on linecard
10393 * @linecard: devlink linecard
10394 * @type: linecard type
10396 * This is either called directly from the provision() op call or
10397 * as a result of the provision() op call asynchronously.
10399 void devlink_linecard_provision_set(struct devlink_linecard *linecard,
10402 mutex_lock(&linecard->state_lock);
10403 WARN_ON(linecard->type && strcmp(linecard->type, type));
10404 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10405 linecard->type = type;
10406 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10407 mutex_unlock(&linecard->state_lock);
10409 EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
10412 * devlink_linecard_provision_clear - Clear provisioning on linecard
10414 * @linecard: devlink linecard
10416 * This is either called directly from the unprovision() op call or
10417 * as a result of the unprovision() op call asynchronously.
10419 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
10421 mutex_lock(&linecard->state_lock);
10422 WARN_ON(linecard->nested_devlink);
10423 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10424 linecard->type = NULL;
10425 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10426 mutex_unlock(&linecard->state_lock);
10428 EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
10431 * devlink_linecard_provision_fail - Fail provisioning on linecard
10433 * @linecard: devlink linecard
10435 * This is either called directly from the provision() op call or
10436 * as a result of the provision() op call asynchronously.
10438 void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
10440 mutex_lock(&linecard->state_lock);
10441 WARN_ON(linecard->nested_devlink);
10442 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
10443 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10444 mutex_unlock(&linecard->state_lock);
10446 EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
10449 * devlink_linecard_activate - Set linecard active
10451 * @linecard: devlink linecard
10453 void devlink_linecard_activate(struct devlink_linecard *linecard)
10455 mutex_lock(&linecard->state_lock);
10456 WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
10457 linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
10458 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10459 mutex_unlock(&linecard->state_lock);
10461 EXPORT_SYMBOL_GPL(devlink_linecard_activate);
10464 * devlink_linecard_deactivate - Set linecard inactive
10466 * @linecard: devlink linecard
10468 void devlink_linecard_deactivate(struct devlink_linecard *linecard)
10470 mutex_lock(&linecard->state_lock);
10471 switch (linecard->state) {
10472 case DEVLINK_LINECARD_STATE_ACTIVE:
10473 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10474 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10476 case DEVLINK_LINECARD_STATE_UNPROVISIONING:
10477 /* Line card is being deactivated as part
10478 * of unprovisioning flow.
10485 mutex_unlock(&linecard->state_lock);
10487 EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
10490 * devlink_linecard_nested_dl_set - Attach/detach nested devlink
10491 * instance to linecard.
10493 * @linecard: devlink linecard
10494 * @nested_devlink: devlink instance to attach or NULL to detach
10496 void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
10497 struct devlink *nested_devlink)
10499 mutex_lock(&linecard->state_lock);
10500 linecard->nested_devlink = nested_devlink;
10501 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10502 mutex_unlock(&linecard->state_lock);
10504 EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
10506 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
10507 u32 size, u16 ingress_pools_count,
10508 u16 egress_pools_count, u16 ingress_tc_count,
10509 u16 egress_tc_count)
10511 struct devlink_sb *devlink_sb;
10513 lockdep_assert_held(&devlink->lock);
10515 if (devlink_sb_index_exists(devlink, sb_index))
10518 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
10521 devlink_sb->index = sb_index;
10522 devlink_sb->size = size;
10523 devlink_sb->ingress_pools_count = ingress_pools_count;
10524 devlink_sb->egress_pools_count = egress_pools_count;
10525 devlink_sb->ingress_tc_count = ingress_tc_count;
10526 devlink_sb->egress_tc_count = egress_tc_count;
10527 list_add_tail(&devlink_sb->list, &devlink->sb_list);
10530 EXPORT_SYMBOL_GPL(devl_sb_register);
10532 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
10533 u32 size, u16 ingress_pools_count,
10534 u16 egress_pools_count, u16 ingress_tc_count,
10535 u16 egress_tc_count)
10539 devl_lock(devlink);
10540 err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
10541 egress_pools_count, ingress_tc_count,
10543 devl_unlock(devlink);
10546 EXPORT_SYMBOL_GPL(devlink_sb_register);
10548 void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10550 struct devlink_sb *devlink_sb;
10552 lockdep_assert_held(&devlink->lock);
10554 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
10555 WARN_ON(!devlink_sb);
10556 list_del(&devlink_sb->list);
10559 EXPORT_SYMBOL_GPL(devl_sb_unregister);
10561 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10563 devl_lock(devlink);
10564 devl_sb_unregister(devlink, sb_index);
10565 devl_unlock(devlink);
10567 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
10570 * devl_dpipe_headers_register - register dpipe headers
10572 * @devlink: devlink
10573 * @dpipe_headers: dpipe header array
10575 * Register the headers supported by hardware.
10577 void devl_dpipe_headers_register(struct devlink *devlink,
10578 struct devlink_dpipe_headers *dpipe_headers)
10580 lockdep_assert_held(&devlink->lock);
10582 devlink->dpipe_headers = dpipe_headers;
10584 EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
10587 * devl_dpipe_headers_unregister - unregister dpipe headers
10589 * @devlink: devlink
10591 * Unregister the headers supported by hardware.
10593 void devl_dpipe_headers_unregister(struct devlink *devlink)
10595 lockdep_assert_held(&devlink->lock);
10597 devlink->dpipe_headers = NULL;
10599 EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
10602 * devlink_dpipe_table_counter_enabled - check if counter allocation
10604 * @devlink: devlink
10605 * @table_name: tables name
10607 * Used by driver to check if counter allocation is required.
10608 * After counter allocation is turned on the table entries
10609 * are updated to include counter statistics.
10611 * After that point on the driver must respect the counter
10612 * state so that each entry added to the table is added
10615 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
10616 const char *table_name)
10618 struct devlink_dpipe_table *table;
10622 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10623 table_name, devlink);
10626 enabled = table->counters_enabled;
10630 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
10633 * devl_dpipe_table_register - register dpipe table
10635 * @devlink: devlink
10636 * @table_name: table name
10637 * @table_ops: table ops
10639 * @counter_control_extern: external control for counters
10641 int devl_dpipe_table_register(struct devlink *devlink,
10642 const char *table_name,
10643 struct devlink_dpipe_table_ops *table_ops,
10644 void *priv, bool counter_control_extern)
10646 struct devlink_dpipe_table *table;
10648 lockdep_assert_held(&devlink->lock);
10650 if (WARN_ON(!table_ops->size_get))
10653 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
10657 table = kzalloc(sizeof(*table), GFP_KERNEL);
10661 table->name = table_name;
10662 table->table_ops = table_ops;
10663 table->priv = priv;
10664 table->counter_control_extern = counter_control_extern;
10666 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
10670 EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
10673 * devl_dpipe_table_unregister - unregister dpipe table
10675 * @devlink: devlink
10676 * @table_name: table name
10678 void devl_dpipe_table_unregister(struct devlink *devlink,
10679 const char *table_name)
10681 struct devlink_dpipe_table *table;
10683 lockdep_assert_held(&devlink->lock);
10685 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10686 table_name, devlink);
10689 list_del_rcu(&table->list);
10690 kfree_rcu(table, rcu);
10692 EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
10695 * devl_resource_register - devlink resource register
10697 * @devlink: devlink
10698 * @resource_name: resource's name
10699 * @resource_size: resource's size
10700 * @resource_id: resource's id
10701 * @parent_resource_id: resource's parent id
10702 * @size_params: size parameters
10704 * Generic resources should reuse the same names across drivers.
10705 * Please see the generic resources list at:
10706 * Documentation/networking/devlink/devlink-resource.rst
10708 int devl_resource_register(struct devlink *devlink,
10709 const char *resource_name,
10712 u64 parent_resource_id,
10713 const struct devlink_resource_size_params *size_params)
10715 struct devlink_resource *resource;
10716 struct list_head *resource_list;
10717 bool top_hierarchy;
10719 lockdep_assert_held(&devlink->lock);
10721 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
10723 resource = devlink_resource_find(devlink, NULL, resource_id);
10727 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
10731 if (top_hierarchy) {
10732 resource_list = &devlink->resource_list;
10734 struct devlink_resource *parent_resource;
10736 parent_resource = devlink_resource_find(devlink, NULL,
10737 parent_resource_id);
10738 if (parent_resource) {
10739 resource_list = &parent_resource->resource_list;
10740 resource->parent = parent_resource;
10747 resource->name = resource_name;
10748 resource->size = resource_size;
10749 resource->size_new = resource_size;
10750 resource->id = resource_id;
10751 resource->size_valid = true;
10752 memcpy(&resource->size_params, size_params,
10753 sizeof(resource->size_params));
10754 INIT_LIST_HEAD(&resource->resource_list);
10755 list_add_tail(&resource->list, resource_list);
10759 EXPORT_SYMBOL_GPL(devl_resource_register);
10762 * devlink_resource_register - devlink resource register
10764 * @devlink: devlink
10765 * @resource_name: resource's name
10766 * @resource_size: resource's size
10767 * @resource_id: resource's id
10768 * @parent_resource_id: resource's parent id
10769 * @size_params: size parameters
10771 * Generic resources should reuse the same names across drivers.
10772 * Please see the generic resources list at:
10773 * Documentation/networking/devlink/devlink-resource.rst
10775 * Context: Takes and release devlink->lock <mutex>.
10777 int devlink_resource_register(struct devlink *devlink,
10778 const char *resource_name,
10781 u64 parent_resource_id,
10782 const struct devlink_resource_size_params *size_params)
10786 devl_lock(devlink);
10787 err = devl_resource_register(devlink, resource_name, resource_size,
10788 resource_id, parent_resource_id, size_params);
10789 devl_unlock(devlink);
10792 EXPORT_SYMBOL_GPL(devlink_resource_register);
10794 static void devlink_resource_unregister(struct devlink *devlink,
10795 struct devlink_resource *resource)
10797 struct devlink_resource *tmp, *child_resource;
10799 list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
10801 devlink_resource_unregister(devlink, child_resource);
10802 list_del(&child_resource->list);
10803 kfree(child_resource);
10808 * devl_resources_unregister - free all resources
10810 * @devlink: devlink
10812 void devl_resources_unregister(struct devlink *devlink)
10814 struct devlink_resource *tmp, *child_resource;
10816 lockdep_assert_held(&devlink->lock);
10818 list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
10820 devlink_resource_unregister(devlink, child_resource);
10821 list_del(&child_resource->list);
10822 kfree(child_resource);
10825 EXPORT_SYMBOL_GPL(devl_resources_unregister);
10828 * devlink_resources_unregister - free all resources
10830 * @devlink: devlink
10832 * Context: Takes and release devlink->lock <mutex>.
10834 void devlink_resources_unregister(struct devlink *devlink)
10836 devl_lock(devlink);
10837 devl_resources_unregister(devlink);
10838 devl_unlock(devlink);
10840 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
10843 * devl_resource_size_get - get and update size
10845 * @devlink: devlink
10846 * @resource_id: the requested resource id
10847 * @p_resource_size: ptr to update
10849 int devl_resource_size_get(struct devlink *devlink,
10851 u64 *p_resource_size)
10853 struct devlink_resource *resource;
10855 lockdep_assert_held(&devlink->lock);
10857 resource = devlink_resource_find(devlink, NULL, resource_id);
10860 *p_resource_size = resource->size_new;
10861 resource->size = resource->size_new;
10864 EXPORT_SYMBOL_GPL(devl_resource_size_get);
10867 * devl_dpipe_table_resource_set - set the resource id
10869 * @devlink: devlink
10870 * @table_name: table name
10871 * @resource_id: resource id
10872 * @resource_units: number of resource's units consumed per table's entry
10874 int devl_dpipe_table_resource_set(struct devlink *devlink,
10875 const char *table_name, u64 resource_id,
10876 u64 resource_units)
10878 struct devlink_dpipe_table *table;
10880 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10881 table_name, devlink);
10885 table->resource_id = resource_id;
10886 table->resource_units = resource_units;
10887 table->resource_valid = true;
10890 EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
10893 * devl_resource_occ_get_register - register occupancy getter
10895 * @devlink: devlink
10896 * @resource_id: resource id
10897 * @occ_get: occupancy getter callback
10898 * @occ_get_priv: occupancy getter callback priv
10900 void devl_resource_occ_get_register(struct devlink *devlink,
10902 devlink_resource_occ_get_t *occ_get,
10903 void *occ_get_priv)
10905 struct devlink_resource *resource;
10907 lockdep_assert_held(&devlink->lock);
10909 resource = devlink_resource_find(devlink, NULL, resource_id);
10910 if (WARN_ON(!resource))
10912 WARN_ON(resource->occ_get);
10914 resource->occ_get = occ_get;
10915 resource->occ_get_priv = occ_get_priv;
10917 EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
10920 * devlink_resource_occ_get_register - register occupancy getter
10922 * @devlink: devlink
10923 * @resource_id: resource id
10924 * @occ_get: occupancy getter callback
10925 * @occ_get_priv: occupancy getter callback priv
10927 * Context: Takes and release devlink->lock <mutex>.
10929 void devlink_resource_occ_get_register(struct devlink *devlink,
10931 devlink_resource_occ_get_t *occ_get,
10932 void *occ_get_priv)
10934 devl_lock(devlink);
10935 devl_resource_occ_get_register(devlink, resource_id,
10936 occ_get, occ_get_priv);
10937 devl_unlock(devlink);
10939 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
10942 * devl_resource_occ_get_unregister - unregister occupancy getter
10944 * @devlink: devlink
10945 * @resource_id: resource id
10947 void devl_resource_occ_get_unregister(struct devlink *devlink,
10950 struct devlink_resource *resource;
10952 lockdep_assert_held(&devlink->lock);
10954 resource = devlink_resource_find(devlink, NULL, resource_id);
10955 if (WARN_ON(!resource))
10957 WARN_ON(!resource->occ_get);
10959 resource->occ_get = NULL;
10960 resource->occ_get_priv = NULL;
10962 EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
10965 * devlink_resource_occ_get_unregister - unregister occupancy getter
10967 * @devlink: devlink
10968 * @resource_id: resource id
10970 * Context: Takes and release devlink->lock <mutex>.
10972 void devlink_resource_occ_get_unregister(struct devlink *devlink,
10975 devl_lock(devlink);
10976 devl_resource_occ_get_unregister(devlink, resource_id);
10977 devl_unlock(devlink);
10979 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
10981 static int devlink_param_verify(const struct devlink_param *param)
10983 if (!param || !param->name || !param->supported_cmodes)
10985 if (param->generic)
10986 return devlink_param_generic_verify(param);
10988 return devlink_param_driver_verify(param);
10992 * devlink_params_register - register configuration parameters
10994 * @devlink: devlink
10995 * @params: configuration parameters array
10996 * @params_count: number of parameters provided
10998 * Register the configuration parameters supported by the driver.
11000 int devlink_params_register(struct devlink *devlink,
11001 const struct devlink_param *params,
11002 size_t params_count)
11004 const struct devlink_param *param = params;
11007 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11009 for (i = 0; i < params_count; i++, param++) {
11010 err = devlink_param_register(devlink, param);
11020 for (param--; i > 0; i--, param--)
11021 devlink_param_unregister(devlink, param);
11024 EXPORT_SYMBOL_GPL(devlink_params_register);
11027 * devlink_params_unregister - unregister configuration parameters
11028 * @devlink: devlink
11029 * @params: configuration parameters to unregister
11030 * @params_count: number of parameters provided
11032 void devlink_params_unregister(struct devlink *devlink,
11033 const struct devlink_param *params,
11034 size_t params_count)
11036 const struct devlink_param *param = params;
11039 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11041 for (i = 0; i < params_count; i++, param++)
11042 devlink_param_unregister(devlink, param);
11044 EXPORT_SYMBOL_GPL(devlink_params_unregister);
11047 * devlink_param_register - register one configuration parameter
11049 * @devlink: devlink
11050 * @param: one configuration parameter
11052 * Register the configuration parameter supported by the driver.
11053 * Return: returns 0 on successful registration or error code otherwise.
11055 int devlink_param_register(struct devlink *devlink,
11056 const struct devlink_param *param)
11058 struct devlink_param_item *param_item;
11060 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11062 WARN_ON(devlink_param_verify(param));
11063 WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
11065 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
11066 WARN_ON(param->get || param->set);
11068 WARN_ON(!param->get || !param->set);
11070 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
11074 param_item->param = param;
11076 list_add_tail(¶m_item->list, &devlink->param_list);
11079 EXPORT_SYMBOL_GPL(devlink_param_register);
11082 * devlink_param_unregister - unregister one configuration parameter
11083 * @devlink: devlink
11084 * @param: configuration parameter to unregister
11086 void devlink_param_unregister(struct devlink *devlink,
11087 const struct devlink_param *param)
11089 struct devlink_param_item *param_item;
11091 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11094 devlink_param_find_by_name(&devlink->param_list, param->name);
11095 WARN_ON(!param_item);
11096 list_del(¶m_item->list);
11099 EXPORT_SYMBOL_GPL(devlink_param_unregister);
11102 * devlink_param_driverinit_value_get - get configuration parameter
11103 * value for driver initializing
11105 * @devlink: devlink
11106 * @param_id: parameter ID
11107 * @init_val: value of parameter in driverinit configuration mode
11109 * This function should be used by the driver to get driverinit
11110 * configuration for initialization after reload command.
11112 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
11113 union devlink_param_value *init_val)
11115 struct devlink_param_item *param_item;
11117 if (!devlink_reload_supported(devlink->ops))
11118 return -EOPNOTSUPP;
11120 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11124 if (!param_item->driverinit_value_valid ||
11125 !devlink_param_cmode_is_supported(param_item->param,
11126 DEVLINK_PARAM_CMODE_DRIVERINIT))
11127 return -EOPNOTSUPP;
11129 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
11130 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
11132 *init_val = param_item->driverinit_value;
11136 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
11139 * devlink_param_driverinit_value_set - set value of configuration
11140 * parameter for driverinit
11141 * configuration mode
11143 * @devlink: devlink
11144 * @param_id: parameter ID
11145 * @init_val: value of parameter to set for driverinit configuration mode
11147 * This function should be used by the driver to set driverinit
11148 * configuration mode default value.
11150 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
11151 union devlink_param_value init_val)
11153 struct devlink_param_item *param_item;
11155 ASSERT_DEVLINK_NOT_REGISTERED(devlink);
11157 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11161 if (!devlink_param_cmode_is_supported(param_item->param,
11162 DEVLINK_PARAM_CMODE_DRIVERINIT))
11163 return -EOPNOTSUPP;
11165 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
11166 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
11168 param_item->driverinit_value = init_val;
11169 param_item->driverinit_value_valid = true;
11172 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
11175 * devlink_param_value_changed - notify devlink on a parameter's value
11176 * change. Should be called by the driver
11177 * right after the change.
11179 * @devlink: devlink
11180 * @param_id: parameter ID
11182 * This function should be used by the driver to notify devlink on value
11183 * change, excluding driverinit configuration mode.
11184 * For driverinit configuration mode driver should use the function
11186 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
11188 struct devlink_param_item *param_item;
11190 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11191 WARN_ON(!param_item);
11193 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
11195 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
11198 * devl_region_create - create a new address region
11200 * @devlink: devlink
11201 * @ops: region operations and name
11202 * @region_max_snapshots: Maximum supported number of snapshots for region
11203 * @region_size: size of region
11205 struct devlink_region *devl_region_create(struct devlink *devlink,
11206 const struct devlink_region_ops *ops,
11207 u32 region_max_snapshots,
11210 struct devlink_region *region;
11212 devl_assert_locked(devlink);
11214 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11215 return ERR_PTR(-EINVAL);
11217 if (devlink_region_get_by_name(devlink, ops->name))
11218 return ERR_PTR(-EEXIST);
11220 region = kzalloc(sizeof(*region), GFP_KERNEL);
11222 return ERR_PTR(-ENOMEM);
11224 region->devlink = devlink;
11225 region->max_snapshots = region_max_snapshots;
11227 region->size = region_size;
11228 INIT_LIST_HEAD(®ion->snapshot_list);
11229 mutex_init(®ion->snapshot_lock);
11230 list_add_tail(®ion->list, &devlink->region_list);
11231 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11235 EXPORT_SYMBOL_GPL(devl_region_create);
11238 * devlink_region_create - create a new address region
11240 * @devlink: devlink
11241 * @ops: region operations and name
11242 * @region_max_snapshots: Maximum supported number of snapshots for region
11243 * @region_size: size of region
11245 * Context: Takes and release devlink->lock <mutex>.
11247 struct devlink_region *
11248 devlink_region_create(struct devlink *devlink,
11249 const struct devlink_region_ops *ops,
11250 u32 region_max_snapshots, u64 region_size)
11252 struct devlink_region *region;
11254 devl_lock(devlink);
11255 region = devl_region_create(devlink, ops, region_max_snapshots,
11257 devl_unlock(devlink);
11260 EXPORT_SYMBOL_GPL(devlink_region_create);
11263 * devlink_port_region_create - create a new address region for a port
11265 * @port: devlink port
11266 * @ops: region operations and name
11267 * @region_max_snapshots: Maximum supported number of snapshots for region
11268 * @region_size: size of region
11270 * Context: Takes and release devlink->lock <mutex>.
11272 struct devlink_region *
11273 devlink_port_region_create(struct devlink_port *port,
11274 const struct devlink_port_region_ops *ops,
11275 u32 region_max_snapshots, u64 region_size)
11277 struct devlink *devlink = port->devlink;
11278 struct devlink_region *region;
11281 ASSERT_DEVLINK_PORT_INITIALIZED(port);
11283 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11284 return ERR_PTR(-EINVAL);
11286 devl_lock(devlink);
11288 if (devlink_port_region_get_by_name(port, ops->name)) {
11293 region = kzalloc(sizeof(*region), GFP_KERNEL);
11299 region->devlink = devlink;
11300 region->port = port;
11301 region->max_snapshots = region_max_snapshots;
11302 region->port_ops = ops;
11303 region->size = region_size;
11304 INIT_LIST_HEAD(®ion->snapshot_list);
11305 mutex_init(®ion->snapshot_lock);
11306 list_add_tail(®ion->list, &port->region_list);
11307 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11309 devl_unlock(devlink);
11313 devl_unlock(devlink);
11314 return ERR_PTR(err);
11316 EXPORT_SYMBOL_GPL(devlink_port_region_create);
11319 * devl_region_destroy - destroy address region
11321 * @region: devlink region to destroy
11323 void devl_region_destroy(struct devlink_region *region)
11325 struct devlink *devlink = region->devlink;
11326 struct devlink_snapshot *snapshot, *ts;
11328 devl_assert_locked(devlink);
11330 /* Free all snapshots of region */
11331 mutex_lock(®ion->snapshot_lock);
11332 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
11333 devlink_region_snapshot_del(region, snapshot);
11334 mutex_unlock(®ion->snapshot_lock);
11336 list_del(®ion->list);
11337 mutex_destroy(®ion->snapshot_lock);
11339 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
11342 EXPORT_SYMBOL_GPL(devl_region_destroy);
11345 * devlink_region_destroy - destroy address region
11347 * @region: devlink region to destroy
11349 * Context: Takes and release devlink->lock <mutex>.
11351 void devlink_region_destroy(struct devlink_region *region)
11353 struct devlink *devlink = region->devlink;
11355 devl_lock(devlink);
11356 devl_region_destroy(region);
11357 devl_unlock(devlink);
11359 EXPORT_SYMBOL_GPL(devlink_region_destroy);
11362 * devlink_region_snapshot_id_get - get snapshot ID
11364 * This callback should be called when adding a new snapshot,
11365 * Driver should use the same id for multiple snapshots taken
11366 * on multiple regions at the same time/by the same trigger.
11368 * The caller of this function must use devlink_region_snapshot_id_put
11369 * when finished creating regions using this id.
11371 * Returns zero on success, or a negative error code on failure.
11373 * @devlink: devlink
11374 * @id: storage to return id
11376 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
11378 return __devlink_region_snapshot_id_get(devlink, id);
11380 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
11383 * devlink_region_snapshot_id_put - put snapshot ID reference
11385 * This should be called by a driver after finishing creating snapshots
11386 * with an id. Doing so ensures that the ID can later be released in the
11387 * event that all snapshots using it have been destroyed.
11389 * @devlink: devlink
11390 * @id: id to release reference on
11392 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
11394 __devlink_snapshot_id_decrement(devlink, id);
11396 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
11399 * devlink_region_snapshot_create - create a new snapshot
11400 * This will add a new snapshot of a region. The snapshot
11401 * will be stored on the region struct and can be accessed
11402 * from devlink. This is useful for future analyses of snapshots.
11403 * Multiple snapshots can be created on a region.
11404 * The @snapshot_id should be obtained using the getter function.
11406 * @region: devlink region of the snapshot
11407 * @data: snapshot data
11408 * @snapshot_id: snapshot id to be created
11410 int devlink_region_snapshot_create(struct devlink_region *region,
11411 u8 *data, u32 snapshot_id)
11415 mutex_lock(®ion->snapshot_lock);
11416 err = __devlink_region_snapshot_create(region, data, snapshot_id);
11417 mutex_unlock(®ion->snapshot_lock);
11420 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
11422 #define DEVLINK_TRAP(_id, _type) \
11424 .type = DEVLINK_TRAP_TYPE_##_type, \
11425 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
11426 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
11429 static const struct devlink_trap devlink_trap_generic[] = {
11430 DEVLINK_TRAP(SMAC_MC, DROP),
11431 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
11432 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
11433 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
11434 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
11435 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
11436 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
11437 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
11438 DEVLINK_TRAP(TAIL_DROP, DROP),
11439 DEVLINK_TRAP(NON_IP_PACKET, DROP),
11440 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
11441 DEVLINK_TRAP(DIP_LB, DROP),
11442 DEVLINK_TRAP(SIP_MC, DROP),
11443 DEVLINK_TRAP(SIP_LB, DROP),
11444 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
11445 DEVLINK_TRAP(IPV4_SIP_BC, DROP),
11446 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
11447 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
11448 DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
11449 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
11450 DEVLINK_TRAP(RPF, EXCEPTION),
11451 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
11452 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
11453 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
11454 DEVLINK_TRAP(NON_ROUTABLE, DROP),
11455 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
11456 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
11457 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
11458 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
11459 DEVLINK_TRAP(STP, CONTROL),
11460 DEVLINK_TRAP(LACP, CONTROL),
11461 DEVLINK_TRAP(LLDP, CONTROL),
11462 DEVLINK_TRAP(IGMP_QUERY, CONTROL),
11463 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
11464 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
11465 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
11466 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
11467 DEVLINK_TRAP(MLD_QUERY, CONTROL),
11468 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
11469 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
11470 DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
11471 DEVLINK_TRAP(IPV4_DHCP, CONTROL),
11472 DEVLINK_TRAP(IPV6_DHCP, CONTROL),
11473 DEVLINK_TRAP(ARP_REQUEST, CONTROL),
11474 DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
11475 DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
11476 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
11477 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
11478 DEVLINK_TRAP(IPV4_BFD, CONTROL),
11479 DEVLINK_TRAP(IPV6_BFD, CONTROL),
11480 DEVLINK_TRAP(IPV4_OSPF, CONTROL),
11481 DEVLINK_TRAP(IPV6_OSPF, CONTROL),
11482 DEVLINK_TRAP(IPV4_BGP, CONTROL),
11483 DEVLINK_TRAP(IPV6_BGP, CONTROL),
11484 DEVLINK_TRAP(IPV4_VRRP, CONTROL),
11485 DEVLINK_TRAP(IPV6_VRRP, CONTROL),
11486 DEVLINK_TRAP(IPV4_PIM, CONTROL),
11487 DEVLINK_TRAP(IPV6_PIM, CONTROL),
11488 DEVLINK_TRAP(UC_LB, CONTROL),
11489 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
11490 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
11491 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
11492 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
11493 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
11494 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
11495 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
11496 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
11497 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
11498 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
11499 DEVLINK_TRAP(PTP_EVENT, CONTROL),
11500 DEVLINK_TRAP(PTP_GENERAL, CONTROL),
11501 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
11502 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
11503 DEVLINK_TRAP(EARLY_DROP, DROP),
11504 DEVLINK_TRAP(VXLAN_PARSING, DROP),
11505 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
11506 DEVLINK_TRAP(VLAN_PARSING, DROP),
11507 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
11508 DEVLINK_TRAP(MPLS_PARSING, DROP),
11509 DEVLINK_TRAP(ARP_PARSING, DROP),
11510 DEVLINK_TRAP(IP_1_PARSING, DROP),
11511 DEVLINK_TRAP(IP_N_PARSING, DROP),
11512 DEVLINK_TRAP(GRE_PARSING, DROP),
11513 DEVLINK_TRAP(UDP_PARSING, DROP),
11514 DEVLINK_TRAP(TCP_PARSING, DROP),
11515 DEVLINK_TRAP(IPSEC_PARSING, DROP),
11516 DEVLINK_TRAP(SCTP_PARSING, DROP),
11517 DEVLINK_TRAP(DCCP_PARSING, DROP),
11518 DEVLINK_TRAP(GTP_PARSING, DROP),
11519 DEVLINK_TRAP(ESP_PARSING, DROP),
11520 DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
11521 DEVLINK_TRAP(DMAC_FILTER, DROP),
11522 DEVLINK_TRAP(EAPOL, CONTROL),
11523 DEVLINK_TRAP(LOCKED_PORT, DROP),
11526 #define DEVLINK_TRAP_GROUP(_id) \
11528 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
11529 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
11532 static const struct devlink_trap_group devlink_trap_group_generic[] = {
11533 DEVLINK_TRAP_GROUP(L2_DROPS),
11534 DEVLINK_TRAP_GROUP(L3_DROPS),
11535 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
11536 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
11537 DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
11538 DEVLINK_TRAP_GROUP(ACL_DROPS),
11539 DEVLINK_TRAP_GROUP(STP),
11540 DEVLINK_TRAP_GROUP(LACP),
11541 DEVLINK_TRAP_GROUP(LLDP),
11542 DEVLINK_TRAP_GROUP(MC_SNOOPING),
11543 DEVLINK_TRAP_GROUP(DHCP),
11544 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
11545 DEVLINK_TRAP_GROUP(BFD),
11546 DEVLINK_TRAP_GROUP(OSPF),
11547 DEVLINK_TRAP_GROUP(BGP),
11548 DEVLINK_TRAP_GROUP(VRRP),
11549 DEVLINK_TRAP_GROUP(PIM),
11550 DEVLINK_TRAP_GROUP(UC_LB),
11551 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
11552 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
11553 DEVLINK_TRAP_GROUP(IPV6),
11554 DEVLINK_TRAP_GROUP(PTP_EVENT),
11555 DEVLINK_TRAP_GROUP(PTP_GENERAL),
11556 DEVLINK_TRAP_GROUP(ACL_SAMPLE),
11557 DEVLINK_TRAP_GROUP(ACL_TRAP),
11558 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
11559 DEVLINK_TRAP_GROUP(EAPOL),
11562 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
11564 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
11567 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
11570 if (trap->type != devlink_trap_generic[trap->id].type)
11576 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
11580 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
11583 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
11584 if (!strcmp(trap->name, devlink_trap_generic[i].name))
11591 static int devlink_trap_verify(const struct devlink_trap *trap)
11593 if (!trap || !trap->name)
11597 return devlink_trap_generic_verify(trap);
11599 return devlink_trap_driver_verify(trap);
11603 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
11605 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11608 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
11615 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
11619 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11622 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
11623 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
11630 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
11632 if (group->generic)
11633 return devlink_trap_group_generic_verify(group);
11635 return devlink_trap_group_driver_verify(group);
11639 devlink_trap_group_notify(struct devlink *devlink,
11640 const struct devlink_trap_group_item *group_item,
11641 enum devlink_command cmd)
11643 struct sk_buff *msg;
11646 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
11647 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
11648 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11651 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11655 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
11662 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11663 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11667 devlink_trap_item_group_link(struct devlink *devlink,
11668 struct devlink_trap_item *trap_item)
11670 u16 group_id = trap_item->trap->init_group_id;
11671 struct devlink_trap_group_item *group_item;
11673 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
11674 if (WARN_ON_ONCE(!group_item))
11677 trap_item->group_item = group_item;
11682 static void devlink_trap_notify(struct devlink *devlink,
11683 const struct devlink_trap_item *trap_item,
11684 enum devlink_command cmd)
11686 struct sk_buff *msg;
11689 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
11690 cmd != DEVLINK_CMD_TRAP_DEL);
11691 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11694 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11698 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
11704 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11705 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11709 devlink_trap_register(struct devlink *devlink,
11710 const struct devlink_trap *trap, void *priv)
11712 struct devlink_trap_item *trap_item;
11715 if (devlink_trap_item_lookup(devlink, trap->name))
11718 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
11722 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11723 if (!trap_item->stats) {
11725 goto err_stats_alloc;
11728 trap_item->trap = trap;
11729 trap_item->action = trap->init_action;
11730 trap_item->priv = priv;
11732 err = devlink_trap_item_group_link(devlink, trap_item);
11734 goto err_group_link;
11736 err = devlink->ops->trap_init(devlink, trap, trap_item);
11738 goto err_trap_init;
11740 list_add_tail(&trap_item->list, &devlink->trap_list);
11741 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
11747 free_percpu(trap_item->stats);
11753 static void devlink_trap_unregister(struct devlink *devlink,
11754 const struct devlink_trap *trap)
11756 struct devlink_trap_item *trap_item;
11758 trap_item = devlink_trap_item_lookup(devlink, trap->name);
11759 if (WARN_ON_ONCE(!trap_item))
11762 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
11763 list_del(&trap_item->list);
11764 if (devlink->ops->trap_fini)
11765 devlink->ops->trap_fini(devlink, trap, trap_item);
11766 free_percpu(trap_item->stats);
11770 static void devlink_trap_disable(struct devlink *devlink,
11771 const struct devlink_trap *trap)
11773 struct devlink_trap_item *trap_item;
11775 trap_item = devlink_trap_item_lookup(devlink, trap->name);
11776 if (WARN_ON_ONCE(!trap_item))
11779 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
11781 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
11785 * devl_traps_register - Register packet traps with devlink.
11786 * @devlink: devlink.
11787 * @traps: Packet traps.
11788 * @traps_count: Count of provided packet traps.
11789 * @priv: Driver private information.
11791 * Return: Non-zero value on failure.
11793 int devl_traps_register(struct devlink *devlink,
11794 const struct devlink_trap *traps,
11795 size_t traps_count, void *priv)
11799 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
11802 devl_assert_locked(devlink);
11803 for (i = 0; i < traps_count; i++) {
11804 const struct devlink_trap *trap = &traps[i];
11806 err = devlink_trap_verify(trap);
11808 goto err_trap_verify;
11810 err = devlink_trap_register(devlink, trap, priv);
11812 goto err_trap_register;
11819 for (i--; i >= 0; i--)
11820 devlink_trap_unregister(devlink, &traps[i]);
11823 EXPORT_SYMBOL_GPL(devl_traps_register);
11826 * devlink_traps_register - Register packet traps with devlink.
11827 * @devlink: devlink.
11828 * @traps: Packet traps.
11829 * @traps_count: Count of provided packet traps.
11830 * @priv: Driver private information.
11832 * Context: Takes and release devlink->lock <mutex>.
11834 * Return: Non-zero value on failure.
11836 int devlink_traps_register(struct devlink *devlink,
11837 const struct devlink_trap *traps,
11838 size_t traps_count, void *priv)
11842 devl_lock(devlink);
11843 err = devl_traps_register(devlink, traps, traps_count, priv);
11844 devl_unlock(devlink);
11847 EXPORT_SYMBOL_GPL(devlink_traps_register);
11850 * devl_traps_unregister - Unregister packet traps from devlink.
11851 * @devlink: devlink.
11852 * @traps: Packet traps.
11853 * @traps_count: Count of provided packet traps.
11855 void devl_traps_unregister(struct devlink *devlink,
11856 const struct devlink_trap *traps,
11857 size_t traps_count)
11861 devl_assert_locked(devlink);
11862 /* Make sure we do not have any packets in-flight while unregistering
11863 * traps by disabling all of them and waiting for a grace period.
11865 for (i = traps_count - 1; i >= 0; i--)
11866 devlink_trap_disable(devlink, &traps[i]);
11868 for (i = traps_count - 1; i >= 0; i--)
11869 devlink_trap_unregister(devlink, &traps[i]);
11871 EXPORT_SYMBOL_GPL(devl_traps_unregister);
11874 * devlink_traps_unregister - Unregister packet traps from devlink.
11875 * @devlink: devlink.
11876 * @traps: Packet traps.
11877 * @traps_count: Count of provided packet traps.
11879 * Context: Takes and release devlink->lock <mutex>.
11881 void devlink_traps_unregister(struct devlink *devlink,
11882 const struct devlink_trap *traps,
11883 size_t traps_count)
11885 devl_lock(devlink);
11886 devl_traps_unregister(devlink, traps, traps_count);
11887 devl_unlock(devlink);
11889 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
11892 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
11895 struct devlink_stats *stats;
11897 stats = this_cpu_ptr(trap_stats);
11898 u64_stats_update_begin(&stats->syncp);
11899 u64_stats_add(&stats->rx_bytes, skb_len);
11900 u64_stats_inc(&stats->rx_packets);
11901 u64_stats_update_end(&stats->syncp);
11905 devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
11906 const struct devlink_trap_item *trap_item,
11907 struct devlink_port *in_devlink_port,
11908 const struct flow_action_cookie *fa_cookie)
11910 metadata->trap_name = trap_item->trap->name;
11911 metadata->trap_group_name = trap_item->group_item->group->name;
11912 metadata->fa_cookie = fa_cookie;
11913 metadata->trap_type = trap_item->trap->type;
11915 spin_lock(&in_devlink_port->type_lock);
11916 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
11917 metadata->input_dev = in_devlink_port->type_eth.netdev;
11918 spin_unlock(&in_devlink_port->type_lock);
11922 * devlink_trap_report - Report trapped packet to drop monitor.
11923 * @devlink: devlink.
11924 * @skb: Trapped packet.
11925 * @trap_ctx: Trap context.
11926 * @in_devlink_port: Input devlink port.
11927 * @fa_cookie: Flow action cookie. Could be NULL.
11929 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
11930 void *trap_ctx, struct devlink_port *in_devlink_port,
11931 const struct flow_action_cookie *fa_cookie)
11934 struct devlink_trap_item *trap_item = trap_ctx;
11936 devlink_trap_stats_update(trap_item->stats, skb->len);
11937 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
11939 if (trace_devlink_trap_report_enabled()) {
11940 struct devlink_trap_metadata metadata = {};
11942 devlink_trap_report_metadata_set(&metadata, trap_item,
11943 in_devlink_port, fa_cookie);
11944 trace_devlink_trap_report(devlink, skb, &metadata);
11947 EXPORT_SYMBOL_GPL(devlink_trap_report);
11950 * devlink_trap_ctx_priv - Trap context to driver private information.
11951 * @trap_ctx: Trap context.
11953 * Return: Driver private information passed during registration.
11955 void *devlink_trap_ctx_priv(void *trap_ctx)
11957 struct devlink_trap_item *trap_item = trap_ctx;
11959 return trap_item->priv;
11961 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
11964 devlink_trap_group_item_policer_link(struct devlink *devlink,
11965 struct devlink_trap_group_item *group_item)
11967 u32 policer_id = group_item->group->init_policer_id;
11968 struct devlink_trap_policer_item *policer_item;
11970 if (policer_id == 0)
11973 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
11974 if (WARN_ON_ONCE(!policer_item))
11977 group_item->policer_item = policer_item;
11983 devlink_trap_group_register(struct devlink *devlink,
11984 const struct devlink_trap_group *group)
11986 struct devlink_trap_group_item *group_item;
11989 if (devlink_trap_group_item_lookup(devlink, group->name))
11992 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
11996 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11997 if (!group_item->stats) {
11999 goto err_stats_alloc;
12002 group_item->group = group;
12004 err = devlink_trap_group_item_policer_link(devlink, group_item);
12006 goto err_policer_link;
12008 if (devlink->ops->trap_group_init) {
12009 err = devlink->ops->trap_group_init(devlink, group);
12011 goto err_group_init;
12014 list_add_tail(&group_item->list, &devlink->trap_group_list);
12015 devlink_trap_group_notify(devlink, group_item,
12016 DEVLINK_CMD_TRAP_GROUP_NEW);
12022 free_percpu(group_item->stats);
12029 devlink_trap_group_unregister(struct devlink *devlink,
12030 const struct devlink_trap_group *group)
12032 struct devlink_trap_group_item *group_item;
12034 group_item = devlink_trap_group_item_lookup(devlink, group->name);
12035 if (WARN_ON_ONCE(!group_item))
12038 devlink_trap_group_notify(devlink, group_item,
12039 DEVLINK_CMD_TRAP_GROUP_DEL);
12040 list_del(&group_item->list);
12041 free_percpu(group_item->stats);
12046 * devl_trap_groups_register - Register packet trap groups with devlink.
12047 * @devlink: devlink.
12048 * @groups: Packet trap groups.
12049 * @groups_count: Count of provided packet trap groups.
12051 * Return: Non-zero value on failure.
12053 int devl_trap_groups_register(struct devlink *devlink,
12054 const struct devlink_trap_group *groups,
12055 size_t groups_count)
12059 devl_assert_locked(devlink);
12060 for (i = 0; i < groups_count; i++) {
12061 const struct devlink_trap_group *group = &groups[i];
12063 err = devlink_trap_group_verify(group);
12065 goto err_trap_group_verify;
12067 err = devlink_trap_group_register(devlink, group);
12069 goto err_trap_group_register;
12074 err_trap_group_register:
12075 err_trap_group_verify:
12076 for (i--; i >= 0; i--)
12077 devlink_trap_group_unregister(devlink, &groups[i]);
12080 EXPORT_SYMBOL_GPL(devl_trap_groups_register);
12083 * devlink_trap_groups_register - Register packet trap groups with devlink.
12084 * @devlink: devlink.
12085 * @groups: Packet trap groups.
12086 * @groups_count: Count of provided packet trap groups.
12088 * Context: Takes and release devlink->lock <mutex>.
12090 * Return: Non-zero value on failure.
12092 int devlink_trap_groups_register(struct devlink *devlink,
12093 const struct devlink_trap_group *groups,
12094 size_t groups_count)
12098 devl_lock(devlink);
12099 err = devl_trap_groups_register(devlink, groups, groups_count);
12100 devl_unlock(devlink);
12103 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
12106 * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
12107 * @devlink: devlink.
12108 * @groups: Packet trap groups.
12109 * @groups_count: Count of provided packet trap groups.
12111 void devl_trap_groups_unregister(struct devlink *devlink,
12112 const struct devlink_trap_group *groups,
12113 size_t groups_count)
12117 devl_assert_locked(devlink);
12118 for (i = groups_count - 1; i >= 0; i--)
12119 devlink_trap_group_unregister(devlink, &groups[i]);
12121 EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
12124 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
12125 * @devlink: devlink.
12126 * @groups: Packet trap groups.
12127 * @groups_count: Count of provided packet trap groups.
12129 * Context: Takes and release devlink->lock <mutex>.
12131 void devlink_trap_groups_unregister(struct devlink *devlink,
12132 const struct devlink_trap_group *groups,
12133 size_t groups_count)
12135 devl_lock(devlink);
12136 devl_trap_groups_unregister(devlink, groups, groups_count);
12137 devl_unlock(devlink);
12139 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
12142 devlink_trap_policer_notify(struct devlink *devlink,
12143 const struct devlink_trap_policer_item *policer_item,
12144 enum devlink_command cmd)
12146 struct sk_buff *msg;
12149 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
12150 cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
12151 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
12154 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12158 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
12165 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
12166 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
12170 devlink_trap_policer_register(struct devlink *devlink,
12171 const struct devlink_trap_policer *policer)
12173 struct devlink_trap_policer_item *policer_item;
12176 if (devlink_trap_policer_item_lookup(devlink, policer->id))
12179 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
12183 policer_item->policer = policer;
12184 policer_item->rate = policer->init_rate;
12185 policer_item->burst = policer->init_burst;
12187 if (devlink->ops->trap_policer_init) {
12188 err = devlink->ops->trap_policer_init(devlink, policer);
12190 goto err_policer_init;
12193 list_add_tail(&policer_item->list, &devlink->trap_policer_list);
12194 devlink_trap_policer_notify(devlink, policer_item,
12195 DEVLINK_CMD_TRAP_POLICER_NEW);
12200 kfree(policer_item);
12205 devlink_trap_policer_unregister(struct devlink *devlink,
12206 const struct devlink_trap_policer *policer)
12208 struct devlink_trap_policer_item *policer_item;
12210 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
12211 if (WARN_ON_ONCE(!policer_item))
12214 devlink_trap_policer_notify(devlink, policer_item,
12215 DEVLINK_CMD_TRAP_POLICER_DEL);
12216 list_del(&policer_item->list);
12217 if (devlink->ops->trap_policer_fini)
12218 devlink->ops->trap_policer_fini(devlink, policer);
12219 kfree(policer_item);
12223 * devl_trap_policers_register - Register packet trap policers with devlink.
12224 * @devlink: devlink.
12225 * @policers: Packet trap policers.
12226 * @policers_count: Count of provided packet trap policers.
12228 * Return: Non-zero value on failure.
12231 devl_trap_policers_register(struct devlink *devlink,
12232 const struct devlink_trap_policer *policers,
12233 size_t policers_count)
12237 devl_assert_locked(devlink);
12238 for (i = 0; i < policers_count; i++) {
12239 const struct devlink_trap_policer *policer = &policers[i];
12241 if (WARN_ON(policer->id == 0 ||
12242 policer->max_rate < policer->min_rate ||
12243 policer->max_burst < policer->min_burst)) {
12245 goto err_trap_policer_verify;
12248 err = devlink_trap_policer_register(devlink, policer);
12250 goto err_trap_policer_register;
12254 err_trap_policer_register:
12255 err_trap_policer_verify:
12256 for (i--; i >= 0; i--)
12257 devlink_trap_policer_unregister(devlink, &policers[i]);
12260 EXPORT_SYMBOL_GPL(devl_trap_policers_register);
12263 * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
12264 * @devlink: devlink.
12265 * @policers: Packet trap policers.
12266 * @policers_count: Count of provided packet trap policers.
12269 devl_trap_policers_unregister(struct devlink *devlink,
12270 const struct devlink_trap_policer *policers,
12271 size_t policers_count)
12275 devl_assert_locked(devlink);
12276 for (i = policers_count - 1; i >= 0; i--)
12277 devlink_trap_policer_unregister(devlink, &policers[i]);
12279 EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
12281 static void __devlink_compat_running_version(struct devlink *devlink,
12282 char *buf, size_t len)
12284 struct devlink_info_req req = {};
12285 const struct nlattr *nlattr;
12286 struct sk_buff *msg;
12289 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12294 err = devlink->ops->info_get(devlink, &req, NULL);
12298 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
12299 const struct nlattr *kv;
12302 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
12305 nla_for_each_nested(kv, nlattr, rem_kv) {
12306 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
12309 strlcat(buf, nla_data(kv), len);
12310 strlcat(buf, " ", len);
12317 void devlink_compat_running_version(struct devlink *devlink,
12318 char *buf, size_t len)
12320 if (!devlink->ops->info_get)
12323 devl_lock(devlink);
12324 __devlink_compat_running_version(devlink, buf, len);
12325 devl_unlock(devlink);
12328 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name)
12330 struct devlink_flash_update_params params = {};
12333 if (!devlink->ops->flash_update)
12334 return -EOPNOTSUPP;
12336 ret = request_firmware(¶ms.fw, file_name, devlink->dev);
12340 devl_lock(devlink);
12341 devlink_flash_update_begin_notify(devlink);
12342 ret = devlink->ops->flash_update(devlink, ¶ms, NULL);
12343 devlink_flash_update_end_notify(devlink);
12344 devl_unlock(devlink);
12346 release_firmware(params.fw);
12351 int devlink_compat_phys_port_name_get(struct net_device *dev,
12352 char *name, size_t len)
12354 struct devlink_port *devlink_port;
12356 /* RTNL mutex is held here which ensures that devlink_port
12357 * instance cannot disappear in the middle. No need to take
12358 * any devlink lock as only permanent values are accessed.
12362 devlink_port = dev->devlink_port;
12364 return -EOPNOTSUPP;
12366 return __devlink_port_phys_port_name_get(devlink_port, name, len);
12369 int devlink_compat_switch_id_get(struct net_device *dev,
12370 struct netdev_phys_item_id *ppid)
12372 struct devlink_port *devlink_port;
12374 /* Caller must hold RTNL mutex or reference to dev, which ensures that
12375 * devlink_port instance cannot disappear in the middle. No need to take
12376 * any devlink lock as only permanent values are accessed.
12378 devlink_port = dev->devlink_port;
12379 if (!devlink_port || !devlink_port->switch_port)
12380 return -EOPNOTSUPP;
12382 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));